diff options
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_event.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/tdls.c | 35 |
3 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 91df7ee4c612..82754ed94a8a 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1234,6 +1234,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, u8 *buf, int len); int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action); int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac); +void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv); bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, u32 pri_chan, u8 chan_bw); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index de4a6affe72e..92ff7b324b00 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -54,6 +54,10 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) priv->scan_block = false; + if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && + ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) + mwifiex_disable_all_tdls_links(priv); + /* Free Tx and Rx packets, report disconnect to upper layer */ mwifiex_clean_txrx(priv); diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index 770dcd727b5c..5efd456af571 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c @@ -1007,3 +1007,38 @@ int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac) return TDLS_NOT_SETUP; } + +void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv) +{ + struct mwifiex_sta_node *sta_ptr; + struct mwifiex_ds_tdls_oper tdls_oper; + unsigned long flags; + + if (list_empty(&priv->sta_list)) + return; + + list_for_each_entry(sta_ptr, &priv->sta_list, list) { + memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper)); + + if (sta_ptr->is_11n_enabled) { + mwifiex_11n_cleanup_reorder_tbl(priv); + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, + flags); + mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + flags); + } + + mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr, + TDLS_LINK_TEARDOWN); + memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN); + tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; + if (mwifiex_send_cmd_async(priv, HostCmd_CMD_TDLS_OPER, + HostCmd_ACT_GEN_SET, 0, &tdls_oper)) + dev_warn(priv->adapter->dev, + "Disable link failed for TDLS peer %pM", + sta_ptr->mac_addr); + } + + mwifiex_del_all_sta_list(priv); +} |