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