|
@@ -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;
|