• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*chipsea_ohos proguard begin*/
16 #include "cs_proguard.h"
17 /*chipsea_ohos proguard end*/
18 #include "wb_co_utils.h"
19 #include "wifi_host_config.h"
20 #include "wifi_mac.h"
21 #include "wifi_mac_frame.h"
22 #include "wifi_msg.h"
23 #include "wifi_host.h"
24 #include "driver_pub.h"
25 #include "trng_api.h"
26 #include "flash_api.h"
27 
28 /// define a channel
29 #define CHAN(_freq, _band, _flags, _pwr) {         \
30         .freq = (_freq),                           \
31         .band = (_band),                           \
32         .flags = (_flags),                         \
33         .tx_power = (_pwr),                        \
34     }
35 
36 /// define a channel in 2.4GHz band
37 #define CHAN_24(_freq, _flag, _pwr) CHAN(_freq, PHY_BAND_2G4, _flag, _pwr)
38 /// define a channel in 5GHz band
39 #define CHAN_5(_freq, _flag, _pwr) CHAN(_freq, PHY_BAND_5G, _flag, _pwr)
40 
41 /** List of supported Channel */
42 struct me_chan_config_req fhost_chan = {
43     #if PLF_HW_PXP
44     .chan2G4_cnt = 1,
45     .chan2G4[0] = CHAN_24(2462, 0, 20),
46     #else  /* PLF_HW_PXP */
47     .chan2G4_cnt = 14,
48     .chan2G4[0] = CHAN_24(2412, 0, 20),
49     #endif /* PLF_HW_PXP */
50     .chan2G4[1] = CHAN_24(2417, 0, 20),
51     .chan2G4[2] = CHAN_24(2422, 0, 20),
52     .chan2G4[3] = CHAN_24(2427, 0, 20),
53     .chan2G4[4] = CHAN_24(2432, 0, 20),
54     .chan2G4[5] = CHAN_24(2437, 0, 20),
55     .chan2G4[6] = CHAN_24(2442, 0, 20),
56     .chan2G4[7] = CHAN_24(2447, 0, 20),
57     .chan2G4[8] = CHAN_24(2452, 0, 20),
58     .chan2G4[9] = CHAN_24(2457, 0, 20),
59     .chan2G4[10] = CHAN_24(2462, 0, 20),
60     .chan2G4[11] = CHAN_24(2467, 0, 20),
61     .chan2G4[12] = CHAN_24(2472, 0, 20),
62     .chan2G4[13] = CHAN_24(2484, 0, 20),
63 
64     #if PLF_BAND5G
65     #if PLF_HW_PXP
66     .chan5G_cnt = 1,
67     .chan5G[0] = CHAN_5(5180, 0, 20),
68     #else  /* PLF_HW_PXP */
69     .chan5G_cnt = 25,
70     .chan5G[0] = CHAN_5(5180, 0, 20),
71     .chan5G[1] = CHAN_5(5200, 0, 20),
72     .chan5G[2] = CHAN_5(5220, 0, 20),
73     .chan5G[3] = CHAN_5(5240, 0, 20),
74     #if PLF_WIFI_AUDIO
75     .chan5G[4] = CHAN_5(5260, 0, 20), //52
76     .chan5G[5] = CHAN_5(5280, 0, 20), //56
77     .chan5G[6] = CHAN_5(5300, 0, 20), //60
78     .chan5G[7] = CHAN_5(5320, 0, 20), //64
79     .chan5G[8] = CHAN_5(5500, 0, 20), //100
80     .chan5G[9] = CHAN_5(5520, 0, 20), //104
81     .chan5G[10] = CHAN_5(5540, 0, 20),//108
82     .chan5G[11] = CHAN_5(5560, 0, 20),//112
83     .chan5G[12] = CHAN_5(5580, 0, 20),//116
84     .chan5G[13] = CHAN_5(5600, 0, 20),//120
85     .chan5G[14] = CHAN_5(5620, 0, 20),//124
86     .chan5G[15] = CHAN_5(5640, 0, 20),//128
87     .chan5G[16] = CHAN_5(5660, 0, 20),//132
88     .chan5G[17] = CHAN_5(5680, 0, 20),//136
89     .chan5G[18] = CHAN_5(5700, 0, 20),//140
90     .chan5G[19] = CHAN_5(5720, 0, 20),//144
91     #else
92     .chan5G[4] = CHAN_5(5260, CHAN_NO_IR|CHAN_RADAR, 20),
93     .chan5G[5] = CHAN_5(5280, CHAN_NO_IR|CHAN_RADAR, 20),
94     .chan5G[6] = CHAN_5(5300, CHAN_NO_IR|CHAN_RADAR, 20),
95     .chan5G[7] = CHAN_5(5320, CHAN_NO_IR|CHAN_RADAR, 20),
96     .chan5G[8] = CHAN_5(5500, CHAN_NO_IR|CHAN_RADAR, 20),
97     .chan5G[9] = CHAN_5(5520, CHAN_NO_IR|CHAN_RADAR, 20),
98     .chan5G[10] = CHAN_5(5540, CHAN_NO_IR|CHAN_RADAR, 20),
99     .chan5G[11] = CHAN_5(5560, CHAN_NO_IR|CHAN_RADAR, 20),
100     .chan5G[12] = CHAN_5(5580, CHAN_NO_IR|CHAN_RADAR, 20),
101     .chan5G[13] = CHAN_5(5600, CHAN_NO_IR|CHAN_RADAR, 20),
102     .chan5G[14] = CHAN_5(5620, CHAN_NO_IR|CHAN_RADAR, 20),
103     .chan5G[15] = CHAN_5(5640, CHAN_NO_IR|CHAN_RADAR, 20),
104     .chan5G[16] = CHAN_5(5660, CHAN_NO_IR|CHAN_RADAR, 20),
105     .chan5G[17] = CHAN_5(5680, CHAN_NO_IR|CHAN_RADAR, 20),
106     .chan5G[18] = CHAN_5(5700, CHAN_NO_IR|CHAN_RADAR, 20),
107     .chan5G[19] = CHAN_5(5720, CHAN_NO_IR|CHAN_RADAR, 20),
108     #endif
109     .chan5G[20] = CHAN_5(5745, 0, 20),
110     .chan5G[21] = CHAN_5(5765, 0, 20),
111     .chan5G[22] = CHAN_5(5785, 0, 20),
112     .chan5G[23] = CHAN_5(5805, 0, 20),
113     .chan5G[24] = CHAN_5(5825, 0, 20),
114     #endif /* PLF_HW_PXP */
115     #else
116     .chan5G_cnt = 0,
117     #endif
118 };
119 
120 #undef CHAN_5
121 #undef CHAN_24
122 #undef CHAN
123 
124 /*******************************************************************************
125  * FW configuration:
126  ******************************************************************************/
127 /// MAC Address
128 #if (CONFIG_SLEEP_LEVEL == 0)
129 static uint8_t fhost_mac_addr[6] = {0x88, 0x00, 0x33, 0x77, 0x69, 0xcc};
130 #elif (CONFIG_SLEEP_LEVEL == 1)
131 static uint8_t fhost_mac_addr[6] = {0x88, 0x00, 0x33, 0x77, 0x69, 0xdd};
132 #else
133 static uint8_t fhost_mac_addr[6] = {0x88, 0x00, 0x33, 0x77, 0x69, 0xee};
134 #endif
135 /// PHY configuration (This is only valid for KARST radio)
136 static uint32_t phy_cfg[] = {0x01000000, 0x01000000, 0x01000000, 0x01000000,
137                              0x01000000, 0x01000000, 0x01000000, 0x01000000,
138                              0x0};
139 
140 static struct {
141     bool ps_on;
142     #if NX_UAPSD
143     uint32_t uapsd_timeout;
144     #endif
145 } ps_cfg = {
146     .ps_on = true,
147     #if NX_UAPSD
148     .uapsd_timeout = 300,
149     #endif
150 };
151 
152 
153 uint8_t tx_lft_ms = 40;
154 
155 bool ht_support  = 1;
156 bool ht_40mhz    = 1;
157 bool vht_support = 1;
158 uint8_t vht_mcs  = 2;
159 bool he_support  = 1;
160 uint8_t he_mcs   = 2;
161 uint8_t nss      = 1;
162 bool stbc        = 1;
163 bool ldpc        = 1;
164 bool su_bfmee    = 1;
165 bool mu_bfmee    = 0;
166 
167 /// Wifi configuration
168 struct fhost_config_item fw_config[] = {
169     {FHOST_CFG_MAC_ADDR, 6, fhost_mac_addr},
170     {FHOST_CFG_PHY_KARST, 33, phy_cfg},
171     {FHOST_CFG_PS, 4, &ps_cfg.ps_on},
172     #if NX_UAPSD
173     {FHOST_CFG_UAPSD_TIMEOUT, 4, &ps_cfg.uapsd_timeout},
174     #endif
175     {FHOST_CFG_TX_LFT, 1, &tx_lft_ms},
176     {FHOST_CFG_NSS, 1, &nss},
177     {FHOST_CFG_LDPC, 1, &ldpc},
178     {FHOST_CFG_STBC, 1, &stbc},
179     {FHOST_CFG_HT, 1, &ht_support},
180     {FHOST_CFG_40MHZ, 1, &ht_40mhz},
181     {FHOST_CFG_VHT, 1, &vht_support},
182     {FHOST_CFG_VHT_MCS, 1, &vht_mcs},
183     {FHOST_CFG_HE, 1, &he_support},
184     {FHOST_CFG_HE_MCS, 1, &he_mcs},
185     {FHOST_CFG_BFMEE, 1, &su_bfmee},
186     {FHOST_CFG_MURX, 1, &mu_bfmee},
187 
188     {FHOST_CFG_END, 0, NULL}
189 };
190 /*
191  * fhost_config_get_next_item: Must return configuration item one by one.
192  * In this console confguration is saved in the global varaible fw_config
193  */
fhost_config_get_next_item(struct fhost_config_item * item)194 void fhost_config_get_next_item(struct fhost_config_item *item)
195 {
196     static int index;
197 
198     // First call, initialize index
199     if (item->data == NULL)
200         index = 0;
201 
202     // Check that we don't read outside of console_config table
203     if (index > (sizeof(fw_config) / sizeof(struct fhost_config_item)))
204     {
205         item->id = FHOST_CFG_END;
206     }
207 
208     // Copy one configuration parameter
209     *item = fw_config[index];
210 
211     // Update index for next call
212     index++;
213 }
214 
fhost_config_prepare(struct me_config_req * me_config,struct mm_start_req * start,struct mac_addr * base_mac_addr,bool init)215 void fhost_config_prepare(struct me_config_req *me_config, struct mm_start_req *start,
216                           struct mac_addr *base_mac_addr, bool init)
217 {
218     struct fhost_config_item item;
219     uint32_t phy_ver1, /*phy_ver2, */sec = 0, usec = 0;
220     uint8_t nss, vht_mcs;
221     bool sgi, sgi80, stbc, ht40, ldpc_rx, bfmee, bfmer, mu_rx, mu_tx, vht80;
222     #if NX_HE
223     uint8_t he_mcs = 0;
224     #endif
225 
226     memset(me_config, 0, sizeof(*me_config));
227     memset(start, 0, sizeof(*start));
228     item.data = NULL;
229 
230     /* Default value */
231     stbc = true;
232     sgi = true;
233     ht40 = true;
234     vht80 = false;
235     sgi80 = false;
236     vht_mcs = 0;
237     me_config->ht_supp = true;
238     me_config->vht_supp = false;
239     me_config->he_supp = true;
240     nss = 1;
241     ldpc_rx = true;
242     bfmee = true;
243     bfmer = false;
244     mu_rx = true;
245     mu_tx = false;
246     phy_ver1 = 0x00220000;
247 
248     fhost_config_get_next_item(&item);
249     while (item.id != FHOST_CFG_END)
250     {
251         switch (item.id)
252         {
253             case FHOST_CFG_MAC_ADDR:
254                 memcpy(base_mac_addr, item.data, sizeof(*base_mac_addr));
255                 break;
256             case FHOST_CFG_PS:
257                 me_config->ps_on = *(bool *)item.data;
258                 break;
259             case FHOST_CFG_DPSM:
260                 me_config->dpsm = *(bool *)item.data;
261                 break;
262             case FHOST_CFG_SGI:
263                 sgi = *(bool *)item.data;
264                 break;
265             case FHOST_CFG_SGI80:
266                 if (vht80)
267                     sgi80 = *(bool *)item.data;
268                 break;
269             case FHOST_CFG_NSS:
270             {
271                 uint8_t val = *(uint8_t *)item.data;
272                 if (val && val < nss)
273                     nss = val;
274             } break;
275             case FHOST_CFG_TX_LFT:
276                 me_config->tx_lft = *(uint16_t *)item.data;
277                 break;
278             case FHOST_CFG_UAPSD_TIMEOUT:
279                 start->uapsd_timeout = *(uint32_t *)item.data;
280                 break;
281             case FHOST_CFG_UAPSD_QUEUES:
282                 if (init)
283                     fhost_vif_set_uapsd_queues(-1, *(uint8_t *)item.data);
284                 break;
285             case FHOST_CFG_LP_CLK_ACCURACY:
286                 start->lp_clk_accuracy = *(uint16_t *)item.data;
287                 break;
288             case FHOST_CFG_HT:
289                 me_config->ht_supp = *(bool *)item.data;
290                 break;
291             case FHOST_CFG_40MHZ:
292                 if (ht40)
293                     ht40 = *(bool *)item.data;
294                 break;
295             case FHOST_CFG_80MHZ:
296                 if (vht80)
297                     vht80 = *(bool *)item.data;
298                 break;
299             case FHOST_CFG_VHT:
300                 #if NX_VHT
301                 //if (phy_vht_supported() && (phy_get_bw() >= 2))
302                     me_config->vht_supp = *(bool *)item.data;
303                 //else
304                 //    me_config->vht_supp = false;
305                 #endif
306                 break;
307             case FHOST_CFG_VHT_MCS:
308                 vht_mcs = *(uint8_t *)item.data;
309                 if (vht_mcs > 2)
310                     vht_mcs = 0;
311                 break;
312             #if NX_HE
313             case FHOST_CFG_HE:
314                 //if (hal_machw_he_support())
315                     me_config->he_supp = *(bool *)item.data;
316                 //else
317                 //    me_config->he_supp = false;
318                 break;
319             case FHOST_CFG_HE_MCS:
320                 he_mcs = *(uint8_t *)item.data;
321                 if (he_mcs > 2)
322                     he_mcs = 0;
323                 break;
324             #endif
325             case FHOST_CFG_LDPC:
326                 //if (!*(bool *)item.data)
327                     ldpc_rx = *(bool *)item.data;
328                 break;
329             case FHOST_CFG_STBC:
330                 stbc = *(bool *)item.data;
331                 break;
332             case FHOST_CFG_BFMEE:
333                 if (!*(bool *)item.data)
334                     bfmee = false;
335                 break;
336             case FHOST_CFG_BFMER:
337                 if (!*(bool *)item.data)
338                     bfmer = false;
339                 break;
340             case FHOST_CFG_MURX:
341                 if (!*(bool *)item.data)
342                     mu_rx = false;
343                 break;
344             case FHOST_CFG_MUTX:
345                 if (!*(bool *)item.data)
346                     mu_tx = false;
347                 break;
348             case FHOST_CFG_PHY_TRD:
349                 if (((phy_ver1 & 0x030000) >> 16) == 0) {
350                     memcpy(&start->phy_cfg.parameters, item.data, item.len);
351                 }
352                 break;
353             case FHOST_CFG_PHY_KARST:
354                 if (((phy_ver1 & 0x030000) >> 16) == 2)
355                 {
356                     memcpy(&start->phy_cfg.parameters, item.data, item.len);
357                 }
358                 break;
359             case FHOST_CFG_ANT_DIV:
360                 me_config->ant_div_on = *(bool *)item.data;
361                 break;
362             case FHOST_CFG_EPOCH_SEC:
363                 sec = *(uint32_t *)item.data;
364                 break;
365             case FHOST_CFG_EPOCH_USEC:
366                 usec = *(uint32_t *)item.data;
367                 break;
368             default :
369                 break;
370         }
371         fhost_config_get_next_item(&item);
372     }
373 
374     if (init)
375     {
376         if (sec && usec)
377         {
378             cs_time_init(sec, usec);
379         }
380 
381         cs_time_get(SINCE_EPOCH, &sec, &usec);
382         co_random_init((sec & 0xffff) * (usec & 0x1ffff));
383     }
384 
385     if (!ht40)
386     {
387         vht80 = false;
388         sgi80 = false;
389     }
390 
391     if (me_config->ht_supp)
392     {
393         int max_rate;
394         me_config->ht_cap.ht_capa_info = 0;
395         if (ldpc_rx)
396             me_config->ht_cap.ht_capa_info |= MAC_HTCAPA_LDPC;
397         if (ht40)
398             me_config->ht_cap.ht_capa_info |= MAC_HTCAPA_40_MHZ;
399         #if !NX_HE
400         me_config->ht_cap.ht_capa_info |= MAC_HTCAPA_GREEN_FIELD;
401         #endif
402         if (sgi)
403         {
404             me_config->ht_cap.ht_capa_info |= MAC_HTCAPA_SHORTGI_20;
405             if (ht40)
406                 me_config->ht_cap.ht_capa_info |= MAC_HTCAPA_SHORTGI_40;
407         }
408         if (nss > 1)
409             me_config->ht_cap.ht_capa_info |= MAC_HTCAPA_TX_STBC;
410         me_config->ht_cap.ht_capa_info |= (1 << MAC_HTCAPA_RX_STBC_OFT);
411 
412         me_config->ht_cap.a_mpdu_param = ((3 << MAC_AMPDU_LEN_EXP_OFT) |
413                                          (7 << MAC_AMPDU_MIN_SPACING_OFT));
414         me_config->ht_cap.mcs_rate[0] = 0xff; /* RX MCS0-7*/
415         if (nss > 1)
416             me_config->ht_cap.mcs_rate[1] = 0xff; /* RX MCS8-15 */
417         if (ht40)
418             me_config->ht_cap.mcs_rate[4] = 1; /* RX MCS32 */
419 
420         if (sgi && ht40)
421             max_rate = 150;
422         else if (sgi)
423             max_rate = 72;
424         else if (ht40)
425             max_rate = 135;
426         else
427             max_rate = 65;
428 
429         me_config->ht_cap.mcs_rate[10] = max_rate * nss; /* highest supported rate */
430         me_config->ht_cap.mcs_rate[12] = 1;              /* TX mcs same as RX mcs */
431 
432         me_config->ht_cap.ht_extended_capa = 0;
433         me_config->ht_cap.tx_beamforming_capa = 0;
434         me_config->ht_cap.asel_capa = 0;
435     }
436     else
437     {
438         ht40 = false;
439     }
440 
441     if (me_config->vht_supp)
442     {
443         int i;
444         me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_MAX_MPDU_LENGTH_3895;
445         me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_SUPP_CHAN_WIDTH_80;
446 
447         if (ldpc_rx)
448             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_RXLDPC;
449         if (sgi80)
450             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_SHORT_GI_80;
451         if (nss > 1)
452             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_TXSTBC;
453         if (stbc)
454             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_RXSTBC_1;
455         if (bfmer)
456             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_SU_BEAMFORMER_CAPABLE;
457         if (bfmee)
458             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_SU_BEAMFORMEE_CAPABLE;
459         me_config->vht_cap.vht_capa_info |= (nss - 1 ) << MAC_VHTCAPA_SOUNDING_DIMENSIONS_OFT;
460         if (mu_tx)
461             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_MU_BEAMFORMER_CAPABLE;
462         if (mu_rx)
463             me_config->vht_cap.vht_capa_info |= MAC_VHTCAPA_MU_BEAMFORMEE_CAPABLE;
464 
465         me_config->vht_cap.vht_capa_info |= (7 << MAC_VHTCAPA_MAX_A_MPDU_LENGTH_EXP_OFT);
466         me_config->vht_cap.vht_capa_info |= (3 << MAC_VHTCAPA_BEAMFORMEE_STS_OFT);
467 
468         me_config->vht_cap.rx_mcs_map = vht_mcs; /* RX MCS for 1 NSS */
469         for (i = 1; i < nss; i++) /* RX MCS for 2 NSS (limit to mcs7) */
470             me_config->vht_cap.rx_mcs_map |= MAC_VHT_MCS_MAP_0_7 << (2 * i);
471         for (; i < 8; i++) /* RX MCS for non-supported NSS */
472             me_config->vht_cap.rx_mcs_map |= MAC_VHT_MCS_MAP_NONE << (2 * i);
473         me_config->vht_cap.rx_highest = 200 * nss;
474 
475         me_config->vht_cap.tx_mcs_map = vht_mcs; /* TX MCS for 1 NSS */
476         if (vht_mcs > MAC_VHT_MCS_MAP_0_9)
477             vht_mcs = MAC_VHT_MCS_MAP_0_9;
478         for (i = 1; i < nss; i++) /* TX MCS for 2 NSS (limit to mcs8) */
479             me_config->vht_cap.tx_mcs_map |= vht_mcs << (2 * i);
480         for (; i < 8; i++) /* TX MCS for non-supported NSS */
481             me_config->vht_cap.tx_mcs_map |= MAC_VHT_MCS_MAP_NONE << (2 * i);
482         me_config->vht_cap.tx_highest = 200 * nss;
483     }
484     else
485     {
486         vht80 = false;
487     }
488 
489     #if NX_HE
490     if (me_config->he_supp)
491     {
492         int i;
493         struct mac_hecapability *he_cap = &me_config->he_cap;
494 
495         memset(he_cap, 0, sizeof(*he_cap));
496 
497         he_cap->ppe_thres[0] = 0x08;
498         he_cap->ppe_thres[1] = 0x1C;
499         he_cap->ppe_thres[2] = 0x07;
500 
501         HE_MAC_CAPA_BIT_SET(he_cap, ALL_ACK);
502         HE_MAC_CAPA_BIT_SET(he_cap, NDP_FB_REP);
503         HE_MAC_CAPA_BIT_SET(he_cap, 32BIT_BA_BITMAP);
504         HE_MAC_CAPA_BIT_SET(he_cap, MU_CASCADING);
505         HE_MAC_CAPA_BIT_SET(he_cap, ACK_EN);
506         HE_MAC_CAPA_BIT_SET(he_cap, OM_CONTROL);
507         HE_MAC_CAPA_BIT_SET(he_cap, OFDMA_RA);
508         HE_MAC_CAPA_BIT_SET(he_cap, HTC_HE);
509         HE_MAC_CAPA_BIT_SET(he_cap, TSR);
510         HE_MAC_CAPA_BIT_SET(he_cap, BSR); // TBD
511         HE_MAC_CAPA_BIT_SET(he_cap, BSRP_BQRP_A_MPDU_AGG);
512 
513         HE_PHY_CAPA_BIT_SET(he_cap, HE_SU_PPDU_1x_LTF_AND_GI_0_8US);
514         HE_PHY_CAPA_BIT_SET(he_cap, NDP_4x_LTF_AND_3_2US);
515         HE_PHY_CAPA_BIT_SET(he_cap, PPE_THRESHOLD_PRESENT);
516 
517         HE_PHY_CAPA_BIT_SET(he_cap, NG16_SU_FEEDBACK);
518         //HE_PHY_CAPA_BIT_SET(he_cap, NG16_MU_FEEDBACK);
519         HE_PHY_CAPA_BIT_SET(he_cap, CODEBOOK_SIZE_42_SU);
520         //HE_PHY_CAPA_BIT_SET(he_cap, CODEBOOK_SIZE_75_MU);
521         HE_PHY_CAPA_BIT_SET(he_cap, TRIG_SU_BEAMFORMER_FB);
522         //HE_PHY_CAPA_BIT_SET(he_cap, TRIG_MU_BEAMFORMER_FB);
523         HE_PHY_CAPA_BIT_SET(he_cap, TRIG_CQI_FB);
524 
525         HE_PHY_CAPA_BIT_SET(he_cap, FULL_BW_UL_MU_MIMO);
526 
527         if (bfmee)
528         {
529             HE_PHY_CAPA_BIT_SET(he_cap, SU_BEAMFORMEE);
530             //HE_PHY_CAPA_VAL_SET(he_cap, BFMEE_MAX_STS_UNDER_80MHZ, 4);
531         }
532 
533         if (ht40)
534         {
535             HE_PHY_CAPA_VAL_SET(he_cap, CHAN_WIDTH_SET, 40MHZ_IN_2G);
536             he_cap->ppe_thres[0] |= 0x10;
537         }
538         if (ldpc_rx)
539             HE_PHY_CAPA_BIT_SET(he_cap, LDPC_CODING_IN_PAYLOAD);
540         else
541             // If no LDPC is supported, we have to limit to MCS0_9, as LDPC is mandatory
542             // for MCS 10 and 11
543             he_mcs = co_min(he_mcs, MAC_HE_MCS_MAP_0_9);
544 
545         if (stbc) {
546             //HE_PHY_CAPA_BIT_SET(he_cap, STBC_TX_UNDER_80MHZ); // not support
547             HE_PHY_CAPA_BIT_SET(he_cap, STBC_RX_UNDER_80MHZ);
548         }
549 
550         memset(&he_cap->mcs_supp, 0, sizeof(he_cap->mcs_supp));
551         he_cap->mcs_supp.rx_mcs_80 = co_min(he_mcs, MAC_HE_MCS_MAP_0_9);
552         for (i = 1; i < nss; i++) {
553             uint16_t unsup_for_ss = MAC_HE_MCS_MAP_NONE << (i*2);
554             he_cap->mcs_supp.rx_mcs_80 |= MAC_HE_MCS_MAP_0_7 << (i*2);
555             he_cap->mcs_supp.rx_mcs_160 |= unsup_for_ss;
556             he_cap->mcs_supp.rx_mcs_80p80 |= unsup_for_ss;
557         }
558         for (; i < 8; i++) {
559             uint16_t unsup_for_ss = MAC_HE_MCS_MAP_NONE << (i*2);
560             he_cap->mcs_supp.rx_mcs_80 |= unsup_for_ss;
561             he_cap->mcs_supp.rx_mcs_160 |= unsup_for_ss;
562             he_cap->mcs_supp.rx_mcs_80p80 |= unsup_for_ss;
563         }
564         he_cap->mcs_supp.tx_mcs_80 = he_mcs;
565         for (i = 1; i < nss; i++) {
566             uint16_t unsup_for_ss = MAC_HE_MCS_MAP_NONE << (i*2);
567             he_cap->mcs_supp.tx_mcs_80 |= MAC_HE_MCS_MAP_0_7 << (i*2);
568             he_cap->mcs_supp.tx_mcs_160 |= unsup_for_ss;
569             he_cap->mcs_supp.tx_mcs_80p80 |= unsup_for_ss;
570         }
571         for (; i < 8; i++) {
572             uint16_t unsup_for_ss = MAC_HE_MCS_MAP_NONE << (i*2);
573             he_cap->mcs_supp.tx_mcs_80 |= unsup_for_ss;
574             he_cap->mcs_supp.tx_mcs_160 |= unsup_for_ss;
575             he_cap->mcs_supp.tx_mcs_80p80 |= unsup_for_ss;
576         }
577     }
578     #endif
579 
580     if (vht80)
581         me_config->phy_bw_max = PHY_CHNL_BW_80;
582     else if (ht40)
583         me_config->phy_bw_max = PHY_CHNL_BW_40;
584     else
585         me_config->phy_bw_max = PHY_CHNL_BW_20;
586 }
587 
588 /**
589  ****************************************************************************************
590  * @brief Return the channel associated to a given frequency
591  *
592  * @param[in] freq Channel frequency
593  *
594  * @return Channel definition whose primary frequency is the requested one and NULL
595  * no such channel doesn't exist.
596  ****************************************************************************************
597  */
fhost_chan_get(int freq)598 struct mac_chan_def *fhost_chan_get(int freq)
599 {
600     int i, nb_chan;
601     struct mac_chan_def *chans, *chan = NULL;
602 
603     if (freq < PHY_FREQ_5G)
604     {
605         chans = fhost_chan.chan2G4;
606         nb_chan = fhost_chan.chan2G4_cnt;
607     }
608     else
609     {
610         chans = fhost_chan.chan5G;
611         nb_chan = fhost_chan.chan5G_cnt;
612     }
613 
614     for (i = 0; i < nb_chan; i++, chans++)
615     {
616         if (freq == chans->freq)
617         {
618             chan = chans;
619             break;
620         }
621     }
622 
623     return chan;
624 }
625 
626 #if (PLF_HW_PXP == 1)
627 extern uint8_t is_ap;
628 #endif /* PLF_HW_PXP */
629 
set_mac_address(uint8_t * addr)630 void set_mac_address(uint8_t *addr)
631 {
632     if (!addr) {
633         unsigned int ap_config;
634         int ret;
635         ret = flash_wifi_ap_config_read(&ap_config);
636         if (ret) {
637             ap_config = 0;
638         }
639         if (ap_config & WIFI_AP_CONFIG_FORCED_AP_MODE_EN) {
640             ret = flash_wifi_ap_macaddr_read(fhost_mac_addr);
641         } else {
642             ret = flash_wifi_sta_macaddr_read(fhost_mac_addr);
643         }
644         if (ret) {
645             fhost_mac_addr[3] = (uint8_t)trng_get_word();
646             fhost_mac_addr[4] = (uint8_t)trng_get_word();
647             fhost_mac_addr[5] = (uint8_t)trng_get_word();
648             flash_wifi_sta_macaddr_write(fhost_mac_addr);
649         }
650     } else {
651         addr[0] &= ~0x01U; // could not be multicast address
652         MAC_ADDR_CPY(fhost_mac_addr, addr);
653     }
654 
655 }
656 
get_mac_address(void)657 uint8_t* get_mac_address(void)
658 {
659     return (uint8_t*)fhost_mac_addr;
660 }
661 
fhost_config_name_get(enum fhost_config_id id)662 const char * fhost_config_name_get(enum fhost_config_id id)
663 {
664     switch (id) {
665     case FHOST_CFG_MAC_ADDR:
666         return "MAC_ADDR";
667     case FHOST_CFG_HT:
668         return "HT";
669     case FHOST_CFG_40MHZ:
670         return "HT40";
671     case FHOST_CFG_VHT:
672         return "VHT";
673     case FHOST_CFG_VHT_MCS:
674         return "VHT_MCS";
675     case FHOST_CFG_HE:
676         return "HE";
677     case FHOST_CFG_HE_MCS:
678         return "HE_MCS";
679     case FHOST_CFG_LDPC:
680         return "LDPC";
681     case FHOST_CFG_STBC:
682         return "STBC";
683     default:
684         return "NOT_SUPPORT_YET";
685     }
686 }
687 
fhost_config_value_get(enum fhost_config_id id)688 uint32_t fhost_config_value_get(enum fhost_config_id id)
689 {
690     switch (id) {
691     case FHOST_CFG_MAC_ADDR:
692         return (uint32_t)fhost_mac_addr; // pointer in RAM
693     case FHOST_CFG_HT:
694         return (uint32_t)ht_support;
695     case FHOST_CFG_40MHZ:
696         return (uint32_t)ht_40mhz;
697     case FHOST_CFG_VHT:
698         return (uint32_t)vht_support;
699     case FHOST_CFG_VHT_MCS:
700         return (uint32_t)vht_mcs;
701     case FHOST_CFG_HE:
702         return (uint32_t)he_support;
703     case FHOST_CFG_HE_MCS:
704         return (uint32_t)he_mcs;
705     case FHOST_CFG_LDPC:
706         return (uint32_t)ldpc;
707     case FHOST_CFG_STBC:
708         return (uint32_t)stbc;
709     default:
710         return 0;
711     }
712 }
713 
fhost_config_value_set(enum fhost_config_id id,uint32_t val)714 void fhost_config_value_set(enum fhost_config_id id, uint32_t val)
715 {
716     switch (id) {
717     case FHOST_CFG_MAC_ADDR:
718         // do nothing
719         break;
720     case FHOST_CFG_HT:
721         ht_support = val;
722         break;
723     case FHOST_CFG_40MHZ:
724         ht_40mhz = val;
725         break;
726     case FHOST_CFG_VHT:
727         vht_support = val;
728         break;
729     case FHOST_CFG_VHT_MCS:
730         vht_mcs = val;
731         break;
732     case FHOST_CFG_HE:
733         he_support = val;
734         break;
735     case FHOST_CFG_HE_MCS:
736         he_mcs = val;
737         break;
738     case FHOST_CFG_LDPC:
739         ldpc = val;
740         break;
741     case FHOST_CFG_STBC:
742         stbc = val;
743         break;
744     default:
745         break;
746     }
747 }
748