aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2013-07-30 20:18:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-08-01 15:34:35 -0400
commit78dfca62f1a0a8d00b155e48197a565da18aebd9 (patch)
tree88755c577a01ecf81988746d3c0f0e0294700c0d
parentc3afd99fb5adfb31925f0b493a0d4152cd6447cc (diff)
mwifiex: populate rates in probe request using cfg80211_scan_request
Whenever available, use cfg80211_scan_request to populates rates in outgoing probe request. This will help to advertise band specific rates and fix an issue where 11b rates were advertised in probe request going out on 11a band. This will also ensure that we do not advertise 11b rates while P2P scan is going on. Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c42
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/scan.c63
3 files changed, 85 insertions, 22 deletions
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 988552dece75..913bb63fd0ad 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -404,11 +404,43 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv)
404 return false; 404 return false;
405} 405}
406 406
407/* 407/* This function gets the supported data rates from bitmask inside
408 * This function gets the supported data rates. 408 * cfg80211_scan_request.
409 * 409 */
410 * The function works in both Ad-Hoc and infra mode by printing the 410u32 mwifiex_get_rates_from_cfg80211(struct mwifiex_private *priv,
411 * band and returning the data rates. 411 u8 *rates, u8 radio_type)
412{
413 struct wiphy *wiphy = priv->adapter->wiphy;
414 struct cfg80211_scan_request *request = priv->scan_request;
415 u32 num_rates, rate_mask;
416 struct ieee80211_supported_band *sband;
417 int i;
418
419 if (radio_type) {
420 sband = wiphy->bands[IEEE80211_BAND_5GHZ];
421 if (WARN_ON_ONCE(!sband))
422 return 0;
423 rate_mask = request->rates[IEEE80211_BAND_5GHZ];
424 } else {
425 sband = wiphy->bands[IEEE80211_BAND_2GHZ];
426 if (WARN_ON_ONCE(!sband))
427 return 0;
428 rate_mask = request->rates[IEEE80211_BAND_2GHZ];
429 }
430
431 num_rates = 0;
432 for (i = 0; i < sband->n_bitrates; i++) {
433 if ((BIT(i) & rate_mask) == 0)
434 continue; /* skip rate */
435 rates[num_rates++] = (u8)(sband->bitrates[i].bitrate / 5);
436 }
437
438 return num_rates;
439}
440
441/* This function gets the supported data rates. The function works in
442 * both Ad-Hoc and infra mode by printing the band and returning the
443 * data rates.
412 */ 444 */
413u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates) 445u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
414{ 446{
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 9ee3b1b7c365..d2e5ccd891da 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -902,6 +902,8 @@ int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
902u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, 902u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv,
903 u8 *rates); 903 u8 *rates);
904u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); 904u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates);
905u32 mwifiex_get_rates_from_cfg80211(struct mwifiex_private *priv,
906 u8 *rates, u8 radio_type);
905u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); 907u8 mwifiex_is_rate_auto(struct mwifiex_private *priv);
906extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; 908extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE];
907void mwifiex_save_curr_bcn(struct mwifiex_private *priv); 909void mwifiex_save_curr_bcn(struct mwifiex_private *priv);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index c447d9bd1aa9..8cf7d50a7603 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -543,6 +543,37 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
543 return chan_idx; 543 return chan_idx;
544} 544}
545 545
546/* This function appends rate TLV to scan config command. */
547static int
548mwifiex_append_rate_tlv(struct mwifiex_private *priv,
549 struct mwifiex_scan_cmd_config *scan_cfg_out,
550 u8 radio)
551{
552 struct mwifiex_ie_types_rates_param_set *rates_tlv;
553 u8 rates[MWIFIEX_SUPPORTED_RATES], *tlv_pos;
554 u32 rates_size;
555
556 memset(rates, 0, sizeof(rates));
557
558 tlv_pos = (u8 *)scan_cfg_out->tlv_buf + scan_cfg_out->tlv_buf_len;
559
560 if (priv->scan_request)
561 rates_size = mwifiex_get_rates_from_cfg80211(priv, rates,
562 radio);
563 else
564 rates_size = mwifiex_get_supported_rates(priv, rates);
565
566 dev_dbg(priv->adapter->dev, "info: SCAN_CMD: Rates size = %d\n",
567 rates_size);
568 rates_tlv = (struct mwifiex_ie_types_rates_param_set *)tlv_pos;
569 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
570 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
571 memcpy(rates_tlv->rates, rates, rates_size);
572 scan_cfg_out->tlv_buf_len += sizeof(rates_tlv->header) + rates_size;
573
574 return rates_size;
575}
576
546/* 577/*
547 * This function constructs and sends multiple scan config commands to 578 * This function constructs and sends multiple scan config commands to
548 * the firmware. 579 * the firmware.
@@ -564,9 +595,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
564 struct mwifiex_chan_scan_param_set *tmp_chan_list; 595 struct mwifiex_chan_scan_param_set *tmp_chan_list;
565 struct mwifiex_chan_scan_param_set *start_chan; 596 struct mwifiex_chan_scan_param_set *start_chan;
566 597
567 u32 tlv_idx; 598 u32 tlv_idx, rates_size;
568 u32 total_scan_time; 599 u32 total_scan_time;
569 u32 done_early; 600 u32 done_early;
601 u8 radio_type;
570 602
571 if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) { 603 if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
572 dev_dbg(priv->adapter->dev, 604 dev_dbg(priv->adapter->dev,
@@ -591,6 +623,7 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
591 623
592 tlv_idx = 0; 624 tlv_idx = 0;
593 total_scan_time = 0; 625 total_scan_time = 0;
626 radio_type = 0;
594 chan_tlv_out->header.len = 0; 627 chan_tlv_out->header.len = 0;
595 start_chan = tmp_chan_list; 628 start_chan = tmp_chan_list;
596 done_early = false; 629 done_early = false;
@@ -612,6 +645,7 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
612 continue; 645 continue;
613 } 646 }
614 647
648 radio_type = tmp_chan_list->radio_type;
615 dev_dbg(priv->adapter->dev, 649 dev_dbg(priv->adapter->dev,
616 "info: Scan: Chan(%3d), Radio(%d)," 650 "info: Scan: Chan(%3d), Radio(%d),"
617 " Mode(%d, %d), Dur(%d)\n", 651 " Mode(%d, %d), Dur(%d)\n",
@@ -692,6 +726,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
692 break; 726 break;
693 } 727 }
694 728
729 rates_size = mwifiex_append_rate_tlv(priv, scan_cfg_out,
730 radio_type);
731
695 priv->adapter->scan_channels = start_chan; 732 priv->adapter->scan_channels = start_chan;
696 733
697 /* Send the scan command to the firmware with the specified 734 /* Send the scan command to the firmware with the specified
@@ -699,6 +736,14 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
699 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, 736 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN,
700 HostCmd_ACT_GEN_SET, 0, 737 HostCmd_ACT_GEN_SET, 0,
701 scan_cfg_out); 738 scan_cfg_out);
739
740 /* rate IE is updated per scan command but same starting
741 * pointer is used each time so that rate IE from earlier
742 * scan_cfg_out->buf is overwritten with new one.
743 */
744 scan_cfg_out->tlv_buf_len -=
745 sizeof(struct mwifiex_ie_types_header) + rates_size;
746
702 if (ret) 747 if (ret)
703 break; 748 break;
704 } 749 }
@@ -741,7 +786,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
741 struct mwifiex_adapter *adapter = priv->adapter; 786 struct mwifiex_adapter *adapter = priv->adapter;
742 struct mwifiex_ie_types_num_probes *num_probes_tlv; 787 struct mwifiex_ie_types_num_probes *num_probes_tlv;
743 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; 788 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
744 struct mwifiex_ie_types_rates_param_set *rates_tlv;
745 u8 *tlv_pos; 789 u8 *tlv_pos;
746 u32 num_probes; 790 u32 num_probes;
747 u32 ssid_len; 791 u32 ssid_len;
@@ -753,8 +797,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
753 u8 radio_type; 797 u8 radio_type;
754 int i; 798 int i;
755 u8 ssid_filter; 799 u8 ssid_filter;
756 u8 rates[MWIFIEX_SUPPORTED_RATES];
757 u32 rates_size;
758 struct mwifiex_ie_types_htcap *ht_cap; 800 struct mwifiex_ie_types_htcap *ht_cap;
759 801
760 /* The tlv_buf_len is calculated for each scan command. The TLVs added 802 /* The tlv_buf_len is calculated for each scan command. The TLVs added
@@ -889,19 +931,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
889 931
890 } 932 }
891 933
892 /* Append rates tlv */
893 memset(rates, 0, sizeof(rates));
894
895 rates_size = mwifiex_get_supported_rates(priv, rates);
896
897 rates_tlv = (struct mwifiex_ie_types_rates_param_set *) tlv_pos;
898 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
899 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
900 memcpy(rates_tlv->rates, rates, rates_size);
901 tlv_pos += sizeof(rates_tlv->header) + rates_size;
902
903 dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size);
904
905 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && 934 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
906 (priv->adapter->config_bands & BAND_GN || 935 (priv->adapter->config_bands & BAND_GN ||
907 priv->adapter->config_bands & BAND_AN)) { 936 priv->adapter->config_bands & BAND_AN)) {