aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/80211.tmpl4
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h1
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c51
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c47
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c10
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c261
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h26
-rw-r--r--drivers/net/wireless/mwifiex/11n.c7
-rw-r--r--drivers/net/wireless/mwifiex/11n.h4
-rw-r--r--drivers/net/wireless/mwifiex/Makefile1
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c177
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c159
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c19
-rw-r--r--drivers/net/wireless/mwifiex/fw.h127
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h4
-rw-r--r--drivers/net/wireless/mwifiex/join.c8
-rw-r--r--drivers/net/wireless/mwifiex/main.h23
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c5
-rw-r--r--drivers/net/wireless/mwifiex/scan.c63
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c1
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c5
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c11
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c44
-rw-r--r--net/mac80211/cfg.c14
-rw-r--r--net/mac80211/iface.c8
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh.c116
-rw-r--r--net/mac80211/mesh.h105
-rw-r--r--net/mac80211/mesh_hwmp.c68
-rw-r--r--net/mac80211/mesh_pathtbl.c89
-rw-r--r--net/mac80211/mesh_plink.c134
-rw-r--r--net/mac80211/mesh_sync.c47
-rw-r--r--net/mac80211/rx.c12
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/trace.h6
-rw-r--r--net/mac80211/tx.c26
-rw-r--r--net/wireless/nl80211.c9
45 files changed, 1297 insertions, 444 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 42e7f030cb16..284ced7a228f 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -107,8 +107,8 @@
107!Finclude/net/cfg80211.h key_params 107!Finclude/net/cfg80211.h key_params
108!Finclude/net/cfg80211.h survey_info_flags 108!Finclude/net/cfg80211.h survey_info_flags
109!Finclude/net/cfg80211.h survey_info 109!Finclude/net/cfg80211.h survey_info
110!Finclude/net/cfg80211.h beacon_parameters 110!Finclude/net/cfg80211.h cfg80211_beacon_data
111!Finclude/net/cfg80211.h plink_actions 111!Finclude/net/cfg80211.h cfg80211_ap_settings
112!Finclude/net/cfg80211.h station_parameters 112!Finclude/net/cfg80211.h station_parameters
113!Finclude/net/cfg80211.h station_info_flags 113!Finclude/net/cfg80211.h station_info_flags
114!Finclude/net/cfg80211.h rate_info_flags 114!Finclude/net/cfg80211.h rate_info_flags
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index c6ea995750db..dd9a18f8dbca 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -376,7 +376,7 @@ int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
376 376
377 entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL); 377 entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL);
378 if (entry == NULL) 378 if (entry == NULL)
379 return -1; 379 return -ENOMEM;
380 380
381 memcpy(entry->addr, mac, ETH_ALEN); 381 memcpy(entry->addr, mac, ETH_ALEN);
382 382
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 02c9ebb3b340..84e2c0fcfef6 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -1403,6 +1403,7 @@ enum {
1403 1403
1404#define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */ 1404#define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */
1405#define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */ 1405#define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */
1406#define AGG_TX_TRY_POS 12
1406 1407
1407#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ 1408#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \
1408 AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ 1409 AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c
index 67e2e1321b40..03f9bc01c0cc 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.c
@@ -471,8 +471,8 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
471 set_bit(STATUS_CT_KILL, &priv->status); 471 set_bit(STATUS_CT_KILL, &priv->status);
472 iwl_perform_ct_kill_task(priv, true); 472 iwl_perform_ct_kill_task(priv, true);
473 } else { 473 } else {
474 iwl_prepare_ct_kill_task(priv);
475 tt->state = old_state; 474 tt->state = old_state;
475 iwl_prepare_ct_kill_task(priv);
476 } 476 }
477 } else if (old_state == IWL_TI_CT_KILL && 477 } else if (old_state == IWL_TI_CT_KILL &&
478 tt->state != IWL_TI_CT_KILL) { 478 tt->state != IWL_TI_CT_KILL) {
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index d1dccb361391..6aec2df3bb27 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -908,6 +908,12 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
908 } 908 }
909} 909}
910 910
911static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
912{
913 return le32_to_cpup((__le32 *)&tx_resp->status +
914 tx_resp->frame_count) & MAX_SN;
915}
916
911static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, 917static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
912 struct iwlagn_tx_resp *tx_resp) 918 struct iwlagn_tx_resp *tx_resp)
913{ 919{
@@ -942,9 +948,15 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
942 if (tx_resp->frame_count == 1) 948 if (tx_resp->frame_count == 1)
943 return; 949 return;
944 950
951 IWL_DEBUG_TX_REPLY(priv, "TXQ %d initial_rate 0x%x ssn %d frm_cnt %d\n",
952 agg->txq_id,
953 le32_to_cpu(tx_resp->rate_n_flags),
954 iwlagn_get_scd_ssn(tx_resp), tx_resp->frame_count);
955
945 /* Construct bit-map of pending frames within Tx window */ 956 /* Construct bit-map of pending frames within Tx window */
946 for (i = 0; i < tx_resp->frame_count; i++) { 957 for (i = 0; i < tx_resp->frame_count; i++) {
947 u16 fstatus = le16_to_cpu(frame_status[i].status); 958 u16 fstatus = le16_to_cpu(frame_status[i].status);
959 u8 retry_cnt = (fstatus & AGG_TX_TRY_MSK) >> AGG_TX_TRY_POS;
948 960
949 if (status & AGG_TX_STATUS_MSK) 961 if (status & AGG_TX_STATUS_MSK)
950 iwlagn_count_agg_tx_err_status(priv, fstatus); 962 iwlagn_count_agg_tx_err_status(priv, fstatus);
@@ -952,6 +964,14 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
952 if (status & (AGG_TX_STATE_FEW_BYTES_MSK | 964 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
953 AGG_TX_STATE_ABORT_MSK)) 965 AGG_TX_STATE_ABORT_MSK))
954 continue; 966 continue;
967
968 if (status & AGG_TX_STATUS_MSK || retry_cnt > 1)
969 IWL_DEBUG_TX_REPLY(priv,
970 "%d: status %s (0x%04x), try-count (0x%01x)\n",
971 i,
972 iwl_get_agg_tx_fail_reason(fstatus),
973 fstatus & AGG_TX_STATUS_MSK,
974 retry_cnt);
955 } 975 }
956} 976}
957 977
@@ -982,12 +1002,6 @@ const char *iwl_get_agg_tx_fail_reason(u16 status)
982} 1002}
983#endif /* CONFIG_IWLWIFI_DEBUG */ 1003#endif /* CONFIG_IWLWIFI_DEBUG */
984 1004
985static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
986{
987 return le32_to_cpup((__le32 *)&tx_resp->status +
988 tx_resp->frame_count) & MAX_SN;
989}
990
991static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) 1005static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
992{ 1006{
993 status &= TX_STATUS_MSK; 1007 status &= TX_STATUS_MSK;
@@ -1119,8 +1133,14 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1119 1133
1120 spin_lock_bh(&priv->sta_lock); 1134 spin_lock_bh(&priv->sta_lock);
1121 1135
1122 if (is_agg) 1136 if (is_agg) {
1137 WARN_ON_ONCE(sta_id >= IWLAGN_STATION_COUNT ||
1138 tid >= IWL_MAX_TID_COUNT);
1139 if (txq_id != priv->tid_data[sta_id][tid].agg.txq_id)
1140 IWL_ERR(priv, "txq_id mismatch: %d %d\n", txq_id,
1141 priv->tid_data[sta_id][tid].agg.txq_id);
1123 iwl_rx_reply_tx_agg(priv, tx_resp); 1142 iwl_rx_reply_tx_agg(priv, tx_resp);
1143 }
1124 1144
1125 __skb_queue_head_init(&skbs); 1145 __skb_queue_head_init(&skbs);
1126 1146
@@ -1224,16 +1244,17 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1224 */ 1244 */
1225 if (is_offchannel_skb && freed != 1) 1245 if (is_offchannel_skb && freed != 1)
1226 IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed); 1246 IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed);
1227 }
1228 1247
1229 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id, 1248 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id,
1230 iwl_get_tx_fail_reason(status), status); 1249 iwl_get_tx_fail_reason(status), status);
1231 1250
1232 IWL_DEBUG_TX_REPLY(priv, 1251 IWL_DEBUG_TX_REPLY(priv,
1233 "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n", 1252 "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n",
1234 le32_to_cpu(tx_resp->rate_n_flags), 1253 le32_to_cpu(tx_resp->rate_n_flags),
1235 tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn, 1254 tx_resp->failure_frame,
1236 le16_to_cpu(tx_resp->seq_ctl)); 1255 SEQ_TO_INDEX(sequence), ssn,
1256 le16_to_cpu(tx_resp->seq_ctl));
1257 }
1237 1258
1238 iwl_check_abort_status(priv, tx_resp->frame_count, status); 1259 iwl_check_abort_status(priv, tx_resp->frame_count, status);
1239 spin_unlock_bh(&priv->sta_lock); 1260 spin_unlock_bh(&priv->sta_lock);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 0854dc338881..341dbc0237ea 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -245,6 +245,10 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
245 * that we should share it with another interface. 245 * that we should share it with another interface.
246 */ 246 */
247 247
248 /* Currently, MAC ID 0 should be used only for the managed vif */
249 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
250 __clear_bit(0, data.available_mac_ids);
251
248 ieee80211_iterate_active_interfaces_atomic( 252 ieee80211_iterate_active_interfaces_atomic(
249 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 253 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
250 iwl_mvm_mac_iface_iterator, &data); 254 iwl_mvm_mac_iface_iterator, &data);
@@ -286,6 +290,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
286 290
287 mvmvif->color = 0; 291 mvmvif->color = 0;
288 292
293 INIT_LIST_HEAD(&mvmvif->time_event_data.list);
294 mvmvif->time_event_data.id = TE_MAX;
295
289 /* No need to allocate data queues to P2P Device MAC.*/ 296 /* No need to allocate data queues to P2P Device MAC.*/
290 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 297 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
291 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 298 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -328,9 +335,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
328 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT; 335 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
329 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 336 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
330 337
331 INIT_LIST_HEAD(&mvmvif->time_event_data.list);
332 mvmvif->time_event_data.id = TE_MAX;
333
334 return 0; 338 return 0;
335 339
336exit_fail: 340exit_fail:
@@ -585,10 +589,43 @@ static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
585 struct iwl_mac_data_sta *ctxt_sta) 589 struct iwl_mac_data_sta *ctxt_sta)
586{ 590{
587 /* We need the dtim_period to set the MAC as associated */ 591 /* We need the dtim_period to set the MAC as associated */
588 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) 592 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) {
593 u32 dtim_offs;
594
595 /*
596 * The DTIM count counts down, so when it is N that means N
597 * more beacon intervals happen until the DTIM TBTT. Therefore
598 * add this to the current time. If that ends up being in the
599 * future, the firmware will handle it.
600 *
601 * Also note that the system_timestamp (which we get here as
602 * "sync_device_ts") and TSF timestamp aren't at exactly the
603 * same offset in the frame -- the TSF is at the first symbol
604 * of the TSF, the system timestamp is at signal acquisition
605 * time. This means there's an offset between them of at most
606 * a few hundred microseconds (24 * 8 bits + PLCP time gives
607 * 384us in the longest case), this is currently not relevant
608 * as the firmware wakes up around 2ms before the TBTT.
609 */
610 dtim_offs = vif->bss_conf.sync_dtim_count *
611 vif->bss_conf.beacon_int;
612 /* convert TU to usecs */
613 dtim_offs *= 1024;
614
615 ctxt_sta->dtim_tsf =
616 cpu_to_le64(vif->bss_conf.sync_tsf + dtim_offs);
617 ctxt_sta->dtim_time =
618 cpu_to_le32(vif->bss_conf.sync_device_ts + dtim_offs);
619
620 IWL_DEBUG_INFO(mvm, "DTIM TBTT is 0x%llx/0x%x, offset %d\n",
621 le64_to_cpu(ctxt_sta->dtim_tsf),
622 le32_to_cpu(ctxt_sta->dtim_time),
623 dtim_offs);
624
589 ctxt_sta->is_assoc = cpu_to_le32(1); 625 ctxt_sta->is_assoc = cpu_to_le32(1);
590 else 626 } else {
591 ctxt_sta->is_assoc = cpu_to_le32(0); 627 ctxt_sta->is_assoc = cpu_to_le32(0);
628 }
592 629
593 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int); 630 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
594 ctxt_sta->bi_reciprocal = 631 ctxt_sta->bi_reciprocal =
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index e27eb9724112..e8264e11b12d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -113,10 +113,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
113 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 113 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
114 IEEE80211_HW_QUEUE_CONTROL | 114 IEEE80211_HW_QUEUE_CONTROL |
115 IEEE80211_HW_WANT_MONITOR_VIF | 115 IEEE80211_HW_WANT_MONITOR_VIF |
116 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC |
117 IEEE80211_HW_SUPPORTS_PS | 116 IEEE80211_HW_SUPPORTS_PS |
118 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 117 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
119 IEEE80211_HW_AMPDU_AGGREGATION; 118 IEEE80211_HW_AMPDU_AGGREGATION |
119 IEEE80211_HW_TIMING_BEACON_ONLY;
120 120
121 hw->queues = IWL_FIRST_AMPDU_QUEUE; 121 hw->queues = IWL_FIRST_AMPDU_QUEUE;
122 hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE; 122 hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;
@@ -857,7 +857,6 @@ iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
857 bool more_data) 857 bool more_data)
858{ 858{
859 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 859 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
860 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
861 860
862 /* TODO: how do we tell the fw to send frames for a specific TID */ 861 /* TODO: how do we tell the fw to send frames for a specific TID */
863 862
@@ -865,8 +864,7 @@ iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
865 * The fw will send EOSP notification when the last frame will be 864 * The fw will send EOSP notification when the last frame will be
866 * transmitted. 865 * transmitted.
867 */ 866 */
868 iwl_mvm_sta_modify_sleep_tx_count(mvm, mvmsta->sta_id, reason, 867 iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames);
869 num_frames);
870} 868}
871 869
872static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw, 870static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
@@ -890,7 +888,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
890 case STA_NOTIFY_AWAKE: 888 case STA_NOTIFY_AWAKE:
891 if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION)) 889 if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION))
892 break; 890 break;
893 iwl_mvm_sta_modify_ps_wake(mvm, mvmsta->sta_id); 891 iwl_mvm_sta_modify_ps_wake(mvm, sta);
894 break; 892 break;
895 default: 893 default:
896 break; 894 break;
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 3f3ce91ad5c2..3f40ab05bbd8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -267,6 +267,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
267 267
268 /* rx_status carries information about the packet to mac80211 */ 268 /* rx_status carries information about the packet to mac80211 */
269 rx_status.mactime = le64_to_cpu(phy_info->timestamp); 269 rx_status.mactime = le64_to_cpu(phy_info->timestamp);
270 rx_status.device_timestamp = le32_to_cpu(phy_info->system_timestamp);
270 rx_status.band = 271 rx_status.band =
271 (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ? 272 (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
272 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 273 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 406c53ad0a49..9b21b92aa8d1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -292,7 +292,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
292 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req); 292 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
293 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 293 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
294 MAC_FILTER_IN_BEACON); 294 MAC_FILTER_IN_BEACON);
295 cmd->type = SCAN_TYPE_FORCED; 295
296 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
297 cmd->type = cpu_to_le32(SCAN_TYPE_DISCOVERY_FORCED);
298 else
299 cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
300
296 cmd->repeats = cpu_to_le32(1); 301 cmd->repeats = cpu_to_le32(1);
297 302
298 /* 303 /*
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index a1eb692d7fad..861a7f9f8e7f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -1188,13 +1188,16 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1188 rcu_read_unlock(); 1188 rcu_read_unlock();
1189} 1189}
1190 1190
1191void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id) 1191void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1192 struct ieee80211_sta *sta)
1192{ 1193{
1194 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1193 struct iwl_mvm_add_sta_cmd cmd = { 1195 struct iwl_mvm_add_sta_cmd cmd = {
1194 .add_modify = STA_MODE_MODIFY, 1196 .add_modify = STA_MODE_MODIFY,
1195 .sta_id = sta_id, 1197 .sta_id = mvmsta->sta_id,
1196 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT, 1198 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1197 .sleep_state_flags = cpu_to_le16(STA_SLEEP_STATE_AWAKE), 1199 .sleep_state_flags = cpu_to_le16(STA_SLEEP_STATE_AWAKE),
1200 .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
1198 }; 1201 };
1199 int ret; 1202 int ret;
1200 1203
@@ -1208,18 +1211,21 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id)
1208 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); 1211 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1209} 1212}
1210 1213
1211void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id, 1214void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1215 struct ieee80211_sta *sta,
1212 enum ieee80211_frame_release_type reason, 1216 enum ieee80211_frame_release_type reason,
1213 u16 cnt) 1217 u16 cnt)
1214{ 1218{
1215 u16 sleep_state_flags = 1219 u16 sleep_state_flags =
1216 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ? 1220 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1217 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL; 1221 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1222 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1218 struct iwl_mvm_add_sta_cmd cmd = { 1223 struct iwl_mvm_add_sta_cmd cmd = {
1219 .add_modify = STA_MODE_MODIFY, 1224 .add_modify = STA_MODE_MODIFY,
1220 .sta_id = sta_id, 1225 .sta_id = mvmsta->sta_id,
1221 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT, 1226 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1222 .sleep_tx_count = cpu_to_le16(cnt), 1227 .sleep_tx_count = cpu_to_le16(cnt),
1228 .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
1223 /* 1229 /*
1224 * Same modify mask for sleep_tx_count and sleep_state_flags so 1230 * Same modify mask for sleep_tx_count and sleep_state_flags so
1225 * we must set the sleep_state_flags too. 1231 * we must set the sleep_state_flags too.
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index bdd7c5ed8222..896f88ac8145 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -362,8 +362,10 @@ int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
362 struct iwl_mvm_int_sta *bsta); 362 struct iwl_mvm_int_sta *bsta);
363int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta); 363int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta);
364void iwl_mvm_sta_drained_wk(struct work_struct *wk); 364void iwl_mvm_sta_drained_wk(struct work_struct *wk);
365void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id); 365void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
366void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id, 366 struct ieee80211_sta *sta);
367void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
368 struct ieee80211_sta *sta,
367 enum ieee80211_frame_release_type reason, 369 enum ieee80211_frame_release_type reason,
368 u16 cnt); 370 u16 cnt);
369int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 371int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index c09b71f23759..e437e02c7149 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -248,6 +248,11 @@ static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
248 } 248 }
249 249
250 resp = (void *)pkt->data; 250 resp = (void *)pkt->data;
251
252 /* we should never get a response to another TIME_EVENT_CMD here */
253 if (WARN_ON_ONCE(le32_to_cpu(resp->id) != te_data->id))
254 return false;
255
251 te_data->uid = le32_to_cpu(resp->unique_id); 256 te_data->uid = le32_to_cpu(resp->unique_id);
252 IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n", 257 IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n",
253 te_data->uid); 258 te_data->uid);
@@ -265,6 +270,9 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
265 270
266 lockdep_assert_held(&mvm->mutex); 271 lockdep_assert_held(&mvm->mutex);
267 272
273 IWL_DEBUG_TE(mvm, "Add new TE, duration %d TU\n",
274 le32_to_cpu(te_cmd->duration));
275
268 spin_lock_bh(&mvm->time_event_lock); 276 spin_lock_bh(&mvm->time_event_lock);
269 if (WARN_ON(te_data->id != TE_MAX)) { 277 if (WARN_ON(te_data->id != TE_MAX)) {
270 spin_unlock_bh(&mvm->time_event_lock); 278 spin_unlock_bh(&mvm->time_event_lock);
@@ -413,7 +421,7 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
413 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 421 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
414 422
415 IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id)); 423 IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id));
416 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_ASYNC, 424 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
417 sizeof(time_cmd), &time_cmd); 425 sizeof(time_cmd), &time_cmd);
418 if (WARN_ON(ret)) 426 if (WARN_ON(ret))
419 return; 427 return;
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
new file mode 100644
index 000000000000..cf43b3c29250
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -0,0 +1,261 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11ac
3 *
4 * Copyright (C) 2013, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "fw.h"
23#include "main.h"
24#include "11ac.h"
25
26/* This function converts the 2-bit MCS map to the highest long GI
27 * VHT data rate.
28 */
29static u16
30mwifiex_convert_mcsmap_to_maxrate(struct mwifiex_private *priv,
31 u8 bands, u16 mcs_map)
32{
33 u8 i, nss, max_mcs;
34 u16 max_rate = 0;
35 u32 usr_vht_cap_info = 0;
36 struct mwifiex_adapter *adapter = priv->adapter;
37 /* tables of the MCS map to the highest data rate (in Mbps)
38 * supported for long GI
39 */
40 u16 max_rate_lgi_80MHZ[8][3] = {
41 {0x124, 0x15F, 0x186}, /* NSS = 1 */
42 {0x249, 0x2BE, 0x30C}, /* NSS = 2 */
43 {0x36D, 0x41D, 0x492}, /* NSS = 3 */
44 {0x492, 0x57C, 0x618}, /* NSS = 4 */
45 {0x5B6, 0x6DB, 0x79E}, /* NSS = 5 */
46 {0x6DB, 0x83A, 0x0}, /* NSS = 6 */
47 {0x7FF, 0x999, 0xAAA}, /* NSS = 7 */
48 {0x924, 0xAF8, 0xC30} /* NSS = 8 */
49 };
50 u16 max_rate_lgi_160MHZ[8][3] = {
51 {0x249, 0x2BE, 0x30C}, /* NSS = 1 */
52 {0x492, 0x57C, 0x618}, /* NSS = 2 */
53 {0x6DB, 0x83A, 0x0}, /* NSS = 3 */
54 {0x924, 0xAF8, 0xC30}, /* NSS = 4 */
55 {0xB6D, 0xDB6, 0xF3C}, /* NSS = 5 */
56 {0xDB6, 0x1074, 0x1248}, /* NSS = 6 */
57 {0xFFF, 0x1332, 0x1554}, /* NSS = 7 */
58 {0x1248, 0x15F0, 0x1860} /* NSS = 8 */
59 };
60
61 if (bands & BAND_AAC)
62 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
63 else
64 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
65
66 /* find the max NSS supported */
67 nss = 0;
68 for (i = 0; i < 8; i++) {
69 max_mcs = (mcs_map >> (2 * i)) & 0x3;
70 if (max_mcs < 3)
71 nss = i;
72 }
73 max_mcs = (mcs_map >> (2 * nss)) & 0x3;
74
75 /* if max_mcs is 3, nss must be 0 (SS = 1). Thus, max mcs is MCS 9 */
76 if (max_mcs >= 3)
77 max_mcs = 2;
78
79 if (GET_VHTCAP_CHWDSET(usr_vht_cap_info)) {
80 /* support 160 MHz */
81 max_rate = max_rate_lgi_160MHZ[nss][max_mcs];
82 if (!max_rate)
83 /* MCS9 is not supported in NSS6 */
84 max_rate = max_rate_lgi_160MHZ[nss][max_mcs - 1];
85 } else {
86 max_rate = max_rate_lgi_80MHZ[nss][max_mcs];
87 if (!max_rate)
88 /* MCS9 is not supported in NSS3 */
89 max_rate = max_rate_lgi_80MHZ[nss][max_mcs - 1];
90 }
91
92 return max_rate;
93}
94
95static void
96mwifiex_fill_vht_cap_info(struct mwifiex_private *priv,
97 struct mwifiex_ie_types_vhtcap *vht_cap, u8 bands)
98{
99 struct mwifiex_adapter *adapter = priv->adapter;
100
101 if (bands & BAND_A)
102 vht_cap->vht_cap.vht_cap_info =
103 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_a);
104 else
105 vht_cap->vht_cap.vht_cap_info =
106 cpu_to_le32(adapter->usr_dot_11ac_dev_cap_bg);
107}
108
109static void
110mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
111 struct mwifiex_ie_types_vhtcap *vht_cap, u8 bands)
112{
113 struct mwifiex_adapter *adapter = priv->adapter;
114 u16 mcs_map_user, mcs_map_resp, mcs_map_result;
115 u16 mcs_user, mcs_resp, nss, tmp;
116
117 /* Fill VHT cap info */
118 mwifiex_fill_vht_cap_info(priv, vht_cap, bands);
119
120 /* rx MCS Set: find the minimum of the user rx mcs and ap rx mcs */
121 mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
122 mcs_map_resp = le16_to_cpu(vht_cap->vht_cap.supp_mcs.rx_mcs_map);
123 mcs_map_result = 0;
124
125 for (nss = 1; nss <= 8; nss++) {
126 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
127 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
128
129 if ((mcs_user == NO_NSS_SUPPORT) ||
130 (mcs_resp == NO_NSS_SUPPORT))
131 SET_VHTNSSMCS(mcs_map_result, nss, NO_NSS_SUPPORT);
132 else
133 SET_VHTNSSMCS(mcs_map_result, nss,
134 min(mcs_user, mcs_resp));
135 }
136
137 vht_cap->vht_cap.supp_mcs.rx_mcs_map = cpu_to_le16(mcs_map_result);
138
139 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
140 vht_cap->vht_cap.supp_mcs.rx_highest = cpu_to_le16(tmp);
141
142 /* tx MCS Set: find the minimum of the user tx mcs and ap tx mcs */
143 mcs_map_user = GET_DEVTXMCSMAP(adapter->usr_dot_11ac_mcs_support);
144 mcs_map_resp = le16_to_cpu(vht_cap->vht_cap.supp_mcs.tx_mcs_map);
145 mcs_map_result = 0;
146
147 for (nss = 1; nss <= 8; nss++) {
148 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
149 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
150 if ((mcs_user == NO_NSS_SUPPORT) ||
151 (mcs_resp == NO_NSS_SUPPORT))
152 SET_VHTNSSMCS(mcs_map_result, nss, NO_NSS_SUPPORT);
153 else
154 SET_VHTNSSMCS(mcs_map_result, nss,
155 min(mcs_user, mcs_resp));
156 }
157
158 vht_cap->vht_cap.supp_mcs.tx_mcs_map = cpu_to_le16(mcs_map_result);
159
160 tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
161 vht_cap->vht_cap.supp_mcs.tx_highest = cpu_to_le16(tmp);
162
163 return;
164}
165
166int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
167 struct mwifiex_bssdescriptor *bss_desc,
168 u8 **buffer)
169{
170 struct mwifiex_ie_types_vhtcap *vht_cap;
171 struct mwifiex_ie_types_oper_mode_ntf *oper_ntf;
172 struct ieee_types_oper_mode_ntf *ieee_oper_ntf;
173 struct mwifiex_ie_types_vht_oper *vht_op;
174 struct mwifiex_adapter *adapter = priv->adapter;
175 u8 supp_chwd_set;
176 u32 usr_vht_cap_info;
177 int ret_len = 0;
178
179 if (bss_desc->bss_band & BAND_A)
180 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
181 else
182 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
183
184 /* VHT Capabilities IE */
185 if (bss_desc->bcn_vht_cap) {
186 vht_cap = (struct mwifiex_ie_types_vhtcap *)*buffer;
187 memset(vht_cap, 0, sizeof(*vht_cap));
188 vht_cap->header.type = cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
189 vht_cap->header.len =
190 cpu_to_le16(sizeof(struct ieee80211_vht_cap));
191 memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header),
192 (u8 *)bss_desc->bcn_vht_cap +
193 sizeof(struct ieee_types_header),
194 le16_to_cpu(vht_cap->header.len));
195
196 mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band);
197 *buffer += sizeof(*vht_cap);
198 ret_len += sizeof(*vht_cap);
199 }
200
201 /* VHT Operation IE */
202 if (bss_desc->bcn_vht_oper) {
203 if (priv->bss_mode == HostCmd_BSS_MODE_IBSS) {
204 vht_op = (struct mwifiex_ie_types_vht_oper *)*buffer;
205 memset(vht_op, 0, sizeof(*vht_op));
206 vht_op->header.type =
207 cpu_to_le16(WLAN_EID_VHT_OPERATION);
208 vht_op->header.len = cpu_to_le16(sizeof(*vht_op) -
209 sizeof(struct mwifiex_ie_types_header));
210 memcpy((u8 *)vht_op +
211 sizeof(struct mwifiex_ie_types_header),
212 (u8 *)bss_desc->bcn_vht_oper +
213 sizeof(struct ieee_types_header),
214 le16_to_cpu(vht_op->header.len));
215
216 /* negotiate the channel width and central freq
217 * and keep the central freq as the peer suggests
218 */
219 supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
220
221 switch (supp_chwd_set) {
222 case 0:
223 vht_op->chan_width =
224 min_t(u8, IEEE80211_VHT_CHANWIDTH_80MHZ,
225 bss_desc->bcn_vht_oper->chan_width);
226 break;
227 case 1:
228 vht_op->chan_width =
229 min_t(u8, IEEE80211_VHT_CHANWIDTH_160MHZ,
230 bss_desc->bcn_vht_oper->chan_width);
231 break;
232 case 2:
233 vht_op->chan_width =
234 min_t(u8, IEEE80211_VHT_CHANWIDTH_80P80MHZ,
235 bss_desc->bcn_vht_oper->chan_width);
236 break;
237 default:
238 vht_op->chan_width =
239 IEEE80211_VHT_CHANWIDTH_USE_HT;
240 break;
241 }
242
243 *buffer += sizeof(*vht_op);
244 ret_len += sizeof(*vht_op);
245 }
246 }
247
248 /* Operating Mode Notification IE */
249 if (bss_desc->oper_mode) {
250 ieee_oper_ntf = bss_desc->oper_mode;
251 oper_ntf = (void *)*buffer;
252 memset(oper_ntf, 0, sizeof(*oper_ntf));
253 oper_ntf->header.type = cpu_to_le16(WLAN_EID_OPMODE_NOTIF);
254 oper_ntf->header.len = cpu_to_le16(sizeof(u8));
255 oper_ntf->oper_mode = ieee_oper_ntf->oper_mode;
256 *buffer += sizeof(*oper_ntf);
257 ret_len += sizeof(*oper_ntf);
258 }
259
260 return ret_len;
261}
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
new file mode 100644
index 000000000000..80fd1ba46200
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -0,0 +1,26 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11ac
3 *
4 * Copyright (C) 2013, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_11AC_H_
21#define _MWIFIEX_11AC_H_
22
23int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
24 struct mwifiex_bssdescriptor *bss_desc,
25 u8 **buffer);
26#endif /* _MWIFIEX_11AC_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 25596ab0c576..45f19716687e 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -250,7 +250,8 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
250 * - Setting HT Tx capability and HT Tx information fields 250 * - Setting HT Tx capability and HT Tx information fields
251 * - Ensuring correct endian-ness 251 * - Ensuring correct endian-ness
252 */ 252 */
253int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, 253int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
254 struct host_cmd_ds_command *cmd, u16 cmd_action,
254 struct mwifiex_ds_11n_tx_cfg *txcfg) 255 struct mwifiex_ds_11n_tx_cfg *txcfg)
255{ 256{
256 struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; 257 struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
@@ -260,6 +261,10 @@ int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action,
260 htcfg->action = cpu_to_le16(cmd_action); 261 htcfg->action = cpu_to_le16(cmd_action);
261 htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap); 262 htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap);
262 htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo); 263 htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo);
264
265 if (priv->adapter->is_hw_11ac_capable)
266 htcfg->misc_config = cpu_to_le16(txcfg->misc_config);
267
263 return 0; 268 return 0;
264} 269}
265 270
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 29a4c02479d6..375db01442bf 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -28,9 +28,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
28 struct host_cmd_ds_command *resp); 28 struct host_cmd_ds_command *resp);
29int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, 29int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
30 struct host_cmd_ds_command *resp); 30 struct host_cmd_ds_command *resp);
31int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, 31int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
32 struct host_cmd_ds_command *cmd, u16 cmd_action,
32 struct mwifiex_ds_11n_tx_cfg *txcfg); 33 struct mwifiex_ds_11n_tx_cfg *txcfg);
33
34int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, 34int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
35 struct mwifiex_bssdescriptor *bss_desc, 35 struct mwifiex_bssdescriptor *bss_desc,
36 u8 **buffer); 36 u8 **buffer);
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index dd0410d2d465..97b245cbafd8 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -23,6 +23,7 @@ mwifiex-y += util.o
23mwifiex-y += txrx.o 23mwifiex-y += txrx.o
24mwifiex-y += wmm.o 24mwifiex-y += wmm.o
25mwifiex-y += 11n.o 25mwifiex-y += 11n.o
26mwifiex-y += 11ac.o
26mwifiex-y += 11n_aggr.o 27mwifiex-y += 11n_aggr.o
27mwifiex-y += 11n_rxreorder.o 28mwifiex-y += 11n_rxreorder.o
28mwifiex-y += scan.o 29mwifiex-y += scan.o
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index dc5357c0098f..a44023a7bd57 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -834,6 +834,66 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
834 return ret; 834 return ret;
835} 835}
836 836
837static void
838mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
839 struct rate_info *rate)
840{
841 struct mwifiex_adapter *adapter = priv->adapter;
842
843 if (adapter->is_hw_11ac_capable) {
844 /* bit[1-0]: 00=LG 01=HT 10=VHT */
845 if (tx_htinfo & BIT(0)) {
846 /* HT */
847 rate->mcs = priv->tx_rate;
848 rate->flags |= RATE_INFO_FLAGS_MCS;
849 }
850 if (tx_htinfo & BIT(1)) {
851 /* VHT */
852 rate->mcs = priv->tx_rate & 0x0F;
853 rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
854 }
855
856 if (tx_htinfo & (BIT(1) | BIT(0))) {
857 /* HT or VHT */
858 switch (tx_htinfo & (BIT(3) | BIT(2))) {
859 case 0:
860 /* This will be 20MHz */
861 break;
862 case (BIT(2)):
863 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
864 break;
865 case (BIT(3)):
866 rate->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
867 break;
868 case (BIT(3) | BIT(2)):
869 rate->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
870 break;
871 }
872
873 if (tx_htinfo & BIT(4))
874 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
875
876 if ((priv->tx_rate >> 4) == 1)
877 rate->nss = 2;
878 else
879 rate->nss = 1;
880 }
881 } else {
882 /*
883 * Bit 0 in tx_htinfo indicates that current Tx rate
884 * is 11n rate. Valid MCS index values for us are 0 to 15.
885 */
886 if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
887 rate->mcs = priv->tx_rate;
888 rate->flags |= RATE_INFO_FLAGS_MCS;
889 if (tx_htinfo & BIT(1))
890 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
891 if (tx_htinfo & BIT(2))
892 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
893 }
894 }
895}
896
837/* 897/*
838 * This function dumps the station information on a buffer. 898 * This function dumps the station information on a buffer.
839 * 899 *
@@ -873,20 +933,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
873 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, 933 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
874 &priv->dtim_period); 934 &priv->dtim_period);
875 935
876 /* 936 mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate);
877 * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
878 * MCS index values for us are 0 to 15.
879 */
880 if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
881 sinfo->txrate.mcs = priv->tx_rate;
882 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
883 /* 40MHz rate */
884 if (priv->tx_htinfo & BIT(1))
885 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
886 /* SGI enabled */
887 if (priv->tx_htinfo & BIT(2))
888 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
889 }
890 937
891 sinfo->signal_avg = priv->bcn_rssi_avg; 938 sinfo->signal_avg = priv->bcn_rssi_avg;
892 sinfo->rx_bytes = priv->stats.rx_bytes; 939 sinfo->rx_bytes = priv->stats.rx_bytes;
@@ -1295,20 +1342,22 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1295 /* Set appropriate bands */ 1342 /* Set appropriate bands */
1296 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) { 1343 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1297 bss_cfg->band_cfg = BAND_CONFIG_BG; 1344 bss_cfg->band_cfg = BAND_CONFIG_BG;
1345 config_bands = BAND_B | BAND_G;
1298 1346
1299 if (cfg80211_get_chandef_type(&params->chandef) == 1347 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1300 NL80211_CHAN_NO_HT) 1348 config_bands |= BAND_GN;
1301 config_bands = BAND_B | BAND_G; 1349
1302 else 1350 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1303 config_bands = BAND_B | BAND_G | BAND_GN; 1351 config_bands |= BAND_GAC;
1304 } else { 1352 } else {
1305 bss_cfg->band_cfg = BAND_CONFIG_A; 1353 bss_cfg->band_cfg = BAND_CONFIG_A;
1354 config_bands = BAND_A;
1306 1355
1307 if (cfg80211_get_chandef_type(&params->chandef) == 1356 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1308 NL80211_CHAN_NO_HT) 1357 config_bands |= BAND_AN;
1309 config_bands = BAND_A; 1358
1310 else 1359 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1311 config_bands = BAND_AN | BAND_A; 1360 config_bands |= BAND_AAC;
1312 } 1361 }
1313 1362
1314 if (!((config_bands | priv->adapter->fw_bands) & 1363 if (!((config_bands | priv->adapter->fw_bands) &
@@ -1879,6 +1928,79 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1879 return 0; 1928 return 0;
1880} 1929}
1881 1930
1931static void mwifiex_setup_vht_caps(struct ieee80211_sta_vht_cap *vht_info,
1932 struct mwifiex_private *priv)
1933{
1934 struct mwifiex_adapter *adapter = priv->adapter;
1935 u32 vht_cap = 0, cap = adapter->hw_dot_11ac_dev_cap;
1936
1937 vht_info->vht_supported = true;
1938
1939 switch (GET_VHTCAP_MAXMPDULEN(cap)) {
1940 case 0x00:
1941 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1942 break;
1943 case 0x01:
1944 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1945 break;
1946 case 0x10:
1947 vht_cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1948 break;
1949 default:
1950 dev_err(adapter->dev, "unsupported MAX MPDU len\n");
1951 break;
1952 }
1953
1954 if (ISSUPP_11ACVHTHTCVHT(cap))
1955 vht_cap |= IEEE80211_VHT_CAP_HTC_VHT;
1956
1957 if (ISSUPP_11ACVHTTXOPPS(cap))
1958 vht_cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1959
1960 if (ISSUPP_11ACMURXBEAMFORMEE(cap))
1961 vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1962
1963 if (ISSUPP_11ACMUTXBEAMFORMEE(cap))
1964 vht_cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1965
1966 if (ISSUPP_11ACSUBEAMFORMER(cap))
1967 vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1968
1969 if (ISSUPP_11ACSUBEAMFORMEE(cap))
1970 vht_cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1971
1972 if (ISSUPP_11ACRXSTBC(cap))
1973 vht_cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1974
1975 if (ISSUPP_11ACTXSTBC(cap))
1976 vht_cap |= IEEE80211_VHT_CAP_TXSTBC;
1977
1978 if (ISSUPP_11ACSGI160(cap))
1979 vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1980
1981 if (ISSUPP_11ACSGI80(cap))
1982 vht_cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1983
1984 if (ISSUPP_11ACLDPC(cap))
1985 vht_cap |= IEEE80211_VHT_CAP_RXLDPC;
1986
1987 if (ISSUPP_11ACBW8080(cap))
1988 vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
1989
1990 if (ISSUPP_11ACBW160(cap))
1991 vht_cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
1992
1993 vht_info->cap = vht_cap;
1994
1995 /* Update MCS support for VHT */
1996 vht_info->vht_mcs.rx_mcs_map = cpu_to_le16(
1997 adapter->hw_dot_11ac_mcs_support & 0xFFFF);
1998 vht_info->vht_mcs.rx_highest = 0;
1999 vht_info->vht_mcs.tx_mcs_map = cpu_to_le16(
2000 adapter->hw_dot_11ac_mcs_support >> 16);
2001 vht_info->vht_mcs.tx_highest = 0;
2002}
2003
1882/* 2004/*
1883 * This function sets up the CFG802.11 specific HT capability fields 2005 * This function sets up the CFG802.11 specific HT capability fields
1884 * with default values. 2006 * with default values.
@@ -2092,11 +2214,18 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2092 priv->netdev = dev; 2214 priv->netdev = dev;
2093 2215
2094 mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); 2216 mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
2217 if (adapter->is_hw_11ac_capable)
2218 mwifiex_setup_vht_caps(
2219 &wiphy->bands[IEEE80211_BAND_2GHZ]->vht_cap, priv);
2095 2220
2096 if (adapter->config_bands & BAND_A) 2221 if (adapter->config_bands & BAND_A)
2097 mwifiex_setup_ht_caps( 2222 mwifiex_setup_ht_caps(
2098 &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); 2223 &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
2099 2224
2225 if ((adapter->config_bands & BAND_A) && adapter->is_hw_11ac_capable)
2226 mwifiex_setup_vht_caps(
2227 &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv);
2228
2100 dev_net_set(dev, wiphy_net(wiphy)); 2229 dev_net_set(dev, wiphy_net(wiphy));
2101 dev->ieee80211_ptr = priv->wdev; 2230 dev->ieee80211_ptr = priv->wdev;
2102 dev->ieee80211_ptr->iftype = priv->bss_mode; 2231 dev->ieee80211_ptr->iftype = priv->bss_mode;
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index f69300f93f42..988552dece75 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -106,8 +106,8 @@ u8 *mwifiex_11d_code_2_region(u8 code)
106 * This function maps an index in supported rates table into 106 * This function maps an index in supported rates table into
107 * the corresponding data rate. 107 * the corresponding data rate.
108 */ 108 */
109u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, 109u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv,
110 u8 ht_info) 110 u8 index, u8 ht_info)
111{ 111{
112 /* 112 /*
113 * For every mcs_rate line, the first 8 bytes are for stream 1x1, 113 * For every mcs_rate line, the first 8 bytes are for stream 1x1,
@@ -130,10 +130,155 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index,
130 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90, 130 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90,
131 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 } 131 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 }
132 }; 132 };
133 /* AC rates */
134 u16 ac_mcs_rate_nss1[8][10] = {
135 /* LG 160M */
136 { 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
137 0x492, 0x57C, 0x618 },
138
139 /* SG 160M */
140 { 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
141 0x514, 0x618, 0x6C6 },
142
143 /* LG 80M */
144 { 0x3B, 0x75, 0xB0, 0xEA, 0x15F, 0x1D4, 0x20F,
145 0x249, 0x2BE, 0x30C },
146
147 /* SG 80M */
148 { 0x41, 0x82, 0xC3, 0x104, 0x186, 0x208, 0x249,
149 0x28A, 0x30C, 0x363 },
150
151 /* LG 40M */
152 { 0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3,
153 0x10E, 0x144, 0x168 },
154
155 /* SG 40M */
156 { 0x1E, 0x3C, 0x5A, 0x78, 0xB4, 0xF0, 0x10E,
157 0x12C, 0x168, 0x190 },
158
159 /* LG 20M */
160 { 0xD, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75, 0x82, 0x9C, 0x00 },
161
162 /* SG 20M */
163 { 0xF, 0x1D, 0x2C, 0x3A, 0x57, 0x74, 0x82, 0x91, 0xAE, 0x00 },
164 };
165 /* NSS2 note: the value in the table is 2 multiplier of the actual
166 * rate
167 */
168 u16 ac_mcs_rate_nss2[8][10] = {
169 /* LG 160M */
170 { 0xEA, 0x1D4, 0x2BE, 0x3A8, 0x57C, 0x750, 0x83A,
171 0x924, 0xAF8, 0xC30 },
172
173 /* SG 160M */
174 { 0x104, 0x208, 0x30C, 0x410, 0x618, 0x820, 0x924,
175 0xA28, 0xC30, 0xD8B },
176
177 /* LG 80M */
178 { 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
179 0x492, 0x57C, 0x618 },
180
181 /* SG 80M */
182 { 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
183 0x514, 0x618, 0x6C6 },
184
185 /* LG 40M */
186 { 0x36, 0x6C, 0xA2, 0xD8, 0x144, 0x1B0, 0x1E6,
187 0x21C, 0x288, 0x2D0 },
188
189 /* SG 40M */
190 { 0x3C, 0x78, 0xB4, 0xF0, 0x168, 0x1E0, 0x21C,
191 0x258, 0x2D0, 0x320 },
192
193 /* LG 20M */
194 { 0x1A, 0x34, 0x4A, 0x68, 0x9C, 0xD0, 0xEA, 0x104,
195 0x138, 0x00 },
196
197 /* SG 20M */
198 { 0x1D, 0x3A, 0x57, 0x74, 0xAE, 0xE6, 0x104, 0x121,
199 0x15B, 0x00 },
200 };
201 u32 rate = 0;
202 u8 mcs_index = 0;
203 u8 bw = 0;
204 u8 gi = 0;
205
206 if ((ht_info & 0x3) == MWIFIEX_RATE_FORMAT_VHT) {
207 mcs_index = min(index & 0xF, 9);
208
209 /* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */
210 bw = (ht_info & 0xC) >> 2;
211
212 /* LGI: gi =0, SGI: gi = 1 */
213 gi = (ht_info & 0x10) >> 4;
214
215 if ((index >> 4) == 1) /* NSS = 2 */
216 rate = ac_mcs_rate_nss2[2 * (3 - bw) + gi][mcs_index];
217 else /* NSS = 1 */
218 rate = ac_mcs_rate_nss1[2 * (3 - bw) + gi][mcs_index];
219 } else if ((ht_info & 0x3) == MWIFIEX_RATE_FORMAT_HT) {
220 /* 20M: bw=0, 40M: bw=1 */
221 bw = (ht_info & 0xC) >> 2;
222
223 /* LGI: gi =0, SGI: gi = 1 */
224 gi = (ht_info & 0x10) >> 4;
225
226 if (index == MWIFIEX_RATE_BITMAP_MCS0) {
227 if (gi == 1)
228 rate = 0x0D; /* MCS 32 SGI rate */
229 else
230 rate = 0x0C; /* MCS 32 LGI rate */
231 } else if (index < 16) {
232 if ((bw == 1) || (bw == 0))
233 rate = mcs_rate[2 * (1 - bw) + gi][index];
234 else
235 rate = mwifiex_data_rates[0];
236 } else {
237 rate = mwifiex_data_rates[0];
238 }
239 } else {
240 /* 11n non-HT rates */
241 if (index >= MWIFIEX_SUPPORTED_RATES_EXT)
242 index = 0;
243 rate = mwifiex_data_rates[index];
244 }
245
246 return rate;
247}
248
249/* This function maps an index in supported rates table into
250 * the corresponding data rate.
251 */
252u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
253 u8 index, u8 ht_info)
254{
255 /* For every mcs_rate line, the first 8 bytes are for stream 1x1,
256 * and all 16 bytes are for stream 2x2.
257 */
258 u16 mcs_rate[4][16] = {
259 /* LGI 40M */
260 { 0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e,
261 0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6, 0x21c },
262
263 /* SGI 40M */
264 { 0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c,
265 0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c, 0x258 },
266
267 /* LGI 20M */
268 { 0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82,
269 0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104 },
270
271 /* SGI 20M */
272 { 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90,
273 0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 }
274 };
133 u32 mcs_num_supp = 275 u32 mcs_num_supp =
134 (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8; 276 (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8;
135 u32 rate; 277 u32 rate;
136 278
279 if (priv->adapter->is_hw_11ac_capable)
280 return mwifiex_index_to_acs_data_rate(priv, index, ht_info);
281
137 if (ht_info & BIT(0)) { 282 if (ht_info & BIT(0)) {
138 if (index == MWIFIEX_RATE_BITMAP_MCS0) { 283 if (index == MWIFIEX_RATE_BITMAP_MCS0) {
139 if (ht_info & BIT(2)) 284 if (ht_info & BIT(2))
@@ -269,6 +414,7 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
269{ 414{
270 u32 k = 0; 415 u32 k = 0;
271 struct mwifiex_adapter *adapter = priv->adapter; 416 struct mwifiex_adapter *adapter = priv->adapter;
417
272 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 418 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
273 switch (adapter->config_bands) { 419 switch (adapter->config_bands) {
274 case BAND_B: 420 case BAND_B:
@@ -279,6 +425,7 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
279 break; 425 break;
280 case BAND_G: 426 case BAND_G:
281 case BAND_G | BAND_GN: 427 case BAND_G | BAND_GN:
428 case BAND_G | BAND_GN | BAND_GAC:
282 dev_dbg(adapter->dev, "info: infra band=%d " 429 dev_dbg(adapter->dev, "info: infra band=%d "
283 "supported_rates_g\n", adapter->config_bands); 430 "supported_rates_g\n", adapter->config_bands);
284 k = mwifiex_copy_rates(rates, k, supported_rates_g, 431 k = mwifiex_copy_rates(rates, k, supported_rates_g,
@@ -288,7 +435,11 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
288 case BAND_A | BAND_B | BAND_G: 435 case BAND_A | BAND_B | BAND_G:
289 case BAND_A | BAND_B: 436 case BAND_A | BAND_B:
290 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN: 437 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
438 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC:
439 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN |
440 BAND_AAC | BAND_GAC:
291 case BAND_B | BAND_G | BAND_GN: 441 case BAND_B | BAND_G | BAND_GN:
442 case BAND_B | BAND_G | BAND_GN | BAND_GAC:
292 dev_dbg(adapter->dev, "info: infra band=%d " 443 dev_dbg(adapter->dev, "info: infra band=%d "
293 "supported_rates_bg\n", adapter->config_bands); 444 "supported_rates_bg\n", adapter->config_bands);
294 k = mwifiex_copy_rates(rates, k, supported_rates_bg, 445 k = mwifiex_copy_rates(rates, k, supported_rates_bg,
@@ -301,14 +452,18 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
301 k = mwifiex_copy_rates(rates, k, supported_rates_a, 452 k = mwifiex_copy_rates(rates, k, supported_rates_a,
302 sizeof(supported_rates_a)); 453 sizeof(supported_rates_a));
303 break; 454 break;
455 case BAND_AN:
304 case BAND_A | BAND_AN: 456 case BAND_A | BAND_AN:
457 case BAND_A | BAND_AN | BAND_AAC:
305 case BAND_A | BAND_G | BAND_AN | BAND_GN: 458 case BAND_A | BAND_G | BAND_AN | BAND_GN:
459 case BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC:
306 dev_dbg(adapter->dev, "info: infra band=%d " 460 dev_dbg(adapter->dev, "info: infra band=%d "
307 "supported_rates_a\n", adapter->config_bands); 461 "supported_rates_a\n", adapter->config_bands);
308 k = mwifiex_copy_rates(rates, k, supported_rates_a, 462 k = mwifiex_copy_rates(rates, k, supported_rates_a,
309 sizeof(supported_rates_a)); 463 sizeof(supported_rates_a));
310 break; 464 break;
311 case BAND_GN: 465 case BAND_GN:
466 case BAND_GN | BAND_GAC:
312 dev_dbg(adapter->dev, "info: infra band=%d " 467 dev_dbg(adapter->dev, "info: infra band=%d "
313 "supported_rates_n\n", adapter->config_bands); 468 "supported_rates_n\n", adapter->config_bands);
314 k = mwifiex_copy_rates(rates, k, supported_rates_n, 469 k = mwifiex_copy_rates(rates, k, supported_rates_n,
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 2b125beecf2c..20a6c5555873 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28/* 29/*
29 * This function initializes a command node. 30 * This function initializes a command node.
@@ -1465,6 +1466,24 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1465 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); 1466 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1466 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); 1467 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1467 1468
1469 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) {
1470 adapter->is_hw_11ac_capable = true;
1471
1472 /* Copy 11AC cap */
1473 adapter->hw_dot_11ac_dev_cap =
1474 le32_to_cpu(hw_spec->dot_11ac_dev_cap);
1475 adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap;
1476 adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap;
1477
1478 /* Copy 11AC mcs */
1479 adapter->hw_dot_11ac_mcs_support =
1480 le32_to_cpu(hw_spec->dot_11ac_mcs_support);
1481 adapter->usr_dot_11ac_mcs_support =
1482 adapter->hw_dot_11ac_mcs_support;
1483 } else {
1484 adapter->is_hw_11ac_capable = false;
1485 }
1486
1468 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", 1487 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
1469 adapter->fw_release_number); 1488 adapter->fw_release_number);
1470 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", 1489 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index ebe2f6a7984c..25acb0682c56 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -49,13 +49,23 @@ struct tx_packet_hdr {
49#define A_SUPPORTED_RATES 9 49#define A_SUPPORTED_RATES 9
50#define HOSTCMD_SUPPORTED_RATES 14 50#define HOSTCMD_SUPPORTED_RATES 14
51#define N_SUPPORTED_RATES 3 51#define N_SUPPORTED_RATES 3
52#define ALL_802_11_BANDS (BAND_A | BAND_B | BAND_G | BAND_GN) 52#define ALL_802_11_BANDS (BAND_A | BAND_B | BAND_G | BAND_GN | \
53 BAND_AN | BAND_GAC | BAND_AAC)
53 54
54#define FW_MULTI_BANDS_SUPPORT (BIT(8) | BIT(9) | BIT(10) | BIT(11)) 55#define FW_MULTI_BANDS_SUPPORT (BIT(8) | BIT(9) | BIT(10) | BIT(11) | \
56 BIT(12) | BIT(13))
55#define IS_SUPPORT_MULTI_BANDS(adapter) \ 57#define IS_SUPPORT_MULTI_BANDS(adapter) \
56 (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT) 58 (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT)
59
60/* shift bit 12 and bit 13 in fw_cap_info from the firmware to bit 13 and 14
61 * for 11ac so that bit 11 is for GN, bit 12 for AN, bit 13 for GAC, and bit
62 * bit 14 for AAC, in order to be compatible with the band capability
63 * defined in the driver after right shift of 8 bits.
64 */
57#define GET_FW_DEFAULT_BANDS(adapter) \ 65#define GET_FW_DEFAULT_BANDS(adapter) \
58 ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS) 66 (((((adapter->fw_cap_info & 0x3000) << 1) | \
67 (adapter->fw_cap_info & ~0xF000)) >> 8) & \
68 ALL_802_11_BANDS)
59 69
60#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff 70#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff
61 71
@@ -216,6 +226,47 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
216 226
217#define LLC_SNAP_LEN 8 227#define LLC_SNAP_LEN 8
218 228
229/* HW_SPEC fw_cap_info */
230
231#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(13)|BIT(14)))
232
233#define GET_VHTCAP_MAXMPDULEN(vht_cap_info) (vht_cap_info & 0x3)
234#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3)
235#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3)
236#define SET_VHTNSSMCS(mcs_mapset, nss, value) (mcs_mapset |= (value & 0x3) << \
237 (2 * (nss - 1)))
238#define NO_NSS_SUPPORT 0x3
239
240/* HW_SPEC: HTC-VHT supported */
241#define ISSUPP_11ACVHTHTCVHT(Dot11acDevCap) (Dot11acDevCap & BIT(22))
242/* HW_SPEC: VHT TXOP PS support */
243#define ISSUPP_11ACVHTTXOPPS(Dot11acDevCap) (Dot11acDevCap & BIT(21))
244/* HW_SPEC: MU RX beamformee support */
245#define ISSUPP_11ACMURXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(20))
246/* HW_SPEC: MU TX beamformee support */
247#define ISSUPP_11ACMUTXBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(19))
248/* HW_SPEC: SU Beamformee support */
249#define ISSUPP_11ACSUBEAMFORMEE(Dot11acDevCap) (Dot11acDevCap & BIT(10))
250/* HW_SPEC: SU Beamformer support */
251#define ISSUPP_11ACSUBEAMFORMER(Dot11acDevCap) (Dot11acDevCap & BIT(9))
252/* HW_SPEC: Rx STBC support */
253#define ISSUPP_11ACRXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(8))
254/* HW_SPEC: Tx STBC support */
255#define ISSUPP_11ACTXSTBC(Dot11acDevCap) (Dot11acDevCap & BIT(7))
256/* HW_SPEC: Short GI support for 160MHz BW */
257#define ISSUPP_11ACSGI160(Dot11acDevCap) (Dot11acDevCap & BIT(6))
258/* HW_SPEC: Short GI support for 80MHz BW */
259#define ISSUPP_11ACSGI80(Dot11acDevCap) (Dot11acDevCap & BIT(5))
260/* HW_SPEC: LDPC coding support */
261#define ISSUPP_11ACLDPC(Dot11acDevCap) (Dot11acDevCap & BIT(4))
262/* HW_SPEC: Channel BW 20/40/80/160/80+80 MHz support */
263#define ISSUPP_11ACBW8080(Dot11acDevCap) (Dot11acDevCap & BIT(3))
264/* HW_SPEC: Channel BW 20/40/80/160 MHz support */
265#define ISSUPP_11ACBW160(Dot11acDevCap) (Dot11acDevCap & BIT(2))
266
267#define GET_DEVTXMCSMAP(dev_mcs_map) (dev_mcs_map >> 16)
268#define GET_DEVRXMCSMAP(dev_mcs_map) (dev_mcs_map & 0xFFFF)
269
219#define MOD_CLASS_HR_DSSS 0x03 270#define MOD_CLASS_HR_DSSS 0x03
220#define MOD_CLASS_OFDM 0x07 271#define MOD_CLASS_OFDM 0x07
221#define MOD_CLASS_HT 0x08 272#define MOD_CLASS_HT 0x08
@@ -455,9 +506,22 @@ struct rxpd {
455 u8 rx_rate; 506 u8 rx_rate;
456 s8 snr; 507 s8 snr;
457 s8 nf; 508 s8 nf;
458 /* Ht Info [Bit 0] RxRate format: LG=0, HT=1 509
510 /* For: Non-802.11 AC cards
511 *
512 * Ht Info [Bit 0] RxRate format: LG=0, HT=1
459 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1 513 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
460 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */ 514 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1
515 *
516 * For: 802.11 AC cards
517 * [Bit 1] [Bit 0] RxRate format: legacy rate = 00 HT = 01 VHT = 10
518 * [Bit 3] [Bit 2] HT/VHT Bandwidth BW20 = 00 BW40 = 01
519 * BW80 = 10 BW160 = 11
520 * [Bit 4] HT/VHT Guard interval LGI = 0 SGI = 1
521 * [Bit 5] STBC support Enabled = 1
522 * [Bit 6] LDPC support Enabled = 1
523 * [Bit 7] Reserved
524 */
461 u8 ht_info; 525 u8 ht_info;
462 u8 reserved; 526 u8 reserved;
463} __packed; 527} __packed;
@@ -680,7 +744,11 @@ struct host_cmd_ds_get_hw_spec {
680 __le32 dot_11n_dev_cap; 744 __le32 dot_11n_dev_cap;
681 u8 dev_mcs_support; 745 u8 dev_mcs_support;
682 __le16 mp_end_port; /* SDIO only, reserved for other interfacces */ 746 __le16 mp_end_port; /* SDIO only, reserved for other interfacces */
683 __le16 reserved_4; 747 __le16 mgmt_buf_count; /* mgmt IE buffer count */
748 __le32 reserved_5;
749 __le32 reserved_6;
750 __le32 dot_11ac_dev_cap;
751 __le32 dot_11ac_mcs_support;
684} __packed; 752} __packed;
685 753
686struct host_cmd_ds_802_11_rssi_info { 754struct host_cmd_ds_802_11_rssi_info {
@@ -786,6 +854,12 @@ union ieee_types_phy_param_set {
786 struct ieee_types_ds_param_set ds_param_set; 854 struct ieee_types_ds_param_set ds_param_set;
787} __packed; 855} __packed;
788 856
857struct ieee_types_oper_mode_ntf {
858 u8 element_id;
859 u8 len;
860 u8 oper_mode;
861} __packed;
862
789struct host_cmd_ds_802_11_ad_hoc_start { 863struct host_cmd_ds_802_11_ad_hoc_start {
790 u8 ssid[IEEE80211_MAX_SSID_LEN]; 864 u8 ssid[IEEE80211_MAX_SSID_LEN];
791 u8 bss_mode; 865 u8 bss_mode;
@@ -846,11 +920,27 @@ struct host_cmd_ds_802_11_get_log {
846 __le32 wep_icv_err_cnt[4]; 920 __le32 wep_icv_err_cnt[4];
847}; 921};
848 922
923/* Enumeration for rate format */
924enum _mwifiex_rate_format {
925 MWIFIEX_RATE_FORMAT_LG = 0,
926 MWIFIEX_RATE_FORMAT_HT,
927 MWIFIEX_RATE_FORMAT_VHT,
928 MWIFIEX_RATE_FORMAT_AUTO = 0xFF,
929};
930
849struct host_cmd_ds_tx_rate_query { 931struct host_cmd_ds_tx_rate_query {
850 u8 tx_rate; 932 u8 tx_rate;
851 /* Ht Info [Bit 0] RxRate format: LG=0, HT=1 933 /* Tx Rate Info: For 802.11 AC cards
934 *
935 * [Bit 0-1] tx rate formate: LG = 0, HT = 1, VHT = 2
936 * [Bit 2-3] HT/VHT Bandwidth: BW20 = 0, BW40 = 1, BW80 = 2, BW160 = 3
937 * [Bit 4] HT/VHT Guard Interval: LGI = 0, SGI = 1
938 *
939 * For non-802.11 AC cards
940 * Ht Info [Bit 0] RxRate format: LG=0, HT=1
852 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1 941 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
853 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */ 942 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1
943 */
854 u8 ht_info; 944 u8 ht_info;
855} __packed; 945} __packed;
856 946
@@ -1096,6 +1186,7 @@ struct host_cmd_ds_11n_cfg {
1096 __le16 action; 1186 __le16 action;
1097 __le16 ht_tx_cap; 1187 __le16 ht_tx_cap;
1098 __le16 ht_tx_info; 1188 __le16 ht_tx_info;
1189 __le16 misc_config; /* Needed for 802.11AC cards only */
1099} __packed; 1190} __packed;
1100 1191
1101struct host_cmd_ds_txbuf_cfg { 1192struct host_cmd_ds_txbuf_cfg {
@@ -1183,6 +1274,26 @@ struct mwifiex_ie_types_htcap {
1183 struct ieee80211_ht_cap ht_cap; 1274 struct ieee80211_ht_cap ht_cap;
1184} __packed; 1275} __packed;
1185 1276
1277struct mwifiex_ie_types_vhtcap {
1278 struct mwifiex_ie_types_header header;
1279 struct ieee80211_vht_cap vht_cap;
1280} __packed;
1281
1282struct mwifiex_ie_types_oper_mode_ntf {
1283 struct mwifiex_ie_types_header header;
1284 u8 oper_mode;
1285} __packed;
1286
1287/* VHT Operations IE */
1288struct mwifiex_ie_types_vht_oper {
1289 struct mwifiex_ie_types_header header;
1290 u8 chan_width;
1291 u8 chan_center_freq_1;
1292 u8 chan_center_freq_2;
1293 /* Basic MCS set map, each 2 bits stands for a NSS */
1294 u16 basic_mcs_map;
1295} __packed;
1296
1186struct mwifiex_ie_types_wmmcap { 1297struct mwifiex_ie_types_wmmcap {
1187 struct mwifiex_ie_types_header header; 1298 struct mwifiex_ie_types_header header;
1188 struct mwifiex_types_wmm_info wmm_info; 1299 struct mwifiex_types_wmm_info wmm_info;
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index f3d9d0445529..d85e6eb1f58a 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -60,6 +60,8 @@ enum {
60 BAND_A = 4, 60 BAND_A = 4,
61 BAND_GN = 8, 61 BAND_GN = 8,
62 BAND_AN = 16, 62 BAND_AN = 16,
63 BAND_GAC = 32,
64 BAND_AAC = 64,
63}; 65};
64 66
65#define MWIFIEX_WPA_PASSHPHRASE_LEN 64 67#define MWIFIEX_WPA_PASSHPHRASE_LEN 64
@@ -103,6 +105,7 @@ struct mwifiex_uap_bss_param {
103 struct wpa_param wpa_cfg; 105 struct wpa_param wpa_cfg;
104 struct wep_key wep_cfg[NUM_WEP_KEYS]; 106 struct wep_key wep_cfg[NUM_WEP_KEYS];
105 struct ieee80211_ht_cap ht_cap; 107 struct ieee80211_ht_cap ht_cap;
108 struct ieee80211_vht_cap vht_cap;
106 u8 rates[MWIFIEX_SUPPORTED_RATES]; 109 u8 rates[MWIFIEX_SUPPORTED_RATES];
107 u32 sta_ao_timer; 110 u32 sta_ao_timer;
108 u32 ps_sta_ao_timer; 111 u32 ps_sta_ao_timer;
@@ -272,6 +275,7 @@ struct mwifiex_ds_pm_cfg {
272struct mwifiex_ds_11n_tx_cfg { 275struct mwifiex_ds_11n_tx_cfg {
273 u16 tx_htcap; 276 u16 tx_htcap;
274 u16 tx_htinfo; 277 u16 tx_htinfo;
278 u16 misc_config; /* Needed for 802.11AC cards only */
275}; 279};
276 280
277struct mwifiex_ds_11n_amsdu_aggr_ctrl { 281struct mwifiex_ds_11n_amsdu_aggr_ctrl {
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index a537297866c6..246aa62a4817 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9))) 29#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
29 30
@@ -512,6 +513,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
512 priv->adapter->config_bands & BAND_AN)) 513 priv->adapter->config_bands & BAND_AN))
513 mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); 514 mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
514 515
516 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
517 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
518 (priv->adapter->config_bands & BAND_GAC ||
519 priv->adapter->config_bands & BAND_AAC))
520 mwifiex_cmd_append_11ac_tlv(priv, bss_desc, &pos);
521
515 /* Append vendor specific IE TLV */ 522 /* Append vendor specific IE TLV */
516 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos); 523 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
517 524
@@ -1421,6 +1428,7 @@ mwifiex_band_to_radio_type(u8 band)
1421 case BAND_A: 1428 case BAND_A:
1422 case BAND_AN: 1429 case BAND_AN:
1423 case BAND_A | BAND_AN: 1430 case BAND_A | BAND_AN:
1431 case BAND_A | BAND_AN | BAND_AAC:
1424 return HostCmd_SCAN_RADIO_TYPE_A; 1432 return HostCmd_SCAN_RADIO_TYPE_A;
1425 case BAND_B: 1433 case BAND_B:
1426 case BAND_G: 1434 case BAND_G:
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index ac799a046eb7..553adfb0aa81 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -295,6 +295,13 @@ struct mwifiex_bssdescriptor {
295 u16 bss_co_2040_offset; 295 u16 bss_co_2040_offset;
296 u8 *bcn_ext_cap; 296 u8 *bcn_ext_cap;
297 u16 ext_cap_offset; 297 u16 ext_cap_offset;
298 struct ieee80211_vht_cap *bcn_vht_cap;
299 u16 vht_cap_offset;
300 struct ieee80211_vht_operation *bcn_vht_oper;
301 u16 vht_info_offset;
302 struct ieee_types_oper_mode_ntf *oper_mode;
303 u16 oper_mode_offset;
304 u8 disable_11ac;
298 struct ieee_types_vendor_specific *bcn_wpa_ie; 305 struct ieee_types_vendor_specific *bcn_wpa_ie;
299 u16 wpa_offset; 306 u16 wpa_offset;
300 struct ieee_types_generic *bcn_rsn_ie; 307 struct ieee_types_generic *bcn_rsn_ie;
@@ -499,6 +506,7 @@ struct mwifiex_private {
499 u16 rsn_idx; 506 u16 rsn_idx;
500 struct timer_list scan_delay_timer; 507 struct timer_list scan_delay_timer;
501 u8 ap_11n_enabled; 508 u8 ap_11n_enabled;
509 u8 ap_11ac_enabled;
502 u32 mgmt_frame_mask; 510 u32 mgmt_frame_mask;
503 struct mwifiex_roc_cfg roc_cfg; 511 struct mwifiex_roc_cfg roc_cfg;
504}; 512};
@@ -722,6 +730,15 @@ struct mwifiex_adapter {
722 u16 max_mgmt_ie_index; 730 u16 max_mgmt_ie_index;
723 u8 scan_delay_cnt; 731 u8 scan_delay_cnt;
724 u8 empty_tx_q_cnt; 732 u8 empty_tx_q_cnt;
733
734 /* 11AC */
735 u32 is_hw_11ac_capable;
736 u32 hw_dot_11ac_dev_cap;
737 u32 hw_dot_11ac_mcs_support;
738 u32 usr_dot_11ac_dev_cap_bg;
739 u32 usr_dot_11ac_dev_cap_a;
740 u32 usr_dot_11ac_mcs_support;
741
725 atomic_t is_tx_received; 742 atomic_t is_tx_received;
726 atomic_t pending_bridged_pkts; 743 atomic_t pending_bridged_pkts;
727}; 744};
@@ -864,8 +881,10 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
864int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); 881int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd);
865struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv, 882struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv,
866 u8 band, u16 channel, u32 freq); 883 u8 band, u16 channel, u32 freq);
867u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, 884u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
868 u8 ht_info); 885 u8 index, u8 ht_info);
886u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv,
887 u8 index, u8 ht_info);
869u32 mwifiex_find_freq_from_band_chan(u8, u8); 888u32 mwifiex_find_freq_from_band_chan(u8, u8);
870int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, 889int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
871 u8 **buffer); 890 u8 **buffer);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 492655c048d1..4b54bcf382f3 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1023,10 +1023,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
1023 adapter->data_sent = false; 1023 adapter->data_sent = false;
1024 1024
1025 if (card->txbd_flush) { 1025 if (card->txbd_flush) {
1026 if (((card->txbd_wrptr & reg->tx_mask) == 1026 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
1027 (card->txbd_rdptr & reg->tx_mask)) &&
1028 ((card->txbd_wrptr & reg->tx_rollover_ind) !=
1029 (card->txbd_rdptr & reg->tx_rollover_ind)))
1030 card->txbd_flush = 0; 1027 card->txbd_flush = 0;
1031 else 1028 else
1032 mwifiex_clean_pcie_ring_buf(adapter); 1029 mwifiex_clean_pcie_ring_buf(adapter);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index e0cce1b52d55..bb60c2754a97 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1250,6 +1250,23 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1250 sizeof(struct ieee_types_header) - 1250 sizeof(struct ieee_types_header) -
1251 bss_entry->beacon_buf); 1251 bss_entry->beacon_buf);
1252 break; 1252 break;
1253 case WLAN_EID_VHT_CAPABILITY:
1254 bss_entry->disable_11ac = false;
1255 bss_entry->bcn_vht_cap =
1256 (void *)(current_ptr +
1257 sizeof(struct ieee_types_header));
1258 bss_entry->vht_cap_offset =
1259 (u16)((u8 *)bss_entry->bcn_vht_cap -
1260 bss_entry->beacon_buf);
1261 break;
1262 case WLAN_EID_VHT_OPERATION:
1263 bss_entry->bcn_vht_oper =
1264 (void *)(current_ptr +
1265 sizeof(struct ieee_types_header));
1266 bss_entry->vht_info_offset =
1267 (u16)((u8 *)bss_entry->bcn_vht_oper -
1268 bss_entry->beacon_buf);
1269 break;
1253 case WLAN_EID_BSS_COEX_2040: 1270 case WLAN_EID_BSS_COEX_2040:
1254 bss_entry->bcn_bss_co_2040 = current_ptr + 1271 bss_entry->bcn_bss_co_2040 = current_ptr +
1255 sizeof(struct ieee_types_header); 1272 sizeof(struct ieee_types_header);
@@ -1264,6 +1281,14 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1264 sizeof(struct ieee_types_header) - 1281 sizeof(struct ieee_types_header) -
1265 bss_entry->beacon_buf); 1282 bss_entry->beacon_buf);
1266 break; 1283 break;
1284 case WLAN_EID_OPMODE_NOTIF:
1285 bss_entry->oper_mode =
1286 (void *)(current_ptr +
1287 sizeof(struct ieee_types_header));
1288 bss_entry->oper_mode_offset =
1289 (u16)((u8 *)bss_entry->oper_mode -
1290 bss_entry->beacon_buf);
1291 break;
1267 default: 1292 default:
1268 break; 1293 break;
1269 } 1294 }
@@ -1479,20 +1504,26 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1479 priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL; 1504 priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
1480 priv->curr_bss_params.bss_descriptor.wapi_offset = 0; 1505 priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
1481 priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL; 1506 priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
1482 priv->curr_bss_params.bss_descriptor.ht_cap_offset = 1507 priv->curr_bss_params.bss_descriptor.ht_cap_offset = 0;
1483 0;
1484 priv->curr_bss_params.bss_descriptor.bcn_ht_oper = NULL; 1508 priv->curr_bss_params.bss_descriptor.bcn_ht_oper = NULL;
1485 priv->curr_bss_params.bss_descriptor.ht_info_offset = 1509 priv->curr_bss_params.bss_descriptor.ht_info_offset = 0;
1486 0; 1510 priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 = NULL;
1487 priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 = 1511 priv->curr_bss_params.bss_descriptor.bss_co_2040_offset = 0;
1488 NULL;
1489 priv->curr_bss_params.bss_descriptor.
1490 bss_co_2040_offset = 0;
1491 priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL; 1512 priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
1492 priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0; 1513 priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
1493 priv->curr_bss_params.bss_descriptor.beacon_buf = NULL; 1514 priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
1494 priv->curr_bss_params.bss_descriptor.beacon_buf_size = 1515 priv->curr_bss_params.bss_descriptor.beacon_buf_size = 0;
1495 0; 1516 priv->curr_bss_params.bss_descriptor.bcn_vht_cap = NULL;
1517 priv->curr_bss_params.bss_descriptor.vht_cap_offset = 0;
1518 priv->curr_bss_params.bss_descriptor.bcn_vht_oper = NULL;
1519 priv->curr_bss_params.bss_descriptor.vht_info_offset = 0;
1520 priv->curr_bss_params.bss_descriptor.oper_mode = NULL;
1521 priv->curr_bss_params.bss_descriptor.oper_mode_offset = 0;
1522
1523 /* Disable 11ac by default. Enable it only where there
1524 * exist VHT_CAP IE in AP beacon
1525 */
1526 priv->curr_bss_params.bss_descriptor.disable_11ac = true;
1496 1527
1497 /* Make a copy of current BSSID descriptor */ 1528 /* Make a copy of current BSSID descriptor */
1498 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, 1529 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
@@ -2022,6 +2053,14 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2022 (curr_bss->beacon_buf + 2053 (curr_bss->beacon_buf +
2023 curr_bss->ht_info_offset); 2054 curr_bss->ht_info_offset);
2024 2055
2056 if (curr_bss->bcn_vht_cap)
2057 curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf +
2058 curr_bss->vht_cap_offset);
2059
2060 if (curr_bss->bcn_vht_oper)
2061 curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf +
2062 curr_bss->vht_info_offset);
2063
2025 if (curr_bss->bcn_bss_co_2040) 2064 if (curr_bss->bcn_bss_co_2040)
2026 curr_bss->bcn_bss_co_2040 = 2065 curr_bss->bcn_bss_co_2040 =
2027 (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset); 2066 (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
@@ -2029,6 +2068,10 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2029 if (curr_bss->bcn_ext_cap) 2068 if (curr_bss->bcn_ext_cap)
2030 curr_bss->bcn_ext_cap = curr_bss->beacon_buf + 2069 curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
2031 curr_bss->ext_cap_offset; 2070 curr_bss->ext_cap_offset;
2071
2072 if (curr_bss->oper_mode)
2073 curr_bss->oper_mode = (void *)(curr_bss->beacon_buf +
2074 curr_bss->oper_mode_offset);
2032} 2075}
2033 2076
2034/* 2077/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index c4607859d59d..c55c5bb93134 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1230,7 +1230,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1230 data_buf); 1230 data_buf);
1231 break; 1231 break;
1232 case HostCmd_CMD_11N_CFG: 1232 case HostCmd_CMD_11N_CFG:
1233 ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); 1233 ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, data_buf);
1234 break; 1234 break;
1235 case HostCmd_CMD_WMM_GET_STATUS: 1235 case HostCmd_CMD_WMM_GET_STATUS:
1236 dev_dbg(priv->adapter->dev, 1236 dev_dbg(priv->adapter->dev,
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 847056415ac9..4669f8d9389f 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -24,6 +24,7 @@
24#include "main.h" 24#include "main.h"
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h"
27 28
28 29
29/* 30/*
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 7eef74564a92..9f33c92c90f5 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -281,9 +281,10 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
281 281
282 if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band) 282 if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
283 == HostCmd_SCAN_RADIO_TYPE_BG) 283 == HostCmd_SCAN_RADIO_TYPE_BG)
284 config_bands = BAND_B | BAND_G | BAND_GN; 284 config_bands = BAND_B | BAND_G | BAND_GN |
285 BAND_GAC;
285 else 286 else
286 config_bands = BAND_A | BAND_AN; 287 config_bands = BAND_A | BAND_AN | BAND_AAC;
287 288
288 if (!((config_bands | adapter->fw_bands) & 289 if (!((config_bands | adapter->fw_bands) &
289 ~adapter->fw_bands)) 290 ~adapter->fw_bands))
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index 01624dcaf73e..7744f42de1ea 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -804,10 +804,15 @@ static inline int ezusb_8051_cpucs(struct ezusb_priv *upriv, int reset)
804static int ezusb_firmware_download(struct ezusb_priv *upriv, 804static int ezusb_firmware_download(struct ezusb_priv *upriv,
805 struct ez_usb_fw *fw) 805 struct ez_usb_fw *fw)
806{ 806{
807 u8 fw_buffer[FW_BUF_SIZE]; 807 u8 *fw_buffer;
808 int retval, addr; 808 int retval, addr;
809 int variant_offset; 809 int variant_offset;
810 810
811 fw_buffer = kmalloc(FW_BUF_SIZE, GFP_KERNEL);
812 if (!fw_buffer) {
813 printk(KERN_ERR PFX "Out of memory for firmware buffer.\n");
814 return -ENOMEM;
815 }
811 /* 816 /*
812 * This byte is 1 and should be replaced with 0. The offset is 817 * This byte is 1 and should be replaced with 0. The offset is
813 * 0x10AD in version 0.0.6. The byte in question should follow 818 * 0x10AD in version 0.0.6. The byte in question should follow
@@ -859,6 +864,7 @@ static int ezusb_firmware_download(struct ezusb_priv *upriv,
859 printk(KERN_ERR PFX "Firmware download failed, error %d\n", 864 printk(KERN_ERR PFX "Firmware download failed, error %d\n",
860 retval); 865 retval);
861 exit: 866 exit:
867 kfree(fw_buffer);
862 return retval; 868 return retval;
863} 869}
864 870
@@ -1681,7 +1687,8 @@ static int ezusb_probe(struct usb_interface *interface,
1681 firmware.code = fw_entry->data; 1687 firmware.code = fw_entry->data;
1682 } 1688 }
1683 if (firmware.size && firmware.code) { 1689 if (firmware.size && firmware.code) {
1684 ezusb_firmware_download(upriv, &firmware); 1690 if (ezusb_firmware_download(upriv, &firmware))
1691 goto error;
1685 } else { 1692 } else {
1686 err("No firmware to download"); 1693 err("No firmware to download");
1687 goto error; 1694 goto error;
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 476eaef5e4a9..156b52732f3d 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -42,8 +42,12 @@
42 42
43static void usbctrl_async_callback(struct urb *urb) 43static void usbctrl_async_callback(struct urb *urb)
44{ 44{
45 if (urb) 45 if (urb) {
46 kfree(urb->context); 46 /* free dr */
47 kfree(urb->setup_packet);
48 /* free databuf */
49 kfree(urb->transfer_buffer);
50 }
47} 51}
48 52
49static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, 53static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
@@ -55,39 +59,47 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
55 u8 reqtype; 59 u8 reqtype;
56 struct usb_ctrlrequest *dr; 60 struct usb_ctrlrequest *dr;
57 struct urb *urb; 61 struct urb *urb;
58 struct rtl819x_async_write_data { 62 const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE;
59 u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE]; 63 u8 *databuf;
60 struct usb_ctrlrequest dr; 64
61 } *buf; 65 if (WARN_ON_ONCE(len > databuf_maxlen))
66 len = databuf_maxlen;
62 67
63 pipe = usb_sndctrlpipe(udev, 0); /* write_out */ 68 pipe = usb_sndctrlpipe(udev, 0); /* write_out */
64 reqtype = REALTEK_USB_VENQT_WRITE; 69 reqtype = REALTEK_USB_VENQT_WRITE;
65 70
66 buf = kmalloc(sizeof(*buf), GFP_ATOMIC); 71 dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
67 if (!buf) 72 if (!dr)
68 return -ENOMEM; 73 return -ENOMEM;
69 74
75 databuf = kmalloc(databuf_maxlen, GFP_ATOMIC);
76 if (!databuf) {
77 kfree(dr);
78 return -ENOMEM;
79 }
80
70 urb = usb_alloc_urb(0, GFP_ATOMIC); 81 urb = usb_alloc_urb(0, GFP_ATOMIC);
71 if (!urb) { 82 if (!urb) {
72 kfree(buf); 83 kfree(databuf);
84 kfree(dr);
73 return -ENOMEM; 85 return -ENOMEM;
74 } 86 }
75 87
76 dr = &buf->dr;
77
78 dr->bRequestType = reqtype; 88 dr->bRequestType = reqtype;
79 dr->bRequest = request; 89 dr->bRequest = request;
80 dr->wValue = cpu_to_le16(value); 90 dr->wValue = cpu_to_le16(value);
81 dr->wIndex = cpu_to_le16(index); 91 dr->wIndex = cpu_to_le16(index);
82 dr->wLength = cpu_to_le16(len); 92 dr->wLength = cpu_to_le16(len);
83 /* data are already in little-endian order */ 93 /* data are already in little-endian order */
84 memcpy(buf, pdata, len); 94 memcpy(databuf, pdata, len);
85 usb_fill_control_urb(urb, udev, pipe, 95 usb_fill_control_urb(urb, udev, pipe,
86 (unsigned char *)dr, buf, len, 96 (unsigned char *)dr, databuf, len,
87 usbctrl_async_callback, buf); 97 usbctrl_async_callback, NULL);
88 rc = usb_submit_urb(urb, GFP_ATOMIC); 98 rc = usb_submit_urb(urb, GFP_ATOMIC);
89 if (rc < 0) 99 if (rc < 0) {
90 kfree(buf); 100 kfree(databuf);
101 kfree(dr);
102 }
91 usb_free_urb(urb); 103 usb_free_urb(urb);
92 return rc; 104 return rc;
93} 105}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 179dcbd8be1c..09d96a8f6c2c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1500,13 +1500,13 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
1500 return -ENOENT; 1500 return -ENOENT;
1501 } 1501 }
1502 1502
1503 err = mesh_path_add(dst, sdata); 1503 err = mesh_path_add(sdata, dst);
1504 if (err) { 1504 if (err) {
1505 rcu_read_unlock(); 1505 rcu_read_unlock();
1506 return err; 1506 return err;
1507 } 1507 }
1508 1508
1509 mpath = mesh_path_lookup(dst, sdata); 1509 mpath = mesh_path_lookup(sdata, dst);
1510 if (!mpath) { 1510 if (!mpath) {
1511 rcu_read_unlock(); 1511 rcu_read_unlock();
1512 return -ENXIO; 1512 return -ENXIO;
@@ -1518,12 +1518,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
1518} 1518}
1519 1519
1520static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, 1520static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
1521 u8 *dst) 1521 u8 *dst)
1522{ 1522{
1523 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1523 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1524 1524
1525 if (dst) 1525 if (dst)
1526 return mesh_path_del(dst, sdata); 1526 return mesh_path_del(sdata, dst);
1527 1527
1528 mesh_path_flush_by_iface(sdata); 1528 mesh_path_flush_by_iface(sdata);
1529 return 0; 1529 return 0;
@@ -1547,7 +1547,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
1547 return -ENOENT; 1547 return -ENOENT;
1548 } 1548 }
1549 1549
1550 mpath = mesh_path_lookup(dst, sdata); 1550 mpath = mesh_path_lookup(sdata, dst);
1551 if (!mpath) { 1551 if (!mpath) {
1552 rcu_read_unlock(); 1552 rcu_read_unlock();
1553 return -ENOENT; 1553 return -ENOENT;
@@ -1611,7 +1611,7 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
1611 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1611 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1612 1612
1613 rcu_read_lock(); 1613 rcu_read_lock();
1614 mpath = mesh_path_lookup(dst, sdata); 1614 mpath = mesh_path_lookup(sdata, dst);
1615 if (!mpath) { 1615 if (!mpath) {
1616 rcu_read_unlock(); 1616 rcu_read_unlock();
1617 return -ENOENT; 1617 return -ENOENT;
@@ -1632,7 +1632,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1632 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1632 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1633 1633
1634 rcu_read_lock(); 1634 rcu_read_lock();
1635 mpath = mesh_path_lookup_by_idx(idx, sdata); 1635 mpath = mesh_path_lookup_by_idx(sdata, idx);
1636 if (!mpath) { 1636 if (!mpath) {
1637 rcu_read_unlock(); 1637 rcu_read_unlock();
1638 return -ENOENT; 1638 return -ENOENT;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 86c83084542a..2c059e54e885 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -294,7 +294,8 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata)
294 } 294 }
295 } 295 }
296 296
297 if ((sdata->vif.type != NL80211_IFTYPE_AP) || 297 if ((sdata->vif.type != NL80211_IFTYPE_AP &&
298 sdata->vif.type != NL80211_IFTYPE_MESH_POINT) ||
298 !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) { 299 !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) {
299 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; 300 sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
300 return 0; 301 return 0;
@@ -695,6 +696,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
695 696
696 ieee80211_roc_purge(sdata); 697 ieee80211_roc_purge(sdata);
697 698
699 if (sdata->vif.type == NL80211_IFTYPE_STATION)
700 ieee80211_mgd_stop(sdata);
701
698 /* 702 /*
699 * Remove all stations associated with this interface. 703 * Remove all stations associated with this interface.
700 * 704 *
@@ -782,8 +786,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
782 } 786 }
783 } 787 }
784 spin_unlock_irqrestore(&ps->bc_buf.lock, flags); 788 spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
785 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
786 ieee80211_mgd_stop(sdata);
787 } 789 }
788 790
789 if (going_down) 791 if (going_down)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index f9747689d604..d0dd11153a6c 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1173,8 +1173,7 @@ static void __exit ieee80211_exit(void)
1173 rc80211_minstrel_ht_exit(); 1173 rc80211_minstrel_ht_exit();
1174 rc80211_minstrel_exit(); 1174 rc80211_minstrel_exit();
1175 1175
1176 if (mesh_allocated) 1176 ieee80211s_stop();
1177 ieee80211s_stop();
1178 1177
1179 ieee80211_iface_exit(); 1178 ieee80211_iface_exit();
1180 1179
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index a77d40ed4e61..29ce2aa87e7b 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -17,7 +17,7 @@
17#define TMR_RUNNING_MP 1 17#define TMR_RUNNING_MP 1
18#define TMR_RUNNING_MPR 2 18#define TMR_RUNNING_MPR 2
19 19
20int mesh_allocated; 20static int mesh_allocated;
21static struct kmem_cache *rm_cache; 21static struct kmem_cache *rm_cache;
22 22
23bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) 23bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
@@ -36,6 +36,8 @@ void ieee80211s_init(void)
36 36
37void ieee80211s_stop(void) 37void ieee80211s_stop(void)
38{ 38{
39 if (!mesh_allocated)
40 return;
39 mesh_pathtbl_unregister(); 41 mesh_pathtbl_unregister();
40 kmem_cache_destroy(rm_cache); 42 kmem_cache_destroy(rm_cache);
41} 43}
@@ -90,24 +92,22 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
90 (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && 92 (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) &&
91 (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && 93 (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) &&
92 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) 94 (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
93 goto mismatch; 95 return false;
94 96
95 ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata), 97 ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata),
96 &basic_rates); 98 &basic_rates);
97 99
98 if (sdata->vif.bss_conf.basic_rates != basic_rates) 100 if (sdata->vif.bss_conf.basic_rates != basic_rates)
99 goto mismatch; 101 return false;
100 102
101 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan, 103 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
102 ie->ht_operation, &sta_chan_def); 104 ie->ht_operation, &sta_chan_def);
103 105
104 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef, 106 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
105 &sta_chan_def)) 107 &sta_chan_def))
106 goto mismatch; 108 return false;
107 109
108 return true; 110 return true;
109mismatch:
110 return false;
111} 111}
112 112
113/** 113/**
@@ -118,7 +118,7 @@ mismatch:
118bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) 118bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
119{ 119{
120 return (ie->mesh_config->meshconf_cap & 120 return (ie->mesh_config->meshconf_cap &
121 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS) != 0; 121 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS) != 0;
122} 122}
123 123
124/** 124/**
@@ -196,11 +196,12 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
196 if (!sdata->u.mesh.rmc) 196 if (!sdata->u.mesh.rmc)
197 return; 197 return;
198 198
199 for (i = 0; i < RMC_BUCKETS; i++) 199 for (i = 0; i < RMC_BUCKETS; i++) {
200 list_for_each_entry_safe(p, n, &rmc->bucket[i], list) { 200 list_for_each_entry_safe(p, n, &rmc->bucket[i], list) {
201 list_del(&p->list); 201 list_del(&p->list);
202 kmem_cache_free(rm_cache, p); 202 kmem_cache_free(rm_cache, p);
203 } 203 }
204 }
204 205
205 kfree(rmc); 206 kfree(rmc);
206 sdata->u.mesh.rmc = NULL; 207 sdata->u.mesh.rmc = NULL;
@@ -209,6 +210,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
209/** 210/**
210 * mesh_rmc_check - Check frame in recent multicast cache and add if absent. 211 * mesh_rmc_check - Check frame in recent multicast cache and add if absent.
211 * 212 *
213 * @sdata: interface
212 * @sa: source address 214 * @sa: source address
213 * @mesh_hdr: mesh_header 215 * @mesh_hdr: mesh_header
214 * 216 *
@@ -218,8 +220,8 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
218 * received this frame lately. If the frame is not in the cache, it is added to 220 * received this frame lately. If the frame is not in the cache, it is added to
219 * it. 221 * it.
220 */ 222 */
221int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, 223int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
222 struct ieee80211_sub_if_data *sdata) 224 const u8 *sa, struct ieee80211s_hdr *mesh_hdr)
223{ 225{
224 struct mesh_rmc *rmc = sdata->u.mesh.rmc; 226 struct mesh_rmc *rmc = sdata->u.mesh.rmc;
225 u32 seqnum = 0; 227 u32 seqnum = 0;
@@ -233,12 +235,11 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
233 list_for_each_entry_safe(p, n, &rmc->bucket[idx], list) { 235 list_for_each_entry_safe(p, n, &rmc->bucket[idx], list) {
234 ++entries; 236 ++entries;
235 if (time_after(jiffies, p->exp_time) || 237 if (time_after(jiffies, p->exp_time) ||
236 (entries == RMC_QUEUE_MAX_LEN)) { 238 entries == RMC_QUEUE_MAX_LEN) {
237 list_del(&p->list); 239 list_del(&p->list);
238 kmem_cache_free(rm_cache, p); 240 kmem_cache_free(rm_cache, p);
239 --entries; 241 --entries;
240 } else if ((seqnum == p->seqnum) && 242 } else if ((seqnum == p->seqnum) && ether_addr_equal(sa, p->sa))
241 (ether_addr_equal(sa, p->sa)))
242 return -1; 243 return -1;
243 } 244 }
244 245
@@ -253,8 +254,8 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
253 return 0; 254 return 0;
254} 255}
255 256
256int 257int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
257mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) 258 struct sk_buff *skb)
258{ 259{
259 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 260 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
260 u8 *pos, neighbors; 261 u8 *pos, neighbors;
@@ -285,19 +286,18 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
285 /* Mesh capability */ 286 /* Mesh capability */
286 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING; 287 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING;
287 *pos |= ifmsh->accepting_plinks ? 288 *pos |= ifmsh->accepting_plinks ?
288 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 289 IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
289 /* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */ 290 /* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */
290 *pos |= ifmsh->ps_peers_deep_sleep ? 291 *pos |= ifmsh->ps_peers_deep_sleep ?
291 IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL : 0x00; 292 IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL : 0x00;
292 *pos++ |= ifmsh->adjusting_tbtt ? 293 *pos++ |= ifmsh->adjusting_tbtt ?
293 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00; 294 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00;
294 *pos++ = 0x00; 295 *pos++ = 0x00;
295 296
296 return 0; 297 return 0;
297} 298}
298 299
299int 300int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
300mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
301{ 301{
302 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 302 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
303 u8 *pos; 303 u8 *pos;
@@ -314,8 +314,8 @@ mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
314 return 0; 314 return 0;
315} 315}
316 316
317int mesh_add_awake_window_ie(struct sk_buff *skb, 317static int mesh_add_awake_window_ie(struct ieee80211_sub_if_data *sdata,
318 struct ieee80211_sub_if_data *sdata) 318 struct sk_buff *skb)
319{ 319{
320 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 320 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
321 u8 *pos; 321 u8 *pos;
@@ -337,8 +337,8 @@ int mesh_add_awake_window_ie(struct sk_buff *skb,
337 return 0; 337 return 0;
338} 338}
339 339
340int 340int mesh_add_vendor_ies(struct ieee80211_sub_if_data *sdata,
341mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) 341 struct sk_buff *skb)
342{ 342{
343 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 343 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
344 u8 offset, len; 344 u8 offset, len;
@@ -361,8 +361,7 @@ mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
361 return 0; 361 return 0;
362} 362}
363 363
364int 364int mesh_add_rsn_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
365mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
366{ 365{
367 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 366 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
368 u8 len = 0; 367 u8 len = 0;
@@ -390,8 +389,8 @@ mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
390 return 0; 389 return 0;
391} 390}
392 391
393int mesh_add_ds_params_ie(struct sk_buff *skb, 392static int mesh_add_ds_params_ie(struct ieee80211_sub_if_data *sdata,
394 struct ieee80211_sub_if_data *sdata) 393 struct sk_buff *skb)
395{ 394{
396 struct ieee80211_chanctx_conf *chanctx_conf; 395 struct ieee80211_chanctx_conf *chanctx_conf;
397 struct ieee80211_channel *chan; 396 struct ieee80211_channel *chan;
@@ -417,8 +416,8 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
417 return 0; 416 return 0;
418} 417}
419 418
420int mesh_add_ht_cap_ie(struct sk_buff *skb, 419int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
421 struct ieee80211_sub_if_data *sdata) 420 struct sk_buff *skb)
422{ 421{
423 struct ieee80211_local *local = sdata->local; 422 struct ieee80211_local *local = sdata->local;
424 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 423 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
@@ -439,8 +438,8 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
439 return 0; 438 return 0;
440} 439}
441 440
442int mesh_add_ht_oper_ie(struct sk_buff *skb, 441int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
443 struct ieee80211_sub_if_data *sdata) 442 struct sk_buff *skb)
444{ 443{
445 struct ieee80211_local *local = sdata->local; 444 struct ieee80211_local *local = sdata->local;
446 struct ieee80211_chanctx_conf *chanctx_conf; 445 struct ieee80211_chanctx_conf *chanctx_conf;
@@ -475,6 +474,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
475 474
476 return 0; 475 return 0;
477} 476}
477
478static void ieee80211_mesh_path_timer(unsigned long data) 478static void ieee80211_mesh_path_timer(unsigned long data)
479{ 479{
480 struct ieee80211_sub_if_data *sdata = 480 struct ieee80211_sub_if_data *sdata =
@@ -520,7 +520,7 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
520 520
521/** 521/**
522 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame 522 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
523 * @hdr: 802.11 frame header 523 * @hdr: 802.11 frame header
524 * @fc: frame control field 524 * @fc: frame control field
525 * @meshda: destination address in the mesh 525 * @meshda: destination address in the mesh
526 * @meshsa: source address address in the mesh. Same as TA, as frame is 526 * @meshsa: source address address in the mesh. Same as TA, as frame is
@@ -551,8 +551,8 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
551 551
552/** 552/**
553 * ieee80211_new_mesh_header - create a new mesh header 553 * ieee80211_new_mesh_header - create a new mesh header
554 * @meshhdr: uninitialized mesh header
555 * @sdata: mesh interface to be used 554 * @sdata: mesh interface to be used
555 * @meshhdr: uninitialized mesh header
556 * @addr4or5: 1st address in the ae header, which may correspond to address 4 556 * @addr4or5: 1st address in the ae header, which may correspond to address 4
557 * (if addr6 is NULL) or address 5 (if addr6 is present). It may 557 * (if addr6 is NULL) or address 5 (if addr6 is present). It may
558 * be NULL. 558 * be NULL.
@@ -561,32 +561,38 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
561 * 561 *
562 * Return the header length. 562 * Return the header length.
563 */ 563 */
564int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 564int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata,
565 struct ieee80211_sub_if_data *sdata, char *addr4or5, 565 struct ieee80211s_hdr *meshhdr,
566 char *addr6) 566 const char *addr4or5, const char *addr6)
567{ 567{
568 int aelen = 0; 568 if (WARN_ON(!addr4or5 && addr6))
569 BUG_ON(!addr4or5 && addr6); 569 return 0;
570
570 memset(meshhdr, 0, sizeof(*meshhdr)); 571 memset(meshhdr, 0, sizeof(*meshhdr));
572
571 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 573 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
574
575 /* FIXME: racy -- TX on multiple queues can be concurrent */
572 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); 576 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
573 sdata->u.mesh.mesh_seqnum++; 577 sdata->u.mesh.mesh_seqnum++;
578
574 if (addr4or5 && !addr6) { 579 if (addr4or5 && !addr6) {
575 meshhdr->flags |= MESH_FLAGS_AE_A4; 580 meshhdr->flags |= MESH_FLAGS_AE_A4;
576 aelen += ETH_ALEN;
577 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); 581 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
582 return 2 * ETH_ALEN;
578 } else if (addr4or5 && addr6) { 583 } else if (addr4or5 && addr6) {
579 meshhdr->flags |= MESH_FLAGS_AE_A5_A6; 584 meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
580 aelen += 2 * ETH_ALEN;
581 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); 585 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
582 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN); 586 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
587 return 3 * ETH_ALEN;
583 } 588 }
584 return 6 + aelen; 589
590 return ETH_ALEN;
585} 591}
586 592
587static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, 593static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
588 struct ieee80211_if_mesh *ifmsh)
589{ 594{
595 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
590 u32 changed; 596 u32 changed;
591 597
592 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 598 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
@@ -596,7 +602,8 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
596 ieee80211_mbss_info_change_notify(sdata, changed); 602 ieee80211_mbss_info_change_notify(sdata, changed);
597 603
598 mod_timer(&ifmsh->housekeeping_timer, 604 mod_timer(&ifmsh->housekeeping_timer,
599 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 605 round_jiffies(jiffies +
606 IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
600} 607}
601 608
602static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) 609static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
@@ -708,7 +715,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
708 *pos++ = 0x0; 715 *pos++ = 0x0;
709 716
710 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 717 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
711 mesh_add_ds_params_ie(skb, sdata)) 718 mesh_add_ds_params_ie(sdata, skb))
712 goto out_free; 719 goto out_free;
713 720
714 bcn->head_len = skb->len; 721 bcn->head_len = skb->len;
@@ -719,13 +726,13 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
719 bcn->tail = bcn->head + bcn->head_len; 726 bcn->tail = bcn->head + bcn->head_len;
720 727
721 if (ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 728 if (ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
722 mesh_add_rsn_ie(skb, sdata) || 729 mesh_add_rsn_ie(sdata, skb) ||
723 mesh_add_ht_cap_ie(skb, sdata) || 730 mesh_add_ht_cap_ie(sdata, skb) ||
724 mesh_add_ht_oper_ie(skb, sdata) || 731 mesh_add_ht_oper_ie(sdata, skb) ||
725 mesh_add_meshid_ie(skb, sdata) || 732 mesh_add_meshid_ie(sdata, skb) ||
726 mesh_add_meshconf_ie(skb, sdata) || 733 mesh_add_meshconf_ie(sdata, skb) ||
727 mesh_add_awake_window_ie(skb, sdata) || 734 mesh_add_awake_window_ie(sdata, skb) ||
728 mesh_add_vendor_ies(skb, sdata)) 735 mesh_add_vendor_ies(sdata, skb))
729 goto out_free; 736 goto out_free;
730 737
731 bcn->tail_len = skb->len; 738 bcn->tail_len = skb->len;
@@ -918,7 +925,6 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata,
918 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 925 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
919 IEEE80211_STYPE_PROBE_RESP); 926 IEEE80211_STYPE_PROBE_RESP);
920 memcpy(hdr->da, mgmt->sa, ETH_ALEN); 927 memcpy(hdr->da, mgmt->sa, ETH_ALEN);
921 mpl_dbg(sdata, "sending probe resp. to %pM\n", hdr->da);
922 IEEE80211_SKB_CB(presp)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 928 IEEE80211_SKB_CB(presp)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
923 ieee80211_tx_skb(sdata, presp); 929 ieee80211_tx_skb(sdata, presp);
924out: 930out:
@@ -1039,7 +1045,7 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
1039 mesh_mpp_table_grow(); 1045 mesh_mpp_table_grow();
1040 1046
1041 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) 1047 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
1042 ieee80211_mesh_housekeeping(sdata, ifmsh); 1048 ieee80211_mesh_housekeeping(sdata);
1043 1049
1044 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags)) 1050 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
1045 ieee80211_mesh_rootpath(sdata); 1051 ieee80211_mesh_rootpath(sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 1a1da877b1d2..336c88a16687 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -26,12 +26,12 @@
26 * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding 26 * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding
27 * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path 27 * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path
28 * @MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence 28 * @MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence
29 * number 29 * number
30 * @MESH_PATH_FIXED: the mesh path has been manually set and should not be 30 * @MESH_PATH_FIXED: the mesh path has been manually set and should not be
31 * modified 31 * modified
32 * @MESH_PATH_RESOLVED: the mesh path can has been resolved 32 * @MESH_PATH_RESOLVED: the mesh path can has been resolved
33 * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination 33 * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
34 * already queued up, waiting for the discovery process to start. 34 * already queued up, waiting for the discovery process to start.
35 * 35 *
36 * MESH_PATH_RESOLVED is used by the mesh path timer to 36 * MESH_PATH_RESOLVED is used by the mesh path timer to
37 * decide when to stop or cancel the mesh path discovery. 37 * decide when to stop or cancel the mesh path discovery.
@@ -73,16 +73,16 @@ enum mesh_deferred_task_flags {
73 * @dst: mesh path destination mac address 73 * @dst: mesh path destination mac address
74 * @sdata: mesh subif 74 * @sdata: mesh subif
75 * @next_hop: mesh neighbor to which frames for this destination will be 75 * @next_hop: mesh neighbor to which frames for this destination will be
76 * forwarded 76 * forwarded
77 * @timer: mesh path discovery timer 77 * @timer: mesh path discovery timer
78 * @frame_queue: pending queue for frames sent to this destination while the 78 * @frame_queue: pending queue for frames sent to this destination while the
79 * path is unresolved 79 * path is unresolved
80 * @sn: target sequence number 80 * @sn: target sequence number
81 * @metric: current metric to this destination 81 * @metric: current metric to this destination
82 * @hop_count: hops to destination 82 * @hop_count: hops to destination
83 * @exp_time: in jiffies, when the path will expire or when it expired 83 * @exp_time: in jiffies, when the path will expire or when it expired
84 * @discovery_timeout: timeout (lapse in jiffies) used for the last discovery 84 * @discovery_timeout: timeout (lapse in jiffies) used for the last discovery
85 * retry 85 * retry
86 * @discovery_retries: number of discovery retries 86 * @discovery_retries: number of discovery retries
87 * @flags: mesh path flags, as specified on &enum mesh_path_flags 87 * @flags: mesh path flags, as specified on &enum mesh_path_flags
88 * @state_lock: mesh path state lock used to protect changes to the 88 * @state_lock: mesh path state lock used to protect changes to the
@@ -206,38 +206,33 @@ struct mesh_rmc {
206/* Various */ 206/* Various */
207int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 207int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
208 const u8 *da, const u8 *sa); 208 const u8 *da, const u8 *sa);
209int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 209int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata,
210 struct ieee80211_sub_if_data *sdata, char *addr4or5, 210 struct ieee80211s_hdr *meshhdr,
211 char *addr6); 211 const char *addr4or5, const char *addr6);
212int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, 212int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
213 struct ieee80211_sub_if_data *sdata); 213 const u8 *addr, struct ieee80211s_hdr *mesh_hdr);
214bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, 214bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
215 struct ieee802_11_elems *ie); 215 struct ieee802_11_elems *ie);
216void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); 216void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
217void mesh_mgmt_ies_add(struct sk_buff *skb, 217void mesh_mgmt_ies_add(struct ieee80211_sub_if_data *sdata,
218 struct ieee80211_sub_if_data *sdata); 218 struct sk_buff *skb);
219int mesh_add_meshconf_ie(struct sk_buff *skb, 219int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
220 struct ieee80211_sub_if_data *sdata); 220 struct sk_buff *skb);
221int mesh_add_meshid_ie(struct sk_buff *skb, 221int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata,
222 struct ieee80211_sub_if_data *sdata); 222 struct sk_buff *skb);
223int mesh_add_rsn_ie(struct sk_buff *skb, 223int mesh_add_rsn_ie(struct ieee80211_sub_if_data *sdata,
224 struct ieee80211_sub_if_data *sdata); 224 struct sk_buff *skb);
225int mesh_add_awake_window_ie(struct sk_buff *skb, 225int mesh_add_vendor_ies(struct ieee80211_sub_if_data *sdata,
226 struct ieee80211_sub_if_data *sdata); 226 struct sk_buff *skb);
227int mesh_add_vendor_ies(struct sk_buff *skb, 227int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
228 struct ieee80211_sub_if_data *sdata); 228 struct sk_buff *skb);
229int mesh_add_ds_params_ie(struct sk_buff *skb, 229int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
230 struct ieee80211_sub_if_data *sdata); 230 struct sk_buff *skb);
231int mesh_add_ht_cap_ie(struct sk_buff *skb,
232 struct ieee80211_sub_if_data *sdata);
233int mesh_add_ht_oper_ie(struct sk_buff *skb,
234 struct ieee80211_sub_if_data *sdata);
235void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 231void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
236int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 232int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
237void ieee80211s_init(void); 233void ieee80211s_init(void);
238void ieee80211s_update_metric(struct ieee80211_local *local, 234void ieee80211s_update_metric(struct ieee80211_local *local,
239 struct sta_info *sta, struct sk_buff *skb); 235 struct sta_info *sta, struct sk_buff *skb);
240void ieee80211s_stop(void);
241void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 236void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
242int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); 237int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
243void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); 238void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
@@ -263,31 +258,32 @@ void ieee80211_mps_frame_release(struct sta_info *sta,
263 struct ieee802_11_elems *elems); 258 struct ieee802_11_elems *elems);
264 259
265/* Mesh paths */ 260/* Mesh paths */
266int mesh_nexthop_lookup(struct sk_buff *skb, 261int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata,
267 struct ieee80211_sub_if_data *sdata); 262 struct sk_buff *skb);
268int mesh_nexthop_resolve(struct sk_buff *skb, 263int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
269 struct ieee80211_sub_if_data *sdata); 264 struct sk_buff *skb);
270void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata); 265void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
271struct mesh_path *mesh_path_lookup(const u8 *dst, 266struct mesh_path *mesh_path_lookup(struct ieee80211_sub_if_data *sdata,
272 struct ieee80211_sub_if_data *sdata); 267 const u8 *dst);
273struct mesh_path *mpp_path_lookup(u8 *dst, 268struct mesh_path *mpp_path_lookup(struct ieee80211_sub_if_data *sdata,
274 struct ieee80211_sub_if_data *sdata); 269 const u8 *dst);
275int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata); 270int mpp_path_add(struct ieee80211_sub_if_data *sdata,
276struct mesh_path *mesh_path_lookup_by_idx(int idx, 271 const u8 *dst, const u8 *mpp);
277 struct ieee80211_sub_if_data *sdata); 272struct mesh_path *
273mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx);
278void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); 274void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
279void mesh_path_expire(struct ieee80211_sub_if_data *sdata); 275void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
280void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 276void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
281 struct ieee80211_mgmt *mgmt, size_t len); 277 struct ieee80211_mgmt *mgmt, size_t len);
282int mesh_path_add(const u8 *dst, struct ieee80211_sub_if_data *sdata); 278int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst);
283 279
284int mesh_path_add_gate(struct mesh_path *mpath); 280int mesh_path_add_gate(struct mesh_path *mpath);
285int mesh_path_send_to_gates(struct mesh_path *mpath); 281int mesh_path_send_to_gates(struct mesh_path *mpath);
286int mesh_gate_num(struct ieee80211_sub_if_data *sdata); 282int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
283
287/* Mesh plinks */ 284/* Mesh plinks */
288void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 285void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
289 u8 *hw_addr, 286 u8 *hw_addr, struct ieee802_11_elems *ie);
290 struct ieee802_11_elems *ie);
291bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 287bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
292u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 288u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
293void mesh_plink_broken(struct sta_info *sta); 289void mesh_plink_broken(struct sta_info *sta);
@@ -304,19 +300,19 @@ void mesh_sta_cleanup(struct sta_info *sta);
304void mesh_mpath_table_grow(void); 300void mesh_mpath_table_grow(void);
305void mesh_mpp_table_grow(void); 301void mesh_mpp_table_grow(void);
306/* Mesh paths */ 302/* Mesh paths */
307int mesh_path_error_tx(u8 ttl, const u8 *target, __le32 target_sn, 303int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
308 __le16 target_rcode, const u8 *ra, 304 u8 ttl, const u8 *target, __le32 target_sn,
309 struct ieee80211_sub_if_data *sdata); 305 __le16 target_rcode, const u8 *ra);
310void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); 306void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
311void mesh_path_flush_pending(struct mesh_path *mpath); 307void mesh_path_flush_pending(struct mesh_path *mpath);
312void mesh_path_tx_pending(struct mesh_path *mpath); 308void mesh_path_tx_pending(struct mesh_path *mpath);
313int mesh_pathtbl_init(void); 309int mesh_pathtbl_init(void);
314void mesh_pathtbl_unregister(void); 310void mesh_pathtbl_unregister(void);
315int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata); 311int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr);
316void mesh_path_timer(unsigned long data); 312void mesh_path_timer(unsigned long data);
317void mesh_path_flush_by_nexthop(struct sta_info *sta); 313void mesh_path_flush_by_nexthop(struct sta_info *sta);
318void mesh_path_discard_frame(struct sk_buff *skb, 314void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
319 struct ieee80211_sub_if_data *sdata); 315 struct sk_buff *skb);
320void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); 316void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
321void mesh_path_restart(struct ieee80211_sub_if_data *sdata); 317void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
322void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); 318void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
@@ -325,8 +321,6 @@ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
325extern int mesh_paths_generation; 321extern int mesh_paths_generation;
326 322
327#ifdef CONFIG_MAC80211_MESH 323#ifdef CONFIG_MAC80211_MESH
328extern int mesh_allocated;
329
330static inline 324static inline
331u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 325u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
332{ 326{
@@ -371,8 +365,8 @@ void mesh_plink_quiesce(struct sta_info *sta);
371void mesh_plink_restart(struct sta_info *sta); 365void mesh_plink_restart(struct sta_info *sta);
372void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); 366void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
373void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); 367void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
368void ieee80211s_stop(void);
374#else 369#else
375#define mesh_allocated 0
376static inline void 370static inline void
377ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {} 371ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
378static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) 372static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
@@ -385,6 +379,7 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
385{ return false; } 379{ return false; }
386static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) 380static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
387{} 381{}
382static inline void ieee80211s_stop(void) {}
388#endif 383#endif
389 384
390#endif /* IEEE80211S_H */ 385#endif /* IEEE80211S_H */
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 585c1e26cca8..bdb8d3b14587 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -238,9 +238,9 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
238 * also acquires in the TX path. To avoid a deadlock we don't transmit the 238 * also acquires in the TX path. To avoid a deadlock we don't transmit the
239 * frame directly but add it to the pending queue instead. 239 * frame directly but add it to the pending queue instead.
240 */ 240 */
241int mesh_path_error_tx(u8 ttl, const u8 *target, __le32 target_sn, 241int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
242 __le16 target_rcode, const u8 *ra, 242 u8 ttl, const u8 *target, __le32 target_sn,
243 struct ieee80211_sub_if_data *sdata) 243 __le16 target_rcode, const u8 *ra)
244{ 244{
245 struct ieee80211_local *local = sdata->local; 245 struct ieee80211_local *local = sdata->local;
246 struct sk_buff *skb; 246 struct sk_buff *skb;
@@ -430,7 +430,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
430 process = false; 430 process = false;
431 fresh_info = false; 431 fresh_info = false;
432 } else { 432 } else {
433 mpath = mesh_path_lookup(orig_addr, sdata); 433 mpath = mesh_path_lookup(sdata, orig_addr);
434 if (mpath) { 434 if (mpath) {
435 spin_lock_bh(&mpath->state_lock); 435 spin_lock_bh(&mpath->state_lock);
436 if (mpath->flags & MESH_PATH_FIXED) 436 if (mpath->flags & MESH_PATH_FIXED)
@@ -445,8 +445,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
445 } 445 }
446 } 446 }
447 } else { 447 } else {
448 mesh_path_add(orig_addr, sdata); 448 mesh_path_add(sdata, orig_addr);
449 mpath = mesh_path_lookup(orig_addr, sdata); 449 mpath = mesh_path_lookup(sdata, orig_addr);
450 if (!mpath) { 450 if (!mpath) {
451 rcu_read_unlock(); 451 rcu_read_unlock();
452 return 0; 452 return 0;
@@ -478,7 +478,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
478 else { 478 else {
479 fresh_info = true; 479 fresh_info = true;
480 480
481 mpath = mesh_path_lookup(ta, sdata); 481 mpath = mesh_path_lookup(sdata, ta);
482 if (mpath) { 482 if (mpath) {
483 spin_lock_bh(&mpath->state_lock); 483 spin_lock_bh(&mpath->state_lock);
484 if ((mpath->flags & MESH_PATH_FIXED) || 484 if ((mpath->flags & MESH_PATH_FIXED) ||
@@ -486,8 +486,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
486 (last_hop_metric > mpath->metric))) 486 (last_hop_metric > mpath->metric)))
487 fresh_info = false; 487 fresh_info = false;
488 } else { 488 } else {
489 mesh_path_add(ta, sdata); 489 mesh_path_add(sdata, ta);
490 mpath = mesh_path_lookup(ta, sdata); 490 mpath = mesh_path_lookup(sdata, ta);
491 if (!mpath) { 491 if (!mpath) {
492 rcu_read_unlock(); 492 rcu_read_unlock();
493 return 0; 493 return 0;
@@ -553,7 +553,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
553 } else if (is_broadcast_ether_addr(target_addr) && 553 } else if (is_broadcast_ether_addr(target_addr) &&
554 (target_flags & IEEE80211_PREQ_TO_FLAG)) { 554 (target_flags & IEEE80211_PREQ_TO_FLAG)) {
555 rcu_read_lock(); 555 rcu_read_lock();
556 mpath = mesh_path_lookup(orig_addr, sdata); 556 mpath = mesh_path_lookup(sdata, orig_addr);
557 if (mpath) { 557 if (mpath) {
558 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { 558 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
559 reply = true; 559 reply = true;
@@ -568,7 +568,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
568 rcu_read_unlock(); 568 rcu_read_unlock();
569 } else { 569 } else {
570 rcu_read_lock(); 570 rcu_read_lock();
571 mpath = mesh_path_lookup(target_addr, sdata); 571 mpath = mesh_path_lookup(sdata, target_addr);
572 if (mpath) { 572 if (mpath) {
573 if ((!(mpath->flags & MESH_PATH_SN_VALID)) || 573 if ((!(mpath->flags & MESH_PATH_SN_VALID)) ||
574 SN_LT(mpath->sn, target_sn)) { 574 SN_LT(mpath->sn, target_sn)) {
@@ -678,7 +678,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
678 } 678 }
679 679
680 rcu_read_lock(); 680 rcu_read_lock();
681 mpath = mesh_path_lookup(orig_addr, sdata); 681 mpath = mesh_path_lookup(sdata, orig_addr);
682 if (mpath) 682 if (mpath)
683 spin_lock_bh(&mpath->state_lock); 683 spin_lock_bh(&mpath->state_lock);
684 else 684 else
@@ -736,7 +736,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
736 target_rcode = PERR_IE_TARGET_RCODE(perr_elem); 736 target_rcode = PERR_IE_TARGET_RCODE(perr_elem);
737 737
738 rcu_read_lock(); 738 rcu_read_lock();
739 mpath = mesh_path_lookup(target_addr, sdata); 739 mpath = mesh_path_lookup(sdata, target_addr);
740 if (mpath) { 740 if (mpath) {
741 struct sta_info *sta; 741 struct sta_info *sta;
742 742
@@ -751,9 +751,10 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
751 spin_unlock_bh(&mpath->state_lock); 751 spin_unlock_bh(&mpath->state_lock);
752 if (!ifmsh->mshcfg.dot11MeshForwarding) 752 if (!ifmsh->mshcfg.dot11MeshForwarding)
753 goto endperr; 753 goto endperr;
754 mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn), 754 mesh_path_error_tx(sdata, ttl, target_addr,
755 cpu_to_le32(target_sn),
755 cpu_to_le16(target_rcode), 756 cpu_to_le16(target_rcode),
756 broadcast_addr, sdata); 757 broadcast_addr);
757 } else 758 } else
758 spin_unlock_bh(&mpath->state_lock); 759 spin_unlock_bh(&mpath->state_lock);
759 } 760 }
@@ -801,10 +802,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
801 802
802 metric_txsta = airtime_link_metric_get(local, sta); 803 metric_txsta = airtime_link_metric_get(local, sta);
803 804
804 mpath = mesh_path_lookup(orig_addr, sdata); 805 mpath = mesh_path_lookup(sdata, orig_addr);
805 if (!mpath) { 806 if (!mpath) {
806 mesh_path_add(orig_addr, sdata); 807 mesh_path_add(sdata, orig_addr);
807 mpath = mesh_path_lookup(orig_addr, sdata); 808 mpath = mesh_path_lookup(sdata, orig_addr);
808 if (!mpath) { 809 if (!mpath) {
809 rcu_read_unlock(); 810 rcu_read_unlock();
810 sdata->u.mesh.mshstats.dropped_frames_no_route++; 811 sdata->u.mesh.mshstats.dropped_frames_no_route++;
@@ -861,8 +862,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
861 862
862 863
863void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 864void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
864 struct ieee80211_mgmt *mgmt, 865 struct ieee80211_mgmt *mgmt, size_t len)
865 size_t len)
866{ 866{
867 struct ieee802_11_elems elems; 867 struct ieee802_11_elems elems;
868 size_t baselen; 868 size_t baselen;
@@ -1006,7 +1006,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
1006 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); 1006 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
1007 1007
1008 rcu_read_lock(); 1008 rcu_read_lock();
1009 mpath = mesh_path_lookup(preq_node->dst, sdata); 1009 mpath = mesh_path_lookup(sdata, preq_node->dst);
1010 if (!mpath) 1010 if (!mpath)
1011 goto enddiscovery; 1011 goto enddiscovery;
1012 1012
@@ -1076,8 +1076,8 @@ enddiscovery:
1076 * Returns: 0 if the next hop was found and -ENOENT if the frame was queued. 1076 * Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
1077 * skb is freeed here if no mpath could be allocated. 1077 * skb is freeed here if no mpath could be allocated.
1078 */ 1078 */
1079int mesh_nexthop_resolve(struct sk_buff *skb, 1079int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
1080 struct ieee80211_sub_if_data *sdata) 1080 struct sk_buff *skb)
1081{ 1081{
1082 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1082 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1083 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1083 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1091,17 +1091,17 @@ int mesh_nexthop_resolve(struct sk_buff *skb,
1091 return 0; 1091 return 0;
1092 1092
1093 rcu_read_lock(); 1093 rcu_read_lock();
1094 err = mesh_nexthop_lookup(skb, sdata); 1094 err = mesh_nexthop_lookup(sdata, skb);
1095 if (!err) 1095 if (!err)
1096 goto endlookup; 1096 goto endlookup;
1097 1097
1098 /* no nexthop found, start resolving */ 1098 /* no nexthop found, start resolving */
1099 mpath = mesh_path_lookup(target_addr, sdata); 1099 mpath = mesh_path_lookup(sdata, target_addr);
1100 if (!mpath) { 1100 if (!mpath) {
1101 mesh_path_add(target_addr, sdata); 1101 mesh_path_add(sdata, target_addr);
1102 mpath = mesh_path_lookup(target_addr, sdata); 1102 mpath = mesh_path_lookup(sdata, target_addr);
1103 if (!mpath) { 1103 if (!mpath) {
1104 mesh_path_discard_frame(skb, sdata); 1104 mesh_path_discard_frame(sdata, skb);
1105 err = -ENOSPC; 1105 err = -ENOSPC;
1106 goto endlookup; 1106 goto endlookup;
1107 } 1107 }
@@ -1118,12 +1118,13 @@ int mesh_nexthop_resolve(struct sk_buff *skb,
1118 skb_queue_tail(&mpath->frame_queue, skb); 1118 skb_queue_tail(&mpath->frame_queue, skb);
1119 err = -ENOENT; 1119 err = -ENOENT;
1120 if (skb_to_free) 1120 if (skb_to_free)
1121 mesh_path_discard_frame(skb_to_free, sdata); 1121 mesh_path_discard_frame(sdata, skb_to_free);
1122 1122
1123endlookup: 1123endlookup:
1124 rcu_read_unlock(); 1124 rcu_read_unlock();
1125 return err; 1125 return err;
1126} 1126}
1127
1127/** 1128/**
1128 * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling 1129 * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
1129 * this function is considered "using" the associated mpath, so preempt a path 1130 * this function is considered "using" the associated mpath, so preempt a path
@@ -1134,8 +1135,8 @@ endlookup:
1134 * 1135 *
1135 * Returns: 0 if the next hop was found. Nonzero otherwise. 1136 * Returns: 0 if the next hop was found. Nonzero otherwise.
1136 */ 1137 */
1137int mesh_nexthop_lookup(struct sk_buff *skb, 1138int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata,
1138 struct ieee80211_sub_if_data *sdata) 1139 struct sk_buff *skb)
1139{ 1140{
1140 struct mesh_path *mpath; 1141 struct mesh_path *mpath;
1141 struct sta_info *next_hop; 1142 struct sta_info *next_hop;
@@ -1144,7 +1145,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
1144 int err = -ENOENT; 1145 int err = -ENOENT;
1145 1146
1146 rcu_read_lock(); 1147 rcu_read_lock();
1147 mpath = mesh_path_lookup(target_addr, sdata); 1148 mpath = mesh_path_lookup(sdata, target_addr);
1148 1149
1149 if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) 1150 if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
1150 goto endlookup; 1151 goto endlookup;
@@ -1203,8 +1204,7 @@ void mesh_path_timer(unsigned long data)
1203 } 1204 }
1204} 1205}
1205 1206
1206void 1207void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1207mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1208{ 1208{
1209 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1209 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1210 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; 1210 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 2ce4c4023a97..6b3c4e119c63 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -24,9 +24,12 @@
24/* Keep the mean chain length below this constant */ 24/* Keep the mean chain length below this constant */
25#define MEAN_CHAIN_LEN 2 25#define MEAN_CHAIN_LEN 2
26 26
27#define MPATH_EXPIRED(mpath) ((mpath->flags & MESH_PATH_ACTIVE) && \ 27static inline bool mpath_expired(struct mesh_path *mpath)
28 time_after(jiffies, mpath->exp_time) && \ 28{
29 !(mpath->flags & MESH_PATH_FIXED)) 29 return (mpath->flags & MESH_PATH_ACTIVE) &&
30 time_after(jiffies, mpath->exp_time) &&
31 !(mpath->flags & MESH_PATH_FIXED);
32}
30 33
31struct mpath_node { 34struct mpath_node {
32 struct hlist_node list; 35 struct hlist_node list;
@@ -185,8 +188,8 @@ static u32 mesh_table_hash(const u8 *addr, struct ieee80211_sub_if_data *sdata,
185 struct mesh_table *tbl) 188 struct mesh_table *tbl)
186{ 189{
187 /* Use last four bytes of hw addr and interface index as hash index */ 190 /* Use last four bytes of hw addr and interface index as hash index */
188 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd) 191 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex,
189 & tbl->hash_mask; 192 tbl->hash_rnd) & tbl->hash_mask;
190} 193}
191 194
192 195
@@ -339,7 +342,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
339 mpath = node->mpath; 342 mpath = node->mpath;
340 if (mpath->sdata == sdata && 343 if (mpath->sdata == sdata &&
341 ether_addr_equal(dst, mpath->dst)) { 344 ether_addr_equal(dst, mpath->dst)) {
342 if (MPATH_EXPIRED(mpath)) { 345 if (mpath_expired(mpath)) {
343 spin_lock_bh(&mpath->state_lock); 346 spin_lock_bh(&mpath->state_lock);
344 mpath->flags &= ~MESH_PATH_ACTIVE; 347 mpath->flags &= ~MESH_PATH_ACTIVE;
345 spin_unlock_bh(&mpath->state_lock); 348 spin_unlock_bh(&mpath->state_lock);
@@ -352,20 +355,21 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
352 355
353/** 356/**
354 * mesh_path_lookup - look up a path in the mesh path table 357 * mesh_path_lookup - look up a path in the mesh path table
355 * @dst: hardware address (ETH_ALEN length) of destination
356 * @sdata: local subif 358 * @sdata: local subif
359 * @dst: hardware address (ETH_ALEN length) of destination
357 * 360 *
358 * Returns: pointer to the mesh path structure, or NULL if not found 361 * Returns: pointer to the mesh path structure, or NULL if not found
359 * 362 *
360 * Locking: must be called within a read rcu section. 363 * Locking: must be called within a read rcu section.
361 */ 364 */
362struct mesh_path *mesh_path_lookup(const u8 *dst, 365struct mesh_path *
363 struct ieee80211_sub_if_data *sdata) 366mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
364{ 367{
365 return mpath_lookup(rcu_dereference(mesh_paths), dst, sdata); 368 return mpath_lookup(rcu_dereference(mesh_paths), dst, sdata);
366} 369}
367 370
368struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) 371struct mesh_path *
372mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
369{ 373{
370 return mpath_lookup(rcu_dereference(mpp_paths), dst, sdata); 374 return mpath_lookup(rcu_dereference(mpp_paths), dst, sdata);
371} 375}
@@ -380,7 +384,8 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
380 * 384 *
381 * Locking: must be called within a read rcu section. 385 * Locking: must be called within a read rcu section.
382 */ 386 */
383struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata) 387struct mesh_path *
388mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
384{ 389{
385 struct mesh_table *tbl = rcu_dereference(mesh_paths); 390 struct mesh_table *tbl = rcu_dereference(mesh_paths);
386 struct mpath_node *node; 391 struct mpath_node *node;
@@ -392,7 +397,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
392 if (sdata && node->mpath->sdata != sdata) 397 if (sdata && node->mpath->sdata != sdata)
393 continue; 398 continue;
394 if (j++ == idx) { 399 if (j++ == idx) {
395 if (MPATH_EXPIRED(node->mpath)) { 400 if (mpath_expired(node->mpath)) {
396 spin_lock_bh(&node->mpath->state_lock); 401 spin_lock_bh(&node->mpath->state_lock);
397 node->mpath->flags &= ~MESH_PATH_ACTIVE; 402 node->mpath->flags &= ~MESH_PATH_ACTIVE;
398 spin_unlock_bh(&node->mpath->state_lock); 403 spin_unlock_bh(&node->mpath->state_lock);
@@ -436,11 +441,10 @@ int mesh_path_add_gate(struct mesh_path *mpath)
436 spin_lock_bh(&tbl->gates_lock); 441 spin_lock_bh(&tbl->gates_lock);
437 hlist_add_head_rcu(&new_gate->list, tbl->known_gates); 442 hlist_add_head_rcu(&new_gate->list, tbl->known_gates);
438 spin_unlock_bh(&tbl->gates_lock); 443 spin_unlock_bh(&tbl->gates_lock);
439 rcu_read_unlock();
440 mpath_dbg(mpath->sdata, 444 mpath_dbg(mpath->sdata,
441 "Mesh path: Recorded new gate: %pM. %d known gates\n", 445 "Mesh path: Recorded new gate: %pM. %d known gates\n",
442 mpath->dst, mpath->sdata->u.mesh.num_gates); 446 mpath->dst, mpath->sdata->u.mesh.num_gates);
443 return 0; 447 err = 0;
444err_rcu: 448err_rcu:
445 rcu_read_unlock(); 449 rcu_read_unlock();
446 return err; 450 return err;
@@ -451,30 +455,27 @@ err_rcu:
451 * @tbl: table which holds our list of known gates 455 * @tbl: table which holds our list of known gates
452 * @mpath: gate mpath 456 * @mpath: gate mpath
453 * 457 *
454 * Returns: 0 on success
455 *
456 * Locking: must be called inside rcu_read_lock() section 458 * Locking: must be called inside rcu_read_lock() section
457 */ 459 */
458static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) 460static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
459{ 461{
460 struct mpath_node *gate; 462 struct mpath_node *gate;
461 struct hlist_node *p, *q; 463 struct hlist_node *p, *q;
462 464
463 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) 465 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) {
464 if (gate->mpath == mpath) { 466 if (gate->mpath != mpath)
465 spin_lock_bh(&tbl->gates_lock); 467 continue;
466 hlist_del_rcu(&gate->list); 468 spin_lock_bh(&tbl->gates_lock);
467 kfree_rcu(gate, rcu); 469 hlist_del_rcu(&gate->list);
468 spin_unlock_bh(&tbl->gates_lock); 470 kfree_rcu(gate, rcu);
469 mpath->sdata->u.mesh.num_gates--; 471 spin_unlock_bh(&tbl->gates_lock);
470 mpath->is_gate = false; 472 mpath->sdata->u.mesh.num_gates--;
471 mpath_dbg(mpath->sdata, 473 mpath->is_gate = false;
472 "Mesh path: Deleted gate: %pM. %d known gates\n", 474 mpath_dbg(mpath->sdata,
473 mpath->dst, mpath->sdata->u.mesh.num_gates); 475 "Mesh path: Deleted gate: %pM. %d known gates\n",
474 break; 476 mpath->dst, mpath->sdata->u.mesh.num_gates);
475 } 477 break;
476 478 }
477 return 0;
478} 479}
479 480
480/** 481/**
@@ -488,14 +489,14 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
488 489
489/** 490/**
490 * mesh_path_add - allocate and add a new path to the mesh path table 491 * mesh_path_add - allocate and add a new path to the mesh path table
491 * @addr: destination address of the path (ETH_ALEN length) 492 * @dst: destination address of the path (ETH_ALEN length)
492 * @sdata: local subif 493 * @sdata: local subif
493 * 494 *
494 * Returns: 0 on success 495 * Returns: 0 on success
495 * 496 *
496 * State: the initial state of the new path is set to 0 497 * State: the initial state of the new path is set to 0
497 */ 498 */
498int mesh_path_add(const u8 *dst, struct ieee80211_sub_if_data *sdata) 499int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
499{ 500{
500 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 501 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
501 struct ieee80211_local *local = sdata->local; 502 struct ieee80211_local *local = sdata->local;
@@ -630,7 +631,8 @@ void mesh_mpp_table_grow(void)
630 write_unlock_bh(&pathtbl_resize_lock); 631 write_unlock_bh(&pathtbl_resize_lock);
631} 632}
632 633
633int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) 634int mpp_path_add(struct ieee80211_sub_if_data *sdata,
635 const u8 *dst, const u8 *mpp)
634{ 636{
635 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 637 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
636 struct ieee80211_local *local = sdata->local; 638 struct ieee80211_local *local = sdata->local;
@@ -739,9 +741,10 @@ void mesh_plink_broken(struct sta_info *sta)
739 mpath->flags &= ~MESH_PATH_ACTIVE; 741 mpath->flags &= ~MESH_PATH_ACTIVE;
740 ++mpath->sn; 742 ++mpath->sn;
741 spin_unlock_bh(&mpath->state_lock); 743 spin_unlock_bh(&mpath->state_lock);
742 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, 744 mesh_path_error_tx(sdata,
743 mpath->dst, cpu_to_le32(mpath->sn), 745 sdata->u.mesh.mshcfg.element_ttl,
744 reason, bcast, sdata); 746 mpath->dst, cpu_to_le32(mpath->sn),
747 reason, bcast);
745 } 748 }
746 } 749 }
747 rcu_read_unlock(); 750 rcu_read_unlock();
@@ -856,7 +859,7 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
856 * 859 *
857 * Returns: 0 if successful 860 * Returns: 0 if successful
858 */ 861 */
859int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) 862int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
860{ 863{
861 struct mesh_table *tbl; 864 struct mesh_table *tbl;
862 struct mesh_path *mpath; 865 struct mesh_path *mpath;
@@ -965,8 +968,8 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
965 * 968 *
966 * Locking: the function must me called within a rcu_read_lock region 969 * Locking: the function must me called within a rcu_read_lock region
967 */ 970 */
968void mesh_path_discard_frame(struct sk_buff *skb, 971void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
969 struct ieee80211_sub_if_data *sdata) 972 struct sk_buff *skb)
970{ 973{
971 kfree_skb(skb); 974 kfree_skb(skb);
972 sdata->u.mesh.mshstats.dropped_frames_no_route++; 975 sdata->u.mesh.mshstats.dropped_frames_no_route++;
@@ -984,7 +987,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath)
984 struct sk_buff *skb; 987 struct sk_buff *skb;
985 988
986 while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL) 989 while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL)
987 mesh_path_discard_frame(skb, mpath->sdata); 990 mesh_path_discard_frame(mpath->sdata, skb);
988} 991}
989 992
990/** 993/**
@@ -1105,7 +1108,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
1105 if ((!(mpath->flags & MESH_PATH_RESOLVING)) && 1108 if ((!(mpath->flags & MESH_PATH_RESOLVING)) &&
1106 (!(mpath->flags & MESH_PATH_FIXED)) && 1109 (!(mpath->flags & MESH_PATH_FIXED)) &&
1107 time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) 1110 time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
1108 mesh_path_del(mpath->dst, mpath->sdata); 1111 mesh_path_del(mpath->sdata, mpath->dst);
1109 } 1112 }
1110 rcu_read_unlock(); 1113 rcu_read_unlock();
1111} 1114}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index f7526e509aa8..07d396d57079 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -37,9 +37,31 @@ enum plink_event {
37 CLS_IGNR 37 CLS_IGNR
38}; 38};
39 39
40static const char * const mplstates[] = {
41 [NL80211_PLINK_LISTEN] = "LISTEN",
42 [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
43 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
44 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
45 [NL80211_PLINK_ESTAB] = "ESTAB",
46 [NL80211_PLINK_HOLDING] = "HOLDING",
47 [NL80211_PLINK_BLOCKED] = "BLOCKED"
48};
49
50static const char * const mplevents[] = {
51 [PLINK_UNDEFINED] = "NONE",
52 [OPN_ACPT] = "OPN_ACPT",
53 [OPN_RJCT] = "OPN_RJCT",
54 [OPN_IGNR] = "OPN_IGNR",
55 [CNF_ACPT] = "CNF_ACPT",
56 [CNF_RJCT] = "CNF_RJCT",
57 [CNF_IGNR] = "CNF_IGNR",
58 [CLS_ACPT] = "CLS_ACPT",
59 [CLS_IGNR] = "CLS_IGNR"
60};
61
40static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 62static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
41 enum ieee80211_self_protected_actioncode action, 63 enum ieee80211_self_protected_actioncode action,
42 u8 *da, __le16 llid, __le16 plid, __le16 reason); 64 u8 *da, __le16 llid, __le16 plid, __le16 reason);
43 65
44/** 66/**
45 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine 67 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
@@ -129,7 +151,6 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
129{ 151{
130 struct ieee80211_local *local = sdata->local; 152 struct ieee80211_local *local = sdata->local;
131 struct sta_info *sta; 153 struct sta_info *sta;
132 u32 changed = 0;
133 u16 ht_opmode; 154 u16 ht_opmode;
134 bool non_ht_sta = false, ht20_sta = false; 155 bool non_ht_sta = false, ht20_sta = false;
135 156
@@ -142,23 +163,19 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
142 sta->plink_state != NL80211_PLINK_ESTAB) 163 sta->plink_state != NL80211_PLINK_ESTAB)
143 continue; 164 continue;
144 165
145 switch (sta->ch_width) { 166 if (sta->sta.bandwidth > IEEE80211_STA_RX_BW_20)
146 case NL80211_CHAN_WIDTH_20_NOHT: 167 continue;
147 mpl_dbg(sdata, 168
148 "mesh_plink %pM: nonHT sta (%pM) is present\n", 169 if (!sta->sta.ht_cap.ht_supported) {
149 sdata->vif.addr, sta->sta.addr); 170 mpl_dbg(sdata, "nonHT sta (%pM) is present\n",
171 sta->sta.addr);
150 non_ht_sta = true; 172 non_ht_sta = true;
151 goto out;
152 case NL80211_CHAN_WIDTH_20:
153 mpl_dbg(sdata,
154 "mesh_plink %pM: HT20 sta (%pM) is present\n",
155 sdata->vif.addr, sta->sta.addr);
156 ht20_sta = true;
157 default:
158 break; 173 break;
159 } 174 }
175
176 mpl_dbg(sdata, "HT20 sta (%pM) is present\n", sta->sta.addr);
177 ht20_sta = true;
160 } 178 }
161out:
162 rcu_read_unlock(); 179 rcu_read_unlock();
163 180
164 if (non_ht_sta) 181 if (non_ht_sta)
@@ -169,16 +186,13 @@ out:
169 else 186 else
170 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 187 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
171 188
172 if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) { 189 if (sdata->vif.bss_conf.ht_operation_mode == ht_opmode)
173 sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 190 return 0;
174 sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
175 changed = BSS_CHANGED_HT;
176 mpl_dbg(sdata,
177 "mesh_plink %pM: protection mode changed to %d\n",
178 sdata->vif.addr, ht_opmode);
179 }
180 191
181 return changed; 192 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
193 sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
194 mpl_dbg(sdata, "selected new HT protection mode %d\n", ht_opmode);
195 return BSS_CHANGED_HT;
182} 196}
183 197
184/** 198/**
@@ -231,8 +245,9 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
231} 245}
232 246
233static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 247static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
234 enum ieee80211_self_protected_actioncode action, 248 enum ieee80211_self_protected_actioncode action,
235 u8 *da, __le16 llid, __le16 plid, __le16 reason) { 249 u8 *da, __le16 llid, __le16 plid, __le16 reason)
250{
236 struct ieee80211_local *local = sdata->local; 251 struct ieee80211_local *local = sdata->local;
237 struct sk_buff *skb; 252 struct sk_buff *skb;
238 struct ieee80211_tx_info *info; 253 struct ieee80211_tx_info *info;
@@ -283,13 +298,13 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
283 } 298 }
284 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 299 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
285 ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 300 ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
286 mesh_add_rsn_ie(skb, sdata) || 301 mesh_add_rsn_ie(sdata, skb) ||
287 mesh_add_meshid_ie(skb, sdata) || 302 mesh_add_meshid_ie(sdata, skb) ||
288 mesh_add_meshconf_ie(skb, sdata)) 303 mesh_add_meshconf_ie(sdata, skb))
289 goto free; 304 goto free;
290 } else { /* WLAN_SP_MESH_PEERING_CLOSE */ 305 } else { /* WLAN_SP_MESH_PEERING_CLOSE */
291 info->flags |= IEEE80211_TX_CTL_NO_ACK; 306 info->flags |= IEEE80211_TX_CTL_NO_ACK;
292 if (mesh_add_meshid_ie(skb, sdata)) 307 if (mesh_add_meshid_ie(sdata, skb))
293 goto free; 308 goto free;
294 } 309 }
295 310
@@ -333,12 +348,12 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
333 } 348 }
334 349
335 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 350 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
336 if (mesh_add_ht_cap_ie(skb, sdata) || 351 if (mesh_add_ht_cap_ie(sdata, skb) ||
337 mesh_add_ht_oper_ie(skb, sdata)) 352 mesh_add_ht_oper_ie(sdata, skb))
338 goto free; 353 goto free;
339 } 354 }
340 355
341 if (mesh_add_vendor_ies(skb, sdata)) 356 if (mesh_add_vendor_ies(sdata, skb))
342 goto free; 357 goto free;
343 358
344 ieee80211_tx_skb(sdata, skb); 359 ieee80211_tx_skb(sdata, skb);
@@ -370,24 +385,18 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
370 if (sta->sta.supp_rates[band] != rates) 385 if (sta->sta.supp_rates[band] != rates)
371 changed |= IEEE80211_RC_SUPP_RATES_CHANGED; 386 changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
372 sta->sta.supp_rates[band] = rates; 387 sta->sta.supp_rates[band] = rates;
373 if (elems->ht_cap_elem &&
374 sdata->vif.bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
375 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
376 elems->ht_cap_elem, sta);
377 else
378 memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap));
379 388
380 if (elems->ht_operation) { 389 if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
381 struct cfg80211_chan_def chandef; 390 elems->ht_cap_elem, sta))
391 changed |= IEEE80211_RC_BW_CHANGED;
382 392
383 if (!(elems->ht_operation->ht_param & 393 /* HT peer is operating 20MHz-only */
384 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) 394 if (elems->ht_operation &&
385 sta->sta.bandwidth = IEEE80211_STA_RX_BW_20; 395 !(elems->ht_operation->ht_param &
386 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan, 396 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
387 elems->ht_operation, &chandef); 397 if (sta->sta.bandwidth != IEEE80211_STA_RX_BW_20)
388 if (sta->ch_width != chandef.width)
389 changed |= IEEE80211_RC_BW_CHANGED; 398 changed |= IEEE80211_RC_BW_CHANGED;
390 sta->ch_width = chandef.width; 399 sta->sta.bandwidth = IEEE80211_STA_RX_BW_20;
391 } 400 }
392 401
393 if (insert) 402 if (insert)
@@ -666,8 +675,9 @@ u32 mesh_plink_block(struct sta_info *sta)
666} 675}
667 676
668 677
669void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, 678void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
670 size_t len, struct ieee80211_rx_status *rx_status) 679 struct ieee80211_mgmt *mgmt, size_t len,
680 struct ieee80211_rx_status *rx_status)
671{ 681{
672 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 682 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
673 struct ieee802_11_elems elems; 683 struct ieee802_11_elems elems;
@@ -680,15 +690,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
680 u8 *baseaddr; 690 u8 *baseaddr;
681 u32 changed = 0; 691 u32 changed = 0;
682 __le16 plid, llid, reason; 692 __le16 plid, llid, reason;
683 static const char *mplstates[] = {
684 [NL80211_PLINK_LISTEN] = "LISTEN",
685 [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
686 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
687 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
688 [NL80211_PLINK_ESTAB] = "ESTAB",
689 [NL80211_PLINK_HOLDING] = "HOLDING",
690 [NL80211_PLINK_BLOCKED] = "BLOCKED"
691 };
692 693
693 /* need action_code, aux */ 694 /* need action_code, aux */
694 if (len < IEEE80211_MIN_ACTION_SIZE + 3) 695 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
@@ -708,13 +709,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
708 baselen += 4; 709 baselen += 4;
709 } 710 }
710 ieee802_11_parse_elems(baseaddr, len - baselen, &elems); 711 ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
712
711 if (!elems.peering) { 713 if (!elems.peering) {
712 mpl_dbg(sdata, 714 mpl_dbg(sdata,
713 "Mesh plink: missing necessary peer link ie\n"); 715 "Mesh plink: missing necessary peer link ie\n");
714 return; 716 return;
715 } 717 }
718
716 if (elems.rsn_len && 719 if (elems.rsn_len &&
717 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 720 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
718 mpl_dbg(sdata, 721 mpl_dbg(sdata,
719 "Mesh plink: can't establish link with secure peer\n"); 722 "Mesh plink: can't establish link with secure peer\n");
720 return; 723 return;
@@ -733,7 +736,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
733 } 736 }
734 737
735 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 738 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
736 (!elems.mesh_id || !elems.mesh_config)) { 739 (!elems.mesh_id || !elems.mesh_config)) {
737 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); 740 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
738 return; 741 return;
739 } 742 }
@@ -859,11 +862,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
859 } 862 }
860 } 863 }
861 864
862 mpl_dbg(sdata, 865 mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
863 "Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 866 mplstates[sta->plink_state], mplevents[event]);
864 mgmt->sa, mplstates[sta->plink_state],
865 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
866 event);
867 reason = 0; 867 reason = 0;
868 spin_lock_bh(&sta->lock); 868 spin_lock_bh(&sta->lock);
869 switch (sta->plink_state) { 869 switch (sta->plink_state) {
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index aa8d1e437385..05a256b38e24 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -43,7 +43,7 @@ struct sync_method {
43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) 43static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
44{ 44{
45 return (ie->mesh_config->meshconf_cap & 45 return (ie->mesh_config->meshconf_cap &
46 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0; 46 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
47} 47}
48 48
49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) 49void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
@@ -112,7 +112,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
112 112
113 if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { 113 if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) {
114 clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); 114 clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN);
115 msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", sta->sta.addr); 115 msync_dbg(sdata, "STA %pM : is adjusting TBTT\n",
116 sta->sta.addr);
116 goto no_sync; 117 goto no_sync;
117 } 118 }
118 119
@@ -129,18 +130,15 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
129 sta->t_offset = t_t - t_r; 130 sta->t_offset = t_t - t_r;
130 131
131 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { 132 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
132 s64 t_clockdrift = sta->t_offset_setpoint 133 s64 t_clockdrift = sta->t_offset_setpoint - sta->t_offset;
133 - sta->t_offset;
134 msync_dbg(sdata, 134 msync_dbg(sdata,
135 "STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld\n", 135 "STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld\n",
136 sta->sta.addr, 136 sta->sta.addr, (long long) sta->t_offset,
137 (long long) sta->t_offset, 137 (long long) sta->t_offset_setpoint,
138 (long long)
139 sta->t_offset_setpoint,
140 (long long) t_clockdrift); 138 (long long) t_clockdrift);
141 139
142 if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT || 140 if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT ||
143 t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) { 141 t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) {
144 msync_dbg(sdata, 142 msync_dbg(sdata,
145 "STA %pM : t_clockdrift=%lld too large, setpoint reset\n", 143 "STA %pM : t_clockdrift=%lld too large, setpoint reset\n",
146 sta->sta.addr, 144 sta->sta.addr,
@@ -149,15 +147,10 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
149 goto no_sync; 147 goto no_sync;
150 } 148 }
151 149
152 rcu_read_unlock();
153
154 spin_lock_bh(&ifmsh->sync_offset_lock); 150 spin_lock_bh(&ifmsh->sync_offset_lock);
155 if (t_clockdrift > 151 if (t_clockdrift > ifmsh->sync_offset_clockdrift_max)
156 ifmsh->sync_offset_clockdrift_max) 152 ifmsh->sync_offset_clockdrift_max = t_clockdrift;
157 ifmsh->sync_offset_clockdrift_max
158 = t_clockdrift;
159 spin_unlock_bh(&ifmsh->sync_offset_lock); 153 spin_unlock_bh(&ifmsh->sync_offset_lock);
160
161 } else { 154 } else {
162 sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN; 155 sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN;
163 set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); 156 set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN);
@@ -165,9 +158,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
165 "STA %pM : offset was invalid, sta->t_offset=%lld\n", 158 "STA %pM : offset was invalid, sta->t_offset=%lld\n",
166 sta->sta.addr, 159 sta->sta.addr,
167 (long long) sta->t_offset); 160 (long long) sta->t_offset);
168 rcu_read_unlock();
169 } 161 }
170 return;
171 162
172no_sync: 163no_sync:
173 rcu_read_unlock(); 164 rcu_read_unlock();
@@ -177,14 +168,12 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
177{ 168{
178 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 169 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
179 170
180 WARN_ON(ifmsh->mesh_sp_id 171 WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET);
181 != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET);
182 BUG_ON(!rcu_read_lock_held()); 172 BUG_ON(!rcu_read_lock_held());
183 173
184 spin_lock_bh(&ifmsh->sync_offset_lock); 174 spin_lock_bh(&ifmsh->sync_offset_lock);
185 175
186 if (ifmsh->sync_offset_clockdrift_max > 176 if (ifmsh->sync_offset_clockdrift_max > TOFFSET_MINIMUM_ADJUSTMENT) {
187 TOFFSET_MINIMUM_ADJUSTMENT) {
188 /* Since ajusting the tsf here would 177 /* Since ajusting the tsf here would
189 * require a possibly blocking call 178 * require a possibly blocking call
190 * to the driver tsf setter, we punt 179 * to the driver tsf setter, we punt
@@ -193,8 +182,7 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
193 msync_dbg(sdata, 182 msync_dbg(sdata,
194 "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n", 183 "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n",
195 ifmsh->sync_offset_clockdrift_max); 184 ifmsh->sync_offset_clockdrift_max);
196 set_bit(MESH_WORK_DRIFT_ADJUST, 185 set_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags);
197 &ifmsh->wrkq_flags);
198 186
199 ifmsh->adjusting_tbtt = true; 187 ifmsh->adjusting_tbtt = true;
200 } else { 188 } else {
@@ -220,14 +208,11 @@ static const struct sync_method sync_methods[] = {
220 208
221const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method) 209const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method)
222{ 210{
223 const struct ieee80211_mesh_sync_ops *ops = NULL; 211 int i;
224 u8 i;
225 212
226 for (i = 0 ; i < ARRAY_SIZE(sync_methods); ++i) { 213 for (i = 0 ; i < ARRAY_SIZE(sync_methods); ++i) {
227 if (sync_methods[i].method == method) { 214 if (sync_methods[i].method == method)
228 ops = &sync_methods[i].ops; 215 return &sync_methods[i].ops;
229 break;
230 }
231 } 216 }
232 return ops; 217 return NULL;
233} 218}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3acb70b73e22..bb73ed2d20b9 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2027,7 +2027,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2027 /* frame is in RMC, don't forward */ 2027 /* frame is in RMC, don't forward */
2028 if (ieee80211_is_data(hdr->frame_control) && 2028 if (ieee80211_is_data(hdr->frame_control) &&
2029 is_multicast_ether_addr(hdr->addr1) && 2029 is_multicast_ether_addr(hdr->addr1) &&
2030 mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) 2030 mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr))
2031 return RX_DROP_MONITOR; 2031 return RX_DROP_MONITOR;
2032 2032
2033 if (!ieee80211_is_data(hdr->frame_control) || 2033 if (!ieee80211_is_data(hdr->frame_control) ||
@@ -2054,9 +2054,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2054 } 2054 }
2055 2055
2056 rcu_read_lock(); 2056 rcu_read_lock();
2057 mppath = mpp_path_lookup(proxied_addr, sdata); 2057 mppath = mpp_path_lookup(sdata, proxied_addr);
2058 if (!mppath) { 2058 if (!mppath) {
2059 mpp_path_add(proxied_addr, mpp_addr, sdata); 2059 mpp_path_add(sdata, proxied_addr, mpp_addr);
2060 } else { 2060 } else {
2061 spin_lock_bh(&mppath->state_lock); 2061 spin_lock_bh(&mppath->state_lock);
2062 if (!ether_addr_equal(mppath->mpp, mpp_addr)) 2062 if (!ether_addr_equal(mppath->mpp, mpp_addr))
@@ -2104,13 +2104,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2104 memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); 2104 memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
2105 /* update power mode indication when forwarding */ 2105 /* update power mode indication when forwarding */
2106 ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); 2106 ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr);
2107 } else if (!mesh_nexthop_lookup(fwd_skb, sdata)) { 2107 } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) {
2108 /* mesh power mode flags updated in mesh_nexthop_lookup */ 2108 /* mesh power mode flags updated in mesh_nexthop_lookup */
2109 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); 2109 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
2110 } else { 2110 } else {
2111 /* unable to resolve next hop */ 2111 /* unable to resolve next hop */
2112 mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3, 2112 mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
2113 0, reason, fwd_hdr->addr2, sdata); 2113 fwd_hdr->addr3, 0, reason, fwd_hdr->addr2);
2114 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); 2114 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
2115 kfree_skb(fwd_skb); 2115 kfree_skb(fwd_skb);
2116 return RX_DROP_MONITOR; 2116 return RX_DROP_MONITOR;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 63dfdb5e91da..4947341a2a82 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -285,7 +285,6 @@ struct sta_ampdu_mlme {
285 * @t_offset: timing offset relative to this host 285 * @t_offset: timing offset relative to this host
286 * @t_offset_setpoint: reference timing offset of this sta to be used when 286 * @t_offset_setpoint: reference timing offset of this sta to be used when
287 * calculating clockdrift 287 * calculating clockdrift
288 * @ch_width: peer's channel width
289 * @local_pm: local link-specific power save mode 288 * @local_pm: local link-specific power save mode
290 * @peer_pm: peer-specific power save mode towards local STA 289 * @peer_pm: peer-specific power save mode towards local STA
291 * @nonpeer_pm: STA power save mode towards non-peer neighbors 290 * @nonpeer_pm: STA power save mode towards non-peer neighbors
@@ -386,7 +385,6 @@ struct sta_info {
386 struct timer_list plink_timer; 385 struct timer_list plink_timer;
387 s64 t_offset; 386 s64 t_offset;
388 s64 t_offset_setpoint; 387 s64 t_offset_setpoint;
389 enum nl80211_chan_width ch_width;
390 /* mesh power save */ 388 /* mesh power save */
391 enum nl80211_mesh_power_mode local_pm; 389 enum nl80211_mesh_power_mode local_pm;
392 enum nl80211_mesh_power_mode peer_pm; 390 enum nl80211_mesh_power_mode peer_pm;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 1183c4a4fee5..3d7cd2a0582f 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -479,7 +479,7 @@ TRACE_EVENT(drv_set_tim,
479 479
480 TP_printk( 480 TP_printk(
481 LOCAL_PR_FMT STA_PR_FMT " set:%d", 481 LOCAL_PR_FMT STA_PR_FMT " set:%d",
482 LOCAL_PR_ARG, STA_PR_FMT, __entry->set 482 LOCAL_PR_ARG, STA_PR_ARG, __entry->set
483 ) 483 )
484); 484);
485 485
@@ -1684,7 +1684,7 @@ TRACE_EVENT(api_sta_block_awake,
1684 1684
1685 TP_printk( 1685 TP_printk(
1686 LOCAL_PR_FMT STA_PR_FMT " block:%d", 1686 LOCAL_PR_FMT STA_PR_FMT " block:%d",
1687 LOCAL_PR_ARG, STA_PR_FMT, __entry->block 1687 LOCAL_PR_ARG, STA_PR_ARG, __entry->block
1688 ) 1688 )
1689); 1689);
1690 1690
@@ -1782,7 +1782,7 @@ TRACE_EVENT(api_eosp,
1782 1782
1783 TP_printk( 1783 TP_printk(
1784 LOCAL_PR_FMT STA_PR_FMT, 1784 LOCAL_PR_FMT STA_PR_FMT,
1785 LOCAL_PR_ARG, STA_PR_FMT 1785 LOCAL_PR_ARG, STA_PR_ARG
1786 ) 1786 )
1787); 1787);
1788 1788
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index fe644f91ae05..5b9602b62405 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1495,7 +1495,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1495 if (ieee80211_vif_is_mesh(&sdata->vif)) { 1495 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1496 if (ieee80211_is_data(hdr->frame_control) && 1496 if (ieee80211_is_data(hdr->frame_control) &&
1497 is_unicast_ether_addr(hdr->addr1)) { 1497 is_unicast_ether_addr(hdr->addr1)) {
1498 if (mesh_nexthop_resolve(skb, sdata)) 1498 if (mesh_nexthop_resolve(sdata, skb))
1499 return; /* skb queued: don't free */ 1499 return; /* skb queued: don't free */
1500 } else { 1500 } else {
1501 ieee80211_mps_set_frame_flags(sdata, NULL, hdr); 1501 ieee80211_mps_set_frame_flags(sdata, NULL, hdr);
@@ -1844,9 +1844,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1844 } 1844 }
1845 1845
1846 if (!is_multicast_ether_addr(skb->data)) { 1846 if (!is_multicast_ether_addr(skb->data)) {
1847 mpath = mesh_path_lookup(skb->data, sdata); 1847 mpath = mesh_path_lookup(sdata, skb->data);
1848 if (!mpath) 1848 if (!mpath)
1849 mppath = mpp_path_lookup(skb->data, sdata); 1849 mppath = mpp_path_lookup(sdata, skb->data);
1850 } 1850 }
1851 1851
1852 /* 1852 /*
@@ -1859,8 +1859,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1859 !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) { 1859 !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) {
1860 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1860 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1861 skb->data, skb->data + ETH_ALEN); 1861 skb->data, skb->data + ETH_ALEN);
1862 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1862 meshhdrlen = ieee80211_new_mesh_header(sdata, &mesh_hdr,
1863 sdata, NULL, NULL); 1863 NULL, NULL);
1864 } else { 1864 } else {
1865 /* DS -> MBSS (802.11-2012 13.11.3.3). 1865 /* DS -> MBSS (802.11-2012 13.11.3.3).
1866 * For unicast with unknown forwarding information, 1866 * For unicast with unknown forwarding information,
@@ -1879,18 +1879,14 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1879 mesh_da, sdata->vif.addr); 1879 mesh_da, sdata->vif.addr);
1880 if (is_multicast_ether_addr(mesh_da)) 1880 if (is_multicast_ether_addr(mesh_da))
1881 /* DA TA mSA AE:SA */ 1881 /* DA TA mSA AE:SA */
1882 meshhdrlen = 1882 meshhdrlen = ieee80211_new_mesh_header(
1883 ieee80211_new_mesh_header(&mesh_hdr, 1883 sdata, &mesh_hdr,
1884 sdata, 1884 skb->data + ETH_ALEN, NULL);
1885 skb->data + ETH_ALEN,
1886 NULL);
1887 else 1885 else
1888 /* RA TA mDA mSA AE:DA SA */ 1886 /* RA TA mDA mSA AE:DA SA */
1889 meshhdrlen = 1887 meshhdrlen = ieee80211_new_mesh_header(
1890 ieee80211_new_mesh_header(&mesh_hdr, 1888 sdata, &mesh_hdr, skb->data,
1891 sdata, 1889 skb->data + ETH_ALEN);
1892 skb->data,
1893 skb->data + ETH_ALEN);
1894 1890
1895 } 1891 }
1896 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 1892 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 580ffeaef3d5..35545ccc30fd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3418,19 +3418,10 @@ nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
3418static int nl80211_set_station_tdls(struct genl_info *info, 3418static int nl80211_set_station_tdls(struct genl_info *info,
3419 struct station_parameters *params) 3419 struct station_parameters *params)
3420{ 3420{
3421 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3422 struct nlattr *tb[NL80211_STA_WME_MAX + 1]; 3421 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
3423 struct nlattr *nla; 3422 struct nlattr *nla;
3424 int err; 3423 int err;
3425 3424
3426 /* Can only set if TDLS ... */
3427 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
3428 return -EOPNOTSUPP;
3429
3430 /* ... with external setup is supported */
3431 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
3432 return -EOPNOTSUPP;
3433
3434 /* Dummy STA entry gets updated once the peer capabilities are known */ 3425 /* Dummy STA entry gets updated once the peer capabilities are known */
3435 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) 3426 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3436 params->ht_capa = 3427 params->ht_capa =