2 * Marvell Wireless LAN device driver: station command handling
4 * Copyright (C) 2011-2014, Marvell International Ltd.
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
30 module_param(drcs
, bool, 0644);
31 MODULE_PARM_DESC(drcs
, "multi-channel operation:1, single-channel operation:0");
33 static bool disable_auto_ds
;
34 module_param(disable_auto_ds
, bool, 0);
35 MODULE_PARM_DESC(disable_auto_ds
,
36 "deepsleep enabled=0(default), deepsleep disabled=1");
38 * This function prepares command to set/get RSSI information.
40 * Preparation includes -
41 * - Setting command ID, action and proper size
42 * - Setting data/beacon average factors
43 * - Resetting SNR/NF/RSSI values in private structure
44 * - Ensuring correct endian-ness
47 mwifiex_cmd_802_11_rssi_info(struct mwifiex_private
*priv
,
48 struct host_cmd_ds_command
*cmd
, u16 cmd_action
)
50 cmd
->command
= cpu_to_le16(HostCmd_CMD_RSSI_INFO
);
51 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rssi_info
) +
53 cmd
->params
.rssi_info
.action
= cpu_to_le16(cmd_action
);
54 cmd
->params
.rssi_info
.ndata
= cpu_to_le16(priv
->data_avg_factor
);
55 cmd
->params
.rssi_info
.nbcn
= cpu_to_le16(priv
->bcn_avg_factor
);
57 /* Reset SNR/NF/RSSI values in private structure */
58 priv
->data_rssi_last
= 0;
59 priv
->data_nf_last
= 0;
60 priv
->data_rssi_avg
= 0;
61 priv
->data_nf_avg
= 0;
62 priv
->bcn_rssi_last
= 0;
63 priv
->bcn_nf_last
= 0;
64 priv
->bcn_rssi_avg
= 0;
71 * This function prepares command to set MAC control.
73 * Preparation includes -
74 * - Setting command ID, action and proper size
75 * - Ensuring correct endian-ness
77 static int mwifiex_cmd_mac_control(struct mwifiex_private
*priv
,
78 struct host_cmd_ds_command
*cmd
,
79 u16 cmd_action
, u16
*action
)
81 struct host_cmd_ds_mac_control
*mac_ctrl
= &cmd
->params
.mac_ctrl
;
83 if (cmd_action
!= HostCmd_ACT_GEN_SET
) {
84 mwifiex_dbg(priv
->adapter
, ERROR
,
85 "mac_control: only support set cmd\n");
89 cmd
->command
= cpu_to_le16(HostCmd_CMD_MAC_CONTROL
);
91 cpu_to_le16(sizeof(struct host_cmd_ds_mac_control
) + S_DS_GEN
);
92 mac_ctrl
->action
= cpu_to_le16(*action
);
98 * This function prepares command to set/get SNMP MIB.
100 * Preparation includes -
101 * - Setting command ID, action and proper size
102 * - Setting SNMP MIB OID number and value
104 * - Ensuring correct endian-ness
106 * The following SNMP MIB OIDs are supported -
107 * - FRAG_THRESH_I : Fragmentation threshold
108 * - RTS_THRESH_I : RTS threshold
109 * - SHORT_RETRY_LIM_I : Short retry limit
110 * - DOT11D_I : 11d support
112 static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private
*priv
,
113 struct host_cmd_ds_command
*cmd
,
114 u16 cmd_action
, u32 cmd_oid
,
117 struct host_cmd_ds_802_11_snmp_mib
*snmp_mib
= &cmd
->params
.smib
;
119 mwifiex_dbg(priv
->adapter
, CMD
,
120 "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid
);
121 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB
);
122 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib
)
125 snmp_mib
->oid
= cpu_to_le16((u16
)cmd_oid
);
126 if (cmd_action
== HostCmd_ACT_GEN_GET
) {
127 snmp_mib
->query_type
= cpu_to_le16(HostCmd_ACT_GEN_GET
);
128 snmp_mib
->buf_size
= cpu_to_le16(MAX_SNMP_BUF_SIZE
);
129 le16_add_cpu(&cmd
->size
, MAX_SNMP_BUF_SIZE
);
130 } else if (cmd_action
== HostCmd_ACT_GEN_SET
) {
131 snmp_mib
->query_type
= cpu_to_le16(HostCmd_ACT_GEN_SET
);
132 snmp_mib
->buf_size
= cpu_to_le16(sizeof(u16
));
133 *((__le16
*) (snmp_mib
->value
)) = cpu_to_le16(*ul_temp
);
134 le16_add_cpu(&cmd
->size
, sizeof(u16
));
137 mwifiex_dbg(priv
->adapter
, CMD
,
138 "cmd: SNMP_CMD: Action=0x%x, OID=0x%x,\t"
139 "OIDSize=0x%x, Value=0x%x\n",
140 cmd_action
, cmd_oid
, le16_to_cpu(snmp_mib
->buf_size
),
141 le16_to_cpu(*(__le16
*)snmp_mib
->value
));
146 * This function prepares command to get log.
148 * Preparation includes -
149 * - Setting command ID and proper size
150 * - Ensuring correct endian-ness
153 mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command
*cmd
)
155 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_GET_LOG
);
156 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log
) +
162 * This function prepares command to set/get Tx data rate configuration.
164 * Preparation includes -
165 * - Setting command ID, action and proper size
166 * - Setting configuration index, rate scope and rate drop pattern
167 * parameters (as required)
168 * - Ensuring correct endian-ness
170 static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private
*priv
,
171 struct host_cmd_ds_command
*cmd
,
172 u16 cmd_action
, u16
*pbitmap_rates
)
174 struct host_cmd_ds_tx_rate_cfg
*rate_cfg
= &cmd
->params
.tx_rate_cfg
;
175 struct mwifiex_rate_scope
*rate_scope
;
176 struct mwifiex_rate_drop_pattern
*rate_drop
;
179 cmd
->command
= cpu_to_le16(HostCmd_CMD_TX_RATE_CFG
);
181 rate_cfg
->action
= cpu_to_le16(cmd_action
);
182 rate_cfg
->cfg_index
= 0;
184 rate_scope
= (struct mwifiex_rate_scope
*) ((u8
*) rate_cfg
+
185 sizeof(struct host_cmd_ds_tx_rate_cfg
));
186 rate_scope
->type
= cpu_to_le16(TLV_TYPE_RATE_SCOPE
);
187 rate_scope
->length
= cpu_to_le16
188 (sizeof(*rate_scope
) - sizeof(struct mwifiex_ie_types_header
));
189 if (pbitmap_rates
!= NULL
) {
190 rate_scope
->hr_dsss_rate_bitmap
= cpu_to_le16(pbitmap_rates
[0]);
191 rate_scope
->ofdm_rate_bitmap
= cpu_to_le16(pbitmap_rates
[1]);
193 i
< sizeof(rate_scope
->ht_mcs_rate_bitmap
) / sizeof(u16
);
195 rate_scope
->ht_mcs_rate_bitmap
[i
] =
196 cpu_to_le16(pbitmap_rates
[2 + i
]);
197 if (priv
->adapter
->fw_api_ver
== MWIFIEX_FW_V15
) {
199 i
< ARRAY_SIZE(rate_scope
->vht_mcs_rate_bitmap
);
201 rate_scope
->vht_mcs_rate_bitmap
[i
] =
202 cpu_to_le16(pbitmap_rates
[10 + i
]);
205 rate_scope
->hr_dsss_rate_bitmap
=
206 cpu_to_le16(priv
->bitmap_rates
[0]);
207 rate_scope
->ofdm_rate_bitmap
=
208 cpu_to_le16(priv
->bitmap_rates
[1]);
210 i
< sizeof(rate_scope
->ht_mcs_rate_bitmap
) / sizeof(u16
);
212 rate_scope
->ht_mcs_rate_bitmap
[i
] =
213 cpu_to_le16(priv
->bitmap_rates
[2 + i
]);
214 if (priv
->adapter
->fw_api_ver
== MWIFIEX_FW_V15
) {
216 i
< ARRAY_SIZE(rate_scope
->vht_mcs_rate_bitmap
);
218 rate_scope
->vht_mcs_rate_bitmap
[i
] =
219 cpu_to_le16(priv
->bitmap_rates
[10 + i
]);
223 rate_drop
= (struct mwifiex_rate_drop_pattern
*) ((u8
*) rate_scope
+
224 sizeof(struct mwifiex_rate_scope
));
225 rate_drop
->type
= cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL
);
226 rate_drop
->length
= cpu_to_le16(sizeof(rate_drop
->rate_drop_mode
));
227 rate_drop
->rate_drop_mode
= 0;
230 cpu_to_le16(S_DS_GEN
+ sizeof(struct host_cmd_ds_tx_rate_cfg
) +
231 sizeof(struct mwifiex_rate_scope
) +
232 sizeof(struct mwifiex_rate_drop_pattern
));
238 * This function prepares command to set/get Tx power configuration.
240 * Preparation includes -
241 * - Setting command ID, action and proper size
242 * - Setting Tx power mode, power group TLV
244 * - Ensuring correct endian-ness
246 static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command
*cmd
,
248 struct host_cmd_ds_txpwr_cfg
*txp
)
250 struct mwifiex_types_power_group
*pg_tlv
;
251 struct host_cmd_ds_txpwr_cfg
*cmd_txp_cfg
= &cmd
->params
.txp_cfg
;
253 cmd
->command
= cpu_to_le16(HostCmd_CMD_TXPWR_CFG
);
255 cpu_to_le16(S_DS_GEN
+ sizeof(struct host_cmd_ds_txpwr_cfg
));
256 switch (cmd_action
) {
257 case HostCmd_ACT_GEN_SET
:
259 pg_tlv
= (struct mwifiex_types_power_group
260 *) ((unsigned long) txp
+
261 sizeof(struct host_cmd_ds_txpwr_cfg
));
262 memmove(cmd_txp_cfg
, txp
,
263 sizeof(struct host_cmd_ds_txpwr_cfg
) +
264 sizeof(struct mwifiex_types_power_group
) +
265 le16_to_cpu(pg_tlv
->length
));
267 pg_tlv
= (struct mwifiex_types_power_group
*) ((u8
*)
269 sizeof(struct host_cmd_ds_txpwr_cfg
));
270 cmd
->size
= cpu_to_le16(le16_to_cpu(cmd
->size
) +
271 sizeof(struct mwifiex_types_power_group
) +
272 le16_to_cpu(pg_tlv
->length
));
274 memmove(cmd_txp_cfg
, txp
, sizeof(*txp
));
276 cmd_txp_cfg
->action
= cpu_to_le16(cmd_action
);
278 case HostCmd_ACT_GEN_GET
:
279 cmd_txp_cfg
->action
= cpu_to_le16(cmd_action
);
287 * This function prepares command to get RF Tx power.
289 static int mwifiex_cmd_rf_tx_power(struct mwifiex_private
*priv
,
290 struct host_cmd_ds_command
*cmd
,
291 u16 cmd_action
, void *data_buf
)
293 struct host_cmd_ds_rf_tx_pwr
*txp
= &cmd
->params
.txp
;
295 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_rf_tx_pwr
)
297 cmd
->command
= cpu_to_le16(HostCmd_CMD_RF_TX_PWR
);
298 txp
->action
= cpu_to_le16(cmd_action
);
304 * This function prepares command to set rf antenna.
306 static int mwifiex_cmd_rf_antenna(struct mwifiex_private
*priv
,
307 struct host_cmd_ds_command
*cmd
,
309 struct mwifiex_ds_ant_cfg
*ant_cfg
)
311 struct host_cmd_ds_rf_ant_mimo
*ant_mimo
= &cmd
->params
.ant_mimo
;
312 struct host_cmd_ds_rf_ant_siso
*ant_siso
= &cmd
->params
.ant_siso
;
314 cmd
->command
= cpu_to_le16(HostCmd_CMD_RF_ANTENNA
);
316 if (cmd_action
!= HostCmd_ACT_GEN_SET
)
319 if (priv
->adapter
->hw_dev_mcs_support
== HT_STREAM_2X2
) {
320 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_rf_ant_mimo
) +
322 ant_mimo
->action_tx
= cpu_to_le16(HostCmd_ACT_SET_TX
);
323 ant_mimo
->tx_ant_mode
= cpu_to_le16((u16
)ant_cfg
->tx_ant
);
324 ant_mimo
->action_rx
= cpu_to_le16(HostCmd_ACT_SET_RX
);
325 ant_mimo
->rx_ant_mode
= cpu_to_le16((u16
)ant_cfg
->rx_ant
);
327 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_rf_ant_siso
) +
329 ant_siso
->action
= cpu_to_le16(HostCmd_ACT_SET_BOTH
);
330 ant_siso
->ant_mode
= cpu_to_le16((u16
)ant_cfg
->tx_ant
);
337 * This function prepares command to set Host Sleep configuration.
339 * Preparation includes -
340 * - Setting command ID and proper size
341 * - Setting Host Sleep action, conditions, ARP filters
343 * - Ensuring correct endian-ness
346 mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private
*priv
,
347 struct host_cmd_ds_command
*cmd
,
349 struct mwifiex_hs_config_param
*hscfg_param
)
351 struct mwifiex_adapter
*adapter
= priv
->adapter
;
352 struct host_cmd_ds_802_11_hs_cfg_enh
*hs_cfg
= &cmd
->params
.opt_hs_cfg
;
353 bool hs_activate
= false;
356 /* New Activate command */
358 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH
);
361 (hscfg_param
->conditions
!= cpu_to_le32(HS_CFG_CANCEL
)) &&
362 ((adapter
->arp_filter_size
> 0) &&
363 (adapter
->arp_filter_size
<= ARP_FILTER_MAX_BUF_SIZE
))) {
364 mwifiex_dbg(adapter
, CMD
,
365 "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n",
366 adapter
->arp_filter_size
);
367 memcpy(((u8
*) hs_cfg
) +
368 sizeof(struct host_cmd_ds_802_11_hs_cfg_enh
),
369 adapter
->arp_filter
, adapter
->arp_filter_size
);
370 cmd
->size
= cpu_to_le16
371 (adapter
->arp_filter_size
+
372 sizeof(struct host_cmd_ds_802_11_hs_cfg_enh
)
375 cmd
->size
= cpu_to_le16(S_DS_GEN
+ sizeof(struct
376 host_cmd_ds_802_11_hs_cfg_enh
));
379 hs_cfg
->action
= cpu_to_le16(HS_ACTIVATE
);
380 hs_cfg
->params
.hs_activate
.resp_ctrl
= cpu_to_le16(RESP_NEEDED
);
382 hs_cfg
->action
= cpu_to_le16(HS_CONFIGURE
);
383 hs_cfg
->params
.hs_config
.conditions
= hscfg_param
->conditions
;
384 hs_cfg
->params
.hs_config
.gpio
= hscfg_param
->gpio
;
385 hs_cfg
->params
.hs_config
.gap
= hscfg_param
->gap
;
386 mwifiex_dbg(adapter
, CMD
,
387 "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
388 hs_cfg
->params
.hs_config
.conditions
,
389 hs_cfg
->params
.hs_config
.gpio
,
390 hs_cfg
->params
.hs_config
.gap
);
397 * This function prepares command to set/get MAC address.
399 * Preparation includes -
400 * - Setting command ID, action and proper size
401 * - Setting MAC address (for SET only)
402 * - Ensuring correct endian-ness
404 static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private
*priv
,
405 struct host_cmd_ds_command
*cmd
,
408 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS
);
409 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_802_11_mac_address
) +
413 cmd
->params
.mac_addr
.action
= cpu_to_le16(cmd_action
);
415 if (cmd_action
== HostCmd_ACT_GEN_SET
)
416 memcpy(cmd
->params
.mac_addr
.mac_addr
, priv
->curr_addr
,
422 * This function prepares command to set MAC multicast address.
424 * Preparation includes -
425 * - Setting command ID, action and proper size
426 * - Setting MAC multicast address
427 * - Ensuring correct endian-ness
430 mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command
*cmd
,
432 struct mwifiex_multicast_list
*mcast_list
)
434 struct host_cmd_ds_mac_multicast_adr
*mcast_addr
= &cmd
->params
.mc_addr
;
436 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr
) +
438 cmd
->command
= cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR
);
440 mcast_addr
->action
= cpu_to_le16(cmd_action
);
441 mcast_addr
->num_of_adrs
=
442 cpu_to_le16((u16
) mcast_list
->num_multicast_addr
);
443 memcpy(mcast_addr
->mac_list
, mcast_list
->mac_list
,
444 mcast_list
->num_multicast_addr
* ETH_ALEN
);
450 * This function prepares command to deauthenticate.
452 * Preparation includes -
453 * - Setting command ID and proper size
454 * - Setting AP MAC address and reason code
455 * - Ensuring correct endian-ness
457 static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private
*priv
,
458 struct host_cmd_ds_command
*cmd
,
461 struct host_cmd_ds_802_11_deauthenticate
*deauth
= &cmd
->params
.deauth
;
463 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE
);
464 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_802_11_deauthenticate
)
467 /* Set AP MAC address */
468 memcpy(deauth
->mac_addr
, mac
, ETH_ALEN
);
470 mwifiex_dbg(priv
->adapter
, CMD
, "cmd: Deauth: %pM\n", deauth
->mac_addr
);
472 deauth
->reason_code
= cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING
);
478 * This function prepares command to stop Ad-Hoc network.
480 * Preparation includes -
481 * - Setting command ID and proper size
482 * - Ensuring correct endian-ness
484 static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command
*cmd
)
486 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP
);
487 cmd
->size
= cpu_to_le16(S_DS_GEN
);
492 * This function sets WEP key(s) to key parameter TLV(s).
494 * Multi-key parameter TLVs are supported, so we can send multiple
495 * WEP keys in a single buffer.
498 mwifiex_set_keyparamset_wep(struct mwifiex_private
*priv
,
499 struct mwifiex_ie_type_key_param_set
*key_param_set
,
502 int cur_key_param_len
;
505 /* Multi-key_param_set TLV is supported */
506 for (i
= 0; i
< NUM_WEP_KEYS
; i
++) {
507 if ((priv
->wep_key
[i
].key_length
== WLAN_KEY_LEN_WEP40
) ||
508 (priv
->wep_key
[i
].key_length
== WLAN_KEY_LEN_WEP104
)) {
509 key_param_set
->type
=
510 cpu_to_le16(TLV_TYPE_KEY_MATERIAL
);
511 /* Key_param_set WEP fixed length */
512 #define KEYPARAMSET_WEP_FIXED_LEN 8
513 key_param_set
->length
= cpu_to_le16((u16
)
516 KEYPARAMSET_WEP_FIXED_LEN
));
517 key_param_set
->key_type_id
=
518 cpu_to_le16(KEY_TYPE_ID_WEP
);
519 key_param_set
->key_info
=
520 cpu_to_le16(KEY_ENABLED
| KEY_UNICAST
|
522 key_param_set
->key_len
=
523 cpu_to_le16(priv
->wep_key
[i
].key_length
);
524 /* Set WEP key index */
525 key_param_set
->key
[0] = i
;
526 /* Set default Tx key flag */
529 wep_key_curr_index
& HostCmd_WEP_KEY_INDEX_MASK
))
530 key_param_set
->key
[1] = 1;
532 key_param_set
->key
[1] = 0;
533 memmove(&key_param_set
->key
[2],
534 priv
->wep_key
[i
].key_material
,
535 priv
->wep_key
[i
].key_length
);
537 cur_key_param_len
= priv
->wep_key
[i
].key_length
+
538 KEYPARAMSET_WEP_FIXED_LEN
+
539 sizeof(struct mwifiex_ie_types_header
);
540 *key_param_len
+= (u16
) cur_key_param_len
;
542 (struct mwifiex_ie_type_key_param_set
*)
543 ((u8
*)key_param_set
+
545 } else if (!priv
->wep_key
[i
].key_length
) {
548 mwifiex_dbg(priv
->adapter
, ERROR
,
549 "key%d Length = %d is incorrect\n",
550 (i
+ 1), priv
->wep_key
[i
].key_length
);
558 /* This function populates key material v2 command
559 * to set network key for AES & CMAC AES.
561 static int mwifiex_set_aes_key_v2(struct mwifiex_private
*priv
,
562 struct host_cmd_ds_command
*cmd
,
563 struct mwifiex_ds_encrypt_key
*enc_key
,
564 struct host_cmd_ds_802_11_key_material_v2
*km
)
566 struct mwifiex_adapter
*adapter
= priv
->adapter
;
567 u16 size
, len
= KEY_PARAMS_FIXED_LEN
;
569 if (enc_key
->is_igtk_key
) {
570 mwifiex_dbg(adapter
, INFO
,
571 "%s: Set CMAC AES Key\n", __func__
);
572 if (enc_key
->is_rx_seq_valid
)
573 memcpy(km
->key_param_set
.key_params
.cmac_aes
.ipn
,
574 enc_key
->pn
, enc_key
->pn_len
);
575 km
->key_param_set
.key_info
&= cpu_to_le16(~KEY_MCAST
);
576 km
->key_param_set
.key_info
|= cpu_to_le16(KEY_IGTK
);
577 km
->key_param_set
.key_type
= KEY_TYPE_ID_AES_CMAC
;
578 km
->key_param_set
.key_params
.cmac_aes
.key_len
=
579 cpu_to_le16(enc_key
->key_len
);
580 memcpy(km
->key_param_set
.key_params
.cmac_aes
.key
,
581 enc_key
->key_material
, enc_key
->key_len
);
582 len
+= sizeof(struct mwifiex_cmac_aes_param
);
584 mwifiex_dbg(adapter
, INFO
,
585 "%s: Set AES Key\n", __func__
);
586 if (enc_key
->is_rx_seq_valid
)
587 memcpy(km
->key_param_set
.key_params
.aes
.pn
,
588 enc_key
->pn
, enc_key
->pn_len
);
589 km
->key_param_set
.key_type
= KEY_TYPE_ID_AES
;
590 km
->key_param_set
.key_params
.aes
.key_len
=
591 cpu_to_le16(enc_key
->key_len
);
592 memcpy(km
->key_param_set
.key_params
.aes
.key
,
593 enc_key
->key_material
, enc_key
->key_len
);
594 len
+= sizeof(struct mwifiex_aes_param
);
597 km
->key_param_set
.len
= cpu_to_le16(len
);
598 size
= len
+ sizeof(struct mwifiex_ie_types_header
) +
599 sizeof(km
->action
) + S_DS_GEN
;
600 cmd
->size
= cpu_to_le16(size
);
605 /* This function prepares command to set/get/reset network key(s).
606 * This function prepares key material command for V2 format.
607 * Preparation includes -
608 * - Setting command ID, action and proper size
609 * - Setting WEP keys, WAPI keys or WPA keys along with required
610 * encryption (TKIP, AES) (as required)
611 * - Ensuring correct endian-ness
614 mwifiex_cmd_802_11_key_material_v2(struct mwifiex_private
*priv
,
615 struct host_cmd_ds_command
*cmd
,
616 u16 cmd_action
, u32 cmd_oid
,
617 struct mwifiex_ds_encrypt_key
*enc_key
)
619 struct mwifiex_adapter
*adapter
= priv
->adapter
;
620 u8
*mac
= enc_key
->mac_addr
;
621 u16 key_info
, len
= KEY_PARAMS_FIXED_LEN
;
622 struct host_cmd_ds_802_11_key_material_v2
*km
=
623 &cmd
->params
.key_material_v2
;
625 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL
);
626 km
->action
= cpu_to_le16(cmd_action
);
628 if (cmd_action
== HostCmd_ACT_GEN_GET
) {
629 mwifiex_dbg(adapter
, INFO
, "%s: Get key\n", __func__
);
630 km
->key_param_set
.key_idx
=
631 enc_key
->key_index
& KEY_INDEX_MASK
;
632 km
->key_param_set
.type
= cpu_to_le16(TLV_TYPE_KEY_PARAM_V2
);
633 km
->key_param_set
.len
= cpu_to_le16(KEY_PARAMS_FIXED_LEN
);
634 memcpy(km
->key_param_set
.mac_addr
, mac
, ETH_ALEN
);
636 if (enc_key
->key_index
& MWIFIEX_KEY_INDEX_UNICAST
)
637 key_info
= KEY_UNICAST
;
639 key_info
= KEY_MCAST
;
641 if (enc_key
->is_igtk_key
)
642 key_info
|= KEY_IGTK
;
644 km
->key_param_set
.key_info
= cpu_to_le16(key_info
);
646 cmd
->size
= cpu_to_le16(sizeof(struct mwifiex_ie_types_header
) +
647 S_DS_GEN
+ KEY_PARAMS_FIXED_LEN
+
652 memset(&km
->key_param_set
, 0,
653 sizeof(struct mwifiex_ie_type_key_param_set_v2
));
655 if (enc_key
->key_disable
) {
656 mwifiex_dbg(adapter
, INFO
, "%s: Remove key\n", __func__
);
657 km
->action
= cpu_to_le16(HostCmd_ACT_GEN_REMOVE
);
658 km
->key_param_set
.type
= cpu_to_le16(TLV_TYPE_KEY_PARAM_V2
);
659 km
->key_param_set
.len
= cpu_to_le16(KEY_PARAMS_FIXED_LEN
);
660 km
->key_param_set
.key_idx
= enc_key
->key_index
& KEY_INDEX_MASK
;
661 key_info
= KEY_MCAST
| KEY_UNICAST
;
662 km
->key_param_set
.key_info
= cpu_to_le16(key_info
);
663 memcpy(km
->key_param_set
.mac_addr
, mac
, ETH_ALEN
);
664 cmd
->size
= cpu_to_le16(sizeof(struct mwifiex_ie_types_header
) +
665 S_DS_GEN
+ KEY_PARAMS_FIXED_LEN
+
670 km
->action
= cpu_to_le16(HostCmd_ACT_GEN_SET
);
671 km
->key_param_set
.key_idx
= enc_key
->key_index
& KEY_INDEX_MASK
;
672 km
->key_param_set
.type
= cpu_to_le16(TLV_TYPE_KEY_PARAM_V2
);
673 key_info
= KEY_ENABLED
;
674 memcpy(km
->key_param_set
.mac_addr
, mac
, ETH_ALEN
);
676 if (enc_key
->key_len
<= WLAN_KEY_LEN_WEP104
) {
677 mwifiex_dbg(adapter
, INFO
, "%s: Set WEP Key\n", __func__
);
678 len
+= sizeof(struct mwifiex_wep_param
);
679 km
->key_param_set
.len
= cpu_to_le16(len
);
680 km
->key_param_set
.key_type
= KEY_TYPE_ID_WEP
;
682 if (GET_BSS_ROLE(priv
) == MWIFIEX_BSS_ROLE_UAP
) {
683 key_info
|= KEY_MCAST
| KEY_UNICAST
;
685 if (enc_key
->is_current_wep_key
) {
686 key_info
|= KEY_MCAST
| KEY_UNICAST
;
687 if (km
->key_param_set
.key_idx
==
688 (priv
->wep_key_curr_index
& KEY_INDEX_MASK
))
689 key_info
|= KEY_DEFAULT
;
692 if (is_broadcast_ether_addr(mac
))
693 key_info
|= KEY_MCAST
;
695 key_info
|= KEY_UNICAST
|
698 key_info
|= KEY_MCAST
;
702 km
->key_param_set
.key_info
= cpu_to_le16(key_info
);
704 km
->key_param_set
.key_params
.wep
.key_len
=
705 cpu_to_le16(enc_key
->key_len
);
706 memcpy(km
->key_param_set
.key_params
.wep
.key
,
707 enc_key
->key_material
, enc_key
->key_len
);
709 cmd
->size
= cpu_to_le16(sizeof(struct mwifiex_ie_types_header
) +
710 len
+ sizeof(km
->action
) + S_DS_GEN
);
714 if (is_broadcast_ether_addr(mac
))
715 key_info
|= KEY_MCAST
| KEY_RX_KEY
;
717 key_info
|= KEY_UNICAST
| KEY_TX_KEY
| KEY_RX_KEY
;
719 if (enc_key
->is_wapi_key
) {
720 mwifiex_dbg(adapter
, INFO
, "%s: Set WAPI Key\n", __func__
);
721 km
->key_param_set
.key_type
= KEY_TYPE_ID_WAPI
;
722 memcpy(km
->key_param_set
.key_params
.wapi
.pn
, enc_key
->pn
,
724 km
->key_param_set
.key_params
.wapi
.key_len
=
725 cpu_to_le16(enc_key
->key_len
);
726 memcpy(km
->key_param_set
.key_params
.wapi
.key
,
727 enc_key
->key_material
, enc_key
->key_len
);
728 if (is_broadcast_ether_addr(mac
))
729 priv
->sec_info
.wapi_key_on
= true;
731 if (!priv
->sec_info
.wapi_key_on
)
732 key_info
|= KEY_DEFAULT
;
733 km
->key_param_set
.key_info
= cpu_to_le16(key_info
);
735 len
+= sizeof(struct mwifiex_wapi_param
);
736 km
->key_param_set
.len
= cpu_to_le16(len
);
737 cmd
->size
= cpu_to_le16(sizeof(struct mwifiex_ie_types_header
) +
738 len
+ sizeof(km
->action
) + S_DS_GEN
);
742 if (priv
->bss_mode
== NL80211_IFTYPE_ADHOC
) {
743 key_info
|= KEY_DEFAULT
;
744 /* Enable unicast bit for WPA-NONE/ADHOC_AES */
745 if (!priv
->sec_info
.wpa2_enabled
&&
746 !is_broadcast_ether_addr(mac
))
747 key_info
|= KEY_UNICAST
;
749 /* Enable default key for WPA/WPA2 */
750 if (!priv
->wpa_is_gtk_set
)
751 key_info
|= KEY_DEFAULT
;
754 km
->key_param_set
.key_info
= cpu_to_le16(key_info
);
756 if (enc_key
->key_len
== WLAN_KEY_LEN_CCMP
)
757 return mwifiex_set_aes_key_v2(priv
, cmd
, enc_key
, km
);
759 if (enc_key
->key_len
== WLAN_KEY_LEN_TKIP
) {
760 mwifiex_dbg(adapter
, INFO
,
761 "%s: Set TKIP Key\n", __func__
);
762 if (enc_key
->is_rx_seq_valid
)
763 memcpy(km
->key_param_set
.key_params
.tkip
.pn
,
764 enc_key
->pn
, enc_key
->pn_len
);
765 km
->key_param_set
.key_type
= KEY_TYPE_ID_TKIP
;
766 km
->key_param_set
.key_params
.tkip
.key_len
=
767 cpu_to_le16(enc_key
->key_len
);
768 memcpy(km
->key_param_set
.key_params
.tkip
.key
,
769 enc_key
->key_material
, enc_key
->key_len
);
771 len
+= sizeof(struct mwifiex_tkip_param
);
772 km
->key_param_set
.len
= cpu_to_le16(len
);
773 cmd
->size
= cpu_to_le16(sizeof(struct mwifiex_ie_types_header
) +
774 len
+ sizeof(km
->action
) + S_DS_GEN
);
781 * This function prepares command to set/get/reset network key(s).
782 * This function prepares key material command for V1 format.
784 * Preparation includes -
785 * - Setting command ID, action and proper size
786 * - Setting WEP keys, WAPI keys or WPA keys along with required
787 * encryption (TKIP, AES) (as required)
788 * - Ensuring correct endian-ness
791 mwifiex_cmd_802_11_key_material_v1(struct mwifiex_private
*priv
,
792 struct host_cmd_ds_command
*cmd
,
793 u16 cmd_action
, u32 cmd_oid
,
794 struct mwifiex_ds_encrypt_key
*enc_key
)
796 struct host_cmd_ds_802_11_key_material
*key_material
=
797 &cmd
->params
.key_material
;
798 struct host_cmd_tlv_mac_addr
*tlv_mac
;
799 u16 key_param_len
= 0, cmd_size
;
802 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL
);
803 key_material
->action
= cpu_to_le16(cmd_action
);
805 if (cmd_action
== HostCmd_ACT_GEN_GET
) {
807 cpu_to_le16(sizeof(key_material
->action
) + S_DS_GEN
);
812 memset(&key_material
->key_param_set
, 0,
814 sizeof(struct mwifiex_ie_type_key_param_set
)));
815 ret
= mwifiex_set_keyparamset_wep(priv
,
816 &key_material
->key_param_set
,
818 cmd
->size
= cpu_to_le16(key_param_len
+
819 sizeof(key_material
->action
) + S_DS_GEN
);
822 memset(&key_material
->key_param_set
, 0,
823 sizeof(struct mwifiex_ie_type_key_param_set
));
824 if (enc_key
->is_wapi_key
) {
825 mwifiex_dbg(priv
->adapter
, INFO
, "info: Set WAPI Key\n");
826 key_material
->key_param_set
.key_type_id
=
827 cpu_to_le16(KEY_TYPE_ID_WAPI
);
828 if (cmd_oid
== KEY_INFO_ENABLED
)
829 key_material
->key_param_set
.key_info
=
830 cpu_to_le16(KEY_ENABLED
);
832 key_material
->key_param_set
.key_info
=
833 cpu_to_le16(!KEY_ENABLED
);
835 key_material
->key_param_set
.key
[0] = enc_key
->key_index
;
836 if (!priv
->sec_info
.wapi_key_on
)
837 key_material
->key_param_set
.key
[1] = 1;
839 /* set 0 when re-key */
840 key_material
->key_param_set
.key
[1] = 0;
842 if (!is_broadcast_ether_addr(enc_key
->mac_addr
)) {
843 /* WAPI pairwise key: unicast */
844 key_material
->key_param_set
.key_info
|=
845 cpu_to_le16(KEY_UNICAST
);
846 } else { /* WAPI group key: multicast */
847 key_material
->key_param_set
.key_info
|=
848 cpu_to_le16(KEY_MCAST
);
849 priv
->sec_info
.wapi_key_on
= true;
852 key_material
->key_param_set
.type
=
853 cpu_to_le16(TLV_TYPE_KEY_MATERIAL
);
854 key_material
->key_param_set
.key_len
=
855 cpu_to_le16(WAPI_KEY_LEN
);
856 memcpy(&key_material
->key_param_set
.key
[2],
857 enc_key
->key_material
, enc_key
->key_len
);
858 memcpy(&key_material
->key_param_set
.key
[2 + enc_key
->key_len
],
859 enc_key
->pn
, PN_LEN
);
860 key_material
->key_param_set
.length
=
861 cpu_to_le16(WAPI_KEY_LEN
+ KEYPARAMSET_FIXED_LEN
);
863 key_param_len
= (WAPI_KEY_LEN
+ KEYPARAMSET_FIXED_LEN
) +
864 sizeof(struct mwifiex_ie_types_header
);
865 cmd
->size
= cpu_to_le16(sizeof(key_material
->action
)
866 + S_DS_GEN
+ key_param_len
);
869 if (enc_key
->key_len
== WLAN_KEY_LEN_CCMP
) {
870 if (enc_key
->is_igtk_key
) {
871 mwifiex_dbg(priv
->adapter
, CMD
, "cmd: CMAC_AES\n");
872 key_material
->key_param_set
.key_type_id
=
873 cpu_to_le16(KEY_TYPE_ID_AES_CMAC
);
874 if (cmd_oid
== KEY_INFO_ENABLED
)
875 key_material
->key_param_set
.key_info
=
876 cpu_to_le16(KEY_ENABLED
);
878 key_material
->key_param_set
.key_info
=
879 cpu_to_le16(!KEY_ENABLED
);
881 key_material
->key_param_set
.key_info
|=
882 cpu_to_le16(KEY_IGTK
);
884 mwifiex_dbg(priv
->adapter
, CMD
, "cmd: WPA_AES\n");
885 key_material
->key_param_set
.key_type_id
=
886 cpu_to_le16(KEY_TYPE_ID_AES
);
887 if (cmd_oid
== KEY_INFO_ENABLED
)
888 key_material
->key_param_set
.key_info
=
889 cpu_to_le16(KEY_ENABLED
);
891 key_material
->key_param_set
.key_info
=
892 cpu_to_le16(!KEY_ENABLED
);
894 if (enc_key
->key_index
& MWIFIEX_KEY_INDEX_UNICAST
)
895 /* AES pairwise key: unicast */
896 key_material
->key_param_set
.key_info
|=
897 cpu_to_le16(KEY_UNICAST
);
898 else /* AES group key: multicast */
899 key_material
->key_param_set
.key_info
|=
900 cpu_to_le16(KEY_MCAST
);
902 } else if (enc_key
->key_len
== WLAN_KEY_LEN_TKIP
) {
903 mwifiex_dbg(priv
->adapter
, CMD
, "cmd: WPA_TKIP\n");
904 key_material
->key_param_set
.key_type_id
=
905 cpu_to_le16(KEY_TYPE_ID_TKIP
);
906 key_material
->key_param_set
.key_info
=
907 cpu_to_le16(KEY_ENABLED
);
909 if (enc_key
->key_index
& MWIFIEX_KEY_INDEX_UNICAST
)
910 /* TKIP pairwise key: unicast */
911 key_material
->key_param_set
.key_info
|=
912 cpu_to_le16(KEY_UNICAST
);
913 else /* TKIP group key: multicast */
914 key_material
->key_param_set
.key_info
|=
915 cpu_to_le16(KEY_MCAST
);
918 if (key_material
->key_param_set
.key_type_id
) {
919 key_material
->key_param_set
.type
=
920 cpu_to_le16(TLV_TYPE_KEY_MATERIAL
);
921 key_material
->key_param_set
.key_len
=
922 cpu_to_le16((u16
) enc_key
->key_len
);
923 memcpy(key_material
->key_param_set
.key
, enc_key
->key_material
,
925 key_material
->key_param_set
.length
=
926 cpu_to_le16((u16
) enc_key
->key_len
+
927 KEYPARAMSET_FIXED_LEN
);
929 key_param_len
= (u16
)(enc_key
->key_len
+ KEYPARAMSET_FIXED_LEN
)
930 + sizeof(struct mwifiex_ie_types_header
);
932 if (le16_to_cpu(key_material
->key_param_set
.key_type_id
) ==
933 KEY_TYPE_ID_AES_CMAC
) {
934 struct mwifiex_cmac_param
*param
=
935 (void *)key_material
->key_param_set
.key
;
937 memcpy(param
->ipn
, enc_key
->pn
, IGTK_PN_LEN
);
938 memcpy(param
->key
, enc_key
->key_material
,
939 WLAN_KEY_LEN_AES_CMAC
);
941 key_param_len
= sizeof(struct mwifiex_cmac_param
);
942 key_material
->key_param_set
.key_len
=
943 cpu_to_le16(key_param_len
);
944 key_param_len
+= KEYPARAMSET_FIXED_LEN
;
945 key_material
->key_param_set
.length
=
946 cpu_to_le16(key_param_len
);
947 key_param_len
+= sizeof(struct mwifiex_ie_types_header
);
950 cmd
->size
= cpu_to_le16(sizeof(key_material
->action
) + S_DS_GEN
953 if (GET_BSS_ROLE(priv
) == MWIFIEX_BSS_ROLE_UAP
) {
954 tlv_mac
= (void *)((u8
*)&key_material
->key_param_set
+
956 tlv_mac
->header
.type
=
957 cpu_to_le16(TLV_TYPE_STA_MAC_ADDR
);
958 tlv_mac
->header
.len
= cpu_to_le16(ETH_ALEN
);
959 memcpy(tlv_mac
->mac_addr
, enc_key
->mac_addr
, ETH_ALEN
);
960 cmd_size
= key_param_len
+ S_DS_GEN
+
961 sizeof(key_material
->action
) +
962 sizeof(struct host_cmd_tlv_mac_addr
);
964 cmd_size
= key_param_len
+ S_DS_GEN
+
965 sizeof(key_material
->action
);
967 cmd
->size
= cpu_to_le16(cmd_size
);
973 /* Wrapper function for setting network key depending upon FW KEY API version */
975 mwifiex_cmd_802_11_key_material(struct mwifiex_private
*priv
,
976 struct host_cmd_ds_command
*cmd
,
977 u16 cmd_action
, u32 cmd_oid
,
978 struct mwifiex_ds_encrypt_key
*enc_key
)
980 if (priv
->adapter
->key_api_major_ver
== KEY_API_VER_MAJOR_V2
)
981 return mwifiex_cmd_802_11_key_material_v2(priv
, cmd
,
986 return mwifiex_cmd_802_11_key_material_v1(priv
, cmd
,
992 * This function prepares command to set/get 11d domain information.
994 * Preparation includes -
995 * - Setting command ID, action and proper size
996 * - Setting domain information fields (for SET only)
997 * - Ensuring correct endian-ness
999 static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private
*priv
,
1000 struct host_cmd_ds_command
*cmd
,
1003 struct mwifiex_adapter
*adapter
= priv
->adapter
;
1004 struct host_cmd_ds_802_11d_domain_info
*domain_info
=
1005 &cmd
->params
.domain_info
;
1006 struct mwifiex_ietypes_domain_param_set
*domain
=
1007 &domain_info
->domain
;
1008 u8 no_of_triplet
= adapter
->domain_reg
.no_of_triplet
;
1010 mwifiex_dbg(adapter
, INFO
,
1011 "info: 11D: no_of_triplet=0x%x\n", no_of_triplet
);
1013 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO
);
1014 domain_info
->action
= cpu_to_le16(cmd_action
);
1015 if (cmd_action
== HostCmd_ACT_GEN_GET
) {
1016 cmd
->size
= cpu_to_le16(sizeof(domain_info
->action
) + S_DS_GEN
);
1020 /* Set domain info fields */
1021 domain
->header
.type
= cpu_to_le16(WLAN_EID_COUNTRY
);
1022 memcpy(domain
->country_code
, adapter
->domain_reg
.country_code
,
1023 sizeof(domain
->country_code
));
1025 domain
->header
.len
=
1026 cpu_to_le16((no_of_triplet
*
1027 sizeof(struct ieee80211_country_ie_triplet
))
1028 + sizeof(domain
->country_code
));
1030 if (no_of_triplet
) {
1031 memcpy(domain
->triplet
, adapter
->domain_reg
.triplet
,
1032 no_of_triplet
* sizeof(struct
1033 ieee80211_country_ie_triplet
));
1035 cmd
->size
= cpu_to_le16(sizeof(domain_info
->action
) +
1036 le16_to_cpu(domain
->header
.len
) +
1037 sizeof(struct mwifiex_ie_types_header
)
1040 cmd
->size
= cpu_to_le16(sizeof(domain_info
->action
) + S_DS_GEN
);
1047 * This function prepares command to set/get IBSS coalescing status.
1049 * Preparation includes -
1050 * - Setting command ID, action and proper size
1051 * - Setting status to enable or disable (for SET only)
1052 * - Ensuring correct endian-ness
1054 static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command
*cmd
,
1055 u16 cmd_action
, u16
*enable
)
1057 struct host_cmd_ds_802_11_ibss_status
*ibss_coal
=
1058 &(cmd
->params
.ibss_coalescing
);
1060 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS
);
1061 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status
) +
1064 ibss_coal
->action
= cpu_to_le16(cmd_action
);
1066 switch (cmd_action
) {
1067 case HostCmd_ACT_GEN_SET
:
1069 ibss_coal
->enable
= cpu_to_le16(*enable
);
1071 ibss_coal
->enable
= 0;
1074 /* In other case.. Nothing to do */
1075 case HostCmd_ACT_GEN_GET
:
1083 /* This function prepares command buffer to get/set memory location value.
1086 mwifiex_cmd_mem_access(struct host_cmd_ds_command
*cmd
, u16 cmd_action
,
1089 struct mwifiex_ds_mem_rw
*mem_rw
= (void *)pdata_buf
;
1090 struct host_cmd_ds_mem_access
*mem_access
= (void *)&cmd
->params
.mem
;
1092 cmd
->command
= cpu_to_le16(HostCmd_CMD_MEM_ACCESS
);
1093 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_mem_access
) +
1096 mem_access
->action
= cpu_to_le16(cmd_action
);
1097 mem_access
->addr
= cpu_to_le32(mem_rw
->addr
);
1098 mem_access
->value
= cpu_to_le32(mem_rw
->value
);
1104 * This function prepares command to set/get register value.
1106 * Preparation includes -
1107 * - Setting command ID, action and proper size
1108 * - Setting register offset (for both GET and SET) and
1109 * register value (for SET only)
1110 * - Ensuring correct endian-ness
1112 * The following type of registers can be accessed with this function -
1120 static int mwifiex_cmd_reg_access(struct host_cmd_ds_command
*cmd
,
1121 u16 cmd_action
, void *data_buf
)
1123 struct mwifiex_ds_reg_rw
*reg_rw
= data_buf
;
1125 switch (le16_to_cpu(cmd
->command
)) {
1126 case HostCmd_CMD_MAC_REG_ACCESS
:
1128 struct host_cmd_ds_mac_reg_access
*mac_reg
;
1130 cmd
->size
= cpu_to_le16(sizeof(*mac_reg
) + S_DS_GEN
);
1131 mac_reg
= &cmd
->params
.mac_reg
;
1132 mac_reg
->action
= cpu_to_le16(cmd_action
);
1134 cpu_to_le16((u16
) le32_to_cpu(reg_rw
->offset
));
1135 mac_reg
->value
= reg_rw
->value
;
1138 case HostCmd_CMD_BBP_REG_ACCESS
:
1140 struct host_cmd_ds_bbp_reg_access
*bbp_reg
;
1142 cmd
->size
= cpu_to_le16(sizeof(*bbp_reg
) + S_DS_GEN
);
1143 bbp_reg
= &cmd
->params
.bbp_reg
;
1144 bbp_reg
->action
= cpu_to_le16(cmd_action
);
1146 cpu_to_le16((u16
) le32_to_cpu(reg_rw
->offset
));
1147 bbp_reg
->value
= (u8
) le32_to_cpu(reg_rw
->value
);
1150 case HostCmd_CMD_RF_REG_ACCESS
:
1152 struct host_cmd_ds_rf_reg_access
*rf_reg
;
1154 cmd
->size
= cpu_to_le16(sizeof(*rf_reg
) + S_DS_GEN
);
1155 rf_reg
= &cmd
->params
.rf_reg
;
1156 rf_reg
->action
= cpu_to_le16(cmd_action
);
1157 rf_reg
->offset
= cpu_to_le16((u16
) le32_to_cpu(reg_rw
->offset
));
1158 rf_reg
->value
= (u8
) le32_to_cpu(reg_rw
->value
);
1161 case HostCmd_CMD_PMIC_REG_ACCESS
:
1163 struct host_cmd_ds_pmic_reg_access
*pmic_reg
;
1165 cmd
->size
= cpu_to_le16(sizeof(*pmic_reg
) + S_DS_GEN
);
1166 pmic_reg
= &cmd
->params
.pmic_reg
;
1167 pmic_reg
->action
= cpu_to_le16(cmd_action
);
1169 cpu_to_le16((u16
) le32_to_cpu(reg_rw
->offset
));
1170 pmic_reg
->value
= (u8
) le32_to_cpu(reg_rw
->value
);
1173 case HostCmd_CMD_CAU_REG_ACCESS
:
1175 struct host_cmd_ds_rf_reg_access
*cau_reg
;
1177 cmd
->size
= cpu_to_le16(sizeof(*cau_reg
) + S_DS_GEN
);
1178 cau_reg
= &cmd
->params
.rf_reg
;
1179 cau_reg
->action
= cpu_to_le16(cmd_action
);
1181 cpu_to_le16((u16
) le32_to_cpu(reg_rw
->offset
));
1182 cau_reg
->value
= (u8
) le32_to_cpu(reg_rw
->value
);
1185 case HostCmd_CMD_802_11_EEPROM_ACCESS
:
1187 struct mwifiex_ds_read_eeprom
*rd_eeprom
= data_buf
;
1188 struct host_cmd_ds_802_11_eeprom_access
*cmd_eeprom
=
1189 &cmd
->params
.eeprom
;
1191 cmd
->size
= cpu_to_le16(sizeof(*cmd_eeprom
) + S_DS_GEN
);
1192 cmd_eeprom
->action
= cpu_to_le16(cmd_action
);
1193 cmd_eeprom
->offset
= rd_eeprom
->offset
;
1194 cmd_eeprom
->byte_count
= rd_eeprom
->byte_count
;
1195 cmd_eeprom
->value
= 0;
1206 * This function prepares command to set PCI-Express
1207 * host buffer configuration
1209 * Preparation includes -
1210 * - Setting command ID, action and proper size
1211 * - Setting host buffer configuration
1212 * - Ensuring correct endian-ness
1215 mwifiex_cmd_pcie_host_spec(struct mwifiex_private
*priv
,
1216 struct host_cmd_ds_command
*cmd
, u16 action
)
1218 struct host_cmd_ds_pcie_details
*host_spec
=
1219 &cmd
->params
.pcie_host_spec
;
1220 struct pcie_service_card
*card
= priv
->adapter
->card
;
1222 cmd
->command
= cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS
);
1223 cmd
->size
= cpu_to_le16(sizeof(struct
1224 host_cmd_ds_pcie_details
) + S_DS_GEN
);
1227 memset(host_spec
, 0, sizeof(struct host_cmd_ds_pcie_details
));
1229 if (action
!= HostCmd_ACT_GEN_SET
)
1232 /* Send the ring base addresses and count to firmware */
1233 host_spec
->txbd_addr_lo
= (u32
)(card
->txbd_ring_pbase
);
1234 host_spec
->txbd_addr_hi
= (u32
)(((u64
)card
->txbd_ring_pbase
)>>32);
1235 host_spec
->txbd_count
= MWIFIEX_MAX_TXRX_BD
;
1236 host_spec
->rxbd_addr_lo
= (u32
)(card
->rxbd_ring_pbase
);
1237 host_spec
->rxbd_addr_hi
= (u32
)(((u64
)card
->rxbd_ring_pbase
)>>32);
1238 host_spec
->rxbd_count
= MWIFIEX_MAX_TXRX_BD
;
1239 host_spec
->evtbd_addr_lo
= (u32
)(card
->evtbd_ring_pbase
);
1240 host_spec
->evtbd_addr_hi
= (u32
)(((u64
)card
->evtbd_ring_pbase
)>>32);
1241 host_spec
->evtbd_count
= MWIFIEX_MAX_EVT_BD
;
1242 if (card
->sleep_cookie_vbase
) {
1243 host_spec
->sleep_cookie_addr_lo
=
1244 (u32
)(card
->sleep_cookie_pbase
);
1245 host_spec
->sleep_cookie_addr_hi
=
1246 (u32
)(((u64
)(card
->sleep_cookie_pbase
)) >> 32);
1247 mwifiex_dbg(priv
->adapter
, INFO
,
1248 "sleep_cook_lo phy addr: 0x%x\n",
1249 host_spec
->sleep_cookie_addr_lo
);
1256 * This function prepares command for event subscription, configuration
1257 * and query. Events can be subscribed or unsubscribed. Current subscribed
1258 * events can be queried. Also, current subscribed events are reported in
1259 * every FW response.
1262 mwifiex_cmd_802_11_subsc_evt(struct mwifiex_private
*priv
,
1263 struct host_cmd_ds_command
*cmd
,
1264 struct mwifiex_ds_misc_subsc_evt
*subsc_evt_cfg
)
1266 struct host_cmd_ds_802_11_subsc_evt
*subsc_evt
= &cmd
->params
.subsc_evt
;
1267 struct mwifiex_ie_types_rssi_threshold
*rssi_tlv
;
1271 cmd
->command
= cpu_to_le16(HostCmd_CMD_802_11_SUBSCRIBE_EVENT
);
1272 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_802_11_subsc_evt
) +
1275 subsc_evt
->action
= cpu_to_le16(subsc_evt_cfg
->action
);
1276 mwifiex_dbg(priv
->adapter
, CMD
,
1277 "cmd: action: %d\n", subsc_evt_cfg
->action
);
1279 /*For query requests, no configuration TLV structures are to be added.*/
1280 if (subsc_evt_cfg
->action
== HostCmd_ACT_GEN_GET
)
1283 subsc_evt
->events
= cpu_to_le16(subsc_evt_cfg
->events
);
1285 event_bitmap
= subsc_evt_cfg
->events
;
1286 mwifiex_dbg(priv
->adapter
, CMD
, "cmd: event bitmap : %16x\n",
1289 if (((subsc_evt_cfg
->action
== HostCmd_ACT_BITWISE_CLR
) ||
1290 (subsc_evt_cfg
->action
== HostCmd_ACT_BITWISE_SET
)) &&
1291 (event_bitmap
== 0)) {
1292 mwifiex_dbg(priv
->adapter
, ERROR
,
1293 "Error: No event specified\t"
1294 "for bitwise action type\n");
1299 * Append TLV structures for each of the specified events for
1300 * subscribing or re-configuring. This is not required for
1301 * bitwise unsubscribing request.
1303 if (subsc_evt_cfg
->action
== HostCmd_ACT_BITWISE_CLR
)
1306 pos
= ((u8
*)subsc_evt
) +
1307 sizeof(struct host_cmd_ds_802_11_subsc_evt
);
1309 if (event_bitmap
& BITMASK_BCN_RSSI_LOW
) {
1310 rssi_tlv
= (struct mwifiex_ie_types_rssi_threshold
*) pos
;
1312 rssi_tlv
->header
.type
= cpu_to_le16(TLV_TYPE_RSSI_LOW
);
1313 rssi_tlv
->header
.len
=
1314 cpu_to_le16(sizeof(struct mwifiex_ie_types_rssi_threshold
) -
1315 sizeof(struct mwifiex_ie_types_header
));
1316 rssi_tlv
->abs_value
= subsc_evt_cfg
->bcn_l_rssi_cfg
.abs_value
;
1317 rssi_tlv
->evt_freq
= subsc_evt_cfg
->bcn_l_rssi_cfg
.evt_freq
;
1319 mwifiex_dbg(priv
->adapter
, EVENT
,
1320 "Cfg Beacon Low Rssi event,\t"
1321 "RSSI:-%d dBm, Freq:%d\n",
1322 subsc_evt_cfg
->bcn_l_rssi_cfg
.abs_value
,
1323 subsc_evt_cfg
->bcn_l_rssi_cfg
.evt_freq
);
1325 pos
+= sizeof(struct mwifiex_ie_types_rssi_threshold
);
1326 le16_add_cpu(&cmd
->size
,
1327 sizeof(struct mwifiex_ie_types_rssi_threshold
));
1330 if (event_bitmap
& BITMASK_BCN_RSSI_HIGH
) {
1331 rssi_tlv
= (struct mwifiex_ie_types_rssi_threshold
*) pos
;
1333 rssi_tlv
->header
.type
= cpu_to_le16(TLV_TYPE_RSSI_HIGH
);
1334 rssi_tlv
->header
.len
=
1335 cpu_to_le16(sizeof(struct mwifiex_ie_types_rssi_threshold
) -
1336 sizeof(struct mwifiex_ie_types_header
));
1337 rssi_tlv
->abs_value
= subsc_evt_cfg
->bcn_h_rssi_cfg
.abs_value
;
1338 rssi_tlv
->evt_freq
= subsc_evt_cfg
->bcn_h_rssi_cfg
.evt_freq
;
1340 mwifiex_dbg(priv
->adapter
, EVENT
,
1341 "Cfg Beacon High Rssi event,\t"
1342 "RSSI:-%d dBm, Freq:%d\n",
1343 subsc_evt_cfg
->bcn_h_rssi_cfg
.abs_value
,
1344 subsc_evt_cfg
->bcn_h_rssi_cfg
.evt_freq
);
1346 pos
+= sizeof(struct mwifiex_ie_types_rssi_threshold
);
1347 le16_add_cpu(&cmd
->size
,
1348 sizeof(struct mwifiex_ie_types_rssi_threshold
));
1355 mwifiex_cmd_append_rpn_expression(struct mwifiex_private
*priv
,
1356 struct mwifiex_mef_entry
*mef_entry
,
1359 struct mwifiex_mef_filter
*filter
= mef_entry
->filter
;
1361 u8
*stack_ptr
= *buffer
;
1363 for (i
= 0; i
< MWIFIEX_MEF_MAX_FILTERS
; i
++) {
1364 filter
= &mef_entry
->filter
[i
];
1365 if (!filter
->filt_type
)
1367 *(__le32
*)stack_ptr
= cpu_to_le32((u32
)filter
->repeat
);
1369 *stack_ptr
= TYPE_DNUM
;
1372 byte_len
= filter
->byte_seq
[MWIFIEX_MEF_MAX_BYTESEQ
];
1373 memcpy(stack_ptr
, filter
->byte_seq
, byte_len
);
1374 stack_ptr
+= byte_len
;
1375 *stack_ptr
= byte_len
;
1377 *stack_ptr
= TYPE_BYTESEQ
;
1380 *(__le32
*)stack_ptr
= cpu_to_le32((u32
)filter
->offset
);
1382 *stack_ptr
= TYPE_DNUM
;
1385 *stack_ptr
= filter
->filt_type
;
1388 if (filter
->filt_action
) {
1389 *stack_ptr
= filter
->filt_action
;
1393 if (stack_ptr
- *buffer
> STACK_NBYTES
)
1397 *buffer
= stack_ptr
;
1402 mwifiex_cmd_mef_cfg(struct mwifiex_private
*priv
,
1403 struct host_cmd_ds_command
*cmd
,
1404 struct mwifiex_ds_mef_cfg
*mef
)
1406 struct host_cmd_ds_mef_cfg
*mef_cfg
= &cmd
->params
.mef_cfg
;
1407 struct mwifiex_fw_mef_entry
*mef_entry
= NULL
;
1408 u8
*pos
= (u8
*)mef_cfg
;
1411 cmd
->command
= cpu_to_le16(HostCmd_CMD_MEF_CFG
);
1413 mef_cfg
->criteria
= cpu_to_le32(mef
->criteria
);
1414 mef_cfg
->num_entries
= cpu_to_le16(mef
->num_entries
);
1415 pos
+= sizeof(*mef_cfg
);
1417 for (i
= 0; i
< mef
->num_entries
; i
++) {
1418 mef_entry
= (struct mwifiex_fw_mef_entry
*)pos
;
1419 mef_entry
->mode
= mef
->mef_entry
[i
].mode
;
1420 mef_entry
->action
= mef
->mef_entry
[i
].action
;
1421 pos
+= sizeof(*mef_cfg
->mef_entry
);
1423 if (mwifiex_cmd_append_rpn_expression(priv
,
1424 &mef
->mef_entry
[i
], &pos
))
1427 mef_entry
->exprsize
=
1428 cpu_to_le16(pos
- mef_entry
->expr
);
1430 cmd
->size
= cpu_to_le16((u16
) (pos
- (u8
*)mef_cfg
) + S_DS_GEN
);
1435 /* This function parse cal data from ASCII to hex */
1436 static u32
mwifiex_parse_cal_cfg(u8
*src
, size_t len
, u8
*dst
)
1438 u8
*s
= src
, *d
= dst
;
1440 while (s
- src
< len
) {
1441 if (*s
&& (isspace(*s
) || *s
== '\t')) {
1446 *d
++ = simple_strtol(s
, NULL
, 16);
1456 int mwifiex_dnld_dt_cfgdata(struct mwifiex_private
*priv
,
1457 struct device_node
*node
, const char *prefix
)
1460 struct property
*prop
;
1461 size_t len
= strlen(prefix
);
1464 /* look for all matching property names */
1465 for_each_property_of_node(node
, prop
) {
1466 if (len
> strlen(prop
->name
) ||
1467 strncmp(prop
->name
, prefix
, len
))
1470 /* property header is 6 bytes, data must fit in cmd buffer */
1471 if (prop
&& prop
->value
&& prop
->length
> 6 &&
1472 prop
->length
<= MWIFIEX_SIZE_OF_CMD_BUFFER
- S_DS_GEN
) {
1473 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_CFG_DATA
,
1474 HostCmd_ACT_GEN_SET
, 0,
1484 /* This function prepares command of set_cfg_data. */
1485 static int mwifiex_cmd_cfg_data(struct mwifiex_private
*priv
,
1486 struct host_cmd_ds_command
*cmd
, void *data_buf
)
1488 struct mwifiex_adapter
*adapter
= priv
->adapter
;
1489 struct property
*prop
= data_buf
;
1491 u8
*data
= (u8
*)cmd
+ S_DS_GEN
;
1496 ret
= of_property_read_u8_array(adapter
->dt_node
, prop
->name
,
1500 mwifiex_dbg(adapter
, INFO
,
1501 "download cfg_data from device tree: %s\n",
1503 } else if (adapter
->cal_data
->data
&& adapter
->cal_data
->size
> 0) {
1504 len
= mwifiex_parse_cal_cfg((u8
*)adapter
->cal_data
->data
,
1505 adapter
->cal_data
->size
, data
);
1506 mwifiex_dbg(adapter
, INFO
,
1507 "download cfg_data from config file\n");
1512 cmd
->command
= cpu_to_le16(HostCmd_CMD_CFG_DATA
);
1513 cmd
->size
= cpu_to_le16(S_DS_GEN
+ len
);
1519 mwifiex_cmd_set_mc_policy(struct mwifiex_private
*priv
,
1520 struct host_cmd_ds_command
*cmd
,
1521 u16 cmd_action
, void *data_buf
)
1523 struct host_cmd_ds_multi_chan_policy
*mc_pol
= &cmd
->params
.mc_policy
;
1524 const u16
*drcs_info
= data_buf
;
1526 mc_pol
->action
= cpu_to_le16(cmd_action
);
1527 mc_pol
->policy
= cpu_to_le16(*drcs_info
);
1528 cmd
->command
= cpu_to_le16(HostCmd_CMD_MC_POLICY
);
1529 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_multi_chan_policy
) +
1534 static int mwifiex_cmd_robust_coex(struct mwifiex_private
*priv
,
1535 struct host_cmd_ds_command
*cmd
,
1536 u16 cmd_action
, bool *is_timeshare
)
1538 struct host_cmd_ds_robust_coex
*coex
= &cmd
->params
.coex
;
1539 struct mwifiex_ie_types_robust_coex
*coex_tlv
;
1541 cmd
->command
= cpu_to_le16(HostCmd_CMD_ROBUST_COEX
);
1542 cmd
->size
= cpu_to_le16(sizeof(*coex
) + sizeof(*coex_tlv
) + S_DS_GEN
);
1544 coex
->action
= cpu_to_le16(cmd_action
);
1545 coex_tlv
= (struct mwifiex_ie_types_robust_coex
*)
1546 ((u8
*)coex
+ sizeof(*coex
));
1547 coex_tlv
->header
.type
= cpu_to_le16(TLV_TYPE_ROBUST_COEX
);
1548 coex_tlv
->header
.len
= cpu_to_le16(sizeof(coex_tlv
->mode
));
1550 if (coex
->action
== HostCmd_ACT_GEN_GET
)
1554 coex_tlv
->mode
= cpu_to_le32(MWIFIEX_COEX_MODE_TIMESHARE
);
1556 coex_tlv
->mode
= cpu_to_le32(MWIFIEX_COEX_MODE_SPATIAL
);
1562 mwifiex_cmd_coalesce_cfg(struct mwifiex_private
*priv
,
1563 struct host_cmd_ds_command
*cmd
,
1564 u16 cmd_action
, void *data_buf
)
1566 struct host_cmd_ds_coalesce_cfg
*coalesce_cfg
=
1567 &cmd
->params
.coalesce_cfg
;
1568 struct mwifiex_ds_coalesce_cfg
*cfg
= data_buf
;
1569 struct coalesce_filt_field_param
*param
;
1570 u16 cnt
, idx
, length
;
1571 struct coalesce_receive_filt_rule
*rule
;
1573 cmd
->command
= cpu_to_le16(HostCmd_CMD_COALESCE_CFG
);
1574 cmd
->size
= cpu_to_le16(S_DS_GEN
);
1576 coalesce_cfg
->action
= cpu_to_le16(cmd_action
);
1577 coalesce_cfg
->num_of_rules
= cpu_to_le16(cfg
->num_of_rules
);
1578 rule
= coalesce_cfg
->rule
;
1580 for (cnt
= 0; cnt
< cfg
->num_of_rules
; cnt
++) {
1581 rule
->header
.type
= cpu_to_le16(TLV_TYPE_COALESCE_RULE
);
1582 rule
->max_coalescing_delay
=
1583 cpu_to_le16(cfg
->rule
[cnt
].max_coalescing_delay
);
1584 rule
->pkt_type
= cfg
->rule
[cnt
].pkt_type
;
1585 rule
->num_of_fields
= cfg
->rule
[cnt
].num_of_fields
;
1589 param
= rule
->params
;
1590 for (idx
= 0; idx
< cfg
->rule
[cnt
].num_of_fields
; idx
++) {
1591 param
->operation
= cfg
->rule
[cnt
].params
[idx
].operation
;
1592 param
->operand_len
=
1593 cfg
->rule
[cnt
].params
[idx
].operand_len
;
1595 cpu_to_le16(cfg
->rule
[cnt
].params
[idx
].offset
);
1596 memcpy(param
->operand_byte_stream
,
1597 cfg
->rule
[cnt
].params
[idx
].operand_byte_stream
,
1598 param
->operand_len
);
1600 length
+= sizeof(struct coalesce_filt_field_param
);
1605 /* Total rule length is sizeof max_coalescing_delay(u16),
1606 * num_of_fields(u8), pkt_type(u8) and total length of the all
1609 rule
->header
.len
= cpu_to_le16(length
+ sizeof(u16
) +
1610 sizeof(u8
) + sizeof(u8
));
1612 /* Add the rule length to the command size*/
1613 le16_add_cpu(&cmd
->size
, le16_to_cpu(rule
->header
.len
) +
1614 sizeof(struct mwifiex_ie_types_header
));
1616 rule
= (void *)((u8
*)rule
->params
+ length
);
1619 /* Add sizeof action, num_of_rules to total command length */
1620 le16_add_cpu(&cmd
->size
, sizeof(u16
) + sizeof(u16
));
1626 mwifiex_cmd_tdls_config(struct mwifiex_private
*priv
,
1627 struct host_cmd_ds_command
*cmd
,
1628 u16 cmd_action
, void *data_buf
)
1630 struct host_cmd_ds_tdls_config
*tdls_config
= &cmd
->params
.tdls_config
;
1631 struct mwifiex_tdls_init_cs_params
*config
;
1632 struct mwifiex_tdls_config
*init_config
;
1635 cmd
->command
= cpu_to_le16(HostCmd_CMD_TDLS_CONFIG
);
1636 cmd
->size
= cpu_to_le16(S_DS_GEN
);
1637 tdls_config
->tdls_action
= cpu_to_le16(cmd_action
);
1638 le16_add_cpu(&cmd
->size
, sizeof(tdls_config
->tdls_action
));
1640 switch (cmd_action
) {
1641 case ACT_TDLS_CS_ENABLE_CONFIG
:
1642 init_config
= data_buf
;
1643 len
= sizeof(*init_config
);
1644 memcpy(tdls_config
->tdls_data
, init_config
, len
);
1646 case ACT_TDLS_CS_INIT
:
1648 len
= sizeof(*config
);
1649 memcpy(tdls_config
->tdls_data
, config
, len
);
1651 case ACT_TDLS_CS_STOP
:
1652 len
= sizeof(struct mwifiex_tdls_stop_cs_params
);
1653 memcpy(tdls_config
->tdls_data
, data_buf
, len
);
1655 case ACT_TDLS_CS_PARAMS
:
1656 len
= sizeof(struct mwifiex_tdls_config_cs_params
);
1657 memcpy(tdls_config
->tdls_data
, data_buf
, len
);
1660 mwifiex_dbg(priv
->adapter
, ERROR
,
1661 "Unknown TDLS configuration\n");
1665 le16_add_cpu(&cmd
->size
, len
);
1670 mwifiex_cmd_tdls_oper(struct mwifiex_private
*priv
,
1671 struct host_cmd_ds_command
*cmd
,
1674 struct host_cmd_ds_tdls_oper
*tdls_oper
= &cmd
->params
.tdls_oper
;
1675 struct mwifiex_ds_tdls_oper
*oper
= data_buf
;
1676 struct mwifiex_sta_node
*sta_ptr
;
1677 struct host_cmd_tlv_rates
*tlv_rates
;
1678 struct mwifiex_ie_types_htcap
*ht_capab
;
1679 struct mwifiex_ie_types_qos_info
*wmm_qos_info
;
1680 struct mwifiex_ie_types_extcap
*extcap
;
1681 struct mwifiex_ie_types_vhtcap
*vht_capab
;
1682 struct mwifiex_ie_types_aid
*aid
;
1683 struct mwifiex_ie_types_tdls_idle_timeout
*timeout
;
1686 struct station_parameters
*params
= priv
->sta_params
;
1688 cmd
->command
= cpu_to_le16(HostCmd_CMD_TDLS_OPER
);
1689 cmd
->size
= cpu_to_le16(S_DS_GEN
);
1690 le16_add_cpu(&cmd
->size
, sizeof(struct host_cmd_ds_tdls_oper
));
1692 tdls_oper
->reason
= 0;
1693 memcpy(tdls_oper
->peer_mac
, oper
->peer_mac
, ETH_ALEN
);
1694 sta_ptr
= mwifiex_get_sta_entry(priv
, oper
->peer_mac
);
1696 pos
= (u8
*)tdls_oper
+ sizeof(struct host_cmd_ds_tdls_oper
);
1698 switch (oper
->tdls_action
) {
1699 case MWIFIEX_TDLS_DISABLE_LINK
:
1700 tdls_oper
->tdls_action
= cpu_to_le16(ACT_TDLS_DELETE
);
1702 case MWIFIEX_TDLS_CREATE_LINK
:
1703 tdls_oper
->tdls_action
= cpu_to_le16(ACT_TDLS_CREATE
);
1705 case MWIFIEX_TDLS_CONFIG_LINK
:
1706 tdls_oper
->tdls_action
= cpu_to_le16(ACT_TDLS_CONFIG
);
1709 mwifiex_dbg(priv
->adapter
, ERROR
,
1710 "TDLS config params not available for %pM\n",
1715 *(__le16
*)pos
= cpu_to_le16(params
->capability
);
1716 config_len
+= sizeof(params
->capability
);
1718 qos_info
= params
->uapsd_queues
| (params
->max_sp
<< 5);
1719 wmm_qos_info
= (struct mwifiex_ie_types_qos_info
*)(pos
+
1721 wmm_qos_info
->header
.type
= cpu_to_le16(WLAN_EID_QOS_CAPA
);
1722 wmm_qos_info
->header
.len
= cpu_to_le16(sizeof(qos_info
));
1723 wmm_qos_info
->qos_info
= qos_info
;
1724 config_len
+= sizeof(struct mwifiex_ie_types_qos_info
);
1726 if (params
->ht_capa
) {
1727 ht_capab
= (struct mwifiex_ie_types_htcap
*)(pos
+
1729 ht_capab
->header
.type
=
1730 cpu_to_le16(WLAN_EID_HT_CAPABILITY
);
1731 ht_capab
->header
.len
=
1732 cpu_to_le16(sizeof(struct ieee80211_ht_cap
));
1733 memcpy(&ht_capab
->ht_cap
, params
->ht_capa
,
1734 sizeof(struct ieee80211_ht_cap
));
1735 config_len
+= sizeof(struct mwifiex_ie_types_htcap
);
1738 if (params
->supported_rates
&& params
->supported_rates_len
) {
1739 tlv_rates
= (struct host_cmd_tlv_rates
*)(pos
+
1741 tlv_rates
->header
.type
=
1742 cpu_to_le16(WLAN_EID_SUPP_RATES
);
1743 tlv_rates
->header
.len
=
1744 cpu_to_le16(params
->supported_rates_len
);
1745 memcpy(tlv_rates
->rates
, params
->supported_rates
,
1746 params
->supported_rates_len
);
1747 config_len
+= sizeof(struct host_cmd_tlv_rates
) +
1748 params
->supported_rates_len
;
1751 if (params
->ext_capab
&& params
->ext_capab_len
) {
1752 extcap
= (struct mwifiex_ie_types_extcap
*)(pos
+
1754 extcap
->header
.type
=
1755 cpu_to_le16(WLAN_EID_EXT_CAPABILITY
);
1756 extcap
->header
.len
= cpu_to_le16(params
->ext_capab_len
);
1757 memcpy(extcap
->ext_capab
, params
->ext_capab
,
1758 params
->ext_capab_len
);
1759 config_len
+= sizeof(struct mwifiex_ie_types_extcap
) +
1760 params
->ext_capab_len
;
1762 if (params
->vht_capa
) {
1763 vht_capab
= (struct mwifiex_ie_types_vhtcap
*)(pos
+
1765 vht_capab
->header
.type
=
1766 cpu_to_le16(WLAN_EID_VHT_CAPABILITY
);
1767 vht_capab
->header
.len
=
1768 cpu_to_le16(sizeof(struct ieee80211_vht_cap
));
1769 memcpy(&vht_capab
->vht_cap
, params
->vht_capa
,
1770 sizeof(struct ieee80211_vht_cap
));
1771 config_len
+= sizeof(struct mwifiex_ie_types_vhtcap
);
1774 aid
= (struct mwifiex_ie_types_aid
*)(pos
+ config_len
);
1775 aid
->header
.type
= cpu_to_le16(WLAN_EID_AID
);
1776 aid
->header
.len
= cpu_to_le16(sizeof(params
->aid
));
1777 aid
->aid
= cpu_to_le16(params
->aid
);
1778 config_len
+= sizeof(struct mwifiex_ie_types_aid
);
1781 timeout
= (void *)(pos
+ config_len
);
1782 timeout
->header
.type
= cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT
);
1783 timeout
->header
.len
= cpu_to_le16(sizeof(timeout
->value
));
1784 timeout
->value
= cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC
);
1785 config_len
+= sizeof(struct mwifiex_ie_types_tdls_idle_timeout
);
1789 mwifiex_dbg(priv
->adapter
, ERROR
, "Unknown TDLS operation\n");
1793 le16_add_cpu(&cmd
->size
, config_len
);
1798 /* This function prepares command of sdio rx aggr info. */
1799 static int mwifiex_cmd_sdio_rx_aggr_cfg(struct host_cmd_ds_command
*cmd
,
1800 u16 cmd_action
, void *data_buf
)
1802 struct host_cmd_sdio_sp_rx_aggr_cfg
*cfg
=
1803 &cmd
->params
.sdio_rx_aggr_cfg
;
1805 cmd
->command
= cpu_to_le16(HostCmd_CMD_SDIO_SP_RX_AGGR_CFG
);
1807 cpu_to_le16(sizeof(struct host_cmd_sdio_sp_rx_aggr_cfg
) +
1809 cfg
->action
= cmd_action
;
1810 if (cmd_action
== HostCmd_ACT_GEN_SET
)
1811 cfg
->enable
= *(u8
*)data_buf
;
1816 /* This function prepares command to get HS wakeup reason.
1818 * Preparation includes -
1819 * - Setting command ID, action and proper size
1820 * - Ensuring correct endian-ness
1822 static int mwifiex_cmd_get_wakeup_reason(struct mwifiex_private
*priv
,
1823 struct host_cmd_ds_command
*cmd
)
1825 cmd
->command
= cpu_to_le16(HostCmd_CMD_HS_WAKEUP_REASON
);
1826 cmd
->size
= cpu_to_le16(sizeof(struct host_cmd_ds_wakeup_reason
) +
1833 * This function prepares the commands before sending them to the firmware.
1835 * This is a generic function which calls specific command preparation
1836 * routines based upon the command number.
1838 int mwifiex_sta_prepare_cmd(struct mwifiex_private
*priv
, uint16_t cmd_no
,
1839 u16 cmd_action
, u32 cmd_oid
,
1840 void *data_buf
, void *cmd_buf
)
1842 struct host_cmd_ds_command
*cmd_ptr
= cmd_buf
;
1845 /* Prepare command */
1847 case HostCmd_CMD_GET_HW_SPEC
:
1848 ret
= mwifiex_cmd_get_hw_spec(priv
, cmd_ptr
);
1850 case HostCmd_CMD_CFG_DATA
:
1851 ret
= mwifiex_cmd_cfg_data(priv
, cmd_ptr
, data_buf
);
1853 case HostCmd_CMD_MAC_CONTROL
:
1854 ret
= mwifiex_cmd_mac_control(priv
, cmd_ptr
, cmd_action
,
1857 case HostCmd_CMD_802_11_MAC_ADDRESS
:
1858 ret
= mwifiex_cmd_802_11_mac_address(priv
, cmd_ptr
,
1861 case HostCmd_CMD_MAC_MULTICAST_ADR
:
1862 ret
= mwifiex_cmd_mac_multicast_adr(cmd_ptr
, cmd_action
,
1865 case HostCmd_CMD_TX_RATE_CFG
:
1866 ret
= mwifiex_cmd_tx_rate_cfg(priv
, cmd_ptr
, cmd_action
,
1869 case HostCmd_CMD_TXPWR_CFG
:
1870 ret
= mwifiex_cmd_tx_power_cfg(cmd_ptr
, cmd_action
,
1873 case HostCmd_CMD_RF_TX_PWR
:
1874 ret
= mwifiex_cmd_rf_tx_power(priv
, cmd_ptr
, cmd_action
,
1877 case HostCmd_CMD_RF_ANTENNA
:
1878 ret
= mwifiex_cmd_rf_antenna(priv
, cmd_ptr
, cmd_action
,
1881 case HostCmd_CMD_802_11_PS_MODE_ENH
:
1882 ret
= mwifiex_cmd_enh_power_mode(priv
, cmd_ptr
, cmd_action
,
1883 (uint16_t)cmd_oid
, data_buf
);
1885 case HostCmd_CMD_802_11_HS_CFG_ENH
:
1886 ret
= mwifiex_cmd_802_11_hs_cfg(priv
, cmd_ptr
, cmd_action
,
1887 (struct mwifiex_hs_config_param
*) data_buf
);
1889 case HostCmd_CMD_802_11_SCAN
:
1890 ret
= mwifiex_cmd_802_11_scan(cmd_ptr
, data_buf
);
1892 case HostCmd_CMD_802_11_BG_SCAN_CONFIG
:
1893 ret
= mwifiex_cmd_802_11_bg_scan_config(priv
, cmd_ptr
,
1896 case HostCmd_CMD_802_11_BG_SCAN_QUERY
:
1897 ret
= mwifiex_cmd_802_11_bg_scan_query(cmd_ptr
);
1899 case HostCmd_CMD_802_11_ASSOCIATE
:
1900 ret
= mwifiex_cmd_802_11_associate(priv
, cmd_ptr
, data_buf
);
1902 case HostCmd_CMD_802_11_DEAUTHENTICATE
:
1903 ret
= mwifiex_cmd_802_11_deauthenticate(priv
, cmd_ptr
,
1906 case HostCmd_CMD_802_11_AD_HOC_START
:
1907 ret
= mwifiex_cmd_802_11_ad_hoc_start(priv
, cmd_ptr
,
1910 case HostCmd_CMD_802_11_GET_LOG
:
1911 ret
= mwifiex_cmd_802_11_get_log(cmd_ptr
);
1913 case HostCmd_CMD_802_11_AD_HOC_JOIN
:
1914 ret
= mwifiex_cmd_802_11_ad_hoc_join(priv
, cmd_ptr
,
1917 case HostCmd_CMD_802_11_AD_HOC_STOP
:
1918 ret
= mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr
);
1920 case HostCmd_CMD_RSSI_INFO
:
1921 ret
= mwifiex_cmd_802_11_rssi_info(priv
, cmd_ptr
, cmd_action
);
1923 case HostCmd_CMD_802_11_SNMP_MIB
:
1924 ret
= mwifiex_cmd_802_11_snmp_mib(priv
, cmd_ptr
, cmd_action
,
1927 case HostCmd_CMD_802_11_TX_RATE_QUERY
:
1929 cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY
);
1931 cpu_to_le16(sizeof(struct host_cmd_ds_tx_rate_query
) +
1936 case HostCmd_CMD_VERSION_EXT
:
1937 cmd_ptr
->command
= cpu_to_le16(cmd_no
);
1938 cmd_ptr
->params
.verext
.version_str_sel
=
1939 (u8
) (*((u32
*) data_buf
));
1940 memcpy(&cmd_ptr
->params
, data_buf
,
1941 sizeof(struct host_cmd_ds_version_ext
));
1943 cpu_to_le16(sizeof(struct host_cmd_ds_version_ext
) +
1947 case HostCmd_CMD_MGMT_FRAME_REG
:
1948 cmd_ptr
->command
= cpu_to_le16(cmd_no
);
1949 cmd_ptr
->params
.reg_mask
.action
= cpu_to_le16(cmd_action
);
1950 cmd_ptr
->params
.reg_mask
.mask
= cpu_to_le32(*(u32
*)data_buf
);
1952 cpu_to_le16(sizeof(struct host_cmd_ds_mgmt_frame_reg
) +
1956 case HostCmd_CMD_REMAIN_ON_CHAN
:
1957 cmd_ptr
->command
= cpu_to_le16(cmd_no
);
1958 memcpy(&cmd_ptr
->params
, data_buf
,
1959 sizeof(struct host_cmd_ds_remain_on_chan
));
1961 cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan
) +
1964 case HostCmd_CMD_11AC_CFG
:
1965 ret
= mwifiex_cmd_11ac_cfg(priv
, cmd_ptr
, cmd_action
, data_buf
);
1967 case HostCmd_CMD_P2P_MODE_CFG
:
1968 cmd_ptr
->command
= cpu_to_le16(cmd_no
);
1969 cmd_ptr
->params
.mode_cfg
.action
= cpu_to_le16(cmd_action
);
1970 cmd_ptr
->params
.mode_cfg
.mode
= cpu_to_le16(*(u16
*)data_buf
);
1972 cpu_to_le16(sizeof(struct host_cmd_ds_p2p_mode_cfg
) +
1975 case HostCmd_CMD_FUNC_INIT
:
1976 if (priv
->adapter
->hw_status
== MWIFIEX_HW_STATUS_RESET
)
1977 priv
->adapter
->hw_status
= MWIFIEX_HW_STATUS_READY
;
1978 cmd_ptr
->command
= cpu_to_le16(cmd_no
);
1979 cmd_ptr
->size
= cpu_to_le16(S_DS_GEN
);
1981 case HostCmd_CMD_FUNC_SHUTDOWN
:
1982 priv
->adapter
->hw_status
= MWIFIEX_HW_STATUS_RESET
;
1983 cmd_ptr
->command
= cpu_to_le16(cmd_no
);
1984 cmd_ptr
->size
= cpu_to_le16(S_DS_GEN
);
1986 case HostCmd_CMD_11N_ADDBA_REQ
:
1987 ret
= mwifiex_cmd_11n_addba_req(cmd_ptr
, data_buf
);
1989 case HostCmd_CMD_11N_DELBA
:
1990 ret
= mwifiex_cmd_11n_delba(cmd_ptr
, data_buf
);
1992 case HostCmd_CMD_11N_ADDBA_RSP
:
1993 ret
= mwifiex_cmd_11n_addba_rsp_gen(priv
, cmd_ptr
, data_buf
);
1995 case HostCmd_CMD_802_11_KEY_MATERIAL
:
1996 ret
= mwifiex_cmd_802_11_key_material(priv
, cmd_ptr
,
1997 cmd_action
, cmd_oid
,
2000 case HostCmd_CMD_802_11D_DOMAIN_INFO
:
2001 ret
= mwifiex_cmd_802_11d_domain_info(priv
, cmd_ptr
,
2004 case HostCmd_CMD_RECONFIGURE_TX_BUFF
:
2005 ret
= mwifiex_cmd_recfg_tx_buf(priv
, cmd_ptr
, cmd_action
,
2008 case HostCmd_CMD_AMSDU_AGGR_CTRL
:
2009 ret
= mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr
, cmd_action
,
2012 case HostCmd_CMD_11N_CFG
:
2013 ret
= mwifiex_cmd_11n_cfg(priv
, cmd_ptr
, cmd_action
, data_buf
);
2015 case HostCmd_CMD_WMM_GET_STATUS
:
2016 mwifiex_dbg(priv
->adapter
, CMD
,
2017 "cmd: WMM: WMM_GET_STATUS cmd sent\n");
2018 cmd_ptr
->command
= cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS
);
2020 cpu_to_le16(sizeof(struct host_cmd_ds_wmm_get_status
) +
2024 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS
:
2025 ret
= mwifiex_cmd_ibss_coalescing_status(cmd_ptr
, cmd_action
,
2028 case HostCmd_CMD_802_11_SCAN_EXT
:
2029 ret
= mwifiex_cmd_802_11_scan_ext(priv
, cmd_ptr
, data_buf
);
2031 case HostCmd_CMD_MEM_ACCESS
:
2032 ret
= mwifiex_cmd_mem_access(cmd_ptr
, cmd_action
, data_buf
);
2034 case HostCmd_CMD_MAC_REG_ACCESS
:
2035 case HostCmd_CMD_BBP_REG_ACCESS
:
2036 case HostCmd_CMD_RF_REG_ACCESS
:
2037 case HostCmd_CMD_PMIC_REG_ACCESS
:
2038 case HostCmd_CMD_CAU_REG_ACCESS
:
2039 case HostCmd_CMD_802_11_EEPROM_ACCESS
:
2040 ret
= mwifiex_cmd_reg_access(cmd_ptr
, cmd_action
, data_buf
);
2042 case HostCmd_CMD_SET_BSS_MODE
:
2043 cmd_ptr
->command
= cpu_to_le16(cmd_no
);
2044 if (priv
->bss_mode
== NL80211_IFTYPE_ADHOC
)
2045 cmd_ptr
->params
.bss_mode
.con_type
=
2046 CONNECTION_TYPE_ADHOC
;
2047 else if (priv
->bss_mode
== NL80211_IFTYPE_STATION
||
2048 priv
->bss_mode
== NL80211_IFTYPE_P2P_CLIENT
)
2049 cmd_ptr
->params
.bss_mode
.con_type
=
2050 CONNECTION_TYPE_INFRA
;
2051 else if (priv
->bss_mode
== NL80211_IFTYPE_AP
||
2052 priv
->bss_mode
== NL80211_IFTYPE_P2P_GO
)
2053 cmd_ptr
->params
.bss_mode
.con_type
= CONNECTION_TYPE_AP
;
2054 cmd_ptr
->size
= cpu_to_le16(sizeof(struct
2055 host_cmd_ds_set_bss_mode
) + S_DS_GEN
);
2058 case HostCmd_CMD_PCIE_DESC_DETAILS
:
2059 ret
= mwifiex_cmd_pcie_host_spec(priv
, cmd_ptr
, cmd_action
);
2061 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT
:
2062 ret
= mwifiex_cmd_802_11_subsc_evt(priv
, cmd_ptr
, data_buf
);
2064 case HostCmd_CMD_MEF_CFG
:
2065 ret
= mwifiex_cmd_mef_cfg(priv
, cmd_ptr
, data_buf
);
2067 case HostCmd_CMD_COALESCE_CFG
:
2068 ret
= mwifiex_cmd_coalesce_cfg(priv
, cmd_ptr
, cmd_action
,
2071 case HostCmd_CMD_TDLS_OPER
:
2072 ret
= mwifiex_cmd_tdls_oper(priv
, cmd_ptr
, data_buf
);
2074 case HostCmd_CMD_TDLS_CONFIG
:
2075 ret
= mwifiex_cmd_tdls_config(priv
, cmd_ptr
, cmd_action
,
2078 case HostCmd_CMD_CHAN_REPORT_REQUEST
:
2079 ret
= mwifiex_cmd_issue_chan_report_request(priv
, cmd_ptr
,
2082 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG
:
2083 ret
= mwifiex_cmd_sdio_rx_aggr_cfg(cmd_ptr
, cmd_action
,
2086 case HostCmd_CMD_HS_WAKEUP_REASON
:
2087 ret
= mwifiex_cmd_get_wakeup_reason(priv
, cmd_ptr
);
2089 case HostCmd_CMD_MC_POLICY
:
2090 ret
= mwifiex_cmd_set_mc_policy(priv
, cmd_ptr
, cmd_action
,
2093 case HostCmd_CMD_ROBUST_COEX
:
2094 ret
= mwifiex_cmd_robust_coex(priv
, cmd_ptr
, cmd_action
,
2098 mwifiex_dbg(priv
->adapter
, ERROR
,
2099 "PREP_CMD: unknown cmd- %#x\n", cmd_no
);
2107 * This function issues commands to initialize firmware.
2109 * This is called after firmware download to bring the card to
2111 * Function is also called during reinitialization of virtual
2114 * The following commands are issued sequentially -
2115 * - Set PCI-Express host buffer configuration (PCIE only)
2116 * - Function init (for first interface only)
2117 * - Read MAC address (for first interface only)
2118 * - Reconfigure Tx buffer size (for first interface only)
2119 * - Enable auto deep sleep (for first interface only)
2122 * - Set IBSS coalescing status
2123 * - Set AMSDU aggregation control
2125 * - Set MAC control (this must be the last command to initialize firmware)
2127 int mwifiex_sta_init_cmd(struct mwifiex_private
*priv
, u8 first_sta
, bool init
)
2129 struct mwifiex_adapter
*adapter
= priv
->adapter
;
2132 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl
;
2133 struct mwifiex_ds_auto_ds auto_ds
;
2134 enum state_11d_t state_11d
;
2135 struct mwifiex_ds_11n_tx_cfg tx_cfg
;
2136 u8 sdio_sp_rx_aggr_enable
;
2139 if (priv
->adapter
->iface_type
== MWIFIEX_PCIE
) {
2140 ret
= mwifiex_send_cmd(priv
,
2141 HostCmd_CMD_PCIE_DESC_DETAILS
,
2142 HostCmd_ACT_GEN_SET
, 0, NULL
,
2148 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_FUNC_INIT
,
2149 HostCmd_ACT_GEN_SET
, 0, NULL
, true);
2153 /* Download calibration data to firmware.
2154 * The cal-data can be read from device tree and/or
2155 * a configuration file and downloaded to firmware.
2158 of_find_node_by_name(NULL
, "marvell_cfgdata");
2159 if (adapter
->dt_node
) {
2160 ret
= mwifiex_dnld_dt_cfgdata(priv
, adapter
->dt_node
,
2166 if (adapter
->cal_data
) {
2167 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_CFG_DATA
,
2168 HostCmd_ACT_GEN_SET
, 0, NULL
,
2174 /* Read MAC address from HW */
2175 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_GET_HW_SPEC
,
2176 HostCmd_ACT_GEN_GET
, 0, NULL
, true);
2180 /** Set SDIO Single Port RX Aggr Info */
2181 if (priv
->adapter
->iface_type
== MWIFIEX_SDIO
&&
2182 ISSUPP_SDIO_SPA_ENABLED(priv
->adapter
->fw_cap_info
) &&
2183 !priv
->adapter
->host_disable_sdio_rx_aggr
) {
2184 sdio_sp_rx_aggr_enable
= true;
2185 ret
= mwifiex_send_cmd(priv
,
2186 HostCmd_CMD_SDIO_SP_RX_AGGR_CFG
,
2187 HostCmd_ACT_GEN_SET
, 0,
2188 &sdio_sp_rx_aggr_enable
,
2191 mwifiex_dbg(priv
->adapter
, ERROR
,
2192 "error while enabling SP aggregation..disable it");
2193 adapter
->sdio_rx_aggr_enable
= false;
2197 /* Reconfigure tx buf size */
2198 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_RECONFIGURE_TX_BUFF
,
2199 HostCmd_ACT_GEN_SET
, 0,
2200 &priv
->adapter
->tx_buf_size
, true);
2204 if (priv
->bss_type
!= MWIFIEX_BSS_TYPE_UAP
) {
2205 /* Enable IEEE PS by default */
2206 priv
->adapter
->ps_mode
= MWIFIEX_802_11_POWER_MODE_PSP
;
2207 ret
= mwifiex_send_cmd(priv
,
2208 HostCmd_CMD_802_11_PS_MODE_ENH
,
2209 EN_AUTO_PS
, BITMAP_STA_PS
, NULL
,
2216 adapter
->drcs_enabled
= true;
2217 if (ISSUPP_DRCS_ENABLED(adapter
->fw_cap_info
))
2218 ret
= mwifiex_send_cmd(priv
,
2219 HostCmd_CMD_MC_POLICY
,
2220 HostCmd_ACT_GEN_SET
, 0,
2221 &adapter
->drcs_enabled
,
2229 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_TX_RATE_CFG
,
2230 HostCmd_ACT_GEN_GET
, 0, NULL
, true);
2233 priv
->data_rate
= 0;
2236 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_RF_TX_PWR
,
2237 HostCmd_ACT_GEN_GET
, 0, NULL
, true);
2241 if (priv
->bss_type
== MWIFIEX_BSS_TYPE_STA
) {
2242 /* set ibss coalescing_status */
2243 ret
= mwifiex_send_cmd(
2245 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS
,
2246 HostCmd_ACT_GEN_SET
, 0, &enable
, true);
2251 memset(&amsdu_aggr_ctrl
, 0, sizeof(amsdu_aggr_ctrl
));
2252 amsdu_aggr_ctrl
.enable
= true;
2253 /* Send request to firmware */
2254 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_AMSDU_AGGR_CTRL
,
2255 HostCmd_ACT_GEN_SET
, 0,
2256 &amsdu_aggr_ctrl
, true);
2259 /* MAC Control must be the last command in init_fw */
2260 /* set MAC Control */
2261 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_MAC_CONTROL
,
2262 HostCmd_ACT_GEN_SET
, 0,
2263 &priv
->curr_pkt_filter
, true);
2267 if (!disable_auto_ds
&&
2268 first_sta
&& priv
->adapter
->iface_type
!= MWIFIEX_USB
&&
2269 priv
->bss_type
!= MWIFIEX_BSS_TYPE_UAP
) {
2270 /* Enable auto deep sleep */
2271 auto_ds
.auto_ds
= DEEP_SLEEP_ON
;
2272 auto_ds
.idle_time
= DEEP_SLEEP_IDLE_TIME
;
2273 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_802_11_PS_MODE_ENH
,
2274 EN_AUTO_PS
, BITMAP_AUTO_DS
,
2280 if (priv
->bss_type
!= MWIFIEX_BSS_TYPE_UAP
) {
2281 /* Send cmd to FW to enable/disable 11D function */
2282 state_11d
= ENABLE_11D
;
2283 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_802_11_SNMP_MIB
,
2284 HostCmd_ACT_GEN_SET
, DOT11D_I
,
2287 mwifiex_dbg(priv
->adapter
, ERROR
,
2288 "11D: failed to enable 11D\n");
2291 /* Send cmd to FW to configure 11n specific configuration
2292 * (Short GI, Channel BW, Green field support etc.) for transmit
2294 tx_cfg
.tx_htcap
= MWIFIEX_FW_DEF_HTTXCFG
;
2295 ret
= mwifiex_send_cmd(priv
, HostCmd_CMD_11N_CFG
,
2296 HostCmd_ACT_GEN_SET
, 0, &tx_cfg
, true);
2299 /* set last_init_cmd before sending the command */
2300 priv
->adapter
->last_init_cmd
= HostCmd_CMD_11N_CFG
;