aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mlme.c2
-rw-r--r--net/mac80211/rate.c29
-rw-r--r--net/mac80211/scan.c3
-rw-r--r--net/mac80211/util.c8
-rw-r--r--net/mac80211/work.c2
8 files changed, 46 insertions, 7 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 90dfcc99b466..1e83afae3c64 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -363,6 +363,9 @@ struct ieee80211_bss_conf {
363 * @IEEE80211_TX_INTFL_TKIP_MIC_FAILURE: Marks this packet to be used for TKIP 363 * @IEEE80211_TX_INTFL_TKIP_MIC_FAILURE: Marks this packet to be used for TKIP
364 * testing. It will be sent out with incorrect Michael MIC key to allow 364 * testing. It will be sent out with incorrect Michael MIC key to allow
365 * TKIP countermeasures to be tested. 365 * TKIP countermeasures to be tested.
366 * @IEEE80211_TX_CTL_NO_CCK_RATE: This frame will be sent at non CCK rate.
367 * This flag is actually used for management frame especially for P2P
368 * frames not being sent at CCK rate in 2GHz band.
366 * 369 *
367 * Note: If you have to add new flags to the enumeration, then don't 370 * Note: If you have to add new flags to the enumeration, then don't
368 * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. 371 * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
@@ -393,6 +396,7 @@ enum mac80211_tx_control_flags {
393 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24), 396 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24),
394 IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25), 397 IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25),
395 IEEE80211_TX_INTFL_TKIP_MIC_FAILURE = BIT(26), 398 IEEE80211_TX_INTFL_TKIP_MIC_FAILURE = BIT(26),
399 IEEE80211_TX_CTL_NO_CCK_RATE = BIT(27),
396}; 400};
397 401
398#define IEEE80211_TX_CTL_STBC_SHIFT 23 402#define IEEE80211_TX_CTL_STBC_SHIFT 23
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9cba0104e291..56c35041ba97 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1897,6 +1897,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1897 flags |= IEEE80211_TX_CTL_TX_OFFCHAN; 1897 flags |= IEEE80211_TX_CTL_TX_OFFCHAN;
1898 } 1898 }
1899 1899
1900 if (no_cck)
1901 flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
1902
1900 if (is_offchan && !offchan) 1903 if (is_offchan && !offchan)
1901 return -EBUSY; 1904 return -EBUSY;
1902 1905
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 21186e280ceb..4822d69930e2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1324,7 +1324,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1324void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1324void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1325 const u8 *ssid, size_t ssid_len, 1325 const u8 *ssid, size_t ssid_len,
1326 const u8 *ie, size_t ie_len, 1326 const u8 *ie, size_t ie_len,
1327 u32 ratemask, bool directed); 1327 u32 ratemask, bool directed, bool no_cck);
1328 1328
1329void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 1329void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1330 const size_t supp_rates_len, 1330 const size_t supp_rates_len,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1a59fb6630d4..cc80d320c922 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1239,7 +1239,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1239 } else { 1239 } else {
1240 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1240 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1241 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0, 1241 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0,
1242 (u32) -1, true); 1242 (u32) -1, true, false);
1243 } 1243 }
1244 1244
1245 ifmgd->probe_send_count++; 1245 ifmgd->probe_send_count++;
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 3d5a2cb835c4..f61244c0e0a2 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -233,6 +233,27 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
233 /* could not find a basic rate; use original selection */ 233 /* could not find a basic rate; use original selection */
234} 234}
235 235
236static inline s8
237rate_lowest_non_cck_index(struct ieee80211_supported_band *sband,
238 struct ieee80211_sta *sta)
239{
240 int i;
241
242 for (i = 0; i < sband->n_bitrates; i++) {
243 struct ieee80211_rate *srate = &sband->bitrates[i];
244 if ((srate->bitrate == 10) || (srate->bitrate == 20) ||
245 (srate->bitrate == 55) || (srate->bitrate == 110))
246 continue;
247
248 if (rate_supported(sta, sband->band, i))
249 return i;
250 }
251
252 /* No matching rate found */
253 return 0;
254}
255
256
236bool rate_control_send_low(struct ieee80211_sta *sta, 257bool rate_control_send_low(struct ieee80211_sta *sta,
237 void *priv_sta, 258 void *priv_sta,
238 struct ieee80211_tx_rate_control *txrc) 259 struct ieee80211_tx_rate_control *txrc)
@@ -242,7 +263,13 @@ bool rate_control_send_low(struct ieee80211_sta *sta,
242 int mcast_rate; 263 int mcast_rate;
243 264
244 if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) { 265 if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) {
245 info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta); 266 if ((sband->band != IEEE80211_BAND_2GHZ) ||
267 !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE))
268 info->control.rates[0].idx =
269 rate_lowest_index(txrc->sband, sta);
270 else
271 info->control.rates[0].idx =
272 rate_lowest_non_cck_index(txrc->sband, sta);
246 info->control.rates[0].count = 273 info->control.rates[0].count =
247 (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 274 (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
248 1 : txrc->hw->max_rate_tries; 275 1 : txrc->hw->max_rate_tries;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 6f09eca01112..830e60f65779 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -660,7 +660,8 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
660 local->scan_req->ssids[i].ssid, 660 local->scan_req->ssids[i].ssid,
661 local->scan_req->ssids[i].ssid_len, 661 local->scan_req->ssids[i].ssid_len,
662 local->scan_req->ie, local->scan_req->ie_len, 662 local->scan_req->ie, local->scan_req->ie_len,
663 local->scan_req->rates[band], false); 663 local->scan_req->rates[band], false,
664 local->scan_req->no_cck);
664 665
665 /* 666 /*
666 * After sending probe requests, wait for probe responses 667 * After sending probe requests, wait for probe responses
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 4b1466d5b6a1..ead345db7127 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -899,14 +899,18 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
899void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 899void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
900 const u8 *ssid, size_t ssid_len, 900 const u8 *ssid, size_t ssid_len,
901 const u8 *ie, size_t ie_len, 901 const u8 *ie, size_t ie_len,
902 u32 ratemask, bool directed) 902 u32 ratemask, bool directed, bool no_cck)
903{ 903{
904 struct sk_buff *skb; 904 struct sk_buff *skb;
905 905
906 skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len, 906 skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
907 ie, ie_len, directed); 907 ie, ie_len, directed);
908 if (skb) 908 if (skb) {
909 if (no_cck)
910 IEEE80211_SKB_CB(skb)->flags |=
911 IEEE80211_TX_CTL_NO_CCK_RATE;
909 ieee80211_tx_skb(sdata, skb); 912 ieee80211_tx_skb(sdata, skb);
913 }
910} 914}
911 915
912u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 916u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index bac34394c05e..af374fab1a12 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -458,7 +458,7 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
458 */ 458 */
459 ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid, 459 ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
460 wk->probe_auth.ssid_len, NULL, 0, 460 wk->probe_auth.ssid_len, NULL, 0,
461 (u32) -1, true); 461 (u32) -1, true, false);
462 462
463 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 463 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
464 run_again(local, wk->timeout); 464 run_again(local, wk->timeout);