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

mwifiex: add HT operation IE in TDLS setup confirm

This patch adds support to populate HT operatation IE in TDLS
setup confirm command. This is required for setting wider
bandwidths for TDLS operations.
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 79ff4346
...@@ -749,3 +749,45 @@ void mwifiex_set_ba_params(struct mwifiex_private *priv) ...@@ -749,3 +749,45 @@ void mwifiex_set_ba_params(struct mwifiex_private *priv)
return; return;
} }
u8 mwifiex_get_sec_chan_offset(int chan)
{
u8 sec_offset;
switch (chan) {
case 36:
case 44:
case 52:
case 60:
case 100:
case 108:
case 116:
case 124:
case 132:
case 140:
case 149:
case 157:
sec_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
break;
case 40:
case 48:
case 56:
case 64:
case 104:
case 112:
case 120:
case 128:
case 136:
case 144:
case 153:
case 161:
sec_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
break;
case 165:
default:
sec_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
break;
}
return sec_offset;
}
...@@ -63,6 +63,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, ...@@ -63,6 +63,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
int cmd_action, int cmd_action,
struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl);
void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra); void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra);
u8 mwifiex_get_sec_chan_offset(int chan);
static inline u8 static inline u8
mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv, mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv,
......
...@@ -230,6 +230,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { ...@@ -230,6 +230,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8)) #define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8))
#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) #define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22))
#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30)) #define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30))
#define ISALLOWED_CHANWIDTH40(ht_param) (ht_param & BIT(2))
/* httxcfg bitmap /* httxcfg bitmap
* 0 reserved * 0 reserved
......
...@@ -185,6 +185,48 @@ static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv, ...@@ -185,6 +185,48 @@ static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv,
return 0; return 0;
} }
static int
mwifiex_tdls_add_ht_oper(struct mwifiex_private *priv, u8 *mac,
u8 vht_enabled, struct sk_buff *skb)
{
struct ieee80211_ht_operation *ht_oper;
struct mwifiex_sta_node *sta_ptr;
struct mwifiex_bssdescriptor *bss_desc =
&priv->curr_bss_params.bss_descriptor;
u8 *pos;
sta_ptr = mwifiex_get_sta_entry(priv, mac);
if (unlikely(!sta_ptr)) {
dev_warn(priv->adapter->dev,
"TDLS peer station not found in list\n");
return -1;
}
pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2);
*pos++ = WLAN_EID_HT_OPERATION;
*pos++ = sizeof(struct ieee80211_ht_operation);
ht_oper = (void *)pos;
ht_oper->primary_chan = bss_desc->channel;
/* follow AP's channel bandwidth */
if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) &&
bss_desc->bcn_ht_cap &&
ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param))
ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param;
if (vht_enabled) {
ht_oper->ht_param =
mwifiex_get_sec_chan_offset(bss_desc->channel);
ht_oper->ht_param |= BIT(2);
}
memcpy(&sta_ptr->tdls_cap.ht_oper, ht_oper,
sizeof(struct ieee80211_ht_operation));
return 0;
}
static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv, static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
u8 *mac, struct sk_buff *skb) u8 *mac, struct sk_buff *skb)
{ {
...@@ -428,6 +470,17 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, ...@@ -428,6 +470,17 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return ret; return ret;
} }
ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb);
if (ret) {
dev_kfree_skb_any(skb);
return ret;
}
} else {
ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb);
if (ret) {
dev_kfree_skb_any(skb);
return ret;
}
} }
break; break;
......
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