Commit b23bce29 authored by Avinash Patil's avatar Avinash Patil Committed by John W. Linville

mwifiex: add tdls_mgmt handler support

This patch adds support for TDLS management frames transmit
handler. mwifiex driver supports TDLS with external support,
i.e. expects user space application to form TDLS frames.
Same is advertised to cfg80211 during registration.
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 341b8800
...@@ -41,6 +41,7 @@ mwifiex-y += uap_txrx.o ...@@ -41,6 +41,7 @@ mwifiex-y += uap_txrx.o
mwifiex-y += cfg80211.o mwifiex-y += cfg80211.o
mwifiex-y += ethtool.o mwifiex-y += ethtool.o
mwifiex-y += 11h.o mwifiex-y += 11h.o
mwifiex-y += tdls.o
mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
obj-$(CONFIG_MWIFIEX) += mwifiex.o obj-$(CONFIG_MWIFIEX) += mwifiex.o
......
...@@ -2594,6 +2594,81 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy, ...@@ -2594,6 +2594,81 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
HostCmd_ACT_GEN_SET, 0, &coalesce_cfg); HostCmd_ACT_GEN_SET, 0, &coalesce_cfg);
} }
/* cfg80211 ops handler for tdls_mgmt.
* Function prepares TDLS action frame packets and forwards them to FW
*/
static int
mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
u8 *peer, u8 action_code, u8 dialog_token,
u16 status_code, const u8 *extra_ies,
size_t extra_ies_len)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
int ret;
if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
return -ENOTSUPP;
/* make sure we are in station mode and connected */
if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
return -ENOTSUPP;
switch (action_code) {
case WLAN_TDLS_SETUP_REQUEST:
dev_dbg(priv->adapter->dev,
"Send TDLS Setup Request to %pM status_code=%d\n", peer,
status_code);
ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
dialog_token, status_code,
extra_ies, extra_ies_len);
break;
case WLAN_TDLS_SETUP_RESPONSE:
dev_dbg(priv->adapter->dev,
"Send TDLS Setup Response to %pM status_code=%d\n",
peer, status_code);
ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
dialog_token, status_code,
extra_ies, extra_ies_len);
break;
case WLAN_TDLS_SETUP_CONFIRM:
dev_dbg(priv->adapter->dev,
"Send TDLS Confirm to %pM status_code=%d\n", peer,
status_code);
ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
dialog_token, status_code,
extra_ies, extra_ies_len);
break;
case WLAN_TDLS_TEARDOWN:
dev_dbg(priv->adapter->dev, "Send TDLS Tear down to %pM\n",
peer);
ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
dialog_token, status_code,
extra_ies, extra_ies_len);
break;
case WLAN_TDLS_DISCOVERY_REQUEST:
dev_dbg(priv->adapter->dev,
"Send TDLS Discovery Request to %pM\n", peer);
ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
dialog_token, status_code,
extra_ies, extra_ies_len);
break;
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
dev_dbg(priv->adapter->dev,
"Send TDLS Discovery Response to %pM\n", peer);
ret = mwifiex_send_tdls_action_frame(priv, peer, action_code,
dialog_token, status_code,
extra_ies, extra_ies_len);
break;
default:
dev_warn(priv->adapter->dev,
"Unknown TDLS mgmt/action frame %pM\n", peer);
ret = -EINVAL;
break;
}
return ret;
}
/* station cfg80211 operations */ /* station cfg80211 operations */
static struct cfg80211_ops mwifiex_cfg80211_ops = { static struct cfg80211_ops mwifiex_cfg80211_ops = {
.add_virtual_intf = mwifiex_add_virtual_intf, .add_virtual_intf = mwifiex_add_virtual_intf,
...@@ -2629,6 +2704,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { ...@@ -2629,6 +2704,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.set_wakeup = mwifiex_cfg80211_set_wakeup, .set_wakeup = mwifiex_cfg80211_set_wakeup,
#endif #endif
.set_coalesce = mwifiex_cfg80211_set_coalesce, .set_coalesce = mwifiex_cfg80211_set_coalesce,
.tdls_mgmt = mwifiex_cfg80211_tdls_mgmt,
}; };
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -2714,6 +2790,11 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) ...@@ -2714,6 +2790,11 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_AP_UAPSD |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
wiphy->regulatory_flags |= wiphy->regulatory_flags |=
REGULATORY_CUSTOM_REG | REGULATORY_CUSTOM_REG |
REGULATORY_STRICT_REG; REGULATORY_STRICT_REG;
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) #define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)
#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 #define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 #define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
......
...@@ -181,6 +181,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { ...@@ -181,6 +181,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192 #define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192
#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14))
#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ #define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \ (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
...@@ -497,6 +498,7 @@ struct mwifiex_ie_types_data { ...@@ -497,6 +498,7 @@ struct mwifiex_ie_types_data {
#define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01 #define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01
#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08 #define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08
#define MWIFIEX_TXPD_FLAGS_TDLS_PACKET 0x10
struct txpd { struct txpd {
u8 bss_type; u8 bss_type;
......
...@@ -85,6 +85,10 @@ struct wep_key { ...@@ -85,6 +85,10 @@ struct wep_key {
#define BAND_CONFIG_A 0x01 #define BAND_CONFIG_A 0x01
#define MWIFIEX_SUPPORTED_RATES 14 #define MWIFIEX_SUPPORTED_RATES 14
#define MWIFIEX_SUPPORTED_RATES_EXT 32 #define MWIFIEX_SUPPORTED_RATES_EXT 32
#define MWIFIEX_TDLS_SUPPORTED_RATES 8
#define MWIFIEX_TDLS_DEF_QOS_CAPAB 0xf
#define MWIFIEX_PRIO_BK 2
#define MWIFIEX_PRIO_VI 5
struct mwifiex_uap_bss_param { struct mwifiex_uap_bss_param {
u8 channel; u8 channel;
......
...@@ -262,6 +262,16 @@ struct ieee_types_generic { ...@@ -262,6 +262,16 @@ struct ieee_types_generic {
u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)]; u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)];
} __packed; } __packed;
struct ieee_types_bss_co_2040 {
struct ieee_types_header ieee_hdr;
u8 bss_2040co;
} __packed;
struct ieee_types_extcap {
struct ieee_types_header ieee_hdr;
u8 ext_capab[8];
} __packed;
struct mwifiex_bssdescriptor { struct mwifiex_bssdescriptor {
u8 mac_address[ETH_ALEN]; u8 mac_address[ETH_ALEN];
struct cfg80211_ssid ssid; struct cfg80211_ssid ssid;
...@@ -1176,6 +1186,14 @@ struct mwifiex_sta_node * ...@@ -1176,6 +1186,14 @@ struct mwifiex_sta_node *
mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac); mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac);
struct mwifiex_sta_node * struct mwifiex_sta_node *
mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac); mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac);
int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, u8 *peer,
u8 action_code, u8 dialog_token,
u16 status_code, const u8 *extra_ies,
size_t extra_ies_len);
int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv,
u8 *peer, u8 action_code, u8 dialog_token,
u16 status_code, const u8 *extra_ies,
size_t extra_ies_len);
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void); void mwifiex_debugfs_init(void);
......
...@@ -95,6 +95,9 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, ...@@ -95,6 +95,9 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
} }
} }
if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
/* Offset of actual data */ /* Offset of actual data */
pkt_offset = sizeof(struct txpd) + pad; pkt_offset = sizeof(struct txpd) + pad;
if (pkt_type == PKT_TYPE_MGMT) { if (pkt_type == PKT_TYPE_MGMT) {
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment