wlcore/wl18xx: mesh: added initial mesh support for wl8
authorMaital Hahn <maitalm@ti.com>
Tue, 28 Jun 2016 10:41:35 +0000 (13:41 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 18 Jul 2016 19:33:26 +0000 (22:33 +0300)
1. Added support for interface and role of mesh type.
2. Enabled enable/start of mesh-point role,
   and opening and closing a connection with a mesh peer.
3. Added multirole combination of mesh and ap
   under the same limits of dual ap mode.
4. Add support for 'sta_rc_update' opcode for mesh IF.
   The 'sta_rc_update' opcode is being used in mesh_plink.c.
Add support in wlcore to handle this opcode correctly for mesh
(as opposed to current implementation that handles STA only).
5. Bumped the firmware version to support new Mesh functionality

Signed-off-by: Maital Hahn <maitalm@ti.com>
Signed-off-by: Yaniv Machani <yanivma@ti.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wl18xx/wl18xx.h
drivers/net/wireless/ti/wlcore/acx.h
drivers/net/wireless/ti/wlcore/boot.c
drivers/net/wireless/ti/wlcore/cmd.c
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/wlcore_i.h

index ae47c79cb9b6c22bd4ba9e7327d97df675ea4e41..4811b74bf939ae285040194f2a2caff7fd553a02 100644 (file)
@@ -1821,9 +1821,12 @@ static const struct ieee80211_iface_limit wl18xx_iface_limits[] = {
        },
        {
                .max = 1,
-               .types = BIT(NL80211_IFTYPE_AP) |
-                        BIT(NL80211_IFTYPE_P2P_GO) |
-                        BIT(NL80211_IFTYPE_P2P_CLIENT),
+               .types =   BIT(NL80211_IFTYPE_AP)
+                        | BIT(NL80211_IFTYPE_P2P_GO)
+                        | BIT(NL80211_IFTYPE_P2P_CLIENT)
+#ifdef CONFIG_MAC80211_MESH
+                        | BIT(NL80211_IFTYPE_MESH_POINT)
+#endif
        },
        {
                .max = 1,
@@ -1836,6 +1839,12 @@ static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = {
                .max = 2,
                .types = BIT(NL80211_IFTYPE_AP),
        },
+#ifdef CONFIG_MAC80211_MESH
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_MESH_POINT),
+       },
+#endif
        {
                .max = 1,
                .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
index 71e9e382ce80881dfbb43ea333e6c2e35158929b..d65cc6dd7dff09084c6ea0da6106d447dcc97eca 100644 (file)
@@ -29,7 +29,7 @@
 #define WL18XX_IFTYPE_VER      9
 #define WL18XX_MAJOR_VER       WLCORE_FW_VER_IGNORE
 #define WL18XX_SUBTYPE_VER     WLCORE_FW_VER_IGNORE
-#define WL18XX_MINOR_VER       11
+#define WL18XX_MINOR_VER       58
 
 #define WL18XX_CMD_MAX_SIZE          740
 
index 0d61fae88dcb811fa53e21b7f73ded8728112297..6321ed47289158f11af77fcc218518cdd70ff868 100644 (file)
@@ -105,6 +105,7 @@ enum wl12xx_role {
        WL1271_ROLE_DEVICE,
        WL1271_ROLE_P2P_CL,
        WL1271_ROLE_P2P_GO,
+       WL1271_ROLE_MESH_POINT,
 
        WL12XX_INVALID_ROLE_TYPE = 0xff
 };
index 19b7ec7b69c21dd12f2355d7fba8c8f8d69b2c8f..f75d3044411719ea10c63200534e25220aeeb311 100644 (file)
@@ -130,7 +130,7 @@ fail:
        wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is invalid.\n"
                     "Please use at least FW %s\n"
                     "You can get the latest firmwares at:\n"
-                    "git://github.com/TI-OpenLink/firmwares.git",
+                    "git://git.ti.com/wilink8-wlan/wl18xx_fw.git",
                     fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE],
                     fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE],
                     fw_ver[FW_VER_MINOR], min_fw_str);
index 5f360cecbb0bf6070777216d0f8b26df2bdb8bb7..7f4da727bb7b6767b2c6ecddd475510ef614f16a 100644 (file)
@@ -629,11 +629,14 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 
        wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id);
 
-       /* trying to use hidden SSID with an old hostapd version */
-       if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) {
-               wl1271_error("got a null SSID from beacon/bss");
-               ret = -EINVAL;
-               goto out;
+       /* If MESH --> ssid_len is always 0 */
+       if (!ieee80211_vif_is_mesh(vif)) {
+               /* trying to use hidden SSID with an old hostapd version */
+               if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) {
+                       wl1271_error("got a null SSID from beacon/bss");
+                       ret = -EINVAL;
+                       goto out;
+               }
        }
 
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
index 9abc15293307bddcfe26486256a6705db1056a8f..4652636e9ecf509ba11c4f47264332892e5f80a3 100644 (file)
@@ -221,6 +221,7 @@ static void wlcore_rc_update_work(struct work_struct *work)
        struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
                                                rc_update_work);
        struct wl1271 *wl = wlvif->wl;
+       struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
 
        mutex_lock(&wl->mutex);
 
@@ -231,8 +232,16 @@ static void wlcore_rc_update_work(struct work_struct *work)
        if (ret < 0)
                goto out;
 
-       wlcore_hw_sta_rc_update(wl, wlvif);
+       if (ieee80211_vif_is_mesh(vif)) {
+               ret = wl1271_acx_set_ht_capabilities(wl, &wlvif->rc_ht_cap,
+                                                    true, wlvif->sta.hlid);
+               if (ret < 0)
+                       goto out_sleep;
+       } else {
+               wlcore_hw_sta_rc_update(wl, wlvif);
+       }
 
+out_sleep:
        wl1271_ps_elp_sleep(wl);
 out:
        mutex_unlock(&wl->mutex);
@@ -2153,10 +2162,14 @@ static void wlcore_free_klv_template(struct wl1271 *wl, u8 *idx)
 
 static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 {
+       struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
+
        switch (wlvif->bss_type) {
        case BSS_TYPE_AP_BSS:
                if (wlvif->p2p)
                        return WL1271_ROLE_P2P_GO;
+               else if (ieee80211_vif_is_mesh(vif))
+                       return WL1271_ROLE_MESH_POINT;
                else
                        return WL1271_ROLE_AP;
 
@@ -2198,6 +2211,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
                wlvif->p2p = 1;
                /* fall-through */
        case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_MESH_POINT:
                wlvif->bss_type = BSS_TYPE_AP_BSS;
                break;
        default:
@@ -4131,9 +4145,14 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
                if (ret < 0)
                        goto out;
 
-               ret = wl1271_ap_set_probe_resp_tmpl(wl, wlvif->basic_rate, vif);
-               if (ret < 0)
-                       goto out;
+               /* No need to set probe resp template for mesh */
+               if (!ieee80211_vif_is_mesh(vif)) {
+                       ret = wl1271_ap_set_probe_resp_tmpl(wl,
+                                                           wlvif->basic_rate,
+                                                           vif);
+                       if (ret < 0)
+                               goto out;
+               }
 
                ret = wlcore_set_beacon_template(wl, vif, true);
                if (ret < 0)
@@ -5641,6 +5660,7 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
 
        /* this callback is atomic, so schedule a new work */
        wlvif->rc_update_bw = sta->bandwidth;
+       memcpy(&wlvif->rc_ht_cap, &sta->ht_cap, sizeof(sta->ht_cap));
        ieee80211_queue_work(hw, &wlvif->rc_update_work);
 }
 
@@ -6062,7 +6082,11 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
                                         BIT(NL80211_IFTYPE_AP) |
                                         BIT(NL80211_IFTYPE_P2P_DEVICE) |
                                         BIT(NL80211_IFTYPE_P2P_CLIENT) |
+#ifdef CONFIG_MAC80211_MESH
+                                        BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
                                         BIT(NL80211_IFTYPE_P2P_GO);
+
        wl->hw->wiphy->max_scan_ssids = 1;
        wl->hw->wiphy->max_sched_scan_ssids = 16;
        wl->hw->wiphy->max_match_sets = 16;
index 5c4199f3a19a9b41b7e6917614a1af4d91866d53..f5f910b59d8622f7d89068be0b88807a0e0918d1 100644 (file)
@@ -472,6 +472,7 @@ struct wl12xx_vif {
 
        /* update rate conrol */
        enum ieee80211_sta_rx_bandwidth rc_update_bw;
+       struct ieee80211_sta_ht_cap rc_ht_cap;
        struct work_struct rc_update_work;
 
        /*