diff options
author | Rajkumar Manoharan <rmanohar@qca.qualcomm.com> | 2011-09-25 05:23:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-27 14:34:10 -0400 |
commit | aad14ceb45f5ff12da2ab5b37a596e6f81566515 (patch) | |
tree | 898380834d260961219b687e377b60c41f5f16e9 /net | |
parent | e9f935e3e8dc0bddd0df6d148165d95925422502 (diff) |
mac80211: Send the management frame at requested rate
Whenever the scan request or tx_mgmt is requesting not to
use CCK rate for managemet frames through
NL80211_ATTR_TX_NO_CCK_RATE attribute, then mac80211 should
select appropriate least non-CCK rate. This could help to
send P2P probes and P2P action frames at non 11b rates
without diabling 11b rates globally.
Cc: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 3 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 2 | ||||
-rw-r--r-- | net/mac80211/rate.c | 29 | ||||
-rw-r--r-- | net/mac80211/scan.c | 3 | ||||
-rw-r--r-- | net/mac80211/util.c | 8 | ||||
-rw-r--r-- | net/mac80211/work.c | 2 |
7 files changed, 42 insertions, 7 deletions
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, | |||
1324 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1324 | void 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 | ||
1329 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | 1329 | void 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 | ||
236 | static inline s8 | ||
237 | rate_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 | |||
236 | bool rate_control_send_low(struct ieee80211_sta *sta, | 257 | bool 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, | |||
899 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 899 | void 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 | ||
912 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | 916 | u32 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); |