1 /** @file wlan_enhanced_tests.c
2  *
3  *  @brief  This file provides WLAN ENHANCED Test API
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 #include <wlan.h>
12 #include <wifi_shell.h>
13 #include <cli_utils.h>
14 #include <string.h>
15 #include <wm_net.h> /* for net_inet_aton */
16 #include <wifi.h>
17 #include <wlan_tests.h>
18 
19 #ifdef WIFI_BT_TX_PWR_LIMITS
20 #include WIFI_BT_TX_PWR_LIMITS
21 #else
22 #error "Region tx power config not defined"
23 #endif
24 
25 /*
26  * NXP Test Framework (MTF) functions
27  */
28 
29 #if UAP_SUPPORT
dump_wlan_uap_get_pmfcfg_usage()30 static void dump_wlan_uap_get_pmfcfg_usage()
31 {
32     (void)PRINTF("Usage:\r\n");
33     (void)PRINTF("wlan-uap-get-pmfcfg \r\n");
34 }
35 
wlan_uap_pmfcfg_get(int argc,char * argv[])36 static void wlan_uap_pmfcfg_get(int argc, char *argv[])
37 {
38     int ret;
39     uint8_t mfpc = 0U;
40     uint8_t mfpr = 0U;
41 
42     if (argc != 1)
43     {
44         dump_wlan_uap_get_pmfcfg_usage();
45         return;
46     }
47 
48     ret = wlan_uap_get_pmfcfg(&mfpc, &mfpr);
49     if (ret == WM_SUCCESS)
50     {
51         (void)PRINTF("Uap Management Frame Protection Capability: %s\r\n", mfpc == 1 ? "Yes" : "No");
52         if (mfpc != 0U)
53             (void)PRINTF("Uap Management Frame Protection: %s\r\n", mfpr == 1 ? "Required" : "Optional");
54     }
55     else
56     {
57         (void)PRINTF("Uap PMF configuration read failed\r\n");
58         dump_wlan_uap_get_pmfcfg_usage();
59     }
60 }
61 #endif /* UAP_SUPPORT */
62 
dump_wlan_get_pmfcfg_usage(void)63 static void dump_wlan_get_pmfcfg_usage(void)
64 {
65     (void)PRINTF("Usage:\r\n");
66     (void)PRINTF("wlan-get-pmfcfg \r\n");
67 }
68 
wlan_pmfcfg_get(int argc,char * argv[])69 static void wlan_pmfcfg_get(int argc, char *argv[])
70 {
71     int ret;
72     uint8_t mfpc, mfpr;
73 
74     if (argc != 1)
75     {
76         dump_wlan_get_pmfcfg_usage();
77         return;
78     }
79 
80     ret = wlan_get_pmfcfg(&mfpc, &mfpr);
81     if (ret == WM_SUCCESS)
82     {
83         (void)PRINTF("Management Frame Protection Capability: %s\r\n", mfpc == 1U ? "Yes" : "No");
84         if (mfpc != 0U)
85         {
86             (void)PRINTF("Management Frame Protection: %s\r\n", mfpr == 1U ? "Required" : "Optional");
87         }
88     }
89     else
90     {
91         (void)PRINTF("PMF configuration read failed\r\n");
92         dump_wlan_get_pmfcfg_usage();
93     }
94 }
95 
dump_wlan_set_ed_mac_mode_usage(void)96 static void dump_wlan_set_ed_mac_mode_usage(void)
97 {
98     (void)PRINTF("Usage:\r\n");
99 #if CONFIG_5GHz_SUPPORT
100     (void)PRINTF("wlan-set-ed-mac-mode <interface> <ed_ctrl_2g> <ed_offset_2g> <ed_ctrl_5g> <ed_offset_5g>\r\n");
101 #else
102     (void)PRINTF("wlan-set-ed-mac-mode <interface> <ed_ctrl_2g> <ed_offset_2g>\r\n");
103 #endif
104     (void)PRINTF("\r\n");
105     (void)PRINTF("\tinterface \r\n");
106     (void)PRINTF("\t    # 0       - for STA\r\n");
107     (void)PRINTF("\t    # 1       - for uAP\r\n");
108     (void)PRINTF("\ted_ctrl_2g \r\n");
109     (void)PRINTF("\t    # 0       - disable EU adaptivity for 2.4GHz band\r\n");
110     (void)PRINTF("\t    # 1       - enable EU adaptivity for 2.4GHz band\r\n");
111     (void)PRINTF("\ted_offset_2g \r\n");
112     (void)PRINTF("\t    # 0       - Default Energy Detect threshold\r\n");
113     (void)PRINTF("\t    # ed_threshold = ed_base - ed_offset_2g\r\n");
114     (void)PRINTF("\t    # e.g., if ed_base default is -62dBm, ed_offset_2g is 0x8, then ed_threshold is -70dBm\r\n");
115 #if CONFIG_5GHz_SUPPORT
116     (void)PRINTF("\ted_ctrl_5g \r\n");
117     (void)PRINTF("\t    # 0       - disable EU adaptivity for 5GHz band\r\n");
118     (void)PRINTF("\t    # 1       - enable EU adaptivity for 5GHz band\r\n");
119     (void)PRINTF("\ted_offset_5g \r\n");
120     (void)PRINTF("\t    # 0       - Default Energy Detect threshold\r\n");
121     (void)PRINTF("\t    # ed_threshold = ed_base - ed_offset_5g\r\n");
122     (void)PRINTF("\t    # e.g., if ed_base default is -62dBm, ed_offset_5g is 0x8, then ed_threshold is -70dBm\r\n");
123 #endif
124 }
125 
wlan_ed_mac_mode_set(int argc,char * argv[])126 static void wlan_ed_mac_mode_set(int argc, char *argv[])
127 {
128     int ret;
129     wlan_ed_mac_ctrl_t wlan_ed_mac_ctrl;
130     t_u8 interface;
131 
132 #if CONFIG_5GHz_SUPPORT
133     if (argc != 6)
134 #else
135     if (argc != 4)
136 #endif
137     {
138         dump_wlan_set_ed_mac_mode_usage();
139         return;
140     }
141 
142     errno     = 0;
143     interface = (t_u8)strtol(argv[1], NULL, 16);
144     if (errno != 0)
145     {
146         (void)PRINTF("Error during strtol errno:%d", errno);
147     }
148     errno                       = 0;
149     wlan_ed_mac_ctrl.ed_ctrl_2g = (t_u16)strtol(argv[2], NULL, 16);
150     if (errno != 0)
151     {
152         (void)PRINTF("Error during strtol errno:%d", errno);
153     }
154     errno                         = 0;
155     wlan_ed_mac_ctrl.ed_offset_2g = (t_s16)strtol(argv[3], NULL, 16);
156     if (errno != 0)
157     {
158         (void)PRINTF("Error during strtol errno:%d", errno);
159     }
160 #if CONFIG_5GHz_SUPPORT
161     errno                       = 0;
162     wlan_ed_mac_ctrl.ed_ctrl_5g = (t_u16)strtol(argv[4], NULL, 16);
163     if (errno != 0)
164     {
165         (void)PRINTF("Error during strtol errno:%d", errno);
166     }
167     errno                         = 0;
168     wlan_ed_mac_ctrl.ed_offset_5g = (t_s16)strtol(argv[5], NULL, 16);
169     if (errno != 0)
170     {
171         (void)PRINTF("Error during strtol errno:%d", errno);
172     }
173 #endif
174 
175     if (wlan_ed_mac_ctrl.ed_ctrl_2g != 0U && wlan_ed_mac_ctrl.ed_ctrl_2g != 1U)
176     {
177         dump_wlan_set_ed_mac_mode_usage();
178         return;
179     }
180 #if CONFIG_5GHz_SUPPORT
181     if (wlan_ed_mac_ctrl.ed_ctrl_5g != 0U && wlan_ed_mac_ctrl.ed_ctrl_5g != 1U)
182     {
183         dump_wlan_set_ed_mac_mode_usage();
184         return;
185     }
186 #endif
187 
188     if (interface == MLAN_BSS_TYPE_STA)
189     {
190         ret = wlan_set_ed_mac_mode(wlan_ed_mac_ctrl);
191     }
192     else if (interface == MLAN_BSS_TYPE_UAP)
193     {
194         ret = wlan_set_uap_ed_mac_mode(wlan_ed_mac_ctrl);
195     }
196     else
197     {
198         ret = -WM_FAIL;
199         (void)PRINTF("Error invalid interface\r\n");
200     }
201 
202     if (ret == WM_SUCCESS)
203     {
204         (void)PRINTF("ED MAC MODE settings configuration successful\r\n");
205     }
206     else
207     {
208         (void)PRINTF("ED MAC MODE settings configuration failed\r\n");
209         dump_wlan_set_ed_mac_mode_usage();
210     }
211 }
212 
dump_wlan_get_ed_mac_mode_usage(void)213 static void dump_wlan_get_ed_mac_mode_usage(void)
214 {
215     (void)PRINTF("Usage:\r\n");
216     (void)PRINTF("wlan-get-ed-mac-mode <interface>\r\n");
217     (void)PRINTF("\r\n");
218     (void)PRINTF("\tinterface \r\n");
219     (void)PRINTF("\t    # 0       - for STA\r\n");
220     (void)PRINTF("\t    # 1       - for uAP\r\n");
221 }
222 
wlan_ed_mac_mode_get(int argc,char * argv[])223 static void wlan_ed_mac_mode_get(int argc, char *argv[])
224 {
225     int ret;
226     wlan_ed_mac_ctrl_t wlan_ed_mac_ctrl;
227     int interface;
228 
229     if (argc != 2)
230     {
231         dump_wlan_get_ed_mac_mode_usage();
232         return;
233     }
234     errno     = 0;
235     interface = (t_u8)strtol(argv[1], NULL, 16);
236     if (errno != 0)
237     {
238         (void)PRINTF("Error during strtol errno:%d", errno);
239     }
240 
241     if (interface == MLAN_BSS_TYPE_STA)
242     {
243         ret = wlan_get_ed_mac_mode(&wlan_ed_mac_ctrl);
244     }
245     else if (interface == MLAN_BSS_TYPE_UAP)
246     {
247         ret = wlan_get_uap_ed_mac_mode(&wlan_ed_mac_ctrl);
248     }
249     else
250     {
251         ret = -WM_FAIL;
252         (void)PRINTF("Error invalid interface\r\n");
253     }
254 
255     if (ret == WM_SUCCESS)
256     {
257         (void)PRINTF("EU adaptivity for 2.4GHz band : %s\r\n",
258                      wlan_ed_mac_ctrl.ed_ctrl_2g == 1U ? "Enabled" : "Disabled");
259         if (wlan_ed_mac_ctrl.ed_ctrl_2g != 0U)
260         {
261             (void)PRINTF("Energy Detect threshold offset : 0X%x\r\n", wlan_ed_mac_ctrl.ed_offset_2g);
262         }
263 #if CONFIG_5GHz_SUPPORT
264         (void)PRINTF("EU adaptivity for 5GHz band : %s\r\n",
265                      wlan_ed_mac_ctrl.ed_ctrl_5g == 1U ? "Enabled" : "Disabled");
266         if (wlan_ed_mac_ctrl.ed_ctrl_5g != 0U)
267         {
268             (void)PRINTF("Energy Detect threshold offset : 0X%x\r\n", wlan_ed_mac_ctrl.ed_offset_5g);
269         }
270 #endif
271     }
272     else
273     {
274         (void)PRINTF("ED MAC MODE read failed\r\n");
275         dump_wlan_get_ed_mac_mode_usage();
276     }
277 }
278 #if 0
279 static int wlan_memrdwr_getset(int argc, char *argv[])
280 {
281     uint8_t action;
282     uint32_t value;
283     int ret;
284 
285     if (argc != 3 && argc != 4)
286     {
287         return -WM_FAIL;
288     }
289 
290     if (argc == 3)
291     {
292         action = ACTION_GET;
293         value  = 0;
294     }
295     else
296     {
297         action = ACTION_SET;
298         value  = a2hex_or_atoi(argv[3]);
299     }
300 
301     ret = wifi_mem_access(action, a2hex_or_atoi(argv[2]), &value);
302 
303     if (ret == WM_SUCCESS)
304     {
305         if (action == ACTION_GET)
306         {
307             (void)PRINTF("At Memory 0x%x: 0x%x\r\n", a2hex_or_atoi(argv[2]), value);
308         }
309         else
310         {
311             (void)PRINTF("Set the Memory successfully\r\n");
312         }
313     }
314     else
315     {
316         wlcm_e("Read/write Mem failed");
317         return -WM_FAIL;
318     }
319     return WM_SUCCESS;
320 }
321 #endif
322 
323 static char *bw[]           = {"20 MHz", "40 MHz", "80 MHz", "160 MHz"};
324 static char *rate_format[4] = {"LG", "HT", "VHT", "HE"};
325 static char *lg_rate[]      = {"1 Mbps",  "2 Mbps",  "5.5 Mbps", "11 Mbps", "6 Mbps",  "9 Mbps",
326                           "12 Mbps", "18 Mbps", "24 Mbps",  "36 Mbps", "48 Mbps", "54 Mbps"};
327 
print_ds_rate(wlan_ds_rate ds_rate)328 static void print_ds_rate(wlan_ds_rate ds_rate)
329 {
330     if (ds_rate.sub_command == WIFI_DS_RATE_CFG)
331     {
332         (void)PRINTF("Tx Rate Configuration: \r\n");
333         /* format */
334         if (ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_AUTO)
335         {
336             (void)PRINTF("    Type:       0xFF (Auto)\r\n");
337         }
338         else if ((unsigned int)(ds_rate.param.rate_cfg.rate_format) <= 3U)
339         {
340             (void)PRINTF("    Type:         %d (%s)\r\n", ds_rate.param.rate_cfg.rate_format,
341                          rate_format[ds_rate.param.rate_cfg.rate_format]);
342             if (ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_LG)
343             {
344                 (void)PRINTF("    Rate Index: %d (%s)\r\n", ds_rate.param.rate_cfg.rate_index,
345                              lg_rate[ds_rate.param.rate_cfg.rate_index]);
346             }
347             else if (ds_rate.param.rate_cfg.rate_format >= MLAN_RATE_FORMAT_HT)
348             {
349                 (void)PRINTF("    MCS Index:  %d\r\n", (int)ds_rate.param.rate_cfg.rate_index);
350             }
351             else
352             { /* Do Nothing */
353             }
354 #if CONFIG_11AC
355             if ((ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_VHT)
356 #if CONFIG_11AX
357                 || (ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_HE)
358 #endif
359             )
360             {
361                 (void)PRINTF("    NSS:        %d\r\n", (int)ds_rate.param.rate_cfg.nss);
362             }
363 #endif
364 #if CONFIG_11AX
365             if (ds_rate.param.rate_cfg.rate_setting == 0xffff)
366                 (void)PRINTF("    Rate setting: Preamble type/BW/GI/STBC/.. : auto \r\n");
367             else
368             {
369                 (void)PRINTF("    HE Rate setting:   0x%x\r\n", ds_rate.param.rate_cfg.rate_setting);
370                 (void)PRINTF("        Preamble type: %x\r\n", (ds_rate.param.rate_cfg.rate_setting & 0x0003));
371                 (void)PRINTF("        BW:            %x\r\n", (ds_rate.param.rate_cfg.rate_setting & 0x001C) >> 2);
372                 (void)PRINTF("        LTF + GI size: %x\r\n", (ds_rate.param.rate_cfg.rate_setting & 0x0060) >> 5);
373                 (void)PRINTF("        STBC:          %x\r\n", (ds_rate.param.rate_cfg.rate_setting & 0x0080) >> 7);
374                 (void)PRINTF("        DCM:           %x\r\n", (ds_rate.param.rate_cfg.rate_setting & 0x0100) >> 8);
375                 (void)PRINTF("        Coding:        %x\r\n", (ds_rate.param.rate_cfg.rate_setting & 0x0200) >> 9);
376                 (void)PRINTF("        maxPE:         %x\r\n", (ds_rate.param.rate_cfg.rate_setting & 0x3000) >> 12);
377             }
378 #endif
379         }
380         else
381         {
382             (void)PRINTF("    Unknown rate format.\r\n");
383         }
384     }
385     else if (ds_rate.sub_command == WIFI_DS_GET_DATA_RATE)
386     {
387         wifi_data_rate_t *datarate = (wifi_data_rate_t *)&(ds_rate.param.data_rate);
388         (void)PRINTF("Data Rate:\r\n");
389 #ifdef SD8801
390         (void)PRINTF("  TX: \r\n");
391         if (datarate->tx_data_rate < 12)
392         {
393             (void)PRINTF("    Type: %s\r\n", rate_format[0]);
394             /* LG */
395             (void)PRINTF("    Rate: %s\r\n", lg_rate[datarate->tx_data_rate]);
396         }
397         else
398         {
399             /* HT*/
400             (void)PRINTF("    Type: %s\r\n", rate_format[1]);
401             if (datarate->tx_bw <= 2)
402                 (void)PRINTF("    BW:   %s\r\n", bw[datarate->tx_bw]);
403             if (datarate->tx_gi == 0)
404                 (void)PRINTF("    GI:   Long\r\n");
405             else
406                 (void)PRINTF("    GI:   Short\r\n");
407             (void)PRINTF("    MCS:  MCS %d\r\n", (int)(datarate->tx_data_rate - 12));
408         }
409 
410         (void)PRINTF("  RX: \n");
411         if (datarate->rx_data_rate < 12)
412         {
413             (void)PRINTF("    Type: %s\r\n", rate_format[0]);
414             /* LG */
415             (void)PRINTF("    Rate: %s\r\n", lg_rate[datarate->rx_data_rate]);
416         }
417         else
418         {
419             /* HT*/
420             (void)PRINTF("    Type: %s\r\n", rate_format[1]);
421             if (datarate->rx_bw <= 2)
422             {
423                 (void)PRINTF("    BW:   %s\r\n", bw[datarate->rx_bw]);
424             }
425             if (datarate->rx_gi == 0)
426             {
427                 (void)PRINTF("    GI:   Long\r\n");
428             }
429             else
430             {
431                 (void)PRINTF("    GI:   Short\r\n");
432             }
433             (void)PRINTF("    MCS:  MCS %d\r\n", (int)(datarate->rx_data_rate - 12));
434         }
435 #else
436         (void)PRINTF("  TX: \r\n");
437         if ((unsigned int)(datarate->tx_rate_format) <= 3U)
438         {
439             (void)PRINTF("    Type: %s\r\n", rate_format[datarate->tx_rate_format]);
440             if ((datarate->tx_rate_format == MLAN_RATE_FORMAT_LG) && datarate->tx_data_rate <= 11U)
441             {
442                 /* LG */
443                 (void)PRINTF("    Rate: %s\r\n", lg_rate[datarate->tx_data_rate]);
444             }
445             else
446             {
447                 /* HT, VHT, HE*/
448                 if (datarate->tx_bw <= 3)
449                     (void)PRINTF("    BW:   %s\r\n", bw[datarate->tx_bw]);
450                 if (datarate->tx_rate_format < 3)
451                 {
452                     if (datarate->tx_gi == 0)
453                         (void)PRINTF("    GI:   Long\r\n");
454                     else
455                         (void)PRINTF("    GI:   Short\r\n");
456                 }
457 #if CONFIG_11AX
458                 else if (datarate->tx_rate_format == 3)
459                 {
460                     switch (datarate->tx_gi)
461                     {
462                         case 0:
463                             (void)PRINTF("    GI:   1xHELTF + GI 0.8us\r\n");
464                             break;
465                         case 1:
466                             (void)PRINTF("    GI:   2xHELTF + GI 0.8us\r\n");
467                             break;
468                         case 2:
469                             (void)PRINTF("    GI:   2xHELTF + GI 1.6us\r\n");
470                             break;
471                         case 3:
472                             (void)PRINTF(
473                                 "    GI:   4xHELTF + GI 0.8us DCM=0 and STBC=0 or\r\n"
474                                 "          4xHELTF + GI 3.2us Otherwise  \r\n");
475                             break;
476                     }
477                 }
478 #endif
479 #if (CONFIG_11AC) || (CONFIG_11AX)
480                 if (datarate->tx_rate_format >= 2)
481                     (void)PRINTF("    NSS:  %d\r\n", datarate->tx_nss + 1);
482 #endif
483                 if (datarate->tx_mcs_index != 0xFFU)
484                 {
485                     (void)PRINTF("    MCS:  MCS %d\r\n", (int)datarate->tx_mcs_index);
486                 }
487                 else
488                 {
489                     (void)PRINTF("    MCS:  Auto\r\n");
490                 }
491                 (void)PRINTF("    Rate: %.2f Mbps\r\n", (double)datarate->tx_data_rate / 2);
492             }
493         }
494 
495         (void)PRINTF("  RX: \r\n");
496         if ((unsigned int)(datarate->rx_rate_format) <= 3U)
497         {
498             (void)PRINTF("    Type: %s\r\n", rate_format[datarate->rx_rate_format]);
499             if ((datarate->rx_rate_format == MLAN_RATE_FORMAT_LG) && datarate->rx_data_rate <= 11U)
500             {
501                 /* LG */
502                 (void)PRINTF("    Rate: %s\r\n", lg_rate[datarate->rx_data_rate]);
503             }
504             else
505             {
506                 /* HT, VHT, HE*/
507                 if (datarate->rx_bw <= 3)
508                     (void)PRINTF("    BW:   %s\r\n", bw[datarate->rx_bw]);
509                 if (datarate->rx_rate_format < 3)
510                 {
511                     if (datarate->rx_gi == 0)
512                         (void)PRINTF("    GI:   Long\r\n");
513                     else
514                         (void)PRINTF("    GI:   Short\r\n");
515                 }
516 #if CONFIG_11AX
517                 else if (datarate->rx_rate_format == 3)
518                 {
519                     switch (datarate->rx_gi)
520                     {
521                         case 0:
522                             (void)PRINTF("    GI:   1xHELTF + GI 0.8us\r\n");
523                             break;
524                         case 1:
525                             (void)PRINTF("    GI:   2xHELTF + GI 0.8us\r\n");
526                             break;
527                         case 2:
528                             (void)PRINTF("    GI:   2xHELTF + GI 1.6us\r\n");
529                             break;
530                         case 3:
531                             (void)PRINTF(
532                                 "    GI:   4xHELTF + GI 0.8us DCM=0 and STBC=0 or\r\n"
533                                 "          4xHELTF + GI 3.2us Otherwise  \r\n");
534                             break;
535                     }
536                 }
537 #endif
538 #if (CONFIG_11AC) || (CONFIG_11AX)
539                 if (datarate->rx_rate_format >= 2)
540                     (void)PRINTF("    NSS:  %d\r\n", datarate->rx_nss + 1);
541 #endif
542                 if (datarate->rx_mcs_index != 0xFFU)
543                 {
544                     (void)PRINTF("    MCS:  MCS %d\r\n", (int)datarate->rx_mcs_index);
545                 }
546                 else
547                 {
548                     (void)PRINTF("    MCS:  Auto\n");
549                 }
550                 (void)PRINTF("    Rate: %.2f Mbps\r\n", (double)datarate->rx_data_rate / 2);
551             }
552         }
553 #endif
554     }
555     else
556     { /* Do Nothing */
557     }
558 }
559 
dump_wlan_set_txratecfg_usage(void)560 static void dump_wlan_set_txratecfg_usage(void)
561 {
562     (void)PRINTF("Usage:\r\n");
563     (void)PRINTF("wlan-set-txratecfg <sta/uap> <format> <index> ");
564 #if (CONFIG_11AC) || (CONFIG_11AX)
565     (void)PRINTF("<nss> ");
566     (void)PRINTF("<rate_setting> ");
567 #endif
568 #if CONFIG_AUTO_NULL_TX
569     (void)PRINTF("<autoTx_set>\r\n");
570 #endif
571     (void)PRINTF("\r\n");
572 
573     (void)PRINTF("\tWhere\r\n");
574     (void)PRINTF("\t<format> - This parameter specifies the data rate format used in this command\r\n");
575     (void)PRINTF("\t        0:    LG\r\n");
576     (void)PRINTF("\t        1:    HT\r\n");
577 #if CONFIG_11AC
578     (void)PRINTF("\t        2:    VHT\r\n");
579 #endif
580 #if CONFIG_11AX
581     (void)PRINTF("\t        3:    HE\r\n");
582 #endif
583     (void)PRINTF("\t        0xff: Auto\r\n");
584     (void)PRINTF("\t<index> - This parameter specifies the rate or MCS index\r\n");
585     (void)PRINTF("\tIf <format> is 0 (LG),\r\n");
586     (void)PRINTF("\t        0       1 Mbps\r\n");
587     (void)PRINTF("\t        1       2 Mbps\r\n");
588     (void)PRINTF("\t        2       5.5 Mbps\r\n");
589     (void)PRINTF("\t        3       11 Mbps\r\n");
590     (void)PRINTF("\t        4       6 Mbps\r\n");
591     (void)PRINTF("\t        5       9 Mbps\r\n");
592     (void)PRINTF("\t        6       12 Mbps\r\n");
593     (void)PRINTF("\t        7       18 Mbps\r\n");
594     (void)PRINTF("\t        8       24 Mbps\r\n");
595     (void)PRINTF("\t        9       36 Mbps\r\n");
596 #ifndef RW610
597     (void)PRINTF("\t        10      48 Mbps\r\n");
598     (void)PRINTF("\t        11      54 Mbps\r\n");
599 #endif
600     (void)PRINTF("\tIf <format> is 1 (HT),\r\n");
601     (void)PRINTF("\t        0       MCS0\r\n");
602     (void)PRINTF("\t        1       MCS1\r\n");
603     (void)PRINTF("\t        2       MCS2\r\n");
604     (void)PRINTF("\t        3       MCS3\r\n");
605     (void)PRINTF("\t        4       MCS4\r\n");
606     (void)PRINTF("\t        5       MCS5\r\n");
607     (void)PRINTF("\t        6       MCS6\r\n");
608     (void)PRINTF("\t        7       MCS7\r\n");
609 #if CONFIG_11AC
610     (void)PRINTF("\tIf <format> is 2 (VHT),\r\n");
611     (void)PRINTF("\t        0       MCS0\r\n");
612     (void)PRINTF("\t        1       MCS1\r\n");
613     (void)PRINTF("\t        2       MCS2\r\n");
614     (void)PRINTF("\t        3       MCS3\r\n");
615     (void)PRINTF("\t        4       MCS4\r\n");
616     (void)PRINTF("\t        5       MCS5\r\n");
617     (void)PRINTF("\t        6       MCS6\r\n");
618     (void)PRINTF("\t        7       MCS7\r\n");
619     (void)PRINTF("\t        8       MCS8\r\n");
620 #ifndef RW610
621     (void)PRINTF("\t        9       MCS9\r\n");
622 #endif
623 #endif
624 #if CONFIG_11AX
625     (void)PRINTF("\tIf <format> is 3 (HE),\r\n");
626     (void)PRINTF("\t        0       MCS0\r\n");
627     (void)PRINTF("\t        1       MCS1\r\n");
628     (void)PRINTF("\t        2       MCS2\r\n");
629     (void)PRINTF("\t        3       MCS3\r\n");
630     (void)PRINTF("\t        4       MCS4\r\n");
631     (void)PRINTF("\t        5       MCS5\r\n");
632     (void)PRINTF("\t        6       MCS6\r\n");
633     (void)PRINTF("\t        7       MCS7\r\n");
634     (void)PRINTF("\t        8       MCS8\r\n");
635     (void)PRINTF("\t        9       MCS9\r\n");
636 #ifndef RW610
637     (void)PRINTF("\t        10      MCS10\r\n");
638     (void)PRINTF("\t        11      MCS11\r\n");
639 #endif
640 #endif
641 #if (CONFIG_11AX) || (CONFIG_11AC)
642     (void)PRINTF("\t<nss> - This parameter specifies the NSS. It is valid only for VHT and HE\r\n");
643     (void)PRINTF("\tIf <format> is 2 (VHT) or 3 (HE),\r\n");
644     (void)PRINTF("\t        1       NSS1\r\n");
645 #ifndef RW610
646     (void)PRINTF("\t        2       NSS2\r\n");
647 #endif
648 #endif
649     (void)PRINTF("\t<rate_setting> - This parameter can only specifies the GI types now.\r\n");
650     (void)PRINTF("\tIf <format> is 1 (HT),\r\n");
651     (void)PRINTF("\t        0x0000  Long GI\r\n");
652     (void)PRINTF("\t        0x0020  Short GI\r\n");
653 #if CONFIG_11AC
654     (void)PRINTF("\tIf <format> is 2 (VHT),\r\n");
655     (void)PRINTF("\t        0x0000  Long GI\r\n");
656     (void)PRINTF("\t        0x0020  Short GI\r\n");
657     (void)PRINTF("\t        0x0060  Short GI and Nsym mod 10=9\r\n");
658 #endif
659 #if CONFIG_11AX
660     (void)PRINTF("\tIf <format> is 3 (HE),\r\n");
661     (void)PRINTF("\t        0x0000  1xHELTF + GI0.8us\r\n");
662     (void)PRINTF("\t        0x0020  2xHELTF + GI0.8us\r\n");
663     (void)PRINTF("\t        0x0040  2xHELTF + GI1.6us\r\n");
664     (void)PRINTF("\t        0x0060  4xHELTF + GI0.8us if DCM = 1 and STBC = 1\r\n");
665     (void)PRINTF("\t                4xHELTF + GI3.2us, otherwise\r\n");
666 #endif
667 #if CONFIG_AUTO_NULL_TX
668     (void)PRINTF(
669         "\t<autoTx_set> - This parameter specifies whether only fix auto tx data rate, this parameter is optional "
670         "\r\n");
671     (void)PRINTF("\t        0:    not fix auto tx data rate\r\n");
672     (void)PRINTF("\t        1:    only fix auto tx data rate\r\n");
673 #endif
674 }
675 
test_wlan_set_txratecfg(int argc,char ** argv)676 static void test_wlan_set_txratecfg(int argc, char **argv)
677 {
678     mlan_bss_type bss_type = (mlan_bss_type)0;
679     wlan_ds_rate ds_rate;
680 #if CONFIG_11AX
681     wlan_txrate_setting *rate_setting = NULL;
682 #endif
683     int rv = WM_SUCCESS;
684 
685     if (argc < 3 ||
686 #if (CONFIG_11AC) || (CONFIG_11AX)
687         argc > 7)
688     {
689 #else
690         argc > 5)
691     {
692 #endif
693         (void)PRINTF("Invalid arguments\r\n");
694         goto done;
695     }
696 
697     if (string_equal("sta", argv[1]))
698         bss_type = MLAN_BSS_TYPE_STA;
699     else if (string_equal("uap", argv[1]))
700         bss_type = MLAN_BSS_TYPE_UAP;
701     else
702     {
703         (void)PRINTF("Invalid bss type selection\r\n");
704         goto done;
705     }
706 
707     (void)memset(&ds_rate, 0, sizeof(wlan_ds_rate));
708 #if CONFIG_AUTO_NULL_TX
709     ds_rate.auto_null_fixrate_enable = 0xff;
710 #endif
711 
712     ds_rate.sub_command = WIFI_DS_RATE_CFG;
713 
714     errno                              = 0;
715     ds_rate.param.rate_cfg.rate_format = (mlan_rate_format)(strtol(argv[2], NULL, 0));
716     if (errno != 0)
717     {
718         (void)PRINTF("Error during strtoul errno:%d", errno);
719     }
720     errno                             = 0;
721     ds_rate.param.rate_cfg.rate_index = (t_u32)strtol(argv[3], NULL, 0);
722     if (errno != 0)
723     {
724         (void)PRINTF("Error during strtoul errno:%d", errno);
725     }
726 #if (CONFIG_11AC) || (CONFIG_11AX)
727     if (argc >= 5)
728     {
729         errno                      = 0;
730         ds_rate.param.rate_cfg.nss = strtol(argv[4], NULL, 0);
731         if (errno != 0)
732         {
733             (void)PRINTF("Error during strtoul errno:%d", errno);
734         }
735         else
736         {
737             /*Do Nothing*/
738         }
739     }
740 
741     if (argc >= 6)
742     {
743         errno                               = 0;
744         ds_rate.param.rate_cfg.rate_setting = strtol(argv[5], NULL, 0);
745         if (errno != 0)
746             (void)PRINTF("Error during strtoul errno:%d", errno);
747     }
748     else
749     {
750         errno                               = 0;
751         ds_rate.param.rate_cfg.rate_setting = 0xffff;
752         if (errno != 0)
753             (void)PRINTF("Error during strtoul errno:%d", errno);
754     }
755 #endif
756 #if CONFIG_AUTO_NULL_TX
757 #if (CONFIG_11AC) || (CONFIG_11AX)
758     if (argc == 7)
759 #else
760     if (argc == 5)
761 #endif
762     {
763         errno                            = 0;
764         ds_rate.auto_null_fixrate_enable = strtol(argv[argc - 1], NULL, 0);
765         ;
766         if (ds_rate.auto_null_fixrate_enable > 1)
767         {
768             ds_rate.auto_null_fixrate_enable = 0xff;
769             (void)PRINTF("Invalid autoTx_only selection\r\n");
770             goto done;
771         }
772     }
773 #endif
774 
775     if ((ds_rate.param.rate_cfg.rate_format != MLAN_RATE_FORMAT_AUTO)
776 #if (CONFIG_11AX)
777         && (ds_rate.param.rate_cfg.rate_format > MLAN_RATE_FORMAT_HE)
778 #elif (CONFIG_11AC)
779         && (ds_rate.param.rate_cfg.rate_format > MLAN_RATE_FORMAT_VHT)
780 #else
781     && (ds_rate.param.rate_cfg.rate_format > MLAN_RATE_FORMAT_HT)
782 #endif
783     )
784     {
785         (void)PRINTF("Invalid format selection\r\n");
786         goto done;
787     }
788 
789     if (ds_rate.param.rate_cfg.rate_format != MLAN_RATE_FORMAT_AUTO)
790     {
791         if (((ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_LG) &&
792              (ds_rate.param.rate_cfg.rate_index > MLAN_RATE_INDEX_OFDM7))
793 #if CONFIG_11N
794             || ((ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_HT) &&
795                 (ds_rate.param.rate_cfg.rate_index != 32U) &&
796 #ifdef STREAM_2X2
797                 (ds_rate.param.rate_cfg.rate_index > 15U)
798 #else
799                 (ds_rate.param.rate_cfg.rate_index > 7U)
800 #endif
801                     )
802 #endif /* CONFIG_11N */
803 #if CONFIG_11AC
804             || ((ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_VHT) &&
805 #ifndef RW610
806                 (ds_rate.param.rate_cfg.rate_index > MLAN_RATE_INDEX_MCS9))
807 #else
808                 (ds_rate.param.rate_cfg.rate_index > MLAN_RATE_INDEX_MCS8))
809 #endif
810 #endif
811 #if CONFIG_11AX
812             || ((ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_HE) &&
813 #ifndef RW610
814                 (ds_rate.param.rate_cfg.rate_index > MLAN_RATE_INDEX_MCS11))
815 #else
816                 (ds_rate.param.rate_cfg.rate_index > MLAN_RATE_INDEX_MCS9))
817 #endif
818 #endif
819         )
820         {
821             (void)PRINTF("Invalid index selection\r\n");
822             goto done;
823         }
824 #if (CONFIG_11AC) || (CONFIG_11AX)
825 #ifndef RW610
826         /* NSS is supported up to 2 */
827         if ((ds_rate.param.rate_cfg.nss <= 0) || (ds_rate.param.rate_cfg.nss >= 3))
828 #else
829         /* NSS is supported up to 1 */
830         if ((ds_rate.param.rate_cfg.nss <= 0) || (ds_rate.param.rate_cfg.nss >= 2))
831 #endif
832         {
833             (void)PRINTF("Invalid nss selection\r\n");
834             goto done;
835         }
836 #endif
837 
838         if (argc >= 6)
839         {
840 #if CONFIG_11AX
841 /* HE Preamble type */
842 // #define HE_SU_PREAMBLE 0
843 #define HE_ER_PREAMBLE 1
844 
845 /* HE ER SU Type */
846 #define HE_ER_SU_BANDWIDTH_TONE242 0
847 #define HE_ER_SU_BANDWIDTH_TONE106 1
848 
849             rate_setting = (wlan_txrate_setting *)&ds_rate.param.rate_cfg.rate_setting;
850 
851 #ifdef RW610
852             if(ds_rate.param.rate_cfg.rate_setting != 0xffff)
853             {
854                 if(rate_setting->stbc != 0)
855                 {
856                     (void)PRINTF("Invalid STBC setting\r\n");
857                     (void)PRINTF("This chip does not support STBC\r\n");
858                     goto done;
859                 }
860                 if(rate_setting->adv_coding != 0)
861                 {
862                     (void)PRINTF("Invalid coding setting\r\n");
863                     (void)PRINTF("This chip does not support LDPC\r\n");
864                     goto done;
865                 }
866                 if(ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_HE && rate_setting->preamble == HE_ER_PREAMBLE)
867                 {
868                     if(rate_setting->bandwidth > HE_ER_SU_BANDWIDTH_TONE106)
869                     {
870                         (void)PRINTF("Invalid BW setting for this extended rate\r\n");
871                         (void)PRINTF("This is 20MHz only chip\r\n");
872                         goto done;
873                     }
874                 }
875                 else
876                 {
877                     if(rate_setting->bandwidth != 0)
878                     {
879                         (void)PRINTF("Invalid BW setting\r\n");
880                         (void)PRINTF("This is 20MHz only chip\r\n");
881                         goto done;
882                     }
883                 }
884             }
885 #endif
886             if (ds_rate.param.rate_cfg.rate_format == MLAN_RATE_FORMAT_HE)
887             {
888                 if (rate_setting->preamble == HE_ER_PREAMBLE)
889                 {
890                     if (rate_setting->bandwidth == HE_ER_SU_BANDWIDTH_TONE242)
891                     {
892                         if ((ds_rate.param.rate_cfg.rate_index > MLAN_RATE_INDEX_MCS2) ||
893                             (ds_rate.param.rate_cfg.nss > MLAN_RATE_NSS1))
894                         {
895                             (void)PRINTF("Invalid rate and MCS or NSS configuration for 242 tone\r\n");
896                             goto done;
897                         }
898                     }
899                     else if (rate_setting->bandwidth == HE_ER_SU_BANDWIDTH_TONE106)
900                     {
901                         if ((ds_rate.param.rate_cfg.rate_index != MLAN_RATE_INDEX_MCS0) ||
902                             (ds_rate.param.rate_cfg.nss != MLAN_RATE_NSS1))
903                         {
904                             (void)PRINTF("Invalid rate and MCS or NSS configuration for 106 tone\r\n");
905                             goto done;
906                         }
907                     }
908                     else
909                     {
910                         (void)PRINTF("Invalid Bandwidth for HE ER Preamble\r\n");
911                         goto done;
912                     }
913                 }
914                 if ((rate_setting->dcm) && (rate_setting->stbc == 0))
915                 {
916                     if ((ds_rate.param.rate_cfg.rate_index == MLAN_RATE_INDEX_MCS2) ||
917                         (ds_rate.param.rate_cfg.rate_index > MLAN_RATE_INDEX_MCS4))
918                     {
919                         (void)PRINTF("Invalid MCS configuration if DCM is supported\r\n");
920                         goto done;
921                     }
922                 }
923             }
924 #endif
925         }
926     }
927 
928     rv = wlan_set_txratecfg(ds_rate, bss_type);
929     if (rv != WM_SUCCESS)
930     {
931         (void)PRINTF("Unable to set txratecfg\r\n");
932         goto done;
933     }
934     (void)PRINTF("Configured txratecfg as below:\r\n");
935     print_ds_rate(ds_rate);
936     return;
937 
938 done:
939     dump_wlan_set_txratecfg_usage();
940 }
941 
942 static void test_wlan_get_txratecfg(int argc, char **argv)
943 {
944     mlan_bss_type bss_type = (mlan_bss_type)0;
945     wlan_ds_rate ds_rate;
946 
947     if (argc != 2)
948     {
949         (void)PRINTF("Invalid arguments\r\n");
950         (void)PRINTF("Usage: wlan-get-txratecfg <sta/uap>\r\n");
951         return;
952     }
953 
954     if (string_equal("sta", argv[1]))
955         bss_type = MLAN_BSS_TYPE_STA;
956     else if (string_equal("uap", argv[1]))
957         bss_type = MLAN_BSS_TYPE_UAP;
958     else
959     {
960         (void)PRINTF("Invalid bss type selection\r\n");
961         return;
962     }
963 
964     (void)memset(&ds_rate, 0, sizeof(wlan_ds_rate));
965 
966     ds_rate.sub_command = WIFI_DS_RATE_CFG;
967 
968     int rv = wlan_get_txratecfg(&ds_rate, bss_type);
969     if (rv != WM_SUCCESS)
970     {
971         (void)PRINTF("Unable to get tx rate cfg\r\n");
972         return;
973     }
974 
975     print_ds_rate(ds_rate);
976 }
977 
978 static void test_wlan_get_data_rate(int argc, char **argv)
979 {
980     mlan_bss_type bss_type = (mlan_bss_type)0;
981     wlan_ds_rate ds_rate;
982 
983     if (argc != 2)
984     {
985         (void)PRINTF("Invalid arguments\r\n");
986         (void)PRINTF("Usage: wlan-get-data-rate <sta/uap>\r\n");
987         return;
988     }
989 
990     if (string_equal("sta", argv[1]))
991         bss_type = MLAN_BSS_TYPE_STA;
992     else if (string_equal("uap", argv[1]))
993         bss_type = MLAN_BSS_TYPE_UAP;
994     else
995     {
996         (void)PRINTF("Invalid bss type selection\r\n");
997         return;
998     }
999 
1000     (void)memset(&ds_rate, 0, sizeof(wlan_ds_rate));
1001 
1002     ds_rate.sub_command = WIFI_DS_GET_DATA_RATE;
1003 
1004     int rv = wlan_get_data_rate(&ds_rate, bss_type);
1005     if (rv != WM_SUCCESS)
1006     {
1007         (void)PRINTF("Unable to get tx rate cfg\r\n");
1008         return;
1009     }
1010 
1011     print_ds_rate(ds_rate);
1012 }
1013 
1014 void print_txpwrlimit(wlan_txpwrlimit_t *txpwrlimit)
1015 {
1016     int i, j;
1017 
1018     (void)PRINTF("--------------------------------------------------------------------------------\r\n");
1019     (void)PRINTF("Get txpwrlimit: sub_band=%x \r\n", txpwrlimit->subband);
1020     for (i = 0; i < txpwrlimit->num_chans; i++)
1021     {
1022         (void)PRINTF("StartFreq: %d\r\n", txpwrlimit->txpwrlimit_config[i].chan_desc.start_freq);
1023         (void)PRINTF("ChanWidth: %d\r\n", txpwrlimit->txpwrlimit_config[i].chan_desc.chan_width);
1024         (void)PRINTF("ChanNum:   %d\r\n", txpwrlimit->txpwrlimit_config[i].chan_desc.chan_num);
1025         (void)PRINTF("Pwr:");
1026         for (j = 0; j < txpwrlimit->txpwrlimit_config[i].num_mod_grps; j++)
1027         {
1028             if (j == (txpwrlimit->txpwrlimit_config[i].num_mod_grps - 1))
1029                 (void)PRINTF("%d,%d", txpwrlimit->txpwrlimit_config[i].txpwrlimit_entry[j].mod_group,
1030                              txpwrlimit->txpwrlimit_config[i].txpwrlimit_entry[j].tx_power);
1031             else
1032                 (void)PRINTF("%d,%d,", txpwrlimit->txpwrlimit_config[i].txpwrlimit_entry[j].mod_group,
1033                              txpwrlimit->txpwrlimit_config[i].txpwrlimit_entry[j].tx_power);
1034         }
1035         (void)PRINTF("\r\n");
1036     }
1037     (void)PRINTF("\r\n");
1038 }
1039 
1040 static void print_chanlist(wlan_chanlist_t chanlist)
1041 {
1042     unsigned char i;
1043 
1044     (void)PRINTF("--------------------------------------------------------------------------------\r\n");
1045     (void)PRINTF("Number of channels configured: %d\r\n", chanlist.num_chans);
1046     (void)PRINTF("\r\n");
1047     for (i = 0; i < chanlist.num_chans; i++)
1048     {
1049         (void)PRINTF("ChanNum: %d\t", chanlist.chan_info[i].chan_num);
1050         (void)PRINTF("ChanFreq: %d\t", chanlist.chan_info[i].chan_freq);
1051         (void)PRINTF("%s", chanlist.chan_info[i].passive_scan_or_radar_detect ? "Passive" : "Active");
1052         (void)PRINTF("\r\n");
1053     }
1054 }
1055 
1056 static void dump_wlan_get_txpwrlimit_usage(void)
1057 {
1058     (void)PRINTF("Usage:\r\n");
1059     (void)PRINTF("wlan-get-txpwrlimit <subband> \r\n");
1060     (void)PRINTF("\r\n");
1061     (void)PRINTF("\t Where subband is: \r\n");
1062     (void)PRINTF("\t       0x00 2G subband  (2.4G: channel 1-14)\r\n");
1063 #if CONFIG_5GHz_SUPPORT
1064     (void)PRINTF("\t       0x10 5G subband0 (5G: channel 36,40,44,48,\r\n");
1065     (void)PRINTF("\t                                     52,56,60,64)\r\n");
1066     (void)PRINTF("\t       0x11 5G subband1 (5G: channel 100,104,108,112,\r\n");
1067     (void)PRINTF("\t                                     116,120,124,128,\r\n");
1068     (void)PRINTF("\t                                     132,136,140,144)\r\n");
1069     (void)PRINTF("\t       0x12 5G subband2 (5G: channel 149,153,157,161,165,172)\r\n");
1070     (void)PRINTF("\t       0x13 5G subband3 (5G: channel 183,184,185,187,188,\r\n");
1071     (void)PRINTF("\t                                     189, 192,196;\r\n");
1072     (void)PRINTF("\t                         5G: channel 7,8,11,12,16,34)\r\n");
1073 #endif
1074 }
1075 
1076 static void test_wlan_get_txpwrlimit(int argc, char **argv)
1077 {
1078     wifi_SubBand_t subband;
1079     wlan_txpwrlimit_t *txpwrlimit = NULL;
1080 
1081     ARG_UNUSED(chanlist_2g_cfg);
1082 #if CONFIG_5GHz_SUPPORT
1083     ARG_UNUSED(chanlist_5g_cfg);
1084 #endif
1085 
1086     if (argc != 2)
1087     {
1088         dump_wlan_get_txpwrlimit_usage();
1089         return;
1090     }
1091 
1092     errno   = 0;
1093     subband = (wifi_SubBand_t)strtol(argv[1], NULL, 16);
1094     if (errno != 0)
1095     {
1096         (void)PRINTF("Error during strtoul errno:%d", errno);
1097     }
1098 
1099     if (subband != SubBand_2_4_GHz
1100 #if CONFIG_5GHz_SUPPORT
1101         && subband != SubBand_5_GHz_0 && subband != SubBand_5_GHz_1 && subband != SubBand_5_GHz_2 &&
1102         subband != SubBand_5_GHz_3
1103 #endif
1104     )
1105     {
1106         dump_wlan_get_txpwrlimit_usage();
1107         return;
1108     }
1109 
1110     txpwrlimit = OSA_MemoryAllocate(sizeof(wlan_txpwrlimit_t));
1111     if (txpwrlimit == NULL)
1112     {
1113         (void)PRINTF("Cannot allocate memory\r\n");
1114         return;
1115     }
1116 
1117     int rv = wlan_get_txpwrlimit(subband, txpwrlimit);
1118     if (rv != WM_SUCCESS)
1119     {
1120         (void)PRINTF("Unable to get TX PWR Limit configuration\r\n");
1121     }
1122     else
1123     {
1124         print_txpwrlimit(txpwrlimit);
1125     }
1126     OSA_MemoryFree(txpwrlimit);
1127 }
1128 
1129 #if !CONFIG_COMPRESS_TX_PWTBL
1130 
1131 static void test_wlan_set_txpwrlimit(int argc, char **argv)
1132 {
1133     wlan_txpwrlimit_t *txpwrlimit = NULL;
1134 
1135     txpwrlimit = OSA_MemoryAllocate(sizeof(wlan_txpwrlimit_t));
1136     if (txpwrlimit == NULL)
1137     {
1138         (void)PRINTF("Cannot allocate memory\r\n");
1139         return;
1140     }
1141 
1142     int rv = wlan_set_txpwrlimit(&tx_pwrlimit_2g_cfg);
1143     if (rv != WM_SUCCESS)
1144     {
1145         (void)PRINTF("Unable to set 2G TX PWR Limit configuration\r\n");
1146     }
1147     else
1148     {
1149 #if CONFIG_5GHz_SUPPORT
1150         rv = wlan_set_txpwrlimit(&tx_pwrlimit_5g_cfg);
1151         if (rv != WM_SUCCESS)
1152         {
1153             (void)PRINTF("Unable to set 5G TX PWR Limit configuration\r\n");
1154         }
1155         else
1156         {
1157 #endif
1158             txpwrlimit->subband = SubBand_2_4_GHz;
1159             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1160             if (rv != WM_SUCCESS)
1161             {
1162                 (void)PRINTF("Unable to get 2G TX PWR Limit configuration\r\n");
1163             }
1164             else
1165             {
1166                 print_txpwrlimit(txpwrlimit);
1167             }
1168 #if CONFIG_5GHz_SUPPORT
1169             txpwrlimit->subband = SubBand_5_GHz_0;
1170             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1171             if (rv != WM_SUCCESS)
1172             {
1173                 (void)PRINTF("Unable to get 5G SubBand0 TX PWR Limit configuration\r\n");
1174             }
1175             else
1176             {
1177                 print_txpwrlimit(txpwrlimit);
1178             }
1179             txpwrlimit->subband = SubBand_5_GHz_1;
1180             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1181             if (rv != WM_SUCCESS)
1182             {
1183                 (void)PRINTF("Unable to get 5G SubBand1 TX PWR Limit configuration\r\n");
1184             }
1185             else
1186             {
1187                 print_txpwrlimit(txpwrlimit);
1188             }
1189             txpwrlimit->subband = SubBand_5_GHz_2;
1190             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1191             if (rv != WM_SUCCESS)
1192             {
1193                 (void)PRINTF("Unable to get 5G SubBand2 TX PWR Limit configuration\r\n");
1194             }
1195             else
1196             {
1197                 print_txpwrlimit(txpwrlimit);
1198             }
1199         }
1200 #endif
1201     }
1202     OSA_MemoryFree(txpwrlimit);
1203 }
1204 
1205 static void test_wlan_set_chanlist_and_txpwrlimit(int argc, char **argv)
1206 {
1207     wlan_txpwrlimit_t *txpwrlimit = NULL;
1208 
1209     txpwrlimit = OSA_MemoryAllocate(sizeof(wlan_txpwrlimit_t));
1210     if (txpwrlimit == NULL)
1211     {
1212         (void)PRINTF("Cannot allocate memory\r\n");
1213         return;
1214     }
1215 
1216     int rv = wlan_set_chanlist_and_txpwrlimit(&chanlist_2g_cfg, &tx_pwrlimit_2g_cfg);
1217     if (rv != WM_SUCCESS)
1218     {
1219         (void)PRINTF("Unable to set 2G TX PWR Limit configuration\r\n");
1220     }
1221     else
1222     {
1223 #if CONFIG_5GHz_SUPPORT
1224         rv = wlan_set_chanlist_and_txpwrlimit(&chanlist_5g_cfg, &tx_pwrlimit_5g_cfg);
1225         if (rv != WM_SUCCESS)
1226         {
1227             (void)PRINTF("Unable to set 5G TX PWR Limit configuration\r\n");
1228         }
1229         else
1230         {
1231 #endif
1232             txpwrlimit->subband = SubBand_2_4_GHz;
1233             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1234             if (rv != WM_SUCCESS)
1235             {
1236                 (void)PRINTF("Unable to get 2G TX PWR Limit configuration\r\n");
1237             }
1238             else
1239             {
1240                 print_txpwrlimit(txpwrlimit);
1241             }
1242 #if CONFIG_5GHz_SUPPORT
1243             txpwrlimit->subband = SubBand_5_GHz_0;
1244             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1245             if (rv != WM_SUCCESS)
1246             {
1247                 (void)PRINTF("Unable to get 5G SubBand0 TX PWR Limit configuration\r\n");
1248             }
1249             else
1250             {
1251                 print_txpwrlimit(txpwrlimit);
1252             }
1253             txpwrlimit->subband = SubBand_5_GHz_1;
1254             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1255             if (rv != WM_SUCCESS)
1256             {
1257                 (void)PRINTF("Unable to get 5G SubBand1 TX PWR Limit configuration\r\n");
1258             }
1259             else
1260             {
1261                 print_txpwrlimit(txpwrlimit);
1262             }
1263             txpwrlimit->subband = SubBand_5_GHz_2;
1264             rv                  = wlan_get_txpwrlimit(txpwrlimit->subband, txpwrlimit);
1265             if (rv != WM_SUCCESS)
1266             {
1267                 (void)PRINTF("Unable to get 5G SubBand2 TX PWR Limit configuration\r\n");
1268             }
1269             else
1270             {
1271                 print_txpwrlimit(txpwrlimit);
1272             }
1273         }
1274 #endif
1275         wlan_chanlist_t chanlist;
1276 
1277         (void)memset(&chanlist, 0x00, sizeof(wlan_chanlist_t));
1278         rv = wlan_get_chanlist(&chanlist);
1279         if (rv != WM_SUCCESS)
1280         {
1281             (void)PRINTF("Unable to get channel list configuration\r\n");
1282         }
1283         else
1284         {
1285             print_chanlist(chanlist);
1286         }
1287     }
1288     OSA_MemoryFree(txpwrlimit);
1289 }
1290 #endif
1291 
1292 static void test_wlan_set_chanlist(int argc, char **argv)
1293 {
1294     wlan_chanlist_t chanlist;
1295 
1296 #if (CONFIG_COMPRESS_TX_PWTBL) && !defined(RW610)
1297     ARG_UNUSED(rg_table_fc);
1298     ARG_UNUSED(rg_table_fc_len);
1299 #endif
1300 
1301 #if (CONFIG_COMPRESS_TX_PWTBL) && defined(RW610)
1302     ARG_UNUSED(tx_pwrlimit_2g_cfg);
1303     ARG_UNUSED(chanlist_2g_cfg);
1304 #if CONFIG_5GHz_SUPPORT
1305     ARG_UNUSED(tx_pwrlimit_5g_cfg);
1306     ARG_UNUSED(chanlist_5g_cfg);
1307 #endif
1308 #endif
1309 
1310     (void)memset(&chanlist, 0x00, sizeof(wlan_chanlist_t));
1311 
1312     /* Get channel list of current region */
1313     int ret = wlan_get_chanlist(&chanlist);
1314     if (ret != WM_SUCCESS)
1315     {
1316         (void)PRINTF("Unable to get channel list of current region\r\n");
1317         return;
1318     }
1319     ret = wlan_set_chanlist(&chanlist);
1320     if (ret != WM_SUCCESS)
1321     {
1322         (void)PRINTF("Failed to set channel list!\r\n");
1323         return;
1324     }
1325     print_chanlist(chanlist);
1326 }
1327 
1328 static void test_wlan_get_chanlist(int argc, char **argv)
1329 {
1330     wlan_chanlist_t chanlist;
1331 
1332     (void)memset(&chanlist, 0x00, sizeof(wlan_chanlist_t));
1333     int rv = wlan_get_chanlist(&chanlist);
1334     if (rv != WM_SUCCESS)
1335     {
1336         (void)PRINTF("Unable to get channel list configuration\r\n");
1337     }
1338     else
1339     {
1340         print_chanlist(chanlist);
1341     }
1342 }
1343 
1344 #if CONFIG_11AX
1345 static void dump_wlan_set_txomi_usage()
1346 {
1347     (void)PRINTF("Usage:\r\n");
1348     (void)PRINTF("wlan-set-tx-omi <interface> <tx-omi> <tx-option> <num_data_pkts>\r\n");
1349     (void)PRINTF("where, interface = uap or sta\r\n");
1350     (void)PRINTF("where, tx-omi =\r\n");
1351     (void)PRINTF("\t Bit 0-2: Rx NSS\r\n");
1352     (void)PRINTF("\t Bit 3-4: Channel Width. 0: 20MHz  1: 40MHz  2: 80MHz\r\n");
1353     (void)PRINTF("\t Bit 5  : UL MU Disable\r\n");
1354     (void)PRINTF("\t Bit 6-8: Tx NSTS (applies to client mode only)\r\n");
1355     (void)PRINTF("\t Bit 9  : ER SU Disable\r\n");
1356     (void)PRINTF("\t Bit 10 : DL MU-MIMO Resound Recommendation\r\n");
1357     (void)PRINTF("\t Bit 11 : DL MU Data Disable\r\n");
1358     (void)PRINTF("\t Example : For 1x1 SoC, to set bandwidth,\r\n");
1359     (void)PRINTF("20M, tx-omi = 0x00\r\n");
1360     (void)PRINTF("40M, tx-omi = 0x08\r\n");
1361     (void)PRINTF("80M, tx-omi = 0x10\r\n");
1362     (void)PRINTF("where, tx-option =\r\n");
1363     (void)PRINTF("\t 0: send OMI in NULL Data\r\n");
1364     (void)PRINTF("\t 1: send OMI in QoS Data\r\n");
1365     (void)PRINTF("\t 0xff: send OMI in either QoS Data or NULL Data\r\n");
1366     (void)PRINTF("where, num_data_pkts =\r\n");
1367     (void)PRINTF("\t Set this value only when tx-option is 1 or 0xff.\r\n");
1368     (void)PRINTF("\t Minimum value is 1\r\n");
1369     (void)PRINTF("\t Maximum value is 16\r\n");
1370     (void)PRINTF("\t num_data_pkts is applied only if OMI is sent in QoS data frame\r\n");
1371     (void)PRINTF("\t It specifies the number of consecutive data frames containing the OMI\r\n");
1372 }
1373 
1374 static void test_wlan_set_rutxpwrlimit(int argc, char **argv)
1375 {
1376     int rv;
1377     uint32_t region_code = (t_u16)strtol(argv[1], NULL, 0);
1378 #if CONFIG_COMPRESS_RU_TX_PWTBL
1379 #ifdef RW610
1380     switch (region_code)
1381     {
1382         case RW610_PACKAGE_TYPE_WW:
1383             rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set_WW, sizeof(rutxpowerlimit_cfg_set_WW));
1384             break;
1385         case RW610_PACKAGE_TYPE_FCC:
1386             rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set_FCC, sizeof(rutxpowerlimit_cfg_set_FCC));
1387             break;
1388         case RW610_PACKAGE_TYPE_EU:
1389             rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set_EU, sizeof(rutxpowerlimit_cfg_set_EU));
1390             break;
1391         case RW610_PACKAGE_TYPE_CN:
1392             rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set_CN, sizeof(rutxpowerlimit_cfg_set_CN));
1393             break;
1394         case RW610_PACKAGE_TYPE_JP:
1395             rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set_JP, sizeof(rutxpowerlimit_cfg_set_JP));
1396             break;
1397         default:
1398             PRINTF("Unknown region code, use WW rutx power limit cfg \r\n");
1399             rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set_WW, sizeof(rutxpowerlimit_cfg_set_WW));
1400             break;
1401     }
1402 #else
1403     rv = wlan_set_11ax_rutxpowerlimit(rutxpowerlimit_cfg_set, sizeof(rutxpowerlimit_cfg_set));
1404 #endif
1405 
1406     if (rv != WM_SUCCESS)
1407     {
1408         (void)PRINTF("Unable to set RU TX PWR Limit configuration\r\n");
1409     }
1410 #else
1411     rv = wlan_set_11ax_rutxpowerlimit_legacy(&rutxpowerlimit_2g_cfg_set);
1412     if (rv != WM_SUCCESS)
1413     {
1414         (void)PRINTF("Unable to set 2G RU TX PWR Limit configuration\r\n");
1415     }
1416 #if CONFIG_5GHz_SUPPORT
1417     else
1418     {
1419         rv = wlan_set_11ax_rutxpowerlimit_legacy(&rutxpowerlimit_5g_cfg_set);
1420         if (rv != WM_SUCCESS)
1421         {
1422             (void)PRINTF("Unable to set 5G RU TX PWR Limit configuration\r\n");
1423         }
1424     }
1425 #endif /* CONFIG_5GHz_SUPPORT */
1426 #endif /* CONFIG_COMPRESS_RU_TX_PWTBL */
1427 }
1428 
1429 static void test_wlan_set_tx_omi(int argc, char **argv)
1430 {
1431     int ret;
1432     t_u8 interface = 0;
1433     uint16_t tx_omi;
1434     uint8_t tx_option     = 0;
1435     uint8_t num_data_pkts = 0;
1436 
1437     if (argc != 4 && argc != 5)
1438     {
1439         dump_wlan_set_txomi_usage();
1440         return;
1441     }
1442 
1443     errno = 0;
1444 
1445     tx_omi    = (uint16_t)strtol(argv[2], NULL, 0);
1446     tx_option = (uint8_t)strtol(argv[3], NULL, 0);
1447 
1448     if (errno != 0)
1449     {
1450         (void)PRINTF("Error during strtoul errno:%d", errno);
1451         errno = 0;
1452     }
1453 
1454     if (argc == 4)
1455     {
1456         if (tx_option != 0)
1457         {
1458             dump_wlan_set_txomi_usage();
1459             return;
1460         }
1461         num_data_pkts = 1;
1462     }
1463     else
1464     {
1465         if (tx_option == 0)
1466         {
1467             dump_wlan_set_txomi_usage();
1468             return;
1469         }
1470         num_data_pkts = (uint8_t)strtol(argv[4], NULL, 0);
1471 
1472         if (errno != 0)
1473             (void)PRINTF("Error during strtoul errno:%d", errno);
1474 
1475         if (num_data_pkts < 1 || num_data_pkts > 16)
1476         {
1477             dump_wlan_set_txomi_usage();
1478             return;
1479         }
1480     }
1481 
1482     if (string_equal("sta", argv[1]))
1483     {
1484         interface = (t_u8)WLAN_BSS_TYPE_STA;
1485     }
1486     else if (string_equal("uap", argv[1]))
1487     {
1488         interface = (t_u8)WLAN_BSS_TYPE_UAP;
1489     }
1490 
1491     ret = wlan_set_11ax_tx_omi(interface, tx_omi, tx_option, num_data_pkts);
1492 
1493     if (ret == WM_SUCCESS)
1494     {
1495         (void)PRINTF("TX OMI: 0x%x set\r\n", tx_omi);
1496         (void)PRINTF("TX OPTION: 0x%x set\r\n", tx_option);
1497         (void)PRINTF("TX NUM_DATA_PKTS: 0x%x set\r\n", num_data_pkts);
1498     }
1499     else
1500     {
1501         (void)PRINTF("Unable to set TX OMI: 0x%x\r\n", tx_omi);
1502         (void)PRINTF("Unable to set TX OPTION: 0x%x\r\n", tx_option);
1503         (void)PRINTF("Unable to set TX NUM_DATA_PKTS: 0x%x\r\n", num_data_pkts);
1504     }
1505 }
1506 
1507 static void dump_wlan_set_tol_time_usage()
1508 {
1509     (void)PRINTF("Usage:\r\n");
1510     (void)PRINTF("set OBSS Narrow Bandwidth RU Tolerance Time\r\n");
1511     (void)PRINTF("Pls set toltime when sta is in disconnect state.\r\n");
1512     (void)PRINTF("wlan-set-toltime value\r\n");
1513     (void)PRINTF("value:\r\n");
1514     (void)PRINTF("Valid range[1..3600]\r\n");
1515 }
1516 
1517 static void test_wlan_set_toltime(int argc, char **argv)
1518 {
1519     unsigned int value;
1520     int ret;
1521     if (argc != 2)
1522     {
1523         (void)PRINTF("Error: invalid number of arguments\r\n");
1524         dump_wlan_set_tol_time_usage();
1525         return;
1526     }
1527 
1528     if (get_uint(argv[1], &value, strlen(argv[1])))
1529     {
1530         (void)PRINTF("Error: invalid option argument\r\n");
1531         dump_wlan_set_tol_time_usage();
1532         return;
1533     }
1534 
1535     ret = wlan_set_11ax_tol_time(value);
1536 
1537     if (ret != WM_SUCCESS)
1538     {
1539         (void)PRINTF("Error: Failed to set Tolerance Time.\r\n");
1540         dump_wlan_set_tol_time_usage();
1541         return;
1542     }
1543 }
1544 
1545 static wlan_11ax_config_t ax_conf;
1546 #if CONFIG_11AX_TWT
1547 static wlan_twt_setup_config_t twt_setup_conf;
1548 static wlan_twt_teardown_config_t teardown_conf;
1549 static wlan_btwt_config_t btwt_config;
1550 #endif /* CONFIG_11AX_TWT */
1551 
1552 /* cfg tables for 11axcfg and twt commands to FW */
1553 static uint8_t g_11ax_cfg[31] = {0};
1554 
1555 const static test_cfg_param_t g_11ax_cfg_param[] = {
1556     /* name                 offset  len     notes */
1557     {"band", 0, 1, NULL},
1558     {"cap_id", 1, 2, NULL},
1559     {"cap_len", 3, 2, NULL},
1560     {"he_cap_id", 5, 1, NULL},
1561     {"he_mac_cap_info", 6, 6, NULL},
1562     {"he_phy_cap_info", 12, 11, NULL},
1563     {"he_mcs_nss_support", 23, 4, NULL},
1564     {"pe", 27, 2, NULL},
1565 };
1566 
1567 #if CONFIG_11AX_TWT
1568 static uint8_t g_btwt_cfg[12] = {0};
1569 
1570 const static test_cfg_param_t g_btwt_cfg_param[] = {
1571     /* name             offset  len   notes */
1572     {"action", 0, 2, "only support 1: Set"},
1573     {"sub_id", 2, 2, "Broadcast TWT AP config"},
1574     {"nominal_wake", 4, 1, "range 64-255"},
1575     {"max_sta_support", 5, 1, "Max STA Support"},
1576     {"twt_mantissa", 6, 2, NULL},
1577     {"twt_offset", 8, 2, NULL},
1578     {"twt_exponent", 10, 1, NULL},
1579     {"sp_gap", 11, 1, NULL},
1580 };
1581 
1582 static uint8_t g_twt_setup_cfg[15] = {0};
1583 
1584 static test_cfg_param_t g_twt_setup_cfg_param[] = {
1585     /* name                 offset  len  notes */
1586     {"implicit", 0, 1, "0: TWT session is explicit, 1: Session is implicit"},
1587     {"announced", 1, 1, "0: Unannounced, 1: Announced TWT"},
1588     {"trigger_enabled", 2, 1, "0: Non-Trigger enabled, 1: Trigger enabled TWT"},
1589     {"twt_info_disabled", 3, 1, "0: TWT info enabled, 1: TWT info disabled"},
1590     {"negotiation_type", 4, 1, "0: Individual TWT, 3: Broadcast TWT"},
1591     {"twt_wakeup_duration", 5, 1, "Min time which a STA need to stay awake in each TWT interval. Unit in (256 μs). Range: [0-sizeof(UINT8)]"},
1592     {"flow_identifier", 6, 1, "Required if setup BTWT. Range: [0-7]"},
1593     {"hard_constraint", 7, 1,
1594      "0: FW can tweak the TWT setup parameters if it is rejected by AP, 1: FW should not tweak any parameters"},
1595     {"twt_interval_exponent", 8, 1, "Range: [0-63]"},
1596     {"twt_interval_mantissa", 9, 2, "TWT interval= mantissa * 2^exponent μs. Range: [0 - (2^16-1)]"},
1597     {"twt_request", 11, 1, "Type, 0: REQUEST_TWT, 1: SUGGEST_TWT"},
1598     /* Skip field: t_u8 twt_setup_state. Needless to input */
1599     {"bcnMiss_threshold", 13, 2, "Link lost timeout threshold when TWT active. Unit in seconds. Range [1-maxof(UINT16)]"},
1600 };
1601 
1602 static uint8_t g_twt_teardown_cfg[3] = {0};
1603 
1604 static test_cfg_param_t g_twt_teardown_cfg_param[] = {
1605     /* name             offset  len  notes */
1606     {"FlowIdentifier", 0, 1, "Range: [0-7]"},
1607     {"NegotiationType", 1, 1, "0: Future Individual TWT SP start time, 1: Next Wake TBTT tim"},
1608     {"TearDownAllTWT", 2, 1, "1: To teardown all TWT, 0 otherwise"},
1609 };
1610 #endif /* CONFIG_11AX_TWT */
1611 
1612 static void test_wlan_11ax_cfg(int argc, char **argv)
1613 {
1614     test_wlan_cfg_process(TEST_WLAN_11AX_CFG, argc, argv);
1615 }
1616 
1617 #if CONFIG_11AX_TWT
1618 static void test_wlan_bcast_twt(int argc, char **argv)
1619 {
1620     test_wlan_cfg_process(TEST_WLAN_BCAST_TWT, argc, argv);
1621 }
1622 
1623 static void test_wlan_twt_setup(int argc, char **argv)
1624 {
1625     test_wlan_cfg_process(TEST_WLAN_TWT_SETUP, argc, argv);
1626 }
1627 
1628 static void test_wlan_twt_teardown(int argc, char **argv)
1629 {
1630     test_wlan_cfg_process(TEST_WLAN_TWT_TEARDOWN, argc, argv);
1631 }
1632 
1633 static void test_wlan_twt_report(int argc, char **argv)
1634 {
1635     int i;
1636     int j;
1637     int num;
1638     wlan_twt_report_t info;
1639     bool tipOnce = MTRUE;
1640 
1641     memset(&info, 0x00, sizeof(info));
1642     wlan_get_twt_report(&info);
1643 
1644     if (info.length == 0)
1645     {
1646         (void)PRINTF("twt_report results:\r\n Ex-AP's beacon doesn't contain BTWT IE.\r\n");
1647         return;
1648     }
1649 
1650     num = info.length / WLAN_BTWT_REPORT_LEN;
1651     num = num <= WLAN_BTWT_REPORT_MAX_NUM ? num : WLAN_BTWT_REPORT_MAX_NUM;
1652 
1653     (void)PRINTF("twt_report results:\r\n Received B-TWT schedule from ex-AP's beacon. Total buff len = %hu, count of schedules = %d, detail:\r\n", info.length, num);
1654     for (i = 0; i < num; i++)
1655     {
1656         t_u8 *p = &info.data[i * WLAN_BTWT_REPORT_LEN];
1657 
1658         t_u16 req_typ = p[0] | p[1] << 8;
1659         t_u8 wake_dur = p[4];
1660         t_u16 mantissa= p[5] | p[6] << 8;
1661         t_u16 twt_info= p[7] | p[8] << 8;
1662         t_u8 btwt_id  = (twt_info & 0xF8) >> 3;
1663 
1664         (void)PRINTF("Schedule-[%d]:\r\n", i);
1665         for (j = 0; j < WLAN_BTWT_REPORT_LEN; j++)
1666         {
1667             (void)PRINTF(" 0x%02x", info.data[i * WLAN_BTWT_REPORT_LEN + j]);
1668         }
1669         (void)PRINTF("\r\n");
1670 
1671         (void)PRINTF(" ## Explain: Broadcast TWT ID = %2d; %s, %s; Interval Exponent = %2d, Mantissa = %2d; Wake Duration = %2d\r\n",
1672                     btwt_id,
1673                     (req_typ & BIT(4)) ? "Trigger":"No trigger",
1674                     (req_typ & BIT(6)) ? "Unannounced":"Announced",
1675                     (req_typ & 0x7C00) >> 10, //IntervalExponent
1676                     mantissa,
1677                     wake_dur);
1678         if (btwt_id == 0 && tipOnce)
1679         {
1680             tipOnce = MFALSE;
1681             (void)PRINTF(" ## BTWT_ID[0] will be auto joined when STA join other BTWT schedule. Don't manually join it.\r\n");
1682         }
1683     }
1684 }
1685 
1686 static void dump_wlan_twt_information_usage(void)
1687 {
1688     (void)PRINTF("Usage:\r\n");
1689     (void)PRINTF("wlan-11ax-twt-information <flow_id> <suspend_duration>\r\n");
1690     (void)PRINTF("TWT information setting. \r\n");
1691     (void)PRINTF(
1692         "<flow_identifier>  TWT flow identifier, range: [0-7], must be same ID as the one got in TWT setup cmd\r\n");
1693     (void)PRINTF("<suspend_duration> TWT operation suspend duration in milli seconds.\r\n");
1694     (void)PRINTF("    # 0     - Suspend forever\r\n");
1695     (void)PRINTF("    # Non-0 - Suspend agreement for specific duration in milli seconds\r\n");
1696 }
1697 
1698 static void test_wlan_twt_information(int argc, char **argv)
1699 {
1700     wlan_twt_information_t info;
1701 
1702     if (argc < 3)
1703     {
1704         dump_wlan_twt_information_usage();
1705         return;
1706     }
1707 
1708     memset(&info, 0x00, sizeof(info));
1709     info.flow_identifier  = a2hex_or_atoi(argv[1]);
1710     info.suspend_duration = a2hex_or_atoi(argv[2]);
1711 
1712     wlan_twt_information(&info);
1713 }
1714 #endif /* CONFIG_11AX_TWT */
1715 
1716 static void wlan_init_g_test_cfg_arrays()
1717 {
1718     memcpy(g_11ax_cfg, wlan_get_11ax_cfg(), 31);
1719 #if CONFIG_11AX_TWT
1720     memcpy(g_btwt_cfg, wlan_get_btwt_cfg(), 12);
1721     memcpy(g_twt_setup_cfg, wlan_get_twt_setup_cfg(), 15);
1722     memcpy(g_twt_teardown_cfg, wlan_get_twt_teardown_cfg(), 3);
1723 #endif /* CONFIG_11AX_TWT */
1724 }
1725 
1726 /*
1727  *  Cfg table for mutiple params commands in freeRTOS.
1728  *  name:          cfg name
1729  *  data:          cfg data stored and prepared to send
1730  *  total_len:     len of cfg data
1731  *  param_list:    param list of cfg data
1732  *  param_num:     number of cfg param list
1733  */
1734 static test_cfg_table_t g_test_cfg_table_list[] = { /*  name         data           total_len    param_list param_num*/
1735                                                     {"11axcfg", g_11ax_cfg, 29, g_11ax_cfg_param, 8},
1736 #if CONFIG_11AX_TWT
1737                                                     {"twt_bcast", g_btwt_cfg, 12, g_btwt_cfg_param, 8},
1738                                                     {"twt_setup", g_twt_setup_cfg, 15, g_twt_setup_cfg_param, 12},
1739                                                     {"twt_teardown", g_twt_teardown_cfg, 3, g_twt_teardown_cfg_param,
1740                                                      3},
1741 #endif /* CONFIG_11AX_TWT */
1742                                                     {NULL}
1743 };
1744 
1745 static void dump_cfg_data_param(int param_id, uint8_t *data, const test_cfg_param_t *param_cfg)
1746 {
1747     int i;
1748 
1749     (void)PRINTF("%s ", param_cfg->name);
1750     if (param_cfg->notes != NULL)
1751         (void)PRINTF("#### %s\r\n", param_cfg->notes);
1752     else
1753         (void)PRINTF("\r\n");
1754 
1755     (void)PRINTF("[%d]: ", param_id);
1756     for (i = 0; i < param_cfg->len; i++)
1757     {
1758         (void)PRINTF("0x%02x ", data[param_cfg->offset + i]);
1759     }
1760     (void)PRINTF("\r\n");
1761 }
1762 
1763 static void set_cfg_data_param(uint8_t *data, const test_cfg_param_t *param_cfg, char **argv)
1764 {
1765     int i;
1766 
1767     for (i = 0; i < param_cfg->len; i++)
1768     {
1769         data[param_cfg->offset + i] = a2hex(argv[3 + i]);
1770     }
1771 }
1772 
1773 static void dump_cfg_data(test_cfg_table_t *cfg)
1774 {
1775     int i;
1776     uint8_t *data = cfg->data;
1777 
1778     (void)PRINTF("cfg[%s] len[%d] param_num[%d]: \r\n", cfg->name, cfg->len, cfg->param_num);
1779     for (i = 0; i < cfg->param_num; i++)
1780     {
1781         dump_cfg_data_param(i, data, &cfg->param_list[i]);
1782     }
1783 }
1784 
1785 static void dump_cfg_help(test_cfg_table_t *cfg)
1786 {
1787     dump_cfg_data(cfg);
1788 }
1789 
1790 /*
1791  *  match param name and set data by input
1792  *  argv[0] "wlan-xxxx"
1793  *  argv[1] "set"
1794  *  argv[2] param_id
1795  *  argv[3] param_data_set
1796  */
1797 static void set_cfg_data(test_cfg_table_t *cfg, int argc, char **argv)
1798 {
1799     uint8_t *data                     = cfg->data;
1800     const test_cfg_param_t *param_cfg = NULL;
1801     int param_id                      = atoi(argv[2]);
1802     /* input data starts from argv[3] */
1803     int input_data_num = argc - 3;
1804 
1805     if (param_id < 0 || param_id >= cfg->param_num)
1806     {
1807         (void)PRINTF("invalid param index %d\r\n", param_id);
1808         return;
1809     }
1810 
1811     param_cfg = &cfg->param_list[param_id];
1812     if (param_cfg->len != input_data_num)
1813     {
1814         (void)PRINTF("invalid input number %d, param has %d u8 arguments\r\n", input_data_num, param_cfg->len);
1815         return;
1816     }
1817 
1818     set_cfg_data_param(data, param_cfg, argv);
1819     dump_cfg_data_param(param_id, data, param_cfg);
1820 }
1821 
1822 static void send_cfg_msg(test_cfg_table_t *cfg, uint32_t index)
1823 {
1824     int ret;
1825 
1826     switch (index)
1827     {
1828         case TEST_WLAN_11AX_CFG:
1829             (void)memcpy((void *)&ax_conf, (void *)cfg->data, sizeof(ax_conf));
1830             ret = wlan_set_11ax_cfg(&ax_conf);
1831             break;
1832 #if CONFIG_11AX_TWT
1833         case TEST_WLAN_BCAST_TWT:
1834             (void)memcpy((void *)&btwt_config, (void *)cfg->data, sizeof(btwt_config));
1835             ret = wlan_set_btwt_cfg(&btwt_config);
1836             break;
1837         case TEST_WLAN_TWT_SETUP:
1838             (void)memcpy((void *)&twt_setup_conf, (void *)cfg->data, sizeof(twt_setup_conf));
1839             ret = wlan_set_twt_setup_cfg(&twt_setup_conf);
1840             break;
1841         case TEST_WLAN_TWT_TEARDOWN:
1842             (void)memcpy((void *)&teardown_conf, (void *)cfg->data, sizeof(teardown_conf));
1843             ret = wlan_set_twt_teardown_cfg(&teardown_conf);
1844             break;
1845 #endif /* CONFIG_11AX_TWT */
1846         default:
1847             ret = -1;
1848             break;
1849     }
1850 
1851     (void)PRINTF("send config [%s] ret %d\r\n", cfg->name, ret);
1852 }
1853 
1854 void test_wlan_cfg_process(uint32_t index, int argc, char **argv)
1855 {
1856     test_cfg_table_t *cfg = NULL;
1857 
1858     /* last cfg table is invalid */
1859     if (index >= (sizeof(g_test_cfg_table_list) / sizeof(test_cfg_table_t) - 1))
1860     {
1861         (void)PRINTF("cfg table too large index %u\r\n", index);
1862         return;
1863     }
1864 
1865     cfg = &g_test_cfg_table_list[index];
1866 
1867     if (argc < 2)
1868     {
1869         dump_cfg_help(cfg);
1870         return;
1871     }
1872 
1873     if (string_equal("help", argv[1]))
1874         dump_cfg_help(cfg);
1875     else if (string_equal("dump", argv[1]))
1876         dump_cfg_data(cfg);
1877     else if (string_equal("set", argv[1]))
1878         set_cfg_data(cfg, argc, argv);
1879     else if (string_equal("done", argv[1]))
1880         send_cfg_msg(cfg, index);
1881     else
1882         (void)PRINTF("unknown argument\r\n");
1883 }
1884 
1885 #endif /* CONFIG_11AX */
1886 
1887 #if CONFIG_WIFI_CLOCKSYNC
1888 static void dump_wlan_get_tsf_info_usage(void)
1889 {
1890     (void)PRINTF("Usage:\r\n");
1891     (void)PRINTF("wlan-get-tsfinfo <tsf_format>\r\n");
1892     (void)PRINTF("where, tsf_format =\r\n");
1893     (void)PRINTF("0:    Report GPIO assert TSF\r\n");
1894     (void)PRINTF("1:    Report Beacon TSF and Offset (valid if CONFIG Mode 2)\r\n");
1895 }
1896 
1897 static void test_get_tsf_info(int argc, char **argv)
1898 {
1899     wlan_tsf_info_t tsf_info;
1900     (void)memset(&tsf_info, 0, sizeof(wlan_tsf_info_t));
1901     if (argc != 2)
1902     {
1903         dump_wlan_get_tsf_info_usage();
1904         return;
1905     }
1906 
1907     errno               = 0;
1908     tsf_info.tsf_format = (uint16_t)strtol(argv[1], NULL, 0);
1909 
1910     if (errno != 0)
1911     {
1912         (void)PRINTF("Error during strtoul errno:%d", errno);
1913     }
1914 
1915     int rv = wlan_get_tsf_info(&tsf_info);
1916 
1917     if (rv != WM_SUCCESS)
1918     {
1919         (void)PRINTF("Unable to get TSF info\r\n");
1920     }
1921     else
1922     {
1923         (void)PRINTF("tsf format:              %d\n\r", tsf_info.tsf_format);
1924         (void)PRINTF("tsf info:                %d\n\r", tsf_info.tsf_info);
1925         (void)PRINTF("tsf:                     %llu\n\r", tsf_info.tsf);
1926         (void)PRINTF("tsf offset:              %d\n\r", tsf_info.tsf_offset);
1927     }
1928 }
1929 
1930 static void dump_wlan_set_clocksync_cfg_usage(void)
1931 {
1932     (void)PRINTF("Usage:\r\n");
1933     (void)PRINTF("wlan-set-clocksync <mode> <role> <gpio_pin> <gpio_level> <pulse width>\r\n");
1934     (void)PRINTF("Set WIFI TSF based clock sync setting. \r\nWhere, \r\n");
1935     (void)PRINTF("<mode> is use to configure GPIO TSF latch mode\r\n");
1936     (void)PRINTF("\t\t0:    GPIO level\r\n");
1937     (void)PRINTF("\t\t1:    GPIO toggle\r\n");
1938     (void)PRINTF("\t\t2:    GPIO toggle on Next Beacon\r\n");
1939     (void)PRINTF("<role> \r\n");
1940     (void)PRINTF("\t\t0: when mode set to 0 or 1\r\n");
1941     (void)PRINTF("\t\t1:  AP\r\n");
1942     (void)PRINTF("\t\t2: STA\r\n");
1943     (void)PRINTF("<gpio pin number>\r\n");
1944     (void)PRINTF("<GPIO Level/Toggle>\r\n");
1945     (void)PRINTF("\t\tmode = 0\r\n");
1946     (void)PRINTF("\t\t0: low    1: high\r\n");
1947     (void)PRINTF("\t\tmode = 1 or 2\r\n");
1948     (void)PRINTF("\t\t0: low to high\r\n");
1949     (void)PRINTF("\t\t1: high to low\r\n");
1950     (void)PRINTF("GPIO pulse width\r\n");
1951     (void)PRINTF("\t\tmode = 0,  reserved, set to 0\r\n");
1952     (void)PRINTF("\t\tmode 1 or 2\r\n");
1953     (void)PRINTF("\t\t0: GPIO remain on toggle level (high or low)\r\n");
1954     (void)PRINTF("\t\tNon-0: GPIO pulse width in microseconds (min 1 us)\r\n");
1955 }
1956 
1957 static void test_set_clocksync_cfg(int argc, char **argv)
1958 {
1959     wlan_clock_sync_gpio_tsf_t tsf_latch;
1960 
1961     if (argc != 6)
1962     {
1963         dump_wlan_set_clocksync_cfg_usage();
1964         return;
1965     }
1966 
1967     errno                     = 0;
1968     tsf_latch.clock_sync_mode = (uint8_t)strtol(argv[1], NULL, 0);
1969 
1970     if (errno != 0)
1971     {
1972         (void)PRINTF("Error during strtoul errno:%d", errno);
1973     }
1974 
1975     errno                     = 0;
1976     tsf_latch.clock_sync_Role = (uint8_t)strtol(argv[2], NULL, 0);
1977 
1978     if (errno != 0)
1979     {
1980         (void)PRINTF("Error during strtoul errno:%d", errno);
1981     }
1982 
1983     errno                                = 0;
1984     tsf_latch.clock_sync_gpio_pin_number = (uint8_t)strtol(argv[3], NULL, 0);
1985 
1986     if (errno != 0)
1987     {
1988         (void)PRINTF("Error during strtoul errno:%d", errno);
1989     }
1990 
1991     errno                                  = 0;
1992     tsf_latch.clock_sync_gpio_level_toggle = (uint8_t)strtol(argv[4], NULL, 0);
1993 
1994     if (errno != 0)
1995     {
1996         (void)PRINTF("Error during strtoul errno:%d", errno);
1997     }
1998 
1999     errno                                 = 0;
2000     tsf_latch.clock_sync_gpio_pulse_width = (uint16_t)strtol(argv[5], NULL, 0);
2001 
2002     if (errno != 0)
2003     {
2004         (void)PRINTF("Error during strtoul errno:%d", errno);
2005     }
2006 
2007     int rv = wlan_set_clocksync_cfg(&tsf_latch);
2008 
2009     if (rv != WM_SUCCESS)
2010     {
2011         (void)PRINTF("Unable to set clocksync config\r\n");
2012     }
2013     else
2014     {
2015         (void)PRINTF("Clock Sync config set as:\r\n");
2016         (void)PRINTF("Mode                 :%d\n\r", tsf_latch.clock_sync_mode);
2017         (void)PRINTF("Role                 :%d\n\r", tsf_latch.clock_sync_Role);
2018         (void)PRINTF("GPIO Pin Number      :%d\n\r", tsf_latch.clock_sync_gpio_pin_number);
2019         (void)PRINTF("GPIO Level or Toggle :%d\n\r", tsf_latch.clock_sync_gpio_level_toggle);
2020         (void)PRINTF("GPIO Pulse Width     :%d\n\r", tsf_latch.clock_sync_gpio_pulse_width);
2021     }
2022 }
2023 #endif /* CONFIG_WIFI_CLOCKSYNC */
2024 
2025 #if CONFIG_1AS
2026 static void test_wlan_get_fw_time(int argc, char **argv)
2027 {
2028     int ret;
2029     wlan_correlated_time_t time;
2030 
2031     ret = wlan_get_fw_timestamp(&time);
2032     if (ret != WM_SUCCESS)
2033     {
2034         (void)PRINTF("get fw timestamp fail\r\n");
2035         return;
2036     }
2037 
2038     (void)PRINTF("host time in ns 0x%x%08x\r\n", (t_u32)(time.time >> 32), (t_u32)time.time);
2039     (void)PRINTF("fw time in ns 0x%x%08x\r\n", (t_u32)(time.fw_time >> 32), (t_u32)time.fw_time);
2040 }
2041 
2042 static void test_wlan_send_tm_req(int argc, char **argv)
2043 {
2044     int ret;
2045     int bss_type;
2046     uint8_t raw_mac[6];
2047 
2048     if (string_equal("sta", argv[1]))
2049     {
2050         bss_type = (int)WLAN_BSS_TYPE_STA;
2051     }
2052     else if (string_equal("uap", argv[1]))
2053     {
2054         bss_type = (int)WLAN_BSS_TYPE_UAP;
2055     }
2056     else
2057     {
2058         (void)PRINTF("Error: invalid [sta/uap] argument\r\n");
2059         return;
2060     }
2061 
2062     ret = (int)get_mac(argv[2], (char *)raw_mac, ':');
2063     if (ret != 0)
2064     {
2065         (void)PRINTF("Error: invalid MAC argument\r\n");
2066         return;
2067     }
2068 
2069     wlan_request_timing_measurement(bss_type, &raw_mac[0], 1);
2070 }
2071 
2072 static void test_wlan_send_tm(int argc, char **argv)
2073 {
2074     int ret;
2075     int bss_type;
2076     uint8_t raw_mac[6];
2077     uint8_t number_of_tm = 2; /* 2 by default */
2078 
2079     if (string_equal("sta", argv[1]))
2080     {
2081         bss_type = (int)WLAN_BSS_TYPE_STA;
2082     }
2083     else if (string_equal("uap", argv[1]))
2084     {
2085         bss_type = (int)WLAN_BSS_TYPE_UAP;
2086     }
2087     else
2088     {
2089         (void)PRINTF("Error: invalid [sta/uap] argument\r\n");
2090         return;
2091     }
2092 
2093     ret = (int)get_mac(argv[2], (char *)raw_mac, ':');
2094     if (ret != 0)
2095     {
2096         (void)PRINTF("Error: invalid MAC argument\r\n");
2097         return;
2098     }
2099 
2100     if (argv[3] != NULL)
2101     {
2102         errno        = 0;
2103         number_of_tm = (uint8_t)strtol(argv[3], NULL, 10);
2104         if (errno != 0)
2105         {
2106             (void)PRINTF("Error during wlan_send_tm arg_3 strtoul errno:%d", errno);
2107         }
2108     }
2109 
2110     ret = wlan_start_timing_measurement(bss_type, &raw_mac[0], number_of_tm);
2111     if (ret != WM_SUCCESS)
2112     {
2113         (void)PRINTF("Error: start timing measurement fail\r\n");
2114         return;
2115     }
2116 }
2117 #endif
2118 
2119 static struct cli_command wlan_enhanced_commands[] = {
2120     {"wlan-get-txpwrlimit", "<subband>", test_wlan_get_txpwrlimit},
2121 #if !CONFIG_COMPRESS_TX_PWTBL
2122     {"wlan-set-txpwrlimit", NULL, test_wlan_set_txpwrlimit},
2123     {"wlan-set-chanlist-and-txpwrlimit", NULL, test_wlan_set_chanlist_and_txpwrlimit},
2124 #endif
2125     {"wlan-set-chanlist", NULL, test_wlan_set_chanlist},
2126     {"wlan-get-chanlist", NULL, test_wlan_get_chanlist},
2127 #if CONFIG_11AC
2128     {"wlan-set-txratecfg", "<sta/uap> <format> <index> <nss> <rate_setting> <autoTx_set>", test_wlan_set_txratecfg},
2129 #else
2130     {"wlan-set-txratecfg", "<sta/uap> <format> <index> <autoTx_set>", test_wlan_set_txratecfg},
2131 #endif
2132     {"wlan-get-txratecfg", "<sta/uap>", test_wlan_get_txratecfg},
2133     {"wlan-get-data-rate", "<sta/uap>", test_wlan_get_data_rate},
2134     {"wlan-get-pmfcfg", NULL, wlan_pmfcfg_get},
2135 #if UAP_SUPPORT
2136     {"wlan-uap-get-pmfcfg", NULL, wlan_uap_pmfcfg_get},
2137 #endif
2138 #if CONFIG_5GHz_SUPPORT
2139     {"wlan-set-ed-mac-mode", "<interface> <ed_ctrl_2g> <ed_offset_2g> <ed_ctrl_5g> <ed_offset_5g>",
2140      wlan_ed_mac_mode_set},
2141 #else
2142     {"wlan-set-ed-mac-mode", "<interface> <ed_ctrl_2g> <ed_offset_2g>", wlan_ed_mac_mode_set},
2143 #endif
2144     {"wlan-get-ed-mac-mode", "<interface>", wlan_ed_mac_mode_get},
2145 #if CONFIG_11AX
2146     {"wlan-set-tx-omi", "<interface> <tx-omi> <tx-option> <num_data_pkts>", test_wlan_set_tx_omi},
2147     {"wlan-set-toltime", "<value>", test_wlan_set_toltime},
2148     {"wlan-set-rutxpwrlimit", NULL, test_wlan_set_rutxpwrlimit},
2149     {"wlan-11ax-cfg", "<11ax_cfg>", test_wlan_11ax_cfg},
2150 #if CONFIG_11AX_TWT
2151     {"wlan-11ax-bcast-twt", "<dump/set/done> [<param_id> <param_data>]", test_wlan_bcast_twt},
2152     {"wlan-11ax-twt-setup", "<dump/set/done> [<param_id> <param_data>]", test_wlan_twt_setup},
2153     {"wlan-11ax-twt-teardown", "<dump/set/done> [<param_id> <param_data>]", test_wlan_twt_teardown},
2154     {"wlan-11ax-twt-report", "", test_wlan_twt_report},
2155     {"wlan-11ax-twt-information", "<flow_identifier> <suspend_duration>", test_wlan_twt_information},
2156 #endif /* CONFIG_11AX_TWT */
2157 #endif /* CONFIG_11AX */
2158 #if CONFIG_WIFI_CLOCKSYNC
2159     {"wlan-get-tsfinfo", "<format-type>", test_get_tsf_info},
2160     {"wlan-set-clocksync", "<mode> <role> <gpio_pin> <gpio_level> <pulse width>", test_set_clocksync_cfg},
2161 #endif /* CONFIG_WIFI_CLOCKSYNC */
2162 #if CONFIG_1AS
2163     {"wlan-get-fw-time", NULL, test_wlan_get_fw_time},
2164     {"wlan-tm-req", "<sta/uap> <mac_addr>", test_wlan_send_tm_req},
2165     {"wlan-tm", "<sta/uap> <mac_addr> <num_of_tm_frame>", test_wlan_send_tm},
2166 #endif
2167 };
2168 
2169 int wlan_enhanced_cli_init(void)
2170 {
2171 #if CONFIG_11AX
2172     wlan_init_g_test_cfg_arrays();
2173 #endif
2174 
2175     if (cli_register_commands(wlan_enhanced_commands,
2176                               (int)(sizeof(wlan_enhanced_commands) / sizeof(struct cli_command))) != 0)
2177     {
2178         return -WM_FAIL;
2179     }
2180 
2181     return WM_SUCCESS;
2182 }
2183 
2184 int wlan_enhanced_cli_deinit(void)
2185 {
2186     if (cli_unregister_commands(wlan_enhanced_commands,
2187                                 (int)(sizeof(wlan_enhanced_commands) / sizeof(struct cli_command))) != 0)
2188     {
2189         return -WM_FAIL;
2190     }
2191 
2192     return WM_SUCCESS;
2193 }
2194