aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2013-05-17 20:50:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-05-22 15:08:54 -0400
commit0f9e9b8ba72bc75ee6189d0e86639f7e7a494a30 (patch)
treec01e5f8021491c49dee446131b0c9b766905165f
parentbdd4d6bf59c046e5a3d1ac67ba7b1c9ea540b6e3 (diff)
mwifiex: add del_station handler
This patch adds cfg80211 del_station handler for mwifiex. If bss is not started or there are no stations in associated stations list, no action is taken. If argument received is null/broadcast mac, all stations in associated station list are deauthenticated. Patch also deletes related RxReorder stream and TxBA stream tables for related station. 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/cfg80211.c46
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1
-rw-r--r--drivers/net/wireless/mwifiex/fw.h7
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c21
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c16
7 files changed, 95 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index fcd293c64118..af79daa331d0 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1231,6 +1231,51 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
1231 return 0; 1231 return 0;
1232} 1232}
1233 1233
1234/* cfg80211 operation handler for del_station.
1235 * Function deauthenticates station which value is provided in mac parameter.
1236 * If mac is NULL/broadcast, all stations in associated station list are
1237 * deauthenticated. If bss is not started or there are no stations in
1238 * associated stations list, no action is taken.
1239 */
1240static int
1241mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1242 u8 *mac)
1243{
1244 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1245 struct mwifiex_sta_node *sta_node;
1246 unsigned long flags;
1247
1248 if (list_empty(&priv->sta_list) || !priv->bss_started)
1249 return 0;
1250
1251 if (!mac || is_broadcast_ether_addr(mac)) {
1252 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
1253 list_for_each_entry(sta_node, &priv->sta_list, list) {
1254 if (mwifiex_send_cmd_sync(priv,
1255 HostCmd_CMD_UAP_STA_DEAUTH,
1256 HostCmd_ACT_GEN_SET, 0,
1257 sta_node->mac_addr))
1258 return -1;
1259 mwifiex_uap_del_sta_data(priv, sta_node);
1260 }
1261 } else {
1262 wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac);
1263 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
1264 sta_node = mwifiex_get_sta_entry(priv, mac);
1265 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1266 if (sta_node) {
1267 if (mwifiex_send_cmd_sync(priv,
1268 HostCmd_CMD_UAP_STA_DEAUTH,
1269 HostCmd_ACT_GEN_SET, 0,
1270 sta_node->mac_addr))
1271 return -1;
1272 mwifiex_uap_del_sta_data(priv, sta_node);
1273 }
1274 }
1275
1276 return 0;
1277}
1278
1234static int 1279static int
1235mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) 1280mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
1236{ 1281{
@@ -2425,6 +2470,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2425 .change_beacon = mwifiex_cfg80211_change_beacon, 2470 .change_beacon = mwifiex_cfg80211_change_beacon,
2426 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, 2471 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
2427 .set_antenna = mwifiex_cfg80211_set_antenna, 2472 .set_antenna = mwifiex_cfg80211_set_antenna,
2473 .del_station = mwifiex_cfg80211_del_station,
2428#ifdef CONFIG_PM 2474#ifdef CONFIG_PM
2429 .suspend = mwifiex_cfg80211_suspend, 2475 .suspend = mwifiex_cfg80211_suspend,
2430 .resume = mwifiex_cfg80211_resume, 2476 .resume = mwifiex_cfg80211_resume,
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 74db0d24a579..4a32f2795c64 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -570,6 +570,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
570 case HostCmd_CMD_UAP_SYS_CONFIG: 570 case HostCmd_CMD_UAP_SYS_CONFIG:
571 case HostCmd_CMD_UAP_BSS_START: 571 case HostCmd_CMD_UAP_BSS_START:
572 case HostCmd_CMD_UAP_BSS_STOP: 572 case HostCmd_CMD_UAP_BSS_STOP:
573 case HostCmd_CMD_UAP_STA_DEAUTH:
573 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, 574 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
574 cmd_oid, data_buf, 575 cmd_oid, data_buf,
575 cmd_ptr); 576 cmd_ptr);
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1f7578d553ec..d3c1e01b4fc2 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -279,6 +279,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
279#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0 279#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0
280#define HostCmd_CMD_UAP_BSS_START 0x00b1 280#define HostCmd_CMD_UAP_BSS_START 0x00b1
281#define HostCmd_CMD_UAP_BSS_STOP 0x00b2 281#define HostCmd_CMD_UAP_BSS_STOP 0x00b2
282#define HostCmd_CMD_UAP_STA_DEAUTH 0x00b5
282#define HostCmd_CMD_11N_CFG 0x00cd 283#define HostCmd_CMD_11N_CFG 0x00cd
283#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce 284#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
284#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf 285#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf
@@ -1197,6 +1198,11 @@ struct host_cmd_ds_amsdu_aggr_ctrl {
1197 __le16 curr_buf_size; 1198 __le16 curr_buf_size;
1198} __packed; 1199} __packed;
1199 1200
1201struct host_cmd_ds_sta_deauth {
1202 u8 mac[ETH_ALEN];
1203 __le16 reason;
1204} __packed;
1205
1200struct mwifiex_ie_types_wmm_param_set { 1206struct mwifiex_ie_types_wmm_param_set {
1201 struct mwifiex_ie_types_header header; 1207 struct mwifiex_ie_types_header header;
1202 u8 wmm_ie[1]; 1208 u8 wmm_ie[1];
@@ -1630,6 +1636,7 @@ struct host_cmd_ds_command {
1630 struct host_cmd_ds_802_11_eeprom_access eeprom; 1636 struct host_cmd_ds_802_11_eeprom_access eeprom;
1631 struct host_cmd_ds_802_11_subsc_evt subsc_evt; 1637 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1632 struct host_cmd_ds_sys_config uap_sys_config; 1638 struct host_cmd_ds_sys_config uap_sys_config;
1639 struct host_cmd_ds_sta_deauth sta_deauth;
1633 struct host_cmd_11ac_vht_cfg vht_cfg; 1640 struct host_cmd_11ac_vht_cfg vht_cfg;
1634 } params; 1641 } params;
1635} __packed; 1642} __packed;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 81251d91491c..9cf6852f6da3 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1115,6 +1115,8 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
1115 struct cfg80211_beacon_data *data); 1115 struct cfg80211_beacon_data *data);
1116int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); 1116int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
1117u8 *mwifiex_11d_code_2_region(u8 code); 1117u8 *mwifiex_11d_code_2_region(u8 code);
1118void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
1119 struct mwifiex_sta_node *node);
1118 1120
1119extern const struct ethtool_ops mwifiex_ethtool_ops; 1121extern const struct ethtool_ops mwifiex_ethtool_ops;
1120 1122
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 9f990e14966e..c710a1bb05ce 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -978,6 +978,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
978 case HostCmd_CMD_UAP_BSS_STOP: 978 case HostCmd_CMD_UAP_BSS_STOP:
979 priv->bss_started = 0; 979 priv->bss_started = 0;
980 break; 980 break;
981 case HostCmd_CMD_UAP_STA_DEAUTH:
982 break;
981 case HostCmd_CMD_MEF_CFG: 983 case HostCmd_CMD_MEF_CFG:
982 break; 984 break;
983 default: 985 default:
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index b04b1db29100..2de882dead0f 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -689,6 +689,23 @@ mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
689 return 0; 689 return 0;
690} 690}
691 691
692/* This function prepares AP specific deauth command with mac supplied in
693 * function parameter.
694 */
695static int mwifiex_cmd_uap_sta_deauth(struct mwifiex_private *priv,
696 struct host_cmd_ds_command *cmd, u8 *mac)
697{
698 struct host_cmd_ds_sta_deauth *sta_deauth = &cmd->params.sta_deauth;
699
700 cmd->command = cpu_to_le16(HostCmd_CMD_UAP_STA_DEAUTH);
701 memcpy(sta_deauth->mac, mac, ETH_ALEN);
702 sta_deauth->reason = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
703
704 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_sta_deauth) +
705 S_DS_GEN);
706 return 0;
707}
708
692/* This function prepares the AP specific commands before sending them 709/* This function prepares the AP specific commands before sending them
693 * to the firmware. 710 * to the firmware.
694 * This is a generic function which calls specific command preparation 711 * This is a generic function which calls specific command preparation
@@ -710,6 +727,10 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
710 cmd->command = cpu_to_le16(cmd_no); 727 cmd->command = cpu_to_le16(cmd_no);
711 cmd->size = cpu_to_le16(S_DS_GEN); 728 cmd->size = cpu_to_le16(S_DS_GEN);
712 break; 729 break;
730 case HostCmd_CMD_UAP_STA_DEAUTH:
731 if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf))
732 return -1;
733 break;
713 default: 734 default:
714 dev_err(priv->adapter->dev, 735 dev_err(priv->adapter->dev,
715 "PREP_CMD: unknown cmd %#x\n", cmd_no); 736 "PREP_CMD: unknown cmd %#x\n", cmd_no);
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 77fb533ae10a..718066577c6c 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -292,3 +292,19 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
292 292
293 return 0; 293 return 0;
294} 294}
295
296/* This function deletes station entry from associated station list.
297 * Also if both AP and STA are 11n enabled, RxReorder tables and TxBA stream
298 * tables created for this station are deleted.
299 */
300void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
301 struct mwifiex_sta_node *node)
302{
303 if (priv->ap_11n_enabled && node->is_11n_enabled) {
304 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr);
305 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr);
306 }
307 mwifiex_del_sta_entry(priv, node->mac_addr);
308
309 return;
310}