aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2014-10-31 06:38:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-10-31 16:07:49 -0400
commitbf35443314acb43fa8a3f9f8046e14cbe178762b (patch)
tree1312ca6d9de7ab6ff736befee045d8bdc774a022 /drivers/net
parent15a892e728299c5879187c8301c10c14af399a0c (diff)
mwifiex: channel statistics support for mwifiex
This patch adds support to record channel statistics during scan. With extended scan, scan results are returned as events from FW while channel statistics are part of scan command response. We store these channel statistics in adapter. Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Xinmin Hu <huxm@marvell.com> Signed-off-by: Cathy Luo <cluo@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c19
-rw-r--r--drivers/net/wireless/mwifiex/decl.h10
-rw-r--r--drivers/net/wireless/mwifiex/fw.h16
-rw-r--r--drivers/net/wireless/mwifiex/main.c6
-rw-r--r--drivers/net/wireless/mwifiex/main.h6
-rw-r--r--drivers/net/wireless/mwifiex/scan.c76
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
7 files changed, 132 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 0dd672954ad1..80b1a54e7792 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2840,6 +2840,25 @@ static const struct wiphy_coalesce_support mwifiex_coalesce_support = {
2840 .max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN, 2840 .max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
2841}; 2841};
2842 2842
2843int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter)
2844{
2845 u32 n_channels_bg, n_channels_a = 0;
2846
2847 n_channels_bg = mwifiex_band_2ghz.n_channels;
2848
2849 if (adapter->config_bands & BAND_A)
2850 n_channels_a = mwifiex_band_5ghz.n_channels;
2851
2852 adapter->num_in_chan_stats = max_t(u32, n_channels_bg, n_channels_a);
2853 adapter->chan_stats = vmalloc(sizeof(*adapter->chan_stats) *
2854 adapter->num_in_chan_stats);
2855
2856 if (!adapter->chan_stats)
2857 return -ENOMEM;
2858
2859 return 0;
2860}
2861
2843/* 2862/*
2844 * This function registers the device with CFG802.11 subsystem. 2863 * This function registers the device with CFG802.11 subsystem.
2845 * 2864 *
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index e0d00a7f0ec3..f53e5b50d3d8 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -185,4 +185,14 @@ struct mwifiex_arp_eth_header {
185 u8 ar_tha[ETH_ALEN]; 185 u8 ar_tha[ETH_ALEN];
186 u8 ar_tip[4]; 186 u8 ar_tip[4];
187} __packed; 187} __packed;
188
189struct mwifiex_chan_stats {
190 u8 chan_num;
191 u8 bandcfg;
192 u8 flags;
193 s8 noise;
194 u16 total_bss;
195 u16 cca_scan_dur;
196 u16 cca_busy_dur;
197} __packed;
188#endif /* !_MWIFIEX_DECL_H_ */ 198#endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1eb61739071f..7f922a882c13 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -172,6 +172,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
172#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) 172#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194)
173#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197) 173#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197)
174#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199) 174#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
175#define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198)
175 176
176#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 177#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
177 178
@@ -611,6 +612,16 @@ struct uap_rxpd {
611 u8 reserved1; 612 u8 reserved1;
612}; 613};
613 614
615struct mwifiex_fw_chan_stats {
616 u8 chan_num;
617 u8 bandcfg;
618 u8 flags;
619 s8 noise;
620 __le16 total_bss;
621 __le16 cca_scan_dur;
622 __le16 cca_busy_dur;
623} __packed;
624
614enum mwifiex_chan_scan_mode_bitmasks { 625enum mwifiex_chan_scan_mode_bitmasks {
615 MWIFIEX_PASSIVE_SCAN = BIT(0), 626 MWIFIEX_PASSIVE_SCAN = BIT(0),
616 MWIFIEX_DISABLE_CHAN_FILT = BIT(1), 627 MWIFIEX_DISABLE_CHAN_FILT = BIT(1),
@@ -660,6 +671,11 @@ struct mwifiex_ie_types_scan_chan_gap {
660 __le16 chan_gap; 671 __le16 chan_gap;
661} __packed; 672} __packed;
662 673
674struct mwifiex_ietypes_chanstats {
675 struct mwifiex_ie_types_header header;
676 struct mwifiex_fw_chan_stats chanstats[0];
677} __packed;
678
663struct mwifiex_ie_types_wildcard_ssid_params { 679struct mwifiex_ie_types_wildcard_ssid_params {
664 struct mwifiex_ie_types_header header; 680 struct mwifiex_ie_types_header header;
665 u8 max_ssid_length; 681 u8 max_ssid_length;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index d5070c444fe1..f26420dbab6f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -122,6 +122,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
122 } 122 }
123 } 123 }
124 124
125 vfree(adapter->chan_stats);
125 kfree(adapter); 126 kfree(adapter);
126 return 0; 127 return 0;
127} 128}
@@ -447,6 +448,11 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
447 goto err_init_fw; 448 goto err_init_fw;
448 } 449 }
449 450
451 if (mwifiex_init_channel_scan_gap(adapter)) {
452 dev_err(adapter->dev, "could not init channel stats table\n");
453 goto err_init_fw;
454 }
455
450 rtnl_lock(); 456 rtnl_lock();
451 /* Create station interface by default */ 457 /* Create station interface by default */
452 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", 458 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e2635747d966..fb47731d45a6 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -844,6 +844,9 @@ struct mwifiex_adapter {
844 u8 curr_mem_idx; 844 u8 curr_mem_idx;
845 bool scan_chan_gap_enabled; 845 bool scan_chan_gap_enabled;
846 struct sk_buff_head rx_data_q; 846 struct sk_buff_head rx_data_q;
847 struct mwifiex_chan_stats *chan_stats;
848 u32 num_in_chan_stats;
849 int survey_idx;
847}; 850};
848 851
849int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 852int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -1030,7 +1033,8 @@ void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv);
1030int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv, 1033int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1031 struct host_cmd_ds_command *cmd, 1034 struct host_cmd_ds_command *cmd,
1032 void *data_buf); 1035 void *data_buf);
1033int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv); 1036int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv,
1037 struct host_cmd_ds_command *resp);
1034int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv, 1038int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
1035 void *buf); 1039 void *buf);
1036 1040
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index ca64d4c94112..3a17821157d7 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1755,6 +1755,7 @@ static void mwifiex_complete_scan(struct mwifiex_private *priv)
1755{ 1755{
1756 struct mwifiex_adapter *adapter = priv->adapter; 1756 struct mwifiex_adapter *adapter = priv->adapter;
1757 1757
1758 adapter->survey_idx = 0;
1758 if (adapter->curr_cmd->wait_q_enabled) { 1759 if (adapter->curr_cmd->wait_q_enabled) {
1759 adapter->cmd_wait_q.status = 0; 1760 adapter->cmd_wait_q.status = 0;
1760 if (!priv->scan_request) { 1761 if (!priv->scan_request) {
@@ -1976,10 +1977,53 @@ int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1976 return 0; 1977 return 0;
1977} 1978}
1978 1979
1980static void
1981mwifiex_update_chan_statistics(struct mwifiex_private *priv,
1982 struct mwifiex_ietypes_chanstats *tlv_stat)
1983{
1984 struct mwifiex_adapter *adapter = priv->adapter;
1985 u8 i, num_chan;
1986 struct mwifiex_fw_chan_stats *fw_chan_stats;
1987 struct mwifiex_chan_stats chan_stats;
1988
1989 fw_chan_stats = (void *)((u8 *)tlv_stat +
1990 sizeof(struct mwifiex_ie_types_header));
1991 num_chan = le16_to_cpu(tlv_stat->header.len) /
1992 sizeof(struct mwifiex_chan_stats);
1993
1994 for (i = 0 ; i < num_chan; i++) {
1995 chan_stats.chan_num = fw_chan_stats->chan_num;
1996 chan_stats.bandcfg = fw_chan_stats->bandcfg;
1997 chan_stats.flags = fw_chan_stats->flags;
1998 chan_stats.noise = fw_chan_stats->noise;
1999 chan_stats.total_bss = le16_to_cpu(fw_chan_stats->total_bss);
2000 chan_stats.cca_scan_dur =
2001 le16_to_cpu(fw_chan_stats->cca_scan_dur);
2002 chan_stats.cca_busy_dur =
2003 le16_to_cpu(fw_chan_stats->cca_busy_dur);
2004 dev_dbg(adapter->dev,
2005 "chan=%d, noise=%d, total_network=%d scan_duration=%d, busy_duration=%d\n",
2006 chan_stats.chan_num,
2007 chan_stats.noise,
2008 chan_stats.total_bss,
2009 chan_stats.cca_scan_dur,
2010 chan_stats.cca_busy_dur);
2011 memcpy(&adapter->chan_stats[adapter->survey_idx++], &chan_stats,
2012 sizeof(struct mwifiex_chan_stats));
2013 fw_chan_stats++;
2014 }
2015}
2016
1979/* This function handles the command response of extended scan */ 2017/* This function handles the command response of extended scan */
1980int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) 2018int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv,
2019 struct host_cmd_ds_command *resp)
1981{ 2020{
1982 struct mwifiex_adapter *adapter = priv->adapter; 2021 struct mwifiex_adapter *adapter = priv->adapter;
2022 struct host_cmd_ds_802_11_scan_ext *ext_scan_resp;
2023 struct mwifiex_ie_types_header *tlv;
2024 struct mwifiex_ietypes_chanstats *tlv_stat;
2025 u16 buf_left, type, len;
2026
1983 struct host_cmd_ds_command *cmd_ptr; 2027 struct host_cmd_ds_command *cmd_ptr;
1984 struct cmd_ctrl_node *cmd_node; 2028 struct cmd_ctrl_node *cmd_node;
1985 unsigned long cmd_flags, scan_flags; 2029 unsigned long cmd_flags, scan_flags;
@@ -1987,6 +2031,36 @@ int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
1987 2031
1988 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n"); 2032 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");
1989 2033
2034 ext_scan_resp = &resp->params.ext_scan;
2035
2036 tlv = (void *)ext_scan_resp->tlv_buffer;
2037 buf_left = le16_to_cpu(resp->size) - (sizeof(*ext_scan_resp) + S_DS_GEN
2038 - 1);
2039
2040 while (buf_left >= sizeof(struct mwifiex_ie_types_header)) {
2041 type = le16_to_cpu(tlv->type);
2042 len = le16_to_cpu(tlv->len);
2043
2044 if (buf_left < (sizeof(struct mwifiex_ie_types_header) + len)) {
2045 dev_err(adapter->dev,
2046 "error processing scan response TLVs");
2047 break;
2048 }
2049
2050 switch (type) {
2051 case TLV_TYPE_CHANNEL_STATS:
2052 tlv_stat = (void *)tlv;
2053 mwifiex_update_chan_statistics(priv, tlv_stat);
2054 break;
2055 default:
2056 break;
2057 }
2058
2059 buf_left -= len + sizeof(struct mwifiex_ie_types_header);
2060 tlv = (void *)((u8 *)tlv + len +
2061 sizeof(struct mwifiex_ie_types_header));
2062 }
2063
1990 spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_flags); 2064 spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_flags);
1991 spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_flags); 2065 spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_flags);
1992 if (list_empty(&adapter->scan_pending_q)) { 2066 if (list_empty(&adapter->scan_pending_q)) {
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 4aad44685f8d..b65e1014b0fc 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -983,7 +983,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
983 adapter->curr_cmd->wait_q_enabled = false; 983 adapter->curr_cmd->wait_q_enabled = false;
984 break; 984 break;
985 case HostCmd_CMD_802_11_SCAN_EXT: 985 case HostCmd_CMD_802_11_SCAN_EXT:
986 ret = mwifiex_ret_802_11_scan_ext(priv); 986 ret = mwifiex_ret_802_11_scan_ext(priv, resp);
987 adapter->curr_cmd->wait_q_enabled = false; 987 adapter->curr_cmd->wait_q_enabled = false;
988 break; 988 break;
989 case HostCmd_CMD_802_11_BG_SCAN_QUERY: 989 case HostCmd_CMD_802_11_BG_SCAN_QUERY: