Skip to content

Commit 28bf831

Browse files
gbhat-marvellKalle Valo
authored andcommitted
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: Cathy Luo <[email protected]> Signed-off-by: Ganapathi Bhat <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent 77423fa commit 28bf831

File tree

7 files changed

+117
-16
lines changed

7 files changed

+117
-16
lines changed

drivers/net/wireless/marvell/mwifiex/cfg80211.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,32 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
9595

9696
/* This function maps IEEE HT secondary channel type to NL80211 channel type
9797
*/
98-
u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset)
98+
u8 mwifiex_get_chan_type(struct mwifiex_private *priv)
9999
{
100-
switch (second_chan_offset) {
101-
case IEEE80211_HT_PARAM_CHA_SEC_NONE:
102-
return NL80211_CHAN_HT20;
103-
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
104-
return NL80211_CHAN_HT40PLUS;
105-
case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
106-
return NL80211_CHAN_HT40MINUS;
107-
default:
108-
return NL80211_CHAN_HT20;
100+
struct mwifiex_channel_band channel_band;
101+
int ret;
102+
103+
ret = mwifiex_get_chan_info(priv, &channel_band);
104+
105+
if (!ret) {
106+
switch (channel_band.band_config.chan_width) {
107+
case CHAN_BW_20MHZ:
108+
if (IS_11N_ENABLED(priv))
109+
return NL80211_CHAN_HT20;
110+
else
111+
return NL80211_CHAN_NO_HT;
112+
case CHAN_BW_40MHZ:
113+
if (channel_band.band_config.chan2_offset ==
114+
SEC_CHAN_ABOVE)
115+
return NL80211_CHAN_HT40PLUS;
116+
else
117+
return NL80211_CHAN_HT40MINUS;
118+
default:
119+
return NL80211_CHAN_HT20;
120+
}
109121
}
122+
123+
return NL80211_CHAN_HT20;
110124
}
111125

112126
/*
@@ -3937,7 +3951,6 @@ static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
39373951
struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
39383952
struct mwifiex_bssdescriptor *curr_bss;
39393953
struct ieee80211_channel *chan;
3940-
u8 second_chan_offset;
39413954
enum nl80211_channel_type chan_type;
39423955
enum nl80211_band band;
39433956
int freq;
@@ -3954,10 +3967,7 @@ static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
39543967
chan = ieee80211_get_channel(wiphy, freq);
39553968

39563969
if (priv->ht_param_present) {
3957-
second_chan_offset = priv->assoc_resp_ht_param &
3958-
IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
3959-
chan_type = mwifiex_sec_chan_offset_to_chan_type
3960-
(second_chan_offset);
3970+
chan_type = mwifiex_get_chan_type(priv);
39613971
cfg80211_chandef_create(chandef, chan, chan_type);
39623972
} else {
39633973
cfg80211_chandef_create(chandef, chan,

drivers/net/wireless/marvell/mwifiex/decl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,4 +294,21 @@ enum rdwr_status {
294294
RDWR_STATUS_DONE = 2
295295
};
296296

297+
enum mwifiex_chan_width {
298+
CHAN_BW_20MHZ = 0,
299+
CHAN_BW_10MHZ,
300+
CHAN_BW_40MHZ,
301+
CHAN_BW_80MHZ,
302+
CHAN_BW_8080MHZ,
303+
CHAN_BW_160MHZ,
304+
CHAN_BW_5MHZ,
305+
};
306+
307+
enum mwifiex_chan_offset {
308+
SEC_CHAN_NONE = 0,
309+
SEC_CHAN_ABOVE = 1,
310+
SEC_CHAN_5MHZ = 2,
311+
SEC_CHAN_BELOW = 3
312+
};
313+
297314
#endif /* !_MWIFIEX_DECL_H_ */

drivers/net/wireless/marvell/mwifiex/fw.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
411411
#define HostCmd_CMD_TDLS_OPER 0x0122
412412
#define HostCmd_CMD_FW_DUMP_EVENT 0x0125
413413
#define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG 0x0223
414+
#define HostCmd_CMD_STA_CONFIGURE 0x023f
414415
#define HostCmd_CMD_CHAN_REGION_CFG 0x0242
415416
#define HostCmd_CMD_PACKET_AGGR_CTRL 0x0251
416417

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

2289+
struct host_cmd_ds_sta_configure {
2290+
__le16 action;
2291+
u8 tlv_buffer[0];
2292+
} __packed;
2293+
22882294
struct host_cmd_ds_command {
22892295
__le16 command;
22902296
__le16 size;
@@ -2361,6 +2367,7 @@ struct host_cmd_ds_command {
23612367
struct host_cmd_ds_gtk_rekey_params rekey;
23622368
struct host_cmd_ds_chan_region_cfg reg_cfg;
23632369
struct host_cmd_ds_pkt_aggr_ctrl pkt_aggr_ctrl;
2370+
struct host_cmd_ds_sta_configure sta_cfg;
23642371
} params;
23652372
} __packed;
23662373

drivers/net/wireless/marvell/mwifiex/main.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,18 @@ enum mwifiex_iface_work_flags {
517517
MWIFIEX_IFACE_WORK_CARD_RESET,
518518
};
519519

520+
struct mwifiex_band_config {
521+
u8 chan_band:2;
522+
u8 chan_width:2;
523+
u8 chan2_offset:2;
524+
u8 scan_mode:2;
525+
} __packed;
526+
527+
struct mwifiex_channel_band {
528+
struct mwifiex_band_config band_config;
529+
u8 channel;
530+
};
531+
520532
struct mwifiex_private {
521533
struct mwifiex_adapter *adapter;
522534
u8 bss_type;
@@ -1557,7 +1569,7 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
15571569
struct mwifiex_bssdescriptor *bss_desc);
15581570

15591571
u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type);
1560-
u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset);
1572+
u8 mwifiex_get_chan_type(struct mwifiex_private *priv);
15611573

15621574
struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
15631575
const char *name,
@@ -1683,6 +1695,8 @@ void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
16831695
int mwifiex_get_wakeup_reason(struct mwifiex_private *priv, u16 action,
16841696
int cmd_type,
16851697
struct mwifiex_ds_wakeup_reason *wakeup_reason);
1698+
int mwifiex_get_chan_info(struct mwifiex_private *priv,
1699+
struct mwifiex_channel_band *channel_band);
16861700
int mwifiex_ret_wakeup_reason(struct mwifiex_private *priv,
16871701
struct host_cmd_ds_command *resp,
16881702
struct host_cmd_ds_wakeup_reason *wakeup_reason);

drivers/net/wireless/marvell/mwifiex/sta_cmd.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,25 @@ static int mwifiex_cmd_get_wakeup_reason(struct mwifiex_private *priv,
18981898
return 0;
18991899
}
19001900

1901+
static int mwifiex_cmd_get_chan_info(struct host_cmd_ds_command *cmd,
1902+
u16 cmd_action)
1903+
{
1904+
struct host_cmd_ds_sta_configure *sta_cfg_cmd = &cmd->params.sta_cfg;
1905+
struct host_cmd_tlv_channel_band *tlv_band_channel =
1906+
(struct host_cmd_tlv_channel_band *)sta_cfg_cmd->tlv_buffer;
1907+
1908+
cmd->command = cpu_to_le16(HostCmd_CMD_STA_CONFIGURE);
1909+
cmd->size = cpu_to_le16(sizeof(*sta_cfg_cmd) +
1910+
sizeof(*tlv_band_channel) + S_DS_GEN);
1911+
sta_cfg_cmd->action = cpu_to_le16(cmd_action);
1912+
memset(tlv_band_channel, 0, sizeof(*tlv_band_channel));
1913+
tlv_band_channel->header.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
1914+
tlv_band_channel->header.len = cpu_to_le16(sizeof(*tlv_band_channel) -
1915+
sizeof(struct mwifiex_ie_types_header));
1916+
1917+
return 0;
1918+
}
1919+
19011920
/* This function check if the command is supported by firmware */
19021921
static int mwifiex_is_cmd_supported(struct mwifiex_private *priv, u16 cmd_no)
19031922
{
@@ -2210,6 +2229,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
22102229
cmd_ptr->command = cpu_to_le16(cmd_no);
22112230
cmd_ptr->size = cpu_to_le16(S_DS_GEN);
22122231
break;
2232+
case HostCmd_CMD_STA_CONFIGURE:
2233+
ret = mwifiex_cmd_get_chan_info(cmd_ptr, cmd_action);
2234+
break;
22132235
default:
22142236
mwifiex_dbg(priv->adapter, ERROR,
22152237
"PREP_CMD: unknown cmd- %#x\n", cmd_no);

drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,22 @@ static int mwifiex_ret_pkt_aggr_ctrl(struct mwifiex_private *priv,
11701170
return 0;
11711171
}
11721172

1173+
static int mwifiex_ret_get_chan_info(struct mwifiex_private *priv,
1174+
struct host_cmd_ds_command *resp,
1175+
struct mwifiex_channel_band *channel_band)
1176+
{
1177+
struct host_cmd_ds_sta_configure *sta_cfg_cmd = &resp->params.sta_cfg;
1178+
struct host_cmd_tlv_channel_band *tlv_band_channel;
1179+
1180+
tlv_band_channel =
1181+
(struct host_cmd_tlv_channel_band *)sta_cfg_cmd->tlv_buffer;
1182+
memcpy(&channel_band->band_config, &tlv_band_channel->band_config,
1183+
sizeof(struct mwifiex_band_config));
1184+
channel_band->channel = tlv_band_channel->channel;
1185+
1186+
return 0;
1187+
}
1188+
11731189
/*
11741190
* This function handles the command responses.
11751191
*
@@ -1393,6 +1409,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
13931409
case HostCmd_CMD_CHAN_REGION_CFG:
13941410
ret = mwifiex_ret_chan_region_cfg(priv, resp);
13951411
break;
1412+
case HostCmd_CMD_STA_CONFIGURE:
1413+
ret = mwifiex_ret_get_chan_info(priv, resp, data_buf);
1414+
break;
13961415
default:
13971416
mwifiex_dbg(adapter, ERROR,
13981417
"CMD_RESP: unknown cmd response %#x\n",

drivers/net/wireless/marvell/mwifiex/sta_ioctl.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,3 +1481,15 @@ int mwifiex_get_wakeup_reason(struct mwifiex_private *priv, u16 action,
14811481

14821482
return status;
14831483
}
1484+
1485+
int mwifiex_get_chan_info(struct mwifiex_private *priv,
1486+
struct mwifiex_channel_band *channel_band)
1487+
{
1488+
int status = 0;
1489+
1490+
status = mwifiex_send_cmd(priv, HostCmd_CMD_STA_CONFIGURE,
1491+
HostCmd_ACT_GEN_GET, 0, channel_band,
1492+
MWIFIEX_SYNC_CMD);
1493+
1494+
return status;
1495+
}

0 commit comments

Comments
 (0)