1 /** @file mlan_misc.c
2 *
3 * @brief This file provides Miscellaneous functions for MLAN module
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 /*************************************************************
12 Change Log:
13 05/11/2009: initial version
14 ************************************************************/
15 #include <mlan_api.h>
16
17 /* Additional WMSDK header files */
18 #include <wmerrno.h>
19 #include <osa.h>
20 #include <mlan_fw.h>
21
22 /* Always keep this include at the end of all include files */
23 #include <mlan_remap_mem_operations.h>
24
25 /**
26 * @brief This function allocates a mlan_buffer.
27 *
28 * @param pmadapter Pointer to mlan_adapter
29 * @param data_len Data length
30 * @param head_room head_room reserved in mlan_buffer
31 * @param malloc_flag flag to user moal_malloc
32 * @return mlan_buffer pointer or MNULL
33 */
wlan_alloc_mlan_buffer(mlan_adapter * pmadapter,t_u32 data_len,t_u32 head_room,t_u32 malloc_flag)34 pmlan_buffer wlan_alloc_mlan_buffer(mlan_adapter *pmadapter, t_u32 data_len, t_u32 head_room, t_u32 malloc_flag)
35 {
36 mlan_status ret = MLAN_STATUS_SUCCESS;
37 pmlan_buffer pmbuf = MNULL;
38 t_u32 buf_size = 0;
39 /* t_u8 *tmp_buf = MNULL; */
40 pmlan_callbacks pcb = &pmadapter->callbacks;
41
42 ENTER();
43
44 /* make sure that the data length is at least SDIO block size */
45 data_len = ALIGN_SZ(data_len, MLAN_SDIO_BLOCK_SIZE);
46
47 /* head_room is not implemented for malloc mlan buffer */
48 if (malloc_flag == MTRUE)
49 {
50 buf_size = sizeof(mlan_buffer) + data_len + DMA_ALIGNMENT;
51 ret =
52 pcb->moal_malloc(pmadapter->pmoal_handle, buf_size, MLAN_MEM_DEF | MLAN_MEM_DMA, (t_u8 **)(void **)&pmbuf);
53 if ((ret != MLAN_STATUS_SUCCESS) || (pmbuf == MNULL))
54 {
55 pmbuf = MNULL;
56 goto exit;
57 }
58 (void)__memset(pmadapter, pmbuf, 0, sizeof(mlan_buffer));
59
60 pmbuf->pdesc = MNULL;
61 /* Align address */
62 pmbuf->pbuf = (t_u8 *)ALIGN_ADDR((t_u8 *)pmbuf + sizeof(mlan_buffer), DMA_ALIGNMENT);
63 pmbuf->data_offset = 0;
64 pmbuf->data_len = data_len;
65 pmbuf->flags |= MLAN_BUF_FLAG_MALLOC_BUF;
66 }
67 exit:
68 LEAVE();
69 return pmbuf;
70 }
71
72 /**
73 * @brief This function frees a mlan_buffer.
74 *
75 * @param pmadapter Pointer to mlan_adapter
76 * @param pmbuf Pointer to mlan_buffer
77 *
78 * @return N/A
79 */
wlan_free_mlan_buffer(mlan_adapter * pmadapter,pmlan_buffer pmbuf)80 t_void wlan_free_mlan_buffer(mlan_adapter *pmadapter, pmlan_buffer pmbuf)
81 {
82 return;
83 }
84
85 /**
86 * @brief This function will check if station list is empty
87 *
88 * @param priv A pointer to mlan_private
89 *
90 * @return MFALSE/MTRUE
91 */
wlan_is_station_list_empty(mlan_private * priv)92 t_u8 wlan_is_station_list_empty(mlan_private *priv)
93 {
94 ENTER();
95 if (!(util_peek_list(priv->adapter->pmoal_handle, &priv->sta_list, priv->adapter->callbacks.moal_spin_lock,
96 priv->adapter->callbacks.moal_spin_unlock)))
97 {
98 LEAVE();
99 return MTRUE;
100 }
101 LEAVE();
102 return MFALSE;
103 }
104
105 /**
106 * @brief This function will return the pointer to station entry in station list
107 * table which matches the give mac address
108 *
109 * @param priv A pointer to mlan_private
110 * @param mac mac address to find in station list table
111 *
112 * @return A pointer to structure sta_node
113 */
wlan_get_station_entry(mlan_private * priv,t_u8 * mac)114 sta_node *wlan_get_station_entry(mlan_private *priv, t_u8 *mac)
115 {
116 sta_node *sta_ptr;
117
118 ENTER();
119
120 if (!mac)
121 {
122 LEAVE();
123 return MNULL;
124 }
125 if (!(sta_ptr = (sta_node *)util_peek_list(priv->adapter->pmoal_handle, &priv->sta_list,
126 priv->adapter->callbacks.moal_spin_lock,
127 priv->adapter->callbacks.moal_spin_unlock)))
128 {
129 LEAVE();
130 return MNULL;
131 }
132 while (sta_ptr != (sta_node *)&priv->sta_list)
133 {
134 if (!__memcmp(priv->adapter, sta_ptr->mac_addr, mac, MLAN_MAC_ADDR_LENGTH))
135 {
136 LEAVE();
137 return sta_ptr;
138 }
139 sta_ptr = sta_ptr->pnext;
140 }
141 LEAVE();
142 return MNULL;
143 }
144
145 /**
146 * @brief This function will add a pointer to station entry in station list
147 * table with the give mac address, if it does not exist already
148 *
149 * @param priv A pointer to mlan_private
150 * @param mac mac address to find in station list table
151 *
152 * @return A pointer to structure sta_node
153 */
wlan_add_station_entry(mlan_private * priv,t_u8 * mac)154 sta_node *wlan_add_station_entry(mlan_private *priv, t_u8 *mac)
155 {
156 sta_node *sta_ptr = MNULL;
157 mlan_adapter *pmadapter = priv->adapter;
158
159 ENTER();
160 pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
161
162 sta_ptr = wlan_get_station_entry(priv, mac);
163 if (sta_ptr)
164 goto done;
165 if (priv->adapter->callbacks.moal_malloc(priv->adapter->pmoal_handle, sizeof(sta_node), MLAN_MEM_DEF,
166 (t_u8 **)&sta_ptr))
167 {
168 PRINTM(MERROR, "Failed to allocate memory for station node\n");
169 LEAVE();
170 return MNULL;
171 }
172 (void)__memset(priv->adapter, sta_ptr, 0, sizeof(sta_node));
173 (void)__memcpy(priv->adapter, sta_ptr->mac_addr, mac, MLAN_MAC_ADDR_LENGTH);
174 util_enqueue_list_tail(priv->adapter->pmoal_handle, &priv->sta_list, (pmlan_linked_list)sta_ptr,
175 priv->adapter->callbacks.moal_spin_lock, priv->adapter->callbacks.moal_spin_unlock);
176 done:
177 pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
178 LEAVE();
179 return sta_ptr;
180 }
181
182 /**
183 * @brief This function will delete a station entry from station list
184 *
185 *
186 * @param priv A pointer to mlan_private
187 * @param mac station's mac address
188 *
189 * @return N/A
190 */
wlan_delete_station_entry(mlan_private * priv,t_u8 * mac)191 t_void wlan_delete_station_entry(mlan_private *priv, t_u8 *mac)
192 {
193 sta_node *sta_ptr = MNULL;
194 mlan_adapter *pmadapter = priv->adapter;
195 ENTER();
196 pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
197 if ((sta_ptr = wlan_get_station_entry(priv, mac)))
198 {
199 util_unlink_list(priv->adapter->pmoal_handle, &priv->sta_list, (pmlan_linked_list)sta_ptr,
200 priv->adapter->callbacks.moal_spin_lock, priv->adapter->callbacks.moal_spin_unlock);
201 priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle, (t_u8 *)sta_ptr);
202 }
203 pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle, priv->wmm.ra_list_spinlock);
204 LEAVE();
205 return;
206 }
207
208 /**
209 * @brief Clean up wapi station list
210 *
211 * @param priv Pointer to the mlan_private driver data struct
212 *
213 * @return N/A
214 */
wlan_delete_station_list(pmlan_private priv)215 t_void wlan_delete_station_list(pmlan_private priv)
216 {
217 sta_node *sta_ptr;
218
219 ENTER();
220 while ((sta_ptr = (sta_node *)util_dequeue_list(priv->adapter->pmoal_handle, &priv->sta_list,
221 priv->adapter->callbacks.moal_spin_lock,
222 priv->adapter->callbacks.moal_spin_unlock)))
223 {
224 priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle, (t_u8 *)sta_ptr);
225 }
226 LEAVE();
227 return;
228 }
229
230 #if CONFIG_P2P
231 extern void wifi_wfd_event(bool peer_event, bool action_frame, void *data);
232 #define ZERO_BUF_LEN 8
233 #endif
234
235 /**
236 * @brief This function processes the 802.11 mgmt Frame
237 *
238 * @param priv A pointer to mlan_private
239 * @param payload A pointer to the received buffer
240 * @param payload_len Length of the received buffer
241 *
242 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
243 */
wlan_process_802dot11_mgmt_pkt(IN mlan_private * priv,IN t_u8 * payload,IN t_u32 payload_len,RxPD * rxpd)244 mlan_status wlan_process_802dot11_mgmt_pkt(IN mlan_private *priv, IN t_u8 *payload, IN t_u32 payload_len, RxPD *rxpd)
245 {
246 mlan_status ret = MLAN_STATUS_SUCCESS;
247 wlan_802_11_header *pieee_pkt_hdr = MNULL;
248 t_u16 sub_type = 0;
249 #if CONFIG_P2P
250 pmlan_adapter pmadapter = priv->adapter;
251 pmlan_callbacks pcb = &pmadapter->callbacks;
252 t_u8 *event_buf = MNULL;
253 mlan_event_p2p *pevent = MNULL;
254 t_u8 unicast = 0;
255 t_u8 zero_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
256 #endif
257 ENTER();
258 #if CONFIG_P2P
259 if (payload_len > (MAX_EVENT_SIZE - sizeof(mlan_event_p2p)))
260 {
261 PRINTM(MERROR, "Dropping large mgmt frame,len =%d\n", payload_len);
262 LEAVE();
263 return ret;
264 }
265 #endif
266 /* Check packet type-subtype and compare with mgmt_passthru_mask If event
267 is needed to host, just eventify it */
268 pieee_pkt_hdr = (wlan_802_11_header *)payload;
269 sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(pieee_pkt_hdr->frm_ctl);
270 if ((((1 << sub_type) & priv->mgmt_frame_passthru_mask) == 0) && (sub_type != SUBTYPE_ACTION))
271 {
272 PRINTM(MINFO, "Dropping mgmt frame for subtype %d.\n", sub_type);
273 LEAVE();
274 return ret;
275 }
276 switch (sub_type)
277 {
278 case SUBTYPE_ACTION:
279 ret = wlan_process_mgmt_action(payload, payload_len, rxpd);
280 if (ret == MLAN_STATUS_SUCCESS)
281 {
282 return ret;
283 }
284 break;
285 case SUBTYPE_ASSOC_REQUEST:
286 case SUBTYPE_REASSOC_REQUEST:
287 case SUBTYPE_DISASSOC:
288 case SUBTYPE_DEAUTH:
289 case SUBTYPE_AUTH:
290 case SUBTYPE_PROBE_RESP:
291 #if CONFIG_P2P
292 unicast = MTRUE;
293 #endif
294 break;
295 default:
296 PRINTM(MINFO, "Unexpected pkt subtype \n");
297 break;
298 }
299 #if CONFIG_P2P
300 if (unicast == MTRUE)
301 {
302 if (__memcmp(pmadapter, pieee_pkt_hdr->addr1, priv->curr_p2p_addr, MLAN_MAC_ADDR_LENGTH))
303 {
304 PRINTM(MINFO, "Dropping mgmt frame for others: type=%d %02x:%02x:%02x:%02x:%02x:%02x\n", sub_type,
305 pieee_pkt_hdr->addr1[0], pieee_pkt_hdr->addr1[1], pieee_pkt_hdr->addr1[2], pieee_pkt_hdr->addr1[3],
306 pieee_pkt_hdr->addr1[4], pieee_pkt_hdr->addr1[5]);
307 LEAVE();
308 return ret;
309 }
310 }
311 /* Allocate memory for event buffer */
312 ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_P2P_EVENT_SIZE, MLAN_MEM_DEF, &event_buf);
313 if ((ret != MLAN_STATUS_SUCCESS) || !event_buf)
314 {
315 PRINTM(MERROR, "Could not allocate buffer for event buf\n");
316 LEAVE();
317 return MLAN_STATUS_FAILURE;
318 }
319 pevent = (pmlan_event_p2p)event_buf;
320 pevent->event_len =
321 payload_len - sizeof(wlan_802_11_header) + sizeof(pevent->event_len) + ZERO_BUF_LEN + MLAN_MAC_ADDR_LENGTH;
322 pevent->event_len = wlan_cpu_to_le32(pevent->event_len);
323 (void)__memcpy(pmadapter, (t_u8 *)pevent->event_buf, (t_u8 *)&pevent->event_len, sizeof(pevent->event_len));
324 (void)__memcpy(pmadapter, (t_u8 *)pevent->event_buf + sizeof(pevent->event_len), (t_u8 *)zero_buf, ZERO_BUF_LEN);
325 (void)__memcpy(pmadapter, (t_u8 *)pevent->event_buf + sizeof(pevent->event_len) + ZERO_BUF_LEN,
326 (t_u8 *)pieee_pkt_hdr->addr2, MLAN_MAC_ADDR_LENGTH);
327 (void)__memcpy(pmadapter,
328 (t_u8 *)(pevent->event_buf + sizeof(pevent->event_len) + ZERO_BUF_LEN + MLAN_MAC_ADDR_LENGTH),
329 payload + sizeof(wlan_802_11_header), payload_len - sizeof(wlan_802_11_header));
330
331 wifi_wfd_event(false, true, (void *)pevent);
332 /* wlan_recv_event(priv, MLAN_EVENT_ID_DRV_MGMT_FRAME, pevent);
333 if (event_buf)
334 pcb->moal_mfree(pmadapter->pmoal_handle, event_buf);*/
335 #endif /* CONFIG_P2P */
336 LEAVE();
337 return ret;
338 }
339
wlan_bypass_802dot11_mgmt_pkt(void * data)340 mlan_status wlan_bypass_802dot11_mgmt_pkt(void *data)
341 {
342 RxPD *rxpd = (RxPD *)data;
343 wlan_mgmt_pkt *pmgmt_pkt_hdr = NULL;
344 t_u16 sub_type = 0;
345 wlan_802_11_header *pieee_pkt_hdr = MNULL;
346 t_u8 category = 0;
347 mlan_private *priv = mlan_adap->priv[0];
348 mlan_status ret = MLAN_STATUS_SUCCESS;
349
350 pmgmt_pkt_hdr = (wlan_mgmt_pkt *)((t_u8 *)rxpd + rxpd->rx_pkt_offset);
351 pieee_pkt_hdr = (wlan_802_11_header *)&pmgmt_pkt_hdr->wlan_header;
352 sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(pieee_pkt_hdr->frm_ctl);
353 // coverity[overrun-local:SUPPRESS]
354 category = *((t_u8 *)pieee_pkt_hdr + sizeof(wlan_802_11_header));
355
356 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
357 /* Currently only support action frame process */
358 if (sub_type != SUBTYPE_ACTION)
359 {
360 PRINTM(MINFO, "Dropping non-action mgmt frame for subtype %d.\n", sub_type);
361 LEAVE();
362 return ret;
363 }
364 #endif
365
366 if ((pmgmt_pkt_hdr->wlan_header.frm_ctl & IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0)
367 {
368 if ((((1 << sub_type) & priv->mgmt_frame_passthru_mask) == 0) && (sub_type != SUBTYPE_ACTION))
369 {
370 PRINTM(MINFO, "Dropping mgmt frame for subtype %d.\n", sub_type);
371 LEAVE();
372 return ret;
373 }
374
375 if (sub_type == SUBTYPE_ACTION)
376 {
377 if (category == IEEE_MGMT_ACTION_CATEGORY_BLOCK_ACK)
378 {
379 PRINTM(MINFO, "Dropping mgmt frame for category %d.\n", category);
380 LEAVE();
381 return ret;
382 }
383
384 if (category != (t_u8)IEEE_MGMT_ACTION_CATEGORY_RADIO_RSRC &&
385 category != (t_u8)IEEE_MGMT_ACTION_CATEGORY_WNM &&
386 category != (t_u8)IEEE_MGMT_ACTION_CATEGORY_UNPROTECT_WNM)
387 {
388 PRINTM(MINFO, "Dropping mgmt frame for host unsupported category %d.\n", category);
389 LEAVE();
390 return ret;
391 }
392 }
393 }
394
395 ret = MLAN_STATUS_FAILURE;
396 return ret;
397 }
398
399 /**
400 * @brief Add Extended Capabilities IE
401 *
402 * @param pmpriv A pointer to mlan_private structure
403 * @param pptlv_out A pointer to TLV to fill in
404 * @param BSSDescriptor A poiter to bss descriptor
405 * @return N/A
406 */
wlan_add_ext_capa_info_ie(IN mlan_private * pmpriv,IN BSSDescriptor_t * pbss_desc,OUT t_u8 ** pptlv_out)407 void wlan_add_ext_capa_info_ie(IN mlan_private *pmpriv, IN BSSDescriptor_t *pbss_desc, OUT t_u8 **pptlv_out)
408 {
409 MrvlIETypes_ExtCap_t *pext_cap = MNULL;
410
411 ENTER();
412
413 pext_cap = (MrvlIETypes_ExtCap_t *)(void *)*pptlv_out;
414 (void)__memset(pmpriv->adapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
415 pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
416 pext_cap->header.len = wlan_cpu_to_le16(sizeof(ExtCap_t));
417 if ((((t_u8)(pmpriv->hotspot_cfg >> 8)) & HOTSPOT_ENABLE_INTERWORKING_IND) != 0U)
418 {
419 pext_cap->ext_cap.Interworking = 1;
420 }
421 if ((((t_u8)(pmpriv->hotspot_cfg >> 8)) & HOTSPOT_ENABLE_TDLS_IND) != 0U)
422 {
423 pext_cap->ext_cap.TDLSSupport = 1;
424 }
425
426 #if (CONFIG_WNM_PS)
427 if ((((mlan_private *)mlan_adap->priv[0])->wnm_set == true) && (pbss_desc != MNULL) &&
428 (pbss_desc->pext_cap->ext_cap.WNM_Sleep == true))
429 {
430 pext_cap->ext_cap.WNM_Sleep = 1;
431 }
432 else
433 {
434 pext_cap->ext_cap.WNM_Sleep = 0;
435 }
436 #endif
437 #if CONFIG_11AX
438 #if CONFIG_MULTI_BSSID_SUPPORT
439 if (pbss_desc && pbss_desc->multi_bssid_ap)
440 SET_EXTCAP_MULTI_BSSID(pext_cap->ext_cap);
441 #endif
442 if (wlan_check_11ax_twt_supported(pmpriv, pbss_desc))
443 SET_EXTCAP_TWT_REQ(pext_cap->ext_cap);
444 #endif
445 #if CONFIG_11V
446 pext_cap->ext_cap.BSS_Transition = 1;
447 #endif
448 #if CONFIG_11MC
449 pext_cap->ext_cap.FTMI = 1;
450 pext_cap->ext_cap.CivicLocation = 1;
451 #endif
452
453 *pptlv_out += sizeof(MrvlIETypes_ExtCap_t);
454
455 LEAVE();
456 }
457
458 /**
459 * @brief Get rate index
460 *
461 * @param pmadapter A pointer to mlan_adapter structure
462 * @param pioctl_req A pointer to ioctl request buffer
463 *
464 * @return MLAN_STATUS_PENDING --success, otherwise fail
465 */
wlan_rate_ioctl_get_rate_index(IN pmlan_adapter pmadapter,IN pmlan_ioctl_req pioctl_req)466 static mlan_status wlan_rate_ioctl_get_rate_index(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
467 {
468 mlan_status ret = MLAN_STATUS_SUCCESS;
469 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
470
471 ENTER();
472
473 /* Send request to firmware */
474 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req, MNULL);
475
476 if (ret == MLAN_STATUS_SUCCESS)
477 {
478 ret = MLAN_STATUS_PENDING;
479 }
480
481 LEAVE();
482 return ret;
483 }
484
485 /**
486 * @brief Set rate index
487 *
488 * @param pmadapter A pointer to mlan_adapter structure
489 * @param pioctl_req A pointer to ioctl request buffer
490 *
491 * @return MLAN_STATUS_PENDING --success, otherwise fail
492 */
wlan_rate_ioctl_set_rate_index(IN pmlan_adapter pmadapter,IN pmlan_ioctl_req pioctl_req)493 static mlan_status wlan_rate_ioctl_set_rate_index(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
494 {
495 t_s32 rate_index;
496 mlan_rate_format rate_format;
497 #if (CONFIG_11AC) || (CONFIG_11AX)
498 t_u32 nss;
499 #endif
500 t_u32 i;
501 mlan_ds_rate *ds_rate = MNULL;
502 mlan_status ret = MLAN_STATUS_FAILURE;
503 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
504 t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
505 t_u16 shift_index = 1U;
506 #ifdef STREAM_2X2
507 #if 0
508 int tx_mcs_supp = GET_TXMCSSUPP(pmpriv->usr_dev_mcs_support);
509 #endif
510 #endif
511
512 ENTER();
513
514 ds_rate = (mlan_ds_rate *)(void *)pioctl_req->pbuf;
515
516 rate_format = ds_rate->param.rate_cfg.rate_format;
517 #if (CONFIG_11AC) || (CONFIG_11AX)
518 nss = ds_rate->param.rate_cfg.nss;
519 #endif
520 rate_index = (t_s32)ds_rate->param.rate_cfg.rate;
521
522 if (ds_rate->param.rate_cfg.is_rate_auto == MTRUE)
523 {
524 (void)__memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
525 /* Rates talbe [0]: HR/DSSS;[1]: OFDM; [2..9] HT; */
526 /* Support all HR/DSSS rates */
527 bitmap_rates[0] = 0x000F;
528 /* Support all OFDM rates */
529 bitmap_rates[1] = 0x00FF;
530 /* Support all HT-MCSs rate */
531 for (i = 2; i < 9U; i++)
532 {
533 bitmap_rates[i] = 0xFFFF;
534 }
535 bitmap_rates[9] = 0x3FFF;
536 #if CONFIG_11AC
537 /* [10..17] VHT */
538 #ifdef RW610
539 /* RW610 only supports VHT MCS0 ~ MCS8*/
540 bitmap_rates[10] = 0x01FF; /* 9 Bits valid */
541 /* RW610 only supports 1 NSS*/
542 bitmap_rates[11] = 0x0;
543 #else
544 /* Support all VHT-MCSs rate for NSS 1 and 2 */
545 for (i = 10; i < 12; i++)
546 {
547 bitmap_rates[i] = 0x03FF; /* 10 Bits valid */
548 }
549 #endif
550 /* Set to 0 as default value for all other NSSs */
551 for (i = 12; i < NELEMENTS(bitmap_rates); i++)
552 {
553 bitmap_rates[i] = 0x0;
554 }
555 #endif
556 #if CONFIG_11AX
557 /* [18..25] HE */
558 #ifdef RW610
559 /* RW610 only supports HE MCS0 ~ MCS9*/
560 bitmap_rates[18] = 0x03FF; /* 10 Bits valid */
561 /* RW610 only supports 1 NSS*/
562 bitmap_rates[19] = 0x0;
563 #else
564 /* Support all HE-MCSs rate for NSS1 and 2 */
565 for (i = 18; i < 20; i++)
566 bitmap_rates[i] = 0x0FFF;
567 #endif
568 for (i = 20; i < NELEMENTS(bitmap_rates); i++)
569 bitmap_rates[i] = 0x0;
570 #endif
571 }
572 else
573 {
574 PRINTM(MINFO, "Rate index is %d\n", rate_index);
575
576 #ifdef STREAM_2X2
577 #if 0
578 if ((rate_format == MLAN_RATE_FORMAT_HT) &&
579 (rate_index > MLAN_RATE_INDEX_MCS7 && rate_index <= MLAN_RATE_INDEX_MCS15) && (tx_mcs_supp < 2))
580 {
581 PRINTM(MERROR, "HW don't support 2x2, rate_index=%d hw_mcs_supp=0x%x\n", rate_index,
582 pmpriv->usr_dev_mcs_support);
583 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
584 LEAVE();
585 return MLAN_STATUS_FAILURE;
586 }
587 #endif
588 #endif
589
590 (void)__memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
591 if (rate_format == MLAN_RATE_FORMAT_LG)
592 {
593 /* Bitmap of HR/DSSS rates */
594 if (rate_index <= MLAN_RATE_INDEX_HRDSSS3)
595 {
596 bitmap_rates[0] = (shift_index << rate_index);
597 ret = MLAN_STATUS_SUCCESS;
598 /* Bitmap of OFDM rates */
599 }
600 else if (rate_index <= MLAN_RATE_INDEX_OFDM7)
601 {
602 bitmap_rates[1] = (shift_index << (rate_index - MLAN_RATE_INDEX_OFDM0));
603 ret = MLAN_STATUS_SUCCESS;
604 }
605 else
606 {
607 /*Do Nothing*/
608 }
609 }
610 else if (rate_format == MLAN_RATE_FORMAT_HT)
611 {
612 if (rate_index <= MLAN_RATE_INDEX_MCS32)
613 {
614 #ifdef SD8801
615 rate_index -= MLAN_RATE_INDEX_MCS0;
616 #endif
617 bitmap_rates[2 + (rate_index / 16)] = (shift_index << (rate_index % 16));
618 ret = MLAN_STATUS_SUCCESS;
619 }
620 }
621 else
622 {
623 /*DO Nothing*/
624 }
625
626 #if CONFIG_11AC
627 if (rate_format == MLAN_RATE_FORMAT_VHT)
628 {
629 if ((rate_index <= MLAN_RATE_INDEX_MCS9) && (MLAN_RATE_NSS1 <= nss) && (nss <= MLAN_RATE_NSS2))
630 {
631 bitmap_rates[10 + nss - MLAN_RATE_NSS1] = (shift_index << rate_index);
632 ret = MLAN_STATUS_SUCCESS;
633 }
634 }
635 #endif
636 #if CONFIG_11AX
637 if (rate_format == MLAN_RATE_FORMAT_HE)
638 {
639 if (IS_FW_SUPPORT_11AX(pmadapter))
640 {
641 if ((rate_index <= MLAN_RATE_INDEX_MCS11) && (MLAN_RATE_NSS1 <= nss) && (nss <= MLAN_RATE_NSS2))
642 {
643 bitmap_rates[18 + nss - MLAN_RATE_NSS1] = (1 << rate_index);
644 ret = MLAN_STATUS_SUCCESS;
645 }
646 }
647 else
648 {
649 PRINTM(MERROR, "Error! Fw doesn't support 11AX\n");
650 LEAVE();
651 return MLAN_STATUS_FAILURE;
652 }
653 }
654 #endif
655 if (ret == MLAN_STATUS_FAILURE)
656 {
657 PRINTM(MERROR, "Invalid MCS index=%d. \n", rate_index);
658 pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
659 LEAVE();
660 return MLAN_STATUS_FAILURE;
661 }
662 }
663
664 PRINTM(MINFO,
665 "RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x"
666 "%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
667 "IsRateAuto=%d, DataRate=%d\n",
668 bitmap_rates[17], bitmap_rates[16], bitmap_rates[15], bitmap_rates[14], bitmap_rates[13], bitmap_rates[12],
669 bitmap_rates[11], bitmap_rates[10], bitmap_rates[9], bitmap_rates[8], bitmap_rates[7], bitmap_rates[6],
670 bitmap_rates[5], bitmap_rates[4], bitmap_rates[3], bitmap_rates[2], bitmap_rates[1], bitmap_rates[0],
671 pmpriv->is_data_rate_auto, pmpriv->data_rate);
672
673 /* Send request to firmware */
674 #if CONFIG_AUTO_NULL_TX
675 if (ds_rate->auto_null_fixrate_enable == 1)
676 {
677 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, HostCmd_ACT_SPC_AUTO_SET, 0, (t_void *)pioctl_req,
678 bitmap_rates);
679 ds_rate->auto_null_fixrate_enable = 0xff;
680 }
681 else if (ds_rate->auto_null_fixrate_enable == 0)
682 {
683 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, HostCmd_ACT_SPC_AUTO_NOSET, 0, (t_void *)pioctl_req,
684 bitmap_rates);
685 ds_rate->auto_null_fixrate_enable = 0xff;
686 }
687 else
688 #endif
689 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG, HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
690 (t_void *)bitmap_rates);
691
692 if (ret == MLAN_STATUS_SUCCESS)
693 {
694 ret = MLAN_STATUS_PENDING;
695 }
696
697 LEAVE();
698 return ret;
699 }
700
701 /**
702 * @brief Rate configuration command handler
703 *
704 * @param pmadapter A pointer to mlan_adapter structure
705 * @param pioctl_req A pointer to ioctl request buffer
706 *
707 * @return MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success, otherwise fail
708 */
wlan_rate_ioctl_cfg(IN pmlan_adapter pmadapter,IN pmlan_ioctl_req pioctl_req)709 mlan_status wlan_rate_ioctl_cfg(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
710 {
711 mlan_status status = MLAN_STATUS_SUCCESS;
712
713 ENTER();
714
715 if (pioctl_req->action == MLAN_ACT_GET)
716 {
717 status = wlan_rate_ioctl_get_rate_index(pmadapter, pioctl_req);
718 }
719 else
720 {
721 status = wlan_rate_ioctl_set_rate_index(pmadapter, pioctl_req);
722 }
723
724 LEAVE();
725 return status;
726 }
727
728 /**
729 * @brief This function prepares command of rf_antenna.
730 *
731 * @param pmpriv A pointer to mlan_private structure
732 * @param cmd A pointer to HostCmd_DS_COMMAND structure
733 * @param cmd_action The action: GET or SET
734 * @param pdata_buf A pointer to data buffer
735 *
736 * @return MLAN_STATUS_SUCCESS
737 */
wlan_cmd_802_11_rf_antenna(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)738 mlan_status wlan_cmd_802_11_rf_antenna(IN pmlan_private pmpriv,
739 IN HostCmd_DS_COMMAND *cmd,
740 IN t_u16 cmd_action,
741 IN t_void *pdata_buf)
742 {
743 HostCmd_DS_802_11_RF_ANTENNA *pantenna = &cmd->params.antenna;
744 #ifdef STREAM_2X2
745 mlan_ds_ant_cfg *ant_cfg = (mlan_ds_ant_cfg *)pdata_buf;
746 #else
747 mlan_ds_ant_cfg_1x1 *ant_cfg_1x1 = (mlan_ds_ant_cfg_1x1 *)pdata_buf;
748 #endif
749
750 ENTER();
751 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_ANTENNA);
752 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_ANTENNA) + S_DS_GEN);
753
754 if (cmd_action == HostCmd_ACT_GEN_SET)
755 {
756 #ifdef STREAM_2X2
757 pantenna->action_tx = wlan_cpu_to_le16(HostCmd_ACT_SET_TX);
758 pantenna->tx_antenna_mode = wlan_cpu_to_le16((t_u16)ant_cfg->tx_antenna);
759 pantenna->action_rx = wlan_cpu_to_le16(HostCmd_ACT_SET_RX);
760 pantenna->rx_antenna_mode = wlan_cpu_to_le16((t_u16)ant_cfg->rx_antenna);
761 #else
762 pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_SET_BOTH);
763 pantenna->antenna_mode = wlan_cpu_to_le16((t_u16)ant_cfg_1x1->antenna);
764 pantenna->evaluate_time = wlan_cpu_to_le16((t_u16)ant_cfg_1x1->evaluate_time);
765 #ifdef RW610
766 pantenna->evaluate_mode = wlan_cpu_to_le16((t_u8)ant_cfg_1x1->evaluate_mode);
767 #endif
768 #endif
769 }
770 else
771 {
772 #ifdef STREAM_2X2
773 pantenna->action_tx = wlan_cpu_to_le16(HostCmd_ACT_GET_TX);
774 pantenna->action_rx = wlan_cpu_to_le16(HostCmd_ACT_GET_RX);
775 #else
776 pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_GET_BOTH);
777 #endif
778 }
779
780 LEAVE();
781 return MLAN_STATUS_SUCCESS;
782 }
783
784 #if CONFIG_NET_MONITOR
wlan_cmd_802_11_net_monitor(IN pmlan_private pmpriv,IN HostCmd_DS_COMMAND * cmd,IN t_u16 cmd_action,IN t_void * pdata_buf)785 mlan_status wlan_cmd_802_11_net_monitor(IN pmlan_private pmpriv,
786 IN HostCmd_DS_COMMAND *cmd,
787 IN t_u16 cmd_action,
788 IN t_void *pdata_buf)
789 {
790 HostCmd_DS_802_11_NET_MONITOR *net_mon = &cmd->params.net_mon;
791 wifi_net_monitor_t *monitor = (wifi_net_monitor_t *)pdata_buf;
792 ENTER();
793
794 (void)__memset(pmpriv->adapter, net_mon, 0x00, sizeof(HostCmd_DS_802_11_NET_MONITOR));
795
796 cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_NET_MONITOR);
797 cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_NET_MONITOR) + S_DS_GEN);
798
799 if (cmd_action == HostCmd_ACT_GEN_SET)
800 {
801 net_mon->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
802 net_mon->monitor_activity = wlan_cpu_to_le16(monitor->monitor_activity);
803 net_mon->filter_flags = wlan_cpu_to_le16(monitor->filter_flags);
804 net_mon->monitor_channel.header.type = TLV_TYPE_UAP_CHAN_BAND_CONFIG;
805 net_mon->monitor_channel.header.len = 2;
806 net_mon->monitor_channel.chan_band_param[0].radio_type = (t_u8)monitor->radio_type;
807 net_mon->monitor_channel.chan_band_param[0].chan_number = (t_u8)monitor->chan_number;
808
809 net_mon->monitor_filter.header.type = TLV_TYPE_UAP_STA_MAC_ADDR_FILTER;
810 net_mon->monitor_filter.header.len = MLAN_MAC_ADDR_LENGTH * monitor->filter_num + sizeof(t_u8);
811 net_mon->monitor_filter.filter_num = (t_u8)monitor->filter_num;
812 __memcpy(priv->adapter, (t_u8 *)net_mon->monitor_filter.mac_list, (t_u8 *)monitor->mac_addr,
813 MAX_MONIT_MAC_FILTER_NUM * MLAN_MAC_ADDR_LENGTH);
814 }
815 else
816 {
817 net_mon->action = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
818 }
819 LEAVE();
820 return MLAN_STATUS_SUCCESS;
821 }
822 #endif
823
824 #ifdef WLAN_LOW_POWER_ENABLE
825 /**
826 * @brief Set/Get Low Power Mode
827 *
828 * @param pmadapter A pointer to mlan_adapter structure
829 * @param pioctl_req A pointer to ioctl request buffer
830 *
831 * @return MLAN_STATUS_SUCCESS
832 */
wlan_misc_ioctl_low_pwr_mode(IN pmlan_adapter pmadapter,IN pmlan_ioctl_req pioctl_req)833 mlan_status wlan_misc_ioctl_low_pwr_mode(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
834 {
835 mlan_status ret = MLAN_STATUS_SUCCESS;
836 mlan_ds_misc_cfg *misc = MNULL;
837 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
838
839 ENTER();
840
841 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
842
843 /* Send request to firmware */
844 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_LOW_POWER_MODE, HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
845 &misc->param.low_pwr_mode);
846
847 if (ret == MLAN_STATUS_SUCCESS)
848 ret = MLAN_STATUS_PENDING;
849
850 LEAVE();
851 return ret;
852 }
853 #endif // WLAN_LOW_POWER_ENABLE
854
855 #if CONFIG_WIFI_CLOCKSYNC
856 /**
857 * @brief Set/Get GPIO TSF Latch config
858 *
859 * @param pmadapter A pointer to mlan_adapter structure
860 * @param pioctl_req A pointer to ioctl request buffer
861 *
862 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
863 */
wlan_misc_gpio_tsf_latch_config(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)864 mlan_status wlan_misc_gpio_tsf_latch_config(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
865 {
866 mlan_status ret = MLAN_STATUS_SUCCESS;
867 mlan_ds_misc_cfg *misc_cfg = MNULL;
868 t_u16 cmd_action = 0;
869 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
870
871 ENTER();
872
873 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
874 if (pioctl_req->action == MLAN_ACT_SET)
875 cmd_action = HostCmd_ACT_GEN_SET;
876 else
877 cmd_action = HostCmd_ACT_GEN_GET;
878
879 /* Send request to firmware */
880 ret = wlan_prepare_cmd(pmpriv, HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG, cmd_action, 0, (t_void *)pioctl_req,
881 &misc_cfg->param.gpio_tsf_latch_config);
882
883 LEAVE();
884 return ret;
885 }
886
887 /**
888 * @brief Get TSF info
889 *
890 * @param pmadapter A pointer to mlan_adapter structure
891 * @param pioctl_req A pointer to ioctl request buffer
892 *
893 * @return MLAN_STATUS_SUCCESS --success, otherwise fail
894 */
wlan_misc_get_tsf_info(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)895 mlan_status wlan_misc_get_tsf_info(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
896 {
897 mlan_status ret = MLAN_STATUS_SUCCESS;
898 mlan_ds_misc_cfg *misc_cfg = MNULL;
899 t_u16 cmd_action = 0;
900 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
901
902 ENTER();
903
904 misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
905 cmd_action = HostCmd_ACT_GEN_GET;
906
907 /* Send request to firmware */
908 ret = wlan_prepare_cmd(pmpriv, HostCmd_GPIO_TSF_LATCH_PARAM_CONFIG, cmd_action, 0, (t_void *)pioctl_req,
909 &misc_cfg->param.tsf_info);
910
911 LEAVE();
912 return ret;
913 }
914 #endif /* CONFIG_WIFI_CLOCKSYNC */
915
916 #if CONFIG_ECSA
917 /**
918 * @brief Get non-global operating class
919 *
920 * @param pmadapter A pointer to mlan_adapter structure
921 * @param pioctl_req Pointer to the IOCTL request buffer
922 *
923 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
924 */
wlan_misc_ioctl_oper_class(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)925 mlan_status wlan_misc_ioctl_oper_class(pmlan_adapter pmadapter, mlan_ioctl_req *pioctl_req)
926 {
927 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
928 mlan_ds_misc_cfg *misc = MNULL;
929 t_u8 channel, bandwidth, oper_class = 0;
930 mlan_status ret = MLAN_STATUS_SUCCESS;
931
932 ENTER();
933
934 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
935 channel = misc->param.bw_chan_oper.channel;
936 switch (misc->param.bw_chan_oper.bandwidth)
937 {
938 case 20:
939 bandwidth = BW_20MHZ;
940 break;
941 case 40:
942 bandwidth = BW_40MHZ;
943 break;
944 case 80:
945 bandwidth = BW_80MHZ;
946 break;
947 default:
948 bandwidth = BW_20MHZ;
949 break;
950 }
951
952 if (pioctl_req->action == MLAN_ACT_GET)
953 {
954 ret = wlan_get_curr_oper_class(pmpriv, channel, bandwidth, &oper_class);
955 misc->param.bw_chan_oper.oper_class = oper_class;
956 }
957 else
958 {
959 PRINTM(MERROR, "Unsupported cmd_action\n");
960 LEAVE();
961 return MLAN_STATUS_FAILURE;
962 }
963
964 LEAVE();
965 return ret;
966 }
967
968 /**
969 * @brief Check operating class validation
970 *
971 * @param pmadapter A pointer to mlan_adapter structure
972 * @param pioctl_req Pointer to the IOCTL request buffer
973 *
974 * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
975 */
wlan_misc_ioctl_operclass_validation(pmlan_adapter pmadapter,mlan_ioctl_req * pioctl_req)976 mlan_status wlan_misc_ioctl_operclass_validation(pmlan_adapter pmadapter, mlan_ioctl_req *pioctl_req)
977 {
978 pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
979 mlan_ds_misc_cfg *misc = MNULL;
980 t_u8 channel, oper_class;
981 mlan_status ret = MLAN_STATUS_SUCCESS;
982
983 ENTER();
984
985 misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
986 channel = misc->param.bw_chan_oper.channel;
987 oper_class = misc->param.bw_chan_oper.oper_class;
988 if (pioctl_req->action == MLAN_ACT_GET)
989 {
990 ret = wlan_check_operclass_validation(pmpriv, channel, oper_class);
991 }
992 else
993 {
994 PRINTM(MERROR, "Unsupported cmd_action\n");
995 LEAVE();
996 return MLAN_STATUS_FAILURE;
997 }
998
999 LEAVE();
1000 return ret;
1001 }
1002 #endif
1003
1004 #if CONFIG_RF_TEST_MODE
1005 /**
1006 * @brief RF Test Mode config
1007 *
1008 * @param pmadapter A pointer to mlan_adapter structure
1009 * @param pioctl_req A pointer to ioctl request buffer
1010 *
1011 * @return MLAN_STATUS_PENDING --success, otherwise fail
1012 */
wlan_misc_ioctl_rf_test_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1013 mlan_status wlan_misc_ioctl_rf_test_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
1014 {
1015 mlan_private *pmpriv = MNULL;
1016 mlan_ds_misc_cfg *pmisc = MNULL;
1017 mlan_status ret = MLAN_STATUS_FAILURE;
1018 t_u16 cmd_action = 0;
1019
1020 ENTER();
1021
1022 if (!pioctl_req)
1023 goto done;
1024
1025 pmpriv = pmadapter->priv[pioctl_req->bss_index];
1026 pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
1027
1028 switch (pmisc->sub_command)
1029 {
1030 case MLAN_OID_MISC_RF_TEST_GENERIC:
1031 if (pioctl_req->action == MLAN_ACT_SET)
1032 cmd_action = HostCmd_ACT_GEN_SET;
1033 else
1034 cmd_action = HostCmd_ACT_GEN_GET;
1035 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
1036 &(pmisc->param.mfg_generic_cfg));
1037 break;
1038 case MLAN_OID_MISC_RF_TEST_TX_CONT:
1039 if (pioctl_req->action == MLAN_ACT_SET)
1040 cmd_action = HostCmd_ACT_GEN_SET;
1041 else
1042 {
1043 PRINTM(MERROR, "Unsupported cmd_action\n");
1044 ret = MLAN_STATUS_FAILURE;
1045 goto done;
1046 }
1047 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
1048 &(pmisc->param.mfg_tx_cont));
1049 break;
1050 case MLAN_OID_MISC_RF_TEST_TX_FRAME:
1051 if (pioctl_req->action == MLAN_ACT_SET)
1052 cmd_action = HostCmd_ACT_GEN_SET;
1053 else
1054 {
1055 PRINTM(MERROR, "Unsupported cmd_action\n");
1056 ret = MLAN_STATUS_FAILURE;
1057 goto done;
1058 }
1059 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
1060 &(pmisc->param.mfg_tx_frame2));
1061 break;
1062 case MLAN_OID_MISC_RF_TEST_CONFIG_TRIGGER_FRAME:
1063 if (pioctl_req->action == MLAN_ACT_SET)
1064 cmd_action = HostCmd_ACT_GEN_SET;
1065 else
1066 {
1067 PRINTM(MERROR, "Unsupported cmd_action\n");
1068 ret = MLAN_STATUS_FAILURE;
1069 goto done;
1070 }
1071 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
1072 &(pmisc->param.mfg_tx_trigger_config));
1073 break;
1074
1075 case MLAN_OID_MISC_RF_TEST_HE_POWER:
1076 if (pioctl_req->action == MLAN_ACT_SET)
1077 cmd_action = HostCmd_ACT_GEN_SET;
1078 else
1079 {
1080 PRINTM(MERROR, "Unsupported cmd_action\n");
1081 ret = MLAN_STATUS_FAILURE;
1082 goto done;
1083 }
1084 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND, cmd_action, 0, (t_void *)pioctl_req,
1085 &(pmisc->param.mfg_he_power));
1086 break;
1087 }
1088
1089 if (ret == MLAN_STATUS_SUCCESS)
1090 ret = MLAN_STATUS_PENDING;
1091 done:
1092 LEAVE();
1093 return ret;
1094 }
1095 #endif
1096
1097 #if (CONFIG_WIFI_IND_RESET) && (CONFIG_WIFI_IND_DNLD)
1098 /**
1099 * @brief Configure GPIO independent reset
1100 *
1101 * @param pmadapter A pointer to mlan_adapter structure
1102 * @param pioctl_req A pointer to ioctl request buffer
1103 *
1104 * @return MLAN_STATUS_PENDING --success, otherwise fail
1105 */
wlan_misc_ioctl_ind_rst_cfg(pmlan_adapter pmadapter,pmlan_ioctl_req pioctl_req)1106 mlan_status wlan_misc_ioctl_ind_rst_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
1107 {
1108 mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
1109 mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
1110 mlan_status ret = MLAN_STATUS_SUCCESS;
1111 t_u16 cmd_action = 0;
1112
1113 ENTER();
1114
1115 if (pioctl_req->action == MLAN_ACT_GET)
1116 cmd_action = HostCmd_ACT_GEN_GET;
1117 else
1118 cmd_action = HostCmd_ACT_GEN_SET;
1119
1120 /* Send request to firmware */
1121 ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_INDEPENDENT_RESET_CFG, cmd_action, 0, (t_void *)pioctl_req,
1122 (t_void *)&misc->param.ind_rst_cfg);
1123
1124 LEAVE();
1125 return ret;
1126 }
1127 #endif
1128