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

Commit 28bf8312 authored by Ganapathi Bhat's avatar Ganapathi Bhat Committed by Kalle Valo
Browse files

mwifiex: get_channel from firmware



At present driver gets chan_type by referring to
IEEE80211_HT_PARAM_CHA_SEC_OFFSET, in ASSOC response. Sometimes
AP shows IEEE80211_HT_PARAM_CHA_SEC_OFFSET as above/below in
assoc response, even if the association is done on HT20 channel
only. So, it will be accurate to get econdary channel offset from
firmware.

Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
Signed-off-by: default avatarGanapathi Bhat <gbhat@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 77423fa7
Loading
Loading
Loading
Loading
+25 −15
Original line number Diff line number Diff line
@@ -95,20 +95,34 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)

/* This function maps IEEE HT secondary channel type to NL80211 channel type
 */
u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset)
u8 mwifiex_get_chan_type(struct mwifiex_private *priv)
{
	switch (second_chan_offset) {
	case IEEE80211_HT_PARAM_CHA_SEC_NONE:
	struct mwifiex_channel_band channel_band;
	int ret;

	ret = mwifiex_get_chan_info(priv, &channel_band);

	if (!ret) {
		switch (channel_band.band_config.chan_width) {
		case CHAN_BW_20MHZ:
			if (IS_11N_ENABLED(priv))
				return NL80211_CHAN_HT20;
	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
			else
				return NL80211_CHAN_NO_HT;
		case CHAN_BW_40MHZ:
			if (channel_band.band_config.chan2_offset ==
			    SEC_CHAN_ABOVE)
				return NL80211_CHAN_HT40PLUS;
	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
			else
				return NL80211_CHAN_HT40MINUS;
		default:
			return NL80211_CHAN_HT20;
		}
	}

	return NL80211_CHAN_HT20;
}

/*
 * This function checks whether WEP is set.
 */
@@ -3937,7 +3951,6 @@ static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
	struct mwifiex_bssdescriptor *curr_bss;
	struct ieee80211_channel *chan;
	u8 second_chan_offset;
	enum nl80211_channel_type chan_type;
	enum nl80211_band band;
	int freq;
@@ -3954,10 +3967,7 @@ static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
		chan = ieee80211_get_channel(wiphy, freq);

		if (priv->ht_param_present) {
			second_chan_offset = priv->assoc_resp_ht_param &
					IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
			chan_type = mwifiex_sec_chan_offset_to_chan_type
							(second_chan_offset);
			chan_type = mwifiex_get_chan_type(priv);
			cfg80211_chandef_create(chandef, chan, chan_type);
		} else {
			cfg80211_chandef_create(chandef, chan,
+17 −0
Original line number Diff line number Diff line
@@ -294,4 +294,21 @@ enum rdwr_status {
	RDWR_STATUS_DONE = 2
};

enum mwifiex_chan_width {
	CHAN_BW_20MHZ = 0,
	CHAN_BW_10MHZ,
	CHAN_BW_40MHZ,
	CHAN_BW_80MHZ,
	CHAN_BW_8080MHZ,
	CHAN_BW_160MHZ,
	CHAN_BW_5MHZ,
};

enum mwifiex_chan_offset {
	SEC_CHAN_NONE = 0,
	SEC_CHAN_ABOVE = 1,
	SEC_CHAN_5MHZ = 2,
	SEC_CHAN_BELOW = 3
};

#endif /* !_MWIFIEX_DECL_H_ */
+7 −0
Original line number Diff line number Diff line
@@ -411,6 +411,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define HostCmd_CMD_TDLS_OPER                         0x0122
#define HostCmd_CMD_FW_DUMP_EVENT		      0x0125
#define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG               0x0223
#define HostCmd_CMD_STA_CONFIGURE		      0x023f
#define HostCmd_CMD_CHAN_REGION_CFG		      0x0242
#define HostCmd_CMD_PACKET_AGGR_CTRL		      0x0251

@@ -2285,6 +2286,11 @@ struct host_cmd_ds_pkt_aggr_ctrl {
	__le16 tx_aggr_align;
} __packed;

struct host_cmd_ds_sta_configure {
	__le16 action;
	u8 tlv_buffer[0];
} __packed;

struct host_cmd_ds_command {
	__le16 command;
	__le16 size;
@@ -2361,6 +2367,7 @@ struct host_cmd_ds_command {
		struct host_cmd_ds_gtk_rekey_params rekey;
		struct host_cmd_ds_chan_region_cfg reg_cfg;
		struct host_cmd_ds_pkt_aggr_ctrl pkt_aggr_ctrl;
		struct host_cmd_ds_sta_configure sta_cfg;
	} params;
} __packed;

+15 −1
Original line number Diff line number Diff line
@@ -517,6 +517,18 @@ enum mwifiex_iface_work_flags {
	MWIFIEX_IFACE_WORK_CARD_RESET,
};

struct mwifiex_band_config {
	u8 chan_band:2;
	u8 chan_width:2;
	u8 chan2_offset:2;
	u8 scan_mode:2;
} __packed;

struct mwifiex_channel_band {
	struct mwifiex_band_config band_config;
	u8 channel;
};

struct mwifiex_private {
	struct mwifiex_adapter *adapter;
	u8 bss_type;
@@ -1557,7 +1569,7 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
					struct mwifiex_bssdescriptor *bss_desc);

u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type);
u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset);
u8 mwifiex_get_chan_type(struct mwifiex_private *priv);

struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
					      const char *name,
@@ -1683,6 +1695,8 @@ void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
int mwifiex_get_wakeup_reason(struct mwifiex_private *priv, u16 action,
			      int cmd_type,
			      struct mwifiex_ds_wakeup_reason *wakeup_reason);
int mwifiex_get_chan_info(struct mwifiex_private *priv,
			  struct mwifiex_channel_band *channel_band);
int mwifiex_ret_wakeup_reason(struct mwifiex_private *priv,
			      struct host_cmd_ds_command *resp,
			      struct host_cmd_ds_wakeup_reason *wakeup_reason);
+22 −0
Original line number Diff line number Diff line
@@ -1898,6 +1898,25 @@ static int mwifiex_cmd_get_wakeup_reason(struct mwifiex_private *priv,
	return 0;
}

static int mwifiex_cmd_get_chan_info(struct host_cmd_ds_command *cmd,
				     u16 cmd_action)
{
	struct host_cmd_ds_sta_configure *sta_cfg_cmd = &cmd->params.sta_cfg;
	struct host_cmd_tlv_channel_band *tlv_band_channel =
	(struct host_cmd_tlv_channel_band *)sta_cfg_cmd->tlv_buffer;

	cmd->command = cpu_to_le16(HostCmd_CMD_STA_CONFIGURE);
	cmd->size = cpu_to_le16(sizeof(*sta_cfg_cmd) +
				sizeof(*tlv_band_channel) + S_DS_GEN);
	sta_cfg_cmd->action = cpu_to_le16(cmd_action);
	memset(tlv_band_channel, 0, sizeof(*tlv_band_channel));
	tlv_band_channel->header.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
	tlv_band_channel->header.len  = cpu_to_le16(sizeof(*tlv_band_channel) -
					sizeof(struct mwifiex_ie_types_header));

	return 0;
}

/* This function check if the command is supported by firmware */
static int mwifiex_is_cmd_supported(struct mwifiex_private *priv, u16 cmd_no)
{
@@ -2210,6 +2229,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
		cmd_ptr->command = cpu_to_le16(cmd_no);
		cmd_ptr->size = cpu_to_le16(S_DS_GEN);
		break;
	case HostCmd_CMD_STA_CONFIGURE:
		ret = mwifiex_cmd_get_chan_info(cmd_ptr, cmd_action);
		break;
	default:
		mwifiex_dbg(priv->adapter, ERROR,
			    "PREP_CMD: unknown cmd- %#x\n", cmd_no);
Loading