]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
mwifiex: add del_station handler
authorAvinash Patil <patila@marvell.com>
Sat, 18 May 2013 00:50:23 +0000 (17:50 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 22 May 2013 19:08:54 +0000 (15:08 -0400)
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>
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/fw.h
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sta_cmdresp.c
drivers/net/wireless/mwifiex/uap_cmd.c
drivers/net/wireless/mwifiex/uap_event.c

index fcd293c64118c879749ac6a516331a630beffaa1..af79daa331d052b8911960466b8a60c0fba5029a 100644 (file)
@@ -1231,6 +1231,51 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
        return 0;
 }
 
+/* cfg80211 operation handler for del_station.
+ * Function deauthenticates station which value is provided in mac parameter.
+ * If mac is NULL/broadcast, all stations in associated station list are
+ * deauthenticated. If bss is not started or there are no stations in
+ * associated stations list, no action is taken.
+ */
+static int
+mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
+                            u8 *mac)
+{
+       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+       struct mwifiex_sta_node *sta_node;
+       unsigned long flags;
+
+       if (list_empty(&priv->sta_list) || !priv->bss_started)
+               return 0;
+
+       if (!mac || is_broadcast_ether_addr(mac)) {
+               wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
+               list_for_each_entry(sta_node, &priv->sta_list, list) {
+                       if (mwifiex_send_cmd_sync(priv,
+                                                 HostCmd_CMD_UAP_STA_DEAUTH,
+                                                 HostCmd_ACT_GEN_SET, 0,
+                                                 sta_node->mac_addr))
+                               return -1;
+                       mwifiex_uap_del_sta_data(priv, sta_node);
+               }
+       } else {
+               wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac);
+               spin_lock_irqsave(&priv->sta_list_spinlock, flags);
+               sta_node = mwifiex_get_sta_entry(priv, mac);
+               spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
+               if (sta_node) {
+                       if (mwifiex_send_cmd_sync(priv,
+                                                 HostCmd_CMD_UAP_STA_DEAUTH,
+                                                 HostCmd_ACT_GEN_SET, 0,
+                                                 sta_node->mac_addr))
+                               return -1;
+                       mwifiex_uap_del_sta_data(priv, sta_node);
+               }
+       }
+
+       return 0;
+}
+
 static int
 mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
 {
@@ -2425,6 +2470,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
        .change_beacon = mwifiex_cfg80211_change_beacon,
        .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
        .set_antenna = mwifiex_cfg80211_set_antenna,
+       .del_station = mwifiex_cfg80211_del_station,
 #ifdef CONFIG_PM
        .suspend = mwifiex_cfg80211_suspend,
        .resume = mwifiex_cfg80211_resume,
index 74db0d24a5790a9ee29b37408092a3cda859c97a..4a32f2795c64601520fff8124c99468f3156592b 100644 (file)
@@ -570,6 +570,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
                case HostCmd_CMD_UAP_SYS_CONFIG:
                case HostCmd_CMD_UAP_BSS_START:
                case HostCmd_CMD_UAP_BSS_STOP:
+               case HostCmd_CMD_UAP_STA_DEAUTH:
                        ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
                                                      cmd_oid, data_buf,
                                                      cmd_ptr);
index 1f7578d553ec982e94b8c329310d08459cf18225..d3c1e01b4fc2bffa5836a6f245c59aa3e2c10f11 100644 (file)
@@ -279,6 +279,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_DEAUTH                    0x00b5
 #define HostCmd_CMD_11N_CFG                           0x00cd
 #define HostCmd_CMD_11N_ADDBA_REQ                     0x00ce
 #define HostCmd_CMD_11N_ADDBA_RSP                     0x00cf
@@ -1197,6 +1198,11 @@ struct host_cmd_ds_amsdu_aggr_ctrl {
        __le16 curr_buf_size;
 } __packed;
 
+struct host_cmd_ds_sta_deauth {
+       u8 mac[ETH_ALEN];
+       __le16 reason;
+} __packed;
+
 struct mwifiex_ie_types_wmm_param_set {
        struct mwifiex_ie_types_header header;
        u8 wmm_ie[1];
@@ -1630,6 +1636,7 @@ struct host_cmd_ds_command {
                struct host_cmd_ds_802_11_eeprom_access eeprom;
                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_11ac_vht_cfg vht_cfg;
        } params;
 } __packed;
index 81251d91491c3b7e8e255d7abaa06323484ca68e..9cf6852f6da3516ee3e88242bdd9b789d2a5b128 100644 (file)
@@ -1115,6 +1115,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_del_sta_data(struct mwifiex_private *priv,
+                             struct mwifiex_sta_node *node);
 
 extern const struct ethtool_ops mwifiex_ethtool_ops;
 
index 9f990e14966e8354a91b6e90bd69c413c3f562e7..c710a1bb05ce480c050a8be654e8ef2cbf50e12b 100644 (file)
@@ -978,6 +978,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
        case HostCmd_CMD_UAP_BSS_STOP:
                priv->bss_started = 0;
                break;
+       case HostCmd_CMD_UAP_STA_DEAUTH:
+               break;
        case HostCmd_CMD_MEF_CFG:
                break;
        default:
index b04b1db291002b8174cb0cf013a69c97e0bf4e40..2de882dead0f879dee34831e0c61adc470d9dd70 100644 (file)
@@ -689,6 +689,23 @@ mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
        return 0;
 }
 
+/* This function prepares AP specific deauth command with mac supplied in
+ * function parameter.
+ */
+static int mwifiex_cmd_uap_sta_deauth(struct mwifiex_private *priv,
+                                     struct host_cmd_ds_command *cmd, u8 *mac)
+{
+       struct host_cmd_ds_sta_deauth *sta_deauth = &cmd->params.sta_deauth;
+
+       cmd->command = cpu_to_le16(HostCmd_CMD_UAP_STA_DEAUTH);
+       memcpy(sta_deauth->mac, mac, ETH_ALEN);
+       sta_deauth->reason = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
+
+       cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_sta_deauth) +
+                               S_DS_GEN);
+       return 0;
+}
+
 /* This function prepares the AP specific commands before sending them
  * to the firmware.
  * 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,
                cmd->command = cpu_to_le16(cmd_no);
                cmd->size = cpu_to_le16(S_DS_GEN);
                break;
+       case HostCmd_CMD_UAP_STA_DEAUTH:
+               if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf))
+                       return -1;
+               break;
        default:
                dev_err(priv->adapter->dev,
                        "PREP_CMD: unknown cmd %#x\n", cmd_no);
index 77fb533ae10a12498b39ac11fb73cff6faf86f15..718066577c6c531f22c9f4387639237875f04862 100644 (file)
@@ -292,3 +292,19 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
 
        return 0;
 }
+
+/* This function deletes station entry from associated station list.
+ * Also if both AP and STA are 11n enabled, RxReorder tables and TxBA stream
+ * tables created for this station are deleted.
+ */
+void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
+                             struct mwifiex_sta_node *node)
+{
+       if (priv->ap_11n_enabled && node->is_11n_enabled) {
+               mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr);
+               mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr);
+       }
+       mwifiex_del_sta_entry(priv, node->mac_addr);
+
+       return;
+}