This patch series mainly adds enhancements for mwifiex AP.
With this series, we support verbose information in station dump command
also information about AP link. Another important enhancement is related
to parsing IEs from Tail of beacon_data.
Few issues seen during DFS testing are also fixed in this series.
Patch series also includes some other misc patches.
Avinash Patil (11):
mwifiex: verbose logging for association failure messages
mwifiex: correct bss_type assignment
mwifiex: support AP reset after bss_stop
mwifiex: enable 11d after bss reset
mwifiex: reset 11h active flag when chandef does not require dfs
mwifiex: disable CAC upon radar detection event
mwifiex: parse power constraint IE from Tail
mwifiex: support downloading IEs from tail
mwifiex: drop block-ack action frames
mwifiex: advertise PS ON by default support to cfg80211
mwifiex: update AP WMM settings from BSS_START event
Xinming Hu (6):
mwifiex: add cfg80211 get_channel handler
mwifiex: maintain station statistic in uap mode
mwifiex: add sta_list firmware command
mwifiex: dump station support in uap mode
mwifiex: using right tid for addressing ra_list
mwifiex: do not decrease tx_pending for AMSDU packet once more
drivers/net/wireless/mwifiex/11h.c | 32 +++++--
drivers/net/wireless/mwifiex/11n.c | 11 ++-
drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 +-
drivers/net/wireless/mwifiex/cfg80211.c | 130 ++++++++++++++++++++++++---
drivers/net/wireless/mwifiex/cmdevt.c | 2 +
drivers/net/wireless/mwifiex/fw.h | 43 ++++++++-
drivers/net/wireless/mwifiex/ie.c | 102 ++++++++++++---------
drivers/net/wireless/mwifiex/ioctl.h | 1 +
drivers/net/wireless/mwifiex/join.c | 30 ++++++-
drivers/net/wireless/mwifiex/main.h | 23 ++++-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 26 ++++++
drivers/net/wireless/mwifiex/txrx.c | 21 +++--
drivers/net/wireless/mwifiex/uap_cmd.c | 55 +++++++++++-
drivers/net/wireless/mwifiex/uap_event.c | 63 +++++++++++++
drivers/net/wireless/mwifiex/uap_txrx.c | 18 +++-
drivers/net/wireless/mwifiex/util.c | 56 +++++++++---
16 files changed, 525 insertions(+), 93 deletions(-)
--
1.8.1.4
From: Xinming Hu <[email protected]>
This patch fixes issue with the accessing correct ra_list by
downgrading corresponding tid number.
Alternatively, ra lists are created in mwifiex_wmm_add_buf_txqueue
using downgraded tid number.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/11n.c | 11 ++++++++---
drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 ++++-
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 8422986..4d8ef49 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -156,7 +156,7 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp)
{
- int tid;
+ int tid, tid_down;
struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp;
struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
struct mwifiex_ra_list_tbl *ra_list;
@@ -167,7 +167,9 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
>> BLOCKACKPARAM_TID_POS;
- ra_list = mwifiex_wmm_get_ralist_node(priv, tid, add_ba_rsp->
+
+ tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
+ ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, add_ba_rsp->
peer_mac_addr);
if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) {
if (ra_list) {
@@ -530,13 +532,16 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
struct mwifiex_tx_ba_stream_tbl *new_node;
struct mwifiex_ra_list_tbl *ra_list;
unsigned long flags;
+ int tid_down;
if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
GFP_ATOMIC);
if (!new_node)
return;
- ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra);
+
+ tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
+ ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, ra);
if (ra_list) {
ra_list->ba_status = ba_status;
ra_list->amsdu_in_ampdu = false;
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 39d7a95..64401a7 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -663,6 +663,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
struct mwifiex_ra_list_tbl *ra_list;
u8 cleanup_rx_reorder_tbl;
unsigned long flags;
+ int tid_down;
if (type == TYPE_DELBA_RECEIVE)
cleanup_rx_reorder_tbl = (initiator) ? true : false;
@@ -688,7 +689,9 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
"event: TID, RA not found in table\n");
return;
}
- ra_list = mwifiex_wmm_get_ralist_node(priv, tid, peer_mac);
+
+ tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
+ ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, peer_mac);
if (ra_list) {
ra_list->amsdu_in_ampdu = false;
ra_list->ba_status = BA_SETUP_NONE;
--
1.8.1.4
From: Xinming Hu <[email protected]>
This patch add sta_list firmware command, which can be used
to get power status and rssi for the stations associated to
mwifiex micro AP.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cmdevt.c | 1 +
drivers/net/wireless/mwifiex/fw.h | 14 ++++++++++++++
drivers/net/wireless/mwifiex/sta_cmdresp.c | 24 ++++++++++++++++++++++++
drivers/net/wireless/mwifiex/uap_cmd.c | 1 +
4 files changed, 40 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index b5033d1..b8f6aa1 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -575,6 +575,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
case HostCmd_CMD_UAP_BSS_STOP:
case HostCmd_CMD_UAP_STA_DEAUTH:
case HOST_CMD_APCMD_SYS_RESET:
+ case HOSTCMD_CMD_UAP_STA_LIST:
ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
cmd_oid, data_buf,
cmd_ptr);
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index b6bbf9a..734551c 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -334,6 +334,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0
#define HostCmd_CMD_UAP_BSS_START 0x00b1
#define HostCmd_CMD_UAP_BSS_STOP 0x00b2
+#define HOSTCMD_CMD_UAP_STA_LIST 0x00b3
#define HostCmd_CMD_UAP_STA_DEAUTH 0x00b5
#define HostCmd_CMD_11N_CFG 0x00cd
#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
@@ -1465,6 +1466,18 @@ struct host_cmd_ds_sta_deauth {
__le16 reason;
} __packed;
+struct mwifiex_ie_types_sta_info {
+ struct mwifiex_ie_types_header header;
+ u8 mac[ETH_ALEN];
+ u8 power_mfg_status;
+ s8 rssi;
+};
+
+struct host_cmd_ds_sta_list {
+ u16 sta_count;
+ u8 tlv[0];
+} __packed;
+
struct mwifiex_ie_types_pwr_capability {
struct mwifiex_ie_types_header header;
s8 min_pwr;
@@ -1994,6 +2007,7 @@ struct host_cmd_ds_command {
struct host_cmd_ds_802_11_subsc_evt subsc_evt;
struct host_cmd_ds_sys_config uap_sys_config;
struct host_cmd_ds_sta_deauth sta_deauth;
+ struct host_cmd_ds_sta_list sta_list;
struct host_cmd_11ac_vht_cfg vht_cfg;
struct host_cmd_ds_coalesce_cfg coalesce_cfg;
struct host_cmd_ds_tdls_oper tdls_oper;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index f20a09e..166e7de 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -958,6 +958,27 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
return 0;
}
+static int mwifiex_ret_uap_sta_list(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_sta_list *sta_list =
+ &resp->params.sta_list;
+ struct mwifiex_ie_types_sta_info *sta_info = (void *)&sta_list->tlv;
+ int i;
+ struct mwifiex_sta_node *sta_node;
+
+ for (i = 0; i < sta_list->sta_count; i++) {
+ sta_node = mwifiex_get_sta_entry(priv, sta_info->mac);
+ if (unlikely(!sta_node))
+ continue;
+
+ sta_node->stats.rssi = sta_info->rssi;
+ sta_info++;
+ }
+
+ return 0;
+}
+
/* This function handles the command response of set_cfg_data */
static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp)
@@ -1148,6 +1169,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
break;
case HostCmd_CMD_UAP_SYS_CONFIG:
break;
+ case HOSTCMD_CMD_UAP_STA_LIST:
+ ret = mwifiex_ret_uap_sta_list(priv, resp);
+ break;
case HostCmd_CMD_UAP_BSS_START:
adapter->tx_lock_flag = false;
adapter->pps_uapsd_mode = false;
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 68fbdf6..865b363 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -755,6 +755,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
case HostCmd_CMD_UAP_BSS_START:
case HostCmd_CMD_UAP_BSS_STOP:
case HOST_CMD_APCMD_SYS_RESET:
+ case HOSTCMD_CMD_UAP_STA_LIST:
cmd->command = cpu_to_le16(cmd_no);
cmd->size = cpu_to_le16(S_DS_GEN);
break;
--
1.8.1.4
This patch adds support to parse power constraint IEs from
Tail buffer. This power constraint is then set to FW during
bss_config download.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 3 +++
drivers/net/wireless/mwifiex/fw.h | 6 ++++++
drivers/net/wireless/mwifiex/ioctl.h | 1 +
drivers/net/wireless/mwifiex/main.h | 3 +++
drivers/net/wireless/mwifiex/uap_cmd.c | 27 +++++++++++++++++++++++++++
5 files changed, 40 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 16528c1..1226555 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1867,6 +1867,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
mwifiex_set_wmm_params(priv, bss_cfg, params);
+ if (mwifiex_is_11h_active(priv))
+ mwifiex_set_tpc_params(priv, bss_cfg, params);
+
if (mwifiex_is_11h_active(priv) &&
!cfg80211_chandef_dfs_required(wiphy, ¶ms->chandef,
priv->bss_mode)) {
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 734551c..703e5e9 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -128,6 +128,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_UAP_SSID 0x0000
#define TLV_TYPE_UAP_RATES 0x0001
+#define TLV_TYPE_PWR_CONSTRAINT 0x0020
#define PROPRIETARY_TLV_BASE_ID 0x0100
#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
@@ -1780,6 +1781,11 @@ struct host_cmd_tlv_ageout_timer {
__le32 sta_ao_timer;
} __packed;
+struct host_cmd_tlv_power_constraint {
+ struct mwifiex_ie_types_header header;
+ u8 constraint;
+} __packed;
+
struct host_cmd_ds_version_ext {
u8 version_str_sel;
char version_str[128];
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 6f11a25..4f0174c 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -113,6 +113,7 @@ struct mwifiex_uap_bss_param {
u32 sta_ao_timer;
u32 ps_sta_ao_timer;
u8 qos_info;
+ u8 power_constraint;
struct mwifiex_types_wmm_info wmm_info;
};
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 837e610..d92c527 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1149,6 +1149,9 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv,
void mwifiex_set_vht_params(struct mwifiex_private *priv,
struct mwifiex_uap_bss_param *bss_cfg,
struct cfg80211_ap_settings *params);
+void mwifiex_set_tpc_params(struct mwifiex_private *priv,
+ struct mwifiex_uap_bss_param *bss_cfg,
+ struct cfg80211_ap_settings *params);
void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
struct cfg80211_ap_settings *params);
void mwifiex_set_vht_width(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 865b363..61e8bf3 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -222,6 +222,23 @@ void mwifiex_set_vht_params(struct mwifiex_private *priv,
return;
}
+/* This function updates 11ac related parameters from IE
+ * and sets them into bss_config structure.
+ */
+void mwifiex_set_tpc_params(struct mwifiex_private *priv,
+ struct mwifiex_uap_bss_param *bss_cfg,
+ struct cfg80211_ap_settings *params)
+{
+ const u8 *tpc_ie;
+
+ tpc_ie = cfg80211_find_ie(WLAN_EID_TPC_REQUEST, params->beacon.tail,
+ params->beacon.tail_len);
+ if (tpc_ie)
+ bss_cfg->power_constraint = *(tpc_ie + 2);
+ else
+ bss_cfg->power_constraint = 0;
+}
+
/* Enable VHT only when cfg80211_ap_settings has VHT IE.
* Otherwise disable VHT.
*/
@@ -466,6 +483,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
struct host_cmd_tlv_auth_type *auth_type;
struct host_cmd_tlv_rates *tlv_rates;
struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer;
+ struct host_cmd_tlv_power_constraint *pwr_ct;
struct mwifiex_ie_types_htcap *htcap;
struct mwifiex_ie_types_wmmcap *wmm_cap;
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
@@ -644,6 +662,15 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
tlv += sizeof(*ao_timer);
}
+ if (bss_cfg->power_constraint) {
+ pwr_ct = (void *)tlv;
+ pwr_ct->header.type = cpu_to_le16(TLV_TYPE_PWR_CONSTRAINT);
+ pwr_ct->header.len = cpu_to_le16(sizeof(u8));
+ pwr_ct->constraint = bss_cfg->power_constraint;
+ cmd_size += sizeof(*pwr_ct);
+ tlv += sizeof(*pwr_ct);
+ }
+
if (bss_cfg->ps_sta_ao_timer) {
ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
ps_ao_timer->header.type =
--
1.8.1.4
This would enable driver to enter powersave as soon as connected.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 1226555..3d3794f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -3685,7 +3685,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
WIPHY_FLAG_AP_UAPSD |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
- WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+ WIPHY_FLAG_HAS_CHANNEL_SWITCH |
+ WIPHY_FLAG_PS_ON_BY_DEFAULT;
if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
--
1.8.1.4
This patch adds support to disable ongoing CAC in FW upon
detecting radar during CAC period.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/11h.c | 30 ++++++++++++++++++++++++++----
drivers/net/wireless/mwifiex/main.h | 2 ++
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index 65cd461..bb2ffd9 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -161,19 +161,38 @@ int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
cr_req->chan_desc.chan_width = radar_params->chandef->width;
cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms);
- mwifiex_dbg(priv->adapter, MSG,
- "11h: issuing DFS Radar check for channel=%d\n",
- radar_params->chandef->chan->hw_value);
+ if (radar_params->cac_time_ms)
+ mwifiex_dbg(priv->adapter, MSG,
+ "11h: issuing DFS Radar check for channel=%d\n",
+ radar_params->chandef->chan->hw_value);
+ else
+ mwifiex_dbg(priv->adapter, MSG, "cancelling CAC\n");
return 0;
}
+int mwifiex_stop_radar_detection(struct mwifiex_private *priv,
+ struct cfg80211_chan_def *chandef)
+{
+ struct mwifiex_radar_params radar_params;
+
+ memset(&radar_params, 0, sizeof(struct mwifiex_radar_params));
+ radar_params.chandef = chandef;
+ radar_params.cac_time_ms = 0;
+
+ return mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST,
+ HostCmd_ACT_GEN_SET, 0, &radar_params, true);
+}
+
/* This function is to abort ongoing CAC upon stopping AP operations
* or during unload.
*/
void mwifiex_abort_cac(struct mwifiex_private *priv)
{
if (priv->wdev.cac_started) {
+ if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
+ mwifiex_dbg(priv->adapter, ERROR,
+ "failed to stop CAC in FW\n");
mwifiex_dbg(priv->adapter, MSG,
"Aborting delayed work for CAC.\n");
cancel_delayed_work_sync(&priv->dfs_cac_work);
@@ -245,6 +264,9 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
if (le32_to_cpu(rdr_event->passed)) {
mwifiex_dbg(priv->adapter, MSG,
"radar detected; indicating kernel\n");
+ if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef))
+ mwifiex_dbg(priv->adapter, ERROR,
+ "Failed to stop CAC in FW\n");
cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef,
GFP_KERNEL);
mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n",
@@ -252,7 +274,7 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n",
rdr_event->det_type);
} else {
- mwifiex_dbg(priv->adapter, ERROR,
+ mwifiex_dbg(priv->adapter, MSG,
"false radar detection event!\n");
}
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 5a6c1c7..3ac18c6 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1473,6 +1473,8 @@ mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
void mwifiex_dfs_cac_work_queue(struct work_struct *work);
void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work);
void mwifiex_abort_cac(struct mwifiex_private *priv);
+int mwifiex_stop_radar_detection(struct mwifiex_private *priv,
+ struct cfg80211_chan_def *chandef);
int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
struct sk_buff *skb);
--
1.8.1.4
From: Xinming Hu <[email protected]>
This patch maintain statistic information for the stations associated
to the mwifiex micro AP, include tx/rx bytes/packets, signal strength,
tx bitrate.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/fw.h | 7 ++++++-
drivers/net/wireless/mwifiex/main.h | 13 +++++++++++++
drivers/net/wireless/mwifiex/txrx.c | 13 +++++++++++--
drivers/net/wireless/mwifiex/uap_txrx.c | 18 +++++++++++++++++-
drivers/net/wireless/mwifiex/util.c | 13 +++++++++++++
5 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 45822a8..b6bbf9a 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -632,7 +632,12 @@ struct uap_rxpd {
__le16 rx_pkt_type;
__le16 seq_num;
u8 priority;
- u8 reserved1;
+ u8 rx_rate;
+ s8 snr;
+ s8 nf;
+ u8 ht_info;
+ u8 reserved[3];
+ u8 flags;
};
struct mwifiex_fw_chan_stats {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 88d3779..837e610 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -741,6 +741,18 @@ struct mwifiex_tdls_capab {
struct ieee80211_vht_operation vhtoper;
};
+struct mwifiex_station_stats {
+ u64 last_rx;
+ s8 rssi;
+ u64 rx_bytes;
+ u64 tx_bytes;
+ u32 rx_packets;
+ u32 tx_packets;
+ u32 tx_failed;
+ u8 last_tx_rate;
+ u8 last_tx_htinfo;
+};
+
/* This is AP/TDLS specific structure which stores information
* about associated/peer STA
*/
@@ -755,6 +767,7 @@ struct mwifiex_sta_node {
u16 max_amsdu;
u8 tdls_status;
struct mwifiex_tdls_capab tdls_cap;
+ struct mwifiex_station_stats stats;
};
struct mwifiex_auto_tdls_peer {
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 28dcc84..c4c7d8d 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -88,13 +88,22 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
struct mwifiex_adapter *adapter = priv->adapter;
u8 *head_ptr;
struct txpd *local_tx_pd = NULL;
+ struct mwifiex_sta_node *dest_node;
+ struct ethhdr *hdr = (void *)skb->data;
hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
- if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
+ if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
+ dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest);
+ if (dest_node) {
+ dest_node->stats.tx_bytes += skb->len;
+ dest_node->stats.tx_packets++;
+ }
+
head_ptr = mwifiex_process_uap_txpd(priv, skb);
- else
+ } else {
head_ptr = mwifiex_process_sta_txpd(priv, skb);
+ }
if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
skb_queue_tail(&adapter->tx_data_q, skb);
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 61c52fd..8766741 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -97,6 +97,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
struct mwifiex_txinfo *tx_info;
int hdr_chop;
struct ethhdr *p_ethhdr;
+ struct mwifiex_sta_node *src_node;
uap_rx_pd = (struct uap_rxpd *)(skb->data);
rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
@@ -180,6 +181,15 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
tx_info->bss_type = priv->bss_type;
tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
+ src_node = mwifiex_get_sta_entry(priv, rx_pkt_hdr->eth803_hdr.h_source);
+ if (src_node) {
+ src_node->stats.last_rx = jiffies;
+ src_node->stats.rx_bytes += skb->len;
+ src_node->stats.rx_packets++;
+ src_node->stats.last_tx_rate = uap_rx_pd->rx_rate;
+ src_node->stats.last_tx_htinfo = uap_rx_pd->ht_info;
+ }
+
if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) {
/* Update bridge packet statistics as the
* packet is not going to kernel/upper layer.
@@ -275,6 +285,8 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
+ ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);
+
if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16) skb->len) {
mwifiex_dbg(adapter, ERROR,
@@ -282,6 +294,11 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset),
le16_to_cpu(uap_rx_pd->rx_pkt_length));
priv->stats.rx_dropped++;
+
+ node = mwifiex_get_sta_entry(priv, ta);
+ if (node)
+ node->stats.tx_failed++;
+
dev_kfree_skb_any(skb);
return 0;
}
@@ -295,7 +312,6 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
return ret;
}
- memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) {
spin_lock_irqsave(&priv->sta_list_spinlock, flags);
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 370323a..2e3dc07 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -416,12 +416,25 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
*/
int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
{
+ struct mwifiex_sta_node *src_node;
+ struct ethhdr *p_ethhdr;
+
if (!skb)
return -1;
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
+ p_ethhdr = (void *)skb->data;
+ src_node = mwifiex_get_sta_entry(priv, p_ethhdr->h_source);
+ if (src_node) {
+ src_node->stats.last_rx = jiffies;
+ src_node->stats.rx_bytes += skb->len;
+ src_node->stats.rx_packets++;
+ }
+ }
+
skb->dev = priv->netdev;
skb->protocol = eth_type_trans(skb, priv->netdev);
skb->ip_summed = CHECKSUM_NONE;
--
1.8.1.4
From: Xinming Hu <[email protected]>
Negative adapter->tx_pending is observed while running data traffic,
because tx_pending is decreased once more for AMSDU packet.
since tx_pending have been decreased for all the source MSDU packets,
we don't need to update once more for AMSDU packet.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/txrx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index c4c7d8d..5ed9b79 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -319,11 +319,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
priv->stats.tx_errors++;
}
- if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) {
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
atomic_dec_return(&adapter->pending_bridged_pkts);
- if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
- goto done;
- }
+
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
+ goto done;
if (aggr)
/* For skb_aggr, do not wake up tx queue */
--
1.8.1.4
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBCasO4cm4gTW9yayBbbWFpbHRv
OmJqb3JuQG1vcmsubm9dDQo+IFNlbnQ6IEZyaWRheSwgTWF5IDI5LCAyMDE1IDU6MzYgUE0NCj4g
VG86IEF2aW5hc2ggUGF0aWwNCj4gQ2M6IGxpbnV4LXdpcmVsZXNzQHZnZXIua2VybmVsLm9yZzsg
QW1pdGt1bWFyIEthcndhcjsgQ2F0aHkgTHVvOyBYaW5taW5nIEh1DQo+IFN1YmplY3Q6IFJlOiBb
UEFUQ0h2MyAwOS8xNl0gbXdpZmlleDogYWRkIHN0YV9saXN0IGZpcm13YXJlIGNvbW1hbmQNCj4g
DQo+IEF2aW5hc2ggUGF0aWwgPHBhdGlsYUBtYXJ2ZWxsLmNvbT4gd3JpdGVzOg0KPiANCj4gPiAg
CQljYXNlIEhvc3RDbWRfQ01EX1VBUF9CU1NfU1RPUDoNCj4gPiAgCQljYXNlIEhvc3RDbWRfQ01E
X1VBUF9TVEFfREVBVVRIOg0KPiA+ICAJCWNhc2UgSE9TVF9DTURfQVBDTURfU1lTX1JFU0VUOg0K
PiA+ICsJCWNhc2UgSE9TVENNRF9DTURfVUFQX1NUQV9MSVNUOg0KPiANCj4gDQo+IEp1c3Qgd29u
ZGVyaW5nLCBub3QgcmVhbGx5IG9iamVjdGluZy4uLi4gQnV0IHdvdWxkbid0IGl0IGJlIG5pY2Ug
d2l0aCBzb21lDQo+IGNvbnNpc3RlbmN5IGhlcmU/DQo+IA0KPg0KDQpUaGFua3MgZm9yIHJldmll
dy4uLndpbGwgbW9kaWZ5IGNhc2UgSE9TVENNRF9DTURfVUFQX1NUQV9MSVNUIHRvIGNhc2UgSE9T
VF9DTURfQVBDTURfU1RBX0xJU1Qgc28gYXMga2VlcCBjb25zaXN0ZW5jeSB3aXRoIFNZU19SRVNF
VC4NCiANCj4gQmrDuHJuDQoNCi1BdmluYXNoDQo=
We often see ADDBA request packets coming to driver because driver
has registered for action frame subtype. We dont process BA action
frames in host. Drop such frames.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Xinmin Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/util.c | 43 +++++++++++++++++++++++++------------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 2e3dc07..790e619 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -329,7 +329,7 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
struct rxpd *rx_pd)
{
u16 stype;
- u8 category, action_code;
+ u8 category, action_code, *addr2;
struct ieee80211_hdr *ieee_hdr = (void *)payload;
stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE);
@@ -337,21 +337,35 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
switch (stype) {
case IEEE80211_STYPE_ACTION:
category = *(payload + sizeof(struct ieee80211_hdr));
- action_code = *(payload + sizeof(struct ieee80211_hdr) + 1);
- if (category == WLAN_CATEGORY_PUBLIC &&
- action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
+ switch (category) {
+ case WLAN_CATEGORY_PUBLIC:
+ action_code = *(payload + sizeof(struct ieee80211_hdr)
+ + 1);
+ if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
+ addr2 = ieee_hdr->addr2;
+ mwifiex_dbg(priv->adapter, INFO,
+ "TDLS discovery response %pM nf=%d, snr=%d\n",
+ addr2, rx_pd->nf, rx_pd->snr);
+ mwifiex_auto_tdls_update_peer_signal(priv,
+ addr2,
+ rx_pd->snr,
+ rx_pd->nf);
+ }
+ break;
+ case WLAN_CATEGORY_BACK:
+ /*we dont indicate BACK action frames to cfg80211*/
+ mwifiex_dbg(priv->adapter, INFO,
+ "drop BACK action frames");
+ return -1;
+ default:
mwifiex_dbg(priv->adapter, INFO,
- "TDLS discovery response %pM nf=%d, snr=%d\n",
- ieee_hdr->addr2, rx_pd->nf, rx_pd->snr);
- mwifiex_auto_tdls_update_peer_signal(priv,
- ieee_hdr->addr2,
- rx_pd->snr,
- rx_pd->nf);
+ "unknown public action frame category %d\n",
+ category);
}
- break;
default:
mwifiex_dbg(priv->adapter, INFO,
- "unknown mgmt frame subtype %#x\n", stype);
+ "unknown mgmt frame subtype %#x\n", stype);
+ return 0;
}
return 0;
@@ -387,8 +401,9 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
ieee_hdr = (void *)skb->data;
if (ieee80211_is_mgmt(ieee_hdr->frame_control)) {
- mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr,
- pkt_len, rx_pd);
+ if (mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr,
+ pkt_len, rx_pd))
+ return -1;
}
/* Remove address4 */
memmove(skb->data + sizeof(struct ieee80211_hdr_3addr),
--
1.8.1.4
Earlier only RSN, WPA and channel switch IEs from tail buffer would
be downloaded to FW.
This patch adds support for downloading more IEs from tail buffer.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/ie.c | 102 ++++++++++++++++++++++----------------
1 file changed, 60 insertions(+), 42 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index f3b6ed2..0ba8945 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -320,63 +320,81 @@ done:
/* This function parses head and tail IEs, from cfg80211_beacon_data and sets
* these IE to FW.
*/
-static int mwifiex_uap_set_head_tail_ies(struct mwifiex_private *priv,
- struct cfg80211_beacon_data *info)
+static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
+ struct cfg80211_beacon_data *info)
{
struct mwifiex_ie *gen_ie;
- struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL;
- struct ieee_types_header *chsw_ie = NULL;
+ struct ieee_types_header *hdr;
+ struct ieee80211_vendor_ie *vendorhdr;
u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
- const u8 *vendor_ie;
+ int left_len, parsed_len = 0;
+
+ if (!info->tail || !info->tail_len)
+ return 0;
gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL);
if (!gen_ie)
return -ENOMEM;
- gen_ie->ie_index = cpu_to_le16(gen_idx);
- gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
- MGMT_MASK_PROBE_RESP |
- MGMT_MASK_ASSOC_RESP);
- if (info->tail && info->tail_len) {
- rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN,
- info->tail, info->tail_len);
- if (rsn_ie) {
- memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2);
- ie_len = rsn_ie->len + 2;
- gen_ie->ie_length = cpu_to_le16(ie_len);
+ left_len = info->tail_len;
+
+ /* Many IEs are generated in FW by parsing bss configuration.
+ * Let's not add them here; else we may end up duplicating these IEs
+ */
+ while (left_len > sizeof(struct ieee_types_header)) {
+ hdr = (void *)(info->tail + parsed_len);
+ switch (hdr->element_id) {
+ case WLAN_EID_SSID:
+ case WLAN_EID_SUPP_RATES:
+ case WLAN_EID_COUNTRY:
+ case WLAN_EID_PWR_CONSTRAINT:
+ case WLAN_EID_EXT_SUPP_RATES:
+ case WLAN_EID_HT_CAPABILITY:
+ case WLAN_EID_HT_OPERATION:
+ case WLAN_EID_VHT_CAPABILITY:
+ case WLAN_EID_VHT_OPERATION:
+ case WLAN_EID_VENDOR_SPECIFIC:
+ break;
+ default:
+ memcpy(gen_ie->ie_buffer + ie_len, hdr,
+ hdr->len + sizeof(struct ieee_types_header));
+ ie_len += hdr->len + sizeof(struct ieee_types_header);
+ break;
}
+ left_len -= hdr->len + sizeof(struct ieee_types_header);
+ parsed_len += hdr->len + sizeof(struct ieee_types_header);
+ }
- vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ /* parse only WPA vendor IE from tail, WMM IE is configured by
+ * bss_config command
+ */
+ vendorhdr = (void *)cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WPA,
- info->tail,
- info->tail_len);
- if (vendor_ie) {
- wpa_ie = (struct ieee_types_header *)vendor_ie;
- memcpy(gen_ie->ie_buffer + ie_len,
- wpa_ie, wpa_ie->len + 2);
- ie_len += wpa_ie->len + 2;
- gen_ie->ie_length = cpu_to_le16(ie_len);
- }
+ info->tail, info->tail_len);
+ if (vendorhdr) {
+ memcpy(gen_ie->ie_buffer + ie_len, vendorhdr,
+ vendorhdr->len + sizeof(struct ieee_types_header));
+ ie_len += vendorhdr->len + sizeof(struct ieee_types_header);
+ }
- chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH,
- info->tail, info->tail_len);
- if (chsw_ie) {
- memcpy(gen_ie->ie_buffer + ie_len,
- chsw_ie, chsw_ie->len + 2);
- ie_len += chsw_ie->len + 2;
- gen_ie->ie_length = cpu_to_le16(ie_len);
- }
+ if (!ie_len) {
+ kfree(gen_ie);
+ return 0;
}
- if (rsn_ie || wpa_ie || chsw_ie) {
- if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL,
- NULL, NULL, NULL)) {
- kfree(gen_ie);
- return -1;
- }
- priv->gen_idx = gen_idx;
+ gen_ie->ie_index = cpu_to_le16(gen_idx);
+ gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
+ MGMT_MASK_PROBE_RESP |
+ MGMT_MASK_ASSOC_RESP);
+ gen_ie->ie_length = cpu_to_le16(ie_len);
+
+ if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL,
+ NULL, NULL)) {
+ kfree(gen_ie);
+ return -1;
}
+ priv->gen_idx = gen_idx;
kfree(gen_ie);
return 0;
}
@@ -390,7 +408,7 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
{
int ret;
- ret = mwifiex_uap_set_head_tail_ies(priv, info);
+ ret = mwifiex_uap_parse_tail_ies(priv, info);
return ret;
return mwifiex_set_mgmt_beacon_data_ies(priv, info);
--
1.8.1.4
From: Xinming Hu <[email protected]>
This patch extend cfg80211 dump_station handler, support for
dump stations associated to mwifiex micro AP.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 51 +++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ddeb919..16528c1 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1229,6 +1229,7 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
*/
static int
mwifiex_dump_station_info(struct mwifiex_private *priv,
+ struct mwifiex_sta_node *node,
struct station_info *sinfo)
{
u32 rate;
@@ -1238,6 +1239,30 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
BIT(NL80211_STA_INFO_TX_BITRATE) |
BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG);
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
+ if (!node)
+ return -ENOENT;
+
+ sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME) |
+ BIT(NL80211_STA_INFO_TX_FAILED);
+ sinfo->inactive_time =
+ jiffies_to_msecs(jiffies - node->stats.last_rx);
+
+ sinfo->signal = node->stats.rssi;
+ sinfo->signal_avg = node->stats.rssi;
+ sinfo->rx_bytes = node->stats.rx_bytes;
+ sinfo->tx_bytes = node->stats.tx_bytes;
+ sinfo->rx_packets = node->stats.rx_packets;
+ sinfo->tx_packets = node->stats.tx_packets;
+ sinfo->tx_failed = node->stats.tx_failed;
+
+ mwifiex_parse_htinfo(priv, node->stats.last_tx_htinfo,
+ &sinfo->txrate);
+ sinfo->txrate.legacy = node->stats.last_tx_rate * 5;
+
+ return 0;
+ }
+
/* Get signal information from the firmware */
if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
HostCmd_ACT_GEN_GET, 0, NULL, true)) {
@@ -1304,7 +1329,7 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
return -ENOENT;
- return mwifiex_dump_station_info(priv, sinfo);
+ return mwifiex_dump_station_info(priv, NULL, sinfo);
}
/*
@@ -1315,13 +1340,29 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
int idx, u8 *mac, struct station_info *sinfo)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ static struct mwifiex_sta_node *node;
- if (!priv->media_connected || idx)
- return -ENOENT;
+ if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+ priv->media_connected && idx == 0) {
+ ether_addr_copy(mac, priv->cfg_bssid);
+ return mwifiex_dump_station_info(priv, NULL, sinfo);
+ } else if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
+ mwifiex_send_cmd(priv, HOSTCMD_CMD_UAP_STA_LIST,
+ HostCmd_ACT_GEN_GET, 0, NULL, true);
+
+ if (node && (&node->list == &priv->sta_list)) {
+ node = NULL;
+ return -ENOENT;
+ }
- memcpy(mac, priv->cfg_bssid, ETH_ALEN);
+ node = list_prepare_entry(node, &priv->sta_list, list);
+ list_for_each_entry_continue(node, &priv->sta_list, list) {
+ ether_addr_copy(mac, node->mac_addr);
+ return mwifiex_dump_station_info(priv, node, sinfo);
+ }
+ }
- return mwifiex_dump_station_info(priv, sinfo);
+ return -ENOENT;
}
static int
--
1.8.1.4
From: Xinming Hu <[email protected]>
This patch add cfg80211 get_channel handler for mwifiex.
The handler will be used to report current channel to upper
layer utility.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/11h.c | 2 +-
drivers/net/wireless/mwifiex/cfg80211.c | 58 ++++++++++++++++++++++++++++++++-
drivers/net/wireless/mwifiex/main.h | 5 ++-
drivers/net/wireless/mwifiex/uap_cmd.c | 5 ++-
4 files changed, 66 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index bb2ffd9..71a1b58 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -305,7 +305,7 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
return;
}
- mwifiex_uap_set_channel(bss_cfg, priv->dfs_chandef);
+ mwifiex_uap_set_channel(priv, bss_cfg, priv->dfs_chandef);
if (mwifiex_config_start_uap(priv, bss_cfg)) {
mwifiex_dbg(priv->adapter, ERROR,
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index fb93e13..ddeb919 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -67,6 +67,22 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
}
}
+/* This function maps IEEE HT secondary channel type to NL80211 channel type
+ */
+u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset)
+{
+ switch (second_chan_offset) {
+ case IEEE80211_HT_PARAM_CHA_SEC_NONE:
+ return NL80211_CHAN_HT20;
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+ return NL80211_CHAN_HT40PLUS;
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+ return NL80211_CHAN_HT40MINUS;
+ default:
+ return NL80211_CHAN_HT20;
+ }
+}
+
/*
* This function checks whether WEP is set.
*/
@@ -1785,7 +1801,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
return -EINVAL;
}
- mwifiex_uap_set_channel(bss_cfg, params->chandef);
+ mwifiex_uap_set_channel(priv, bss_cfg, params->chandef);
mwifiex_set_uap_rates(bss_cfg, params);
if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
@@ -3373,6 +3389,45 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
+static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_chan_def *chandef)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
+ struct mwifiex_bssdescriptor *curr_bss;
+ struct ieee80211_channel *chan;
+ u8 second_chan_offset;
+ enum nl80211_channel_type chan_type;
+ enum ieee80211_band band;
+ int freq;
+ int ret = -ENODATA;
+
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
+ cfg80211_chandef_valid(&priv->bss_chandef)) {
+ *chandef = priv->bss_chandef;
+ ret = 0;
+ } else if (priv->media_connected) {
+ curr_bss = &priv->curr_bss_params.bss_descriptor;
+ band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
+ freq = ieee80211_channel_to_frequency(curr_bss->channel, band);
+ chan = ieee80211_get_channel(wiphy, freq);
+
+ if (curr_bss->bcn_ht_oper) {
+ second_chan_offset = curr_bss->bcn_ht_oper->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
+ chan_type = mwifiex_sec_chan_offset_to_chan_type
+ (second_chan_offset);
+ cfg80211_chandef_create(chandef, chan, chan_type);
+ } else {
+ cfg80211_chandef_create(chandef, chan,
+ NL80211_CHAN_NO_HT);
+ }
+ ret = 0;
+ }
+
+ return ret;
+}
+
static int
mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
struct net_device *dev,
@@ -3478,6 +3533,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.tdls_oper = mwifiex_cfg80211_tdls_oper,
.add_station = mwifiex_cfg80211_add_station,
.change_station = mwifiex_cfg80211_change_station,
+ .get_channel = mwifiex_cfg80211_get_channel,
.start_radar_detection = mwifiex_cfg80211_start_radar_detection,
.channel_switch = mwifiex_cfg80211_channel_switch,
};
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 3ac18c6..88d3779 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -642,6 +642,7 @@ struct mwifiex_private {
u8 del_list_idx;
bool hs2_enabled;
struct mwifiex_uap_bss_param bss_cfg;
+ struct cfg80211_chan_def bss_chandef;
struct station_parameters *sta_params;
struct sk_buff_head tdls_txq;
u8 check_tdls_tx;
@@ -1382,6 +1383,7 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
struct mwifiex_bssdescriptor *bss_desc);
u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type);
+u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset);
struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
const char *name,
@@ -1399,7 +1401,8 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
struct cfg80211_beacon_data *data);
int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
u8 *mwifiex_11d_code_2_region(u8 code);
-void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg,
+void mwifiex_uap_set_channel(struct mwifiex_private *priv,
+ struct mwifiex_uap_bss_param *bss_cfg,
struct cfg80211_chan_def chandef);
int mwifiex_config_start_uap(struct mwifiex_private *priv,
struct mwifiex_uap_bss_param *bss_cfg);
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 56a4768..68fbdf6 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -776,11 +776,14 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
return 0;
}
-void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg,
+void mwifiex_uap_set_channel(struct mwifiex_private *priv,
+ struct mwifiex_uap_bss_param *bss_cfg,
struct cfg80211_chan_def chandef)
{
u8 config_bands = 0;
+ priv->bss_chandef = chandef;
+
bss_cfg->channel = ieee80211_frequency_to_channel(
chandef.chan->center_freq);
--
1.8.1.4
This patch adds more detailed information about association failures
- reason and states.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/fw.h | 15 +++++++++++++--
drivers/net/wireless/mwifiex/join.c | 30 +++++++++++++++++++++++++++---
2 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index c404390..cf386bc 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -419,8 +419,12 @@ enum P2P_MODES {
#define HS_CFG_COND_MAC_EVENT 0x00000004
#define HS_CFG_COND_MULTICAST_DATA 0x00000008
-#define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc
-#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2
+#define CONNECT_ERR_AUTH_ERR_STA_FAILURE 0xFFFB
+#define CONNECT_ERR_ASSOC_ERR_TIMEOUT 0xFFFC
+#define CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD
+#define CONNECT_ERR_AUTH_MSG_UNHANDLED 0xFFFE
+#define CONNECT_ERR_STA_FAILURE 0xFFFF
+
#define CMD_F_HOSTCMD (1 << 0)
#define CMD_F_CANCELED (1 << 1)
@@ -1151,6 +1155,13 @@ enum SNMP_MIB_INDEX {
DOT11H_I = 10,
};
+enum mwifiex_assocmd_failurepoint {
+ MWIFIEX_ASSOC_CMD_SUCCESS = 0,
+ MWIFIEX_ASSOC_CMD_FAILURE_ASSOC,
+ MWIFIEX_ASSOC_CMD_FAILURE_AUTH,
+ MWIFIEX_ASSOC_CMD_FAILURE_JOIN
+};
+
#define MAX_SNMP_BUF_SIZE 128
struct host_cmd_ds_802_11_snmp_mib {
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 6208ef1..e233b04 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
return 0;
}
+static const char *assoc_failure_reason_to_str(u16 cap_info)
+{
+ switch (cap_info) {
+ case CONNECT_ERR_AUTH_ERR_STA_FAILURE:
+ return "CONNECT_ERR_AUTH_ERR_STA_FAILURE";
+ case CONNECT_ERR_AUTH_MSG_UNHANDLED:
+ return "CONNECT_ERR_AUTH_MSG_UNHANDLED";
+ case CONNECT_ERR_ASSOC_ERR_TIMEOUT:
+ return "CONNECT_ERR_ASSOC_ERR_TIMEOUT";
+ case CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED:
+ return "CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED";
+ case CONNECT_ERR_STA_FAILURE:
+ return "CONNECT_ERR_STA_FAILURE";
+ }
+
+ return "Unknown connect failure";
+}
/*
* Association firmware command response handler
*
@@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
status_code, cap_info,
le16_to_cpu(assoc_rsp->a_id));
- if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) {
- if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT)
+ mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n",
+ assoc_failure_reason_to_str(cap_info));
+ if (cap_info == CONNECT_ERR_ASSOC_ERR_TIMEOUT) {
+ if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) {
ret = WLAN_STATUS_AUTH_TIMEOUT;
- else
+ mwifiex_dbg(priv->adapter, ERROR,
+ "ASSOC_RESP: AUTH timeout\n");
+ } else {
ret = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ mwifiex_dbg(priv->adapter, ERROR,
+ "ASSOC_RESP: UNSPECIFIED failure\n");
+ }
} else {
ret = status_code;
}
--
1.8.1.4
Correct bss_type assignment in add_virtual_interface.
This would ensure correct operation in multiple station scenarios.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 4eeceda..3a14d3a 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2518,7 +2518,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
priv->bss_priority = 0;
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
- priv->bss_num = 0;
+ priv->bss_num = adapter->curr_iface_comb.sta_intf;
break;
case NL80211_IFTYPE_AP:
@@ -2544,7 +2544,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->bss_priority = 0;
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
priv->bss_started = 0;
- priv->bss_num = 0;
+ priv->bss_num = adapter->curr_iface_comb.uap_intf;
priv->bss_mode = type;
break;
@@ -2580,7 +2580,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_started = 0;
- priv->bss_num = 0;
+ priv->bss_num = adapter->curr_iface_comb.p2p_intf;
if (mwifiex_cfg80211_init_p2p_client(priv)) {
memset(&priv->wdev, 0, sizeof(priv->wdev));
--
1.8.1.4
This would enable clearing of FW bss data structures when AP
operations are stopped.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 7 +++++++
drivers/net/wireless/mwifiex/cmdevt.c | 1 +
drivers/net/wireless/mwifiex/fw.h | 1 +
drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 ++
drivers/net/wireless/mwifiex/uap_cmd.c | 10 ++++++++--
5 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 3a14d3a..d47799a 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1725,6 +1725,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
return -1;
}
+ if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
+ HostCmd_ACT_GEN_SET, 0, NULL, true)) {
+ mwifiex_dbg(priv->adapter, ERROR,
+ "Failed to reset BSS\n");
+ return -1;
+ }
+
return 0;
}
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index a1de83f..b5033d1 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -574,6 +574,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
case HostCmd_CMD_UAP_BSS_START:
case HostCmd_CMD_UAP_BSS_STOP:
case HostCmd_CMD_UAP_STA_DEAUTH:
+ case HOST_CMD_APCMD_SYS_RESET:
ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
cmd_oid, data_buf,
cmd_ptr);
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index cf386bc..45822a8 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -330,6 +330,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define HostCmd_CMD_RSSI_INFO 0x00a4
#define HostCmd_CMD_FUNC_INIT 0x00a9
#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa
+#define HOST_CMD_APCMD_SYS_RESET 0x00af
#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0
#define HostCmd_CMD_UAP_BSS_START 0x00b1
#define HostCmd_CMD_UAP_BSS_STOP 0x00b2
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index aa5b9a3..f20a09e 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -1159,6 +1159,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
break;
case HostCmd_CMD_UAP_STA_DEAUTH:
break;
+ case HOST_CMD_APCMD_SYS_RESET:
+ break;
case HostCmd_CMD_MEF_CFG:
break;
case HostCmd_CMD_COALESCE_CFG:
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index a4ae283..0a3297e 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -754,6 +754,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
break;
case HostCmd_CMD_UAP_BSS_START:
case HostCmd_CMD_UAP_BSS_STOP:
+ case HOST_CMD_APCMD_SYS_RESET:
cmd->command = cpu_to_le16(cmd_no);
cmd->size = cpu_to_le16(S_DS_GEN);
break;
@@ -811,8 +812,13 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
HostCmd_ACT_GEN_SET, 0, NULL, true)) {
- mwifiex_dbg(priv->adapter, ERROR,
- "Failed to stop the BSS\n");
+ mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n");
+ return -1;
+ }
+
+ if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
+ HostCmd_ACT_GEN_SET, 0, NULL, true)) {
+ mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n");
return -1;
}
--
1.8.1.4
BSS reset would reset all state information in FW.
Issue 11d config command after reset to enabled 11d in FW.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/uap_cmd.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 0a3297e..56a4768 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -806,6 +806,8 @@ void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg,
int mwifiex_config_start_uap(struct mwifiex_private *priv,
struct mwifiex_uap_bss_param *bss_cfg)
{
+ enum state_11d_t state_11d;
+
if (mwifiex_del_mgmt_ies(priv))
mwifiex_dbg(priv->adapter, ERROR,
"Failed to delete mgmt IEs!\n");
@@ -830,6 +832,16 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
return -1;
}
+ /* Send cmd to FW to enable 11D function */
+ state_11d = ENABLE_11D;
+ if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
+ HostCmd_ACT_GEN_SET, DOT11D_I,
+ &state_11d, true)) {
+ mwifiex_dbg(priv->adapter, ERROR,
+ "11D: failed to enable 11D\n");
+ return -1;
+ }
+
if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
HostCmd_ACT_GEN_SET, 0, NULL, false)) {
mwifiex_dbg(priv->adapter, ERROR,
--
1.8.1.4
Avinash Patil <[email protected]> writes:
> case HostCmd_CMD_UAP_BSS_STOP:
> case HostCmd_CMD_UAP_STA_DEAUTH:
> case HOST_CMD_APCMD_SYS_RESET:
> + case HOSTCMD_CMD_UAP_STA_LIST:
Just wondering, not really objecting.... But wouldn't it be nice with
some consistency here?
Bjørn
This patch fixes an issue where we were still setting 11h_active
flag to true for channel defs where DFS is not required.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index d47799a..fb93e13 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1820,7 +1820,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
"Failed to disable 11h extensions!!");
return -1;
}
- priv->state_11h.is_11h_active = true;
+ priv->state_11h.is_11h_active = false;
}
if (mwifiex_config_start_uap(priv, bss_cfg)) {
--
1.8.1.4
This was missing and would cause issue in WMM handling.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
---
drivers/net/wireless/mwifiex/uap_event.c | 63 ++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 06ce3fe..fee05f5 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -21,8 +21,70 @@
#include "main.h"
#include "11n.h"
+#define MWIFIEX_BSS_START_EVT_FIX_SIZE 12
+static int mwifiex_check_uap_capabilties(struct mwifiex_private *priv,
+ struct sk_buff *event)
+{
+ int evt_len;
+ u8 *curr;
+ u16 tlv_len;
+ struct mwifiex_ie_types_data *tlv_hdr;
+ struct ieee_types_wmm_parameter *wmm_param_ie = NULL;
+ int mask = IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK;
+
+ priv->wmm_enabled = false;
+ skb_pull(event, MWIFIEX_BSS_START_EVT_FIX_SIZE);
+ evt_len = event->len;
+ curr = event->data;
+
+ mwifiex_dbg_dump(priv->adapter, EVT_D, "uap capabilties:",
+ event->data, event->len);
+
+ while ((evt_len >= sizeof(tlv_hdr->header))) {
+ tlv_hdr = (struct mwifiex_ie_types_data *)curr;
+ tlv_len = le16_to_cpu(tlv_hdr->header.len);
+
+ if (evt_len < tlv_len + sizeof(tlv_hdr->header))
+ break;
+
+ switch (le16_to_cpu(tlv_hdr->header.type)) {
+ case WLAN_EID_HT_CAPABILITY:
+ priv->ap_11n_enabled = true;
+ break;
+
+ case WLAN_EID_VHT_CAPABILITY:
+ priv->ap_11ac_enabled = true;
+ break;
+ case WLAN_EID_VENDOR_SPECIFIC:
+ /* Point the regular IEEE IE 2 bytes into the Marvell IE
+ * and setup the IEEE IE type and length byte fields
+ */
+ wmm_param_ie = (void *)(curr + 2);
+ wmm_param_ie->vend_hdr.len = (u8)tlv_len;
+ wmm_param_ie->vend_hdr.element_id =
+ WLAN_EID_VENDOR_SPECIFIC;
+ mwifiex_dbg(priv->adapter, EVENT,
+ "info: check uap capabilities:\t"
+ "wmm parameter set count: %d\n",
+ wmm_param_ie->qos_info_bitmap & mask);
+
+ mwifiex_wmm_setup_ac_downgrade(priv);
+ priv->wmm_enabled = true;
+ mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
+ break;
+
+ default:
+ break;
+ }
+
+ curr += (tlv_len + sizeof(tlv_hdr->header));
+ evt_len -= (tlv_len + sizeof(tlv_hdr->header));
+ }
+
+ return 0;
+}
/*
* This function handles AP interface specific events generated by firmware.
@@ -134,6 +196,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
ETH_ALEN);
if (priv->hist_data)
mwifiex_hist_data_reset(priv);
+ mwifiex_check_uap_capabilties(priv, adapter->event_skb);
break;
case EVENT_UAP_MIC_COUNTERMEASURES:
/* For future development */
--
1.8.1.4