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