Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f6d5983 authored by Avinash Patil's avatar Avinash Patil Committed by John W. Linville
Browse files

mwifiex: add VHT support for TDLS



During TDLS setup request/response, if HW is 11ac capable,
we add VHT Capability IEs in outgoing data frame. Also while
processing received setup request/response, we preserve peer's
11ac capability retrieved from IEs.

Patch also gets VHT parameters from config_station handlers and
sets it to FW using TDLS config command.

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 9ed230bc
Loading
Loading
Loading
Loading
+80 −3
Original line number Diff line number Diff line
@@ -108,8 +108,7 @@ mwifiex_fill_vht_cap_info(struct mwifiex_private *priv,
				cpu_to_le32(adapter->usr_dot_11ac_dev_cap_bg);
}

static void
mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
void mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
			      struct ieee80211_vht_cap *vht_cap, u8 bands)
{
	struct mwifiex_adapter *adapter = priv->adapter;
@@ -305,3 +304,81 @@ void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv)

	return;
}

bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv)
{
	struct mwifiex_bssdescriptor *bss_desc;
	struct ieee80211_vht_operation *vht_oper;

	bss_desc = &priv->curr_bss_params.bss_descriptor;
	vht_oper = bss_desc->bcn_vht_oper;

	if (!bss_desc->bcn_vht_cap || !vht_oper)
		return false;

	if (vht_oper->chan_width == IEEE80211_VHT_CHANWIDTH_USE_HT)
		return false;

	return true;
}

u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
				 u32 pri_chan, u8 chan_bw)
{
	u8 center_freq_idx = 0;

	if (band & BAND_AAC) {
		switch (pri_chan) {
		case 36:
		case 40:
		case 44:
		case 48:
			if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
				center_freq_idx = 42;
			break;
		case 52:
		case 56:
		case 60:
		case 64:
			if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
				center_freq_idx = 58;
			else if (chan_bw == IEEE80211_VHT_CHANWIDTH_160MHZ)
				center_freq_idx = 50;
			break;
		case 100:
		case 104:
		case 108:
		case 112:
			if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
				center_freq_idx = 106;
			break;
		case 116:
		case 120:
		case 124:
		case 128:
			if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
				center_freq_idx = 122;
			else if (chan_bw == IEEE80211_VHT_CHANWIDTH_160MHZ)
				center_freq_idx = 114;
			break;
		case 132:
		case 136:
		case 140:
		case 144:
			if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
				center_freq_idx = 138;
			break;
		case 149:
		case 153:
		case 157:
		case 161:
			if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
				center_freq_idx = 155;
			break;
		default:
			center_freq_idx = 42;
		}
	}

	return center_freq_idx;
}
+2 −0
Original line number Diff line number Diff line
@@ -40,4 +40,6 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv,
			 struct host_cmd_ds_command *cmd, u16 cmd_action,
			 struct mwifiex_11ac_vht_cfg *cfg);
void mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
			      struct ieee80211_vht_cap *vht_cap, u8 bands);
#endif /* _MWIFIEX_11AC_H_ */
+5 −0
Original line number Diff line number Diff line
@@ -1356,6 +1356,11 @@ struct mwifiex_ie_types_vhtcap {
	struct ieee80211_vht_cap vht_cap;
} __packed;

struct mwifiex_ie_types_aid {
	struct mwifiex_ie_types_header header;
	__le16 aid;
} __packed;

struct mwifiex_ie_types_oper_mode_ntf {
	struct mwifiex_ie_types_header header;
	u8 oper_mode;
+22 −0
Original line number Diff line number Diff line
@@ -273,6 +273,21 @@ struct ieee_types_extcap {
	u8 ext_capab[8];
} __packed;

struct ieee_types_vht_cap {
	struct ieee_types_header ieee_hdr;
	struct ieee80211_vht_cap vhtcap;
} __packed;

struct ieee_types_vht_oper {
	struct ieee_types_header ieee_hdr;
	struct ieee80211_vht_operation vhtoper;
} __packed;

struct ieee_types_aid {
	struct ieee_types_header ieee_hdr;
	u16 aid;
} __packed;

struct mwifiex_bssdescriptor {
	u8 mac_address[ETH_ALEN];
	struct cfg80211_ssid ssid;
@@ -603,10 +618,13 @@ struct mwifiex_tdls_capab {
	u8 rates_len;
	u8 qos_info;
	u8 coex_2040;
	u16 aid;
	struct ieee80211_ht_cap ht_capb;
	struct ieee80211_ht_operation ht_oper;
	struct ieee_types_extcap extcap;
	struct ieee_types_generic rsn_ie;
	struct ieee80211_vht_cap vhtcap;
	struct ieee80211_vht_operation vhtoper;
};

/* This is AP/TDLS specific structure which stores information
@@ -617,6 +635,7 @@ struct mwifiex_sta_node {
	u8 mac_addr[ETH_ALEN];
	u8 is_wmm_enabled;
	u8 is_11n_enabled;
	u8 is_11ac_enabled;
	u8 ampdu_sta[MAX_NUM_TID];
	u16 rx_seq[MAX_NUM_TID];
	u16 max_amsdu;
@@ -1215,6 +1234,9 @@ 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);
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);

#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);
+20 −0
Original line number Diff line number Diff line
@@ -1292,6 +1292,8 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
	struct mwifiex_ie_types_htcap *ht_capab;
	struct mwifiex_ie_types_qos_info *wmm_qos_info;
	struct mwifiex_ie_types_extcap *extcap;
	struct mwifiex_ie_types_vhtcap *vht_capab;
	struct mwifiex_ie_types_aid *aid;
	u8 *pos, qos_info;
	u16 config_len = 0;
	struct station_parameters *params = priv->sta_params;
@@ -1370,6 +1372,24 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
			config_len += sizeof(struct mwifiex_ie_types_extcap) +
				      params->ext_capab_len;
		}
		if (params->vht_capa) {
			vht_capab = (struct mwifiex_ie_types_vhtcap *)(pos +
								    config_len);
			vht_capab->header.type =
					   cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
			vht_capab->header.len =
				  cpu_to_le16(sizeof(struct ieee80211_vht_cap));
			memcpy(&vht_capab->vht_cap, params->vht_capa,
			       sizeof(struct ieee80211_vht_cap));
			config_len += sizeof(struct mwifiex_ie_types_vhtcap);
		}
		if (params->aid) {
			aid = (struct mwifiex_ie_types_aid *)(pos + config_len);
			aid->header.type = cpu_to_le16(WLAN_EID_AID);
			aid->header.len = cpu_to_le16(sizeof(params->aid));
			aid->aid = cpu_to_le16(params->aid);
			config_len += sizeof(struct mwifiex_ie_types_aid);
		}

		break;
	default:
Loading