it cause ap6xxx wifi con't open
[GitHub/LineageOS/G12/android_hardware_amlogic_kernel-modules_dhd-driver.git] / bcmdhd.1.363.59.144.x.cn / dhd_config.c
1
2 #include <typedefs.h>
3 #include <osl.h>
4
5 #include <bcmutils.h>
6 #include <hndsoc.h>
7 #include <bcmsdbus.h>
8 #if defined(HW_OOB) || defined(FORCE_WOWLAN)
9 #include <bcmdefs.h>
10 #include <bcmsdh.h>
11 #include <sdio.h>
12 #include <sbchipc.h>
13 #endif
14
15 #include <dhd_config.h>
16 #include <dhd_dbg.h>
17
18 /* message levels */
19 #define CONFIG_ERROR_LEVEL 0x0001
20 #define CONFIG_TRACE_LEVEL 0x0002
21
22 uint config_msg_level = CONFIG_ERROR_LEVEL;
23
24 #define CONFIG_ERROR(x) \
25 do { \
26 if (config_msg_level & CONFIG_ERROR_LEVEL) { \
27 printk(KERN_ERR "CONFIG-ERROR) "); \
28 printk x; \
29 } \
30 } while (0)
31 #define CONFIG_TRACE(x) \
32 do { \
33 if (config_msg_level & CONFIG_TRACE_LEVEL) { \
34 printk(KERN_ERR "CONFIG-TRACE) "); \
35 printk x; \
36 } \
37 } while (0)
38
39 #define MAXSZ_BUF 1000
40 #define MAXSZ_CONFIG 4096
41
42 #define FW_TYPE_STA 0
43 #define FW_TYPE_APSTA 1
44 #define FW_TYPE_P2P 2
45 #define FW_TYPE_ES 3
46 #define FW_TYPE_MFG 4
47 #define FW_TYPE_G 0
48 #define FW_TYPE_AG 1
49
50 #ifdef CONFIG_PATH_AUTO_SELECT
51 #ifdef BCMSDIO
52 #define CONFIG_BCM4330B2 "config_40183b2.txt"
53 #define CONFIG_BCM43362A0 "config_40181a0.txt"
54 #define CONFIG_BCM43362A2 "config_40181a2.txt"
55 #define CONFIG_BCM43438A0 "config_43438a0.txt"
56 #define CONFIG_BCM43438A1 "config_43438a1.txt"
57 #define CONFIG_BCM43436B0 "config_43436b0.txt"
58 #define CONFIG_BCM4334B1 "config_4334b1.txt"
59 #define CONFIG_BCM43341B0 "config_43341b0.txt"
60 #define CONFIG_BCM43241B4 "config_43241b4.txt"
61 #define CONFIG_BCM4339A0 "config_4339a0.txt"
62 #define CONFIG_BCM43454C0 "config_43454c0.txt"
63 #define CONFIG_BCM43455C0 "config_43455c0.txt"
64 #define CONFIG_BCM43456C5 "config_43456c5.txt"
65 #define CONFIG_BCM4354A1 "config_4354a1.txt"
66 #endif
67 #define CONFIG_BCM4356A2 "config_4356a2.txt"
68 #define CONFIG_BCM4358A3 "config_4358a3.txt"
69 #define CONFIG_BCM4359B1 "config_4359b1.txt"
70 #define CONFIG_BCM4359C0 "config_4359c0.txt"
71 #endif
72
73 #ifdef BCMSDIO
74 #define SBSDIO_CIS_SIZE_LIMIT 0x200
75
76 #define FW_BCM4330B2 "fw_bcm40183b2"
77 #define FW_BCM4330B2_AG "fw_bcm40183b2_ag"
78 #define FW_BCM43362A0 "fw_bcm40181a0"
79 #define FW_BCM43362A2 "fw_bcm40181a2"
80 #define FW_BCM4334B1 "fw_bcm4334b1_ag"
81 #define FW_BCM43438A0 "fw_bcm43438a0"
82 #define FW_BCM43438A1 "fw_bcm43438a1"
83 #define FW_BCM43436B0 "fw_bcm43436b0"
84 #define FW_BCM43012B0 "fw_bcm43012b0"
85 #define FW_BCM43341B1 "fw_bcm43341b0_ag"
86 #define FW_BCM43241B4 "fw_bcm43241b4_ag"
87 #define FW_BCM4339A0 "fw_bcm4339a0_ag"
88 #define FW_BCM43455C0 "fw_bcm43455c0_ag"
89 #define FW_BCM43456C5 "fw_bcm43456c5_ag"
90 #define FW_BCM4354A1 "fw_bcm4354a1_ag"
91 #define FW_BCM4356A2 "fw_bcm4356a2_ag"
92 #define FW_BCM4358A3 "fw_bcm4358a3_ag"
93 #define FW_BCM4359B1 "fw_bcm4359b1_ag"
94 #define FW_BCM4359C0 "fw_bcm4359c0_ag"
95
96 #define CLM_BCM43012B0 "clm_bcm43012b0"
97 #endif
98 #ifdef BCMPCIE
99 #define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"
100 #endif
101
102 #define htod32(i) i
103 #define htod16(i) i
104 #define dtoh32(i) i
105 #define dtoh16(i) i
106 #define htodchanspec(i) i
107 #define dtohchanspec(i) i
108
109 #ifdef BCMSDIO
110 void
111 dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list)
112 {
113 int i;
114
115 CONFIG_TRACE(("%s called\n", __FUNCTION__));
116 if (mac_list->m_mac_list_head) {
117 for (i=0; i<mac_list->count; i++) {
118 if (mac_list->m_mac_list_head[i].mac) {
119 CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac));
120 kfree(mac_list->m_mac_list_head[i].mac);
121 }
122 }
123 CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head));
124 kfree(mac_list->m_mac_list_head);
125 }
126 mac_list->count = 0;
127 }
128
129 void
130 dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list)
131 {
132 CONFIG_TRACE(("%s called\n", __FUNCTION__));
133
134 if (chip_nv_list->m_chip_nv_path_head) {
135 CONFIG_TRACE(("%s Free %p\n", __FUNCTION__, chip_nv_list->m_chip_nv_path_head));
136 kfree(chip_nv_list->m_chip_nv_path_head);
137 }
138 chip_nv_list->count = 0;
139 }
140
141 #if defined(HW_OOB) || defined(FORCE_WOWLAN)
142 void
143 dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip)
144 {
145 uint32 gpiocontrol, addr;
146
147 if (CHIPID(chip) == BCM43362_CHIP_ID) {
148 printf("%s: Enable HW OOB for 43362\n", __FUNCTION__);
149 addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);
150 gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);
151 gpiocontrol |= 0x2;
152 bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);
153 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);
154 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);
155 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);
156 }
157 }
158 #endif
159
160 int
161 dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac)
162 {
163 int i, err = -1;
164 uint8 *ptr = 0;
165 unsigned char tpl_code, tpl_link='\0';
166 uint8 header[3] = {0x80, 0x07, 0x19};
167 uint8 *cis;
168
169 if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) {
170 CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__));
171 return err;
172 }
173 bzero(cis, SBSDIO_CIS_SIZE_LIMIT);
174
175 if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) {
176 CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err));
177 MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
178 return err;
179 }
180 err = -1; // reset err;
181 ptr = cis;
182 do {
183 /* 0xff means we're done */
184 tpl_code = *ptr;
185 ptr++;
186 if (tpl_code == 0xff)
187 break;
188
189 /* null entries have no link field or data */
190 if (tpl_code == 0x00)
191 continue;
192
193 tpl_link = *ptr;
194 ptr++;
195 /* a size of 0xff also means we're done */
196 if (tpl_link == 0xff)
197 break;
198 if (config_msg_level & CONFIG_TRACE_LEVEL) {
199 printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n",
200 __FUNCTION__, tpl_code, tpl_link, *ptr);
201 printk("%s: value:", __FUNCTION__);
202 for (i=0; i<tpl_link-1; i++) {
203 printk("%02x ", ptr[i+1]);
204 if ((i+1) % 16 == 0)
205 printk("\n");
206 }
207 printk("\n");
208 }
209
210 if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19)
211 break;
212
213 ptr += tpl_link;
214 } while (1);
215
216 if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19) {
217 /* Normal OTP */
218 memcpy(mac, ptr+1, 6);
219 err = 0;
220 } else {
221 ptr = cis;
222 /* Special OTP */
223 if (bcmsdh_reg_read(sdh, SI_ENUM_BASE, 4) == 0x16044330) {
224 for (i=0; i<SBSDIO_CIS_SIZE_LIMIT; i++) {
225 if (!memcmp(header, ptr, 3)) {
226 memcpy(mac, ptr+3, 6);
227 err = 0;
228 break;
229 }
230 ptr++;
231 }
232 }
233 }
234
235 ASSERT(cis);
236 MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
237
238 return err;
239 }
240
241 void
242 dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path)
243 {
244 int i, j;
245 uint8 mac[6]={0};
246 int fw_num=0, mac_num=0;
247 uint32 oui, nic;
248 wl_mac_list_t *mac_list;
249 wl_mac_range_t *mac_range;
250 char *pfw_name;
251 int fw_type, fw_type_new;
252
253 mac_list = dhd->conf->fw_by_mac.m_mac_list_head;
254 fw_num = dhd->conf->fw_by_mac.count;
255 if (!mac_list || !fw_num)
256 return;
257
258 if (dhd_conf_get_mac(dhd, sdh, mac)) {
259 CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));
260 return;
261 }
262 oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
263 nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
264
265 /* find out the last '/' */
266 i = strlen(fw_path);
267 while (i > 0) {
268 if (fw_path[i] == '/') break;
269 i--;
270 }
271 pfw_name = &fw_path[i+1];
272 fw_type = (strstr(pfw_name, "_mfg") ?
273 FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ?
274 FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ?
275 FW_TYPE_P2P : FW_TYPE_STA)));
276
277 for (i=0; i<fw_num; i++) {
278 mac_num = mac_list[i].count;
279 mac_range = mac_list[i].mac;
280 fw_type_new = (strstr(mac_list[i].name, "_mfg") ?
281 FW_TYPE_MFG : (strstr(mac_list[i].name, "_apsta") ?
282 FW_TYPE_APSTA : (strstr(mac_list[i].name, "_p2p") ?
283 FW_TYPE_P2P : FW_TYPE_STA)));
284 if (fw_type != fw_type_new) {
285 printf("%s: fw_typ=%d != fw_type_new=%d\n", __FUNCTION__, fw_type, fw_type_new);
286 continue;
287 }
288 for (j=0; j<mac_num; j++) {
289 if (oui == mac_range[j].oui) {
290 if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
291 strcpy(pfw_name, mac_list[i].name);
292 printf("%s: matched oui=0x%06X, nic=0x%06X\n",
293 __FUNCTION__, oui, nic);
294 printf("%s: fw_path=%s\n", __FUNCTION__, fw_path);
295 return;
296 }
297 }
298 }
299 }
300 }
301
302 void
303 dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path)
304 {
305 int i, j;
306 uint8 mac[6]={0};
307 int nv_num=0, mac_num=0;
308 uint32 oui, nic;
309 wl_mac_list_t *mac_list;
310 wl_mac_range_t *mac_range;
311 char *pnv_name;
312
313 mac_list = dhd->conf->nv_by_mac.m_mac_list_head;
314 nv_num = dhd->conf->nv_by_mac.count;
315 if (!mac_list || !nv_num)
316 return;
317
318 if (dhd_conf_get_mac(dhd, sdh, mac)) {
319 CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));
320 return;
321 }
322 oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
323 nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
324
325 /* find out the last '/' */
326 i = strlen(nv_path);
327 while (i > 0) {
328 if (nv_path[i] == '/') break;
329 i--;
330 }
331 pnv_name = &nv_path[i+1];
332
333 for (i=0; i<nv_num; i++) {
334 mac_num = mac_list[i].count;
335 mac_range = mac_list[i].mac;
336 for (j=0; j<mac_num; j++) {
337 if (oui == mac_range[j].oui) {
338 if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
339 strcpy(pnv_name, mac_list[i].name);
340 printf("%s: matched oui=0x%06X, nic=0x%06X\n",
341 __FUNCTION__, oui, nic);
342 printf("%s: nv_path=%s\n", __FUNCTION__, nv_path);
343 return;
344 }
345 }
346 }
347 }
348 }
349 #endif
350
351 void
352 dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
353 {
354 int fw_type, ag_type;
355 uint chip, chiprev;
356 int i;
357 char fw_tail[20];
358
359 chip = dhd->conf->chip;
360 chiprev = dhd->conf->chiprev;
361
362 if (fw_path[0] == '\0') {
363 #ifdef CONFIG_BCMDHD_FW_PATH
364 bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
365 if (fw_path[0] == '\0')
366 #endif
367 {
368 printf("firmware path is null\n");
369 return;
370 }
371 }
372 #ifndef FW_PATH_AUTO_SELECT
373 return;
374 #endif
375
376 /* find out the last '/' */
377 i = strlen(fw_path);
378 while (i > 0) {
379 if (fw_path[i] == '/') break;
380 i--;
381 }
382 #ifdef BAND_AG
383 ag_type = FW_TYPE_AG;
384 #else
385 ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G;
386 #endif
387 fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG :
388 (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA :
389 (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P :
390 (strstr(&fw_path[i], "_es") ? FW_TYPE_ES :
391 FW_TYPE_STA))));
392
393 if (fw_type == FW_TYPE_STA)
394 strcpy(fw_tail, ".bin");
395 else if (fw_type == FW_TYPE_APSTA)
396 strcpy(fw_tail, "_apsta.bin");
397 else if (fw_type == FW_TYPE_P2P)
398 strcpy(fw_tail, "_p2p.bin");
399 else if (fw_type == FW_TYPE_ES)
400 strcpy(fw_tail, "_es.bin");
401 else if (fw_type == FW_TYPE_MFG)
402 strcpy(fw_tail, "_mfg.bin");
403
404 switch (chip) {
405 #ifdef BCMSDIO
406 case BCM4330_CHIP_ID:
407 if (ag_type == FW_TYPE_G) {
408 if (chiprev == BCM4330B2_CHIP_REV)
409 strcpy(&fw_path[i+1], FW_BCM4330B2);
410 } else {
411 if (chiprev == BCM4330B2_CHIP_REV)
412 strcpy(&fw_path[i+1], FW_BCM4330B2_AG);
413 }
414 break;
415 case BCM43362_CHIP_ID:
416 if (chiprev == BCM43362A0_CHIP_REV)
417 strcpy(&fw_path[i+1], FW_BCM43362A0);
418 else
419 strcpy(&fw_path[i+1], FW_BCM43362A2);
420 break;
421 case BCM43430_CHIP_ID:
422 if (chiprev == BCM43430A0_CHIP_REV)
423 strcpy(&fw_path[i+1], FW_BCM43438A0);
424 else if (chiprev == BCM43430A1_CHIP_REV)
425 strcpy(&fw_path[i+1], FW_BCM43438A1);
426 else if (chiprev == BCM43430A2_CHIP_REV)
427 strcpy(&fw_path[i+1], FW_BCM43436B0);
428 break;
429 case BCM43012_CHIP_ID:
430 if (chiprev == BCM43012B0_CHIP_REV)
431 strcpy(&fw_path[i+1], FW_BCM43012B0);
432 break;
433 case BCM4334_CHIP_ID:
434 if (chiprev == BCM4334B1_CHIP_REV)
435 strcpy(&fw_path[i+1], FW_BCM4334B1);
436 break;
437 case BCM43340_CHIP_ID:
438 case BCM43341_CHIP_ID:
439 if (chiprev == BCM43341B0_CHIP_REV)
440 strcpy(&fw_path[i+1], FW_BCM43341B1);
441 break;
442 case BCM4324_CHIP_ID:
443 if (chiprev == BCM43241B4_CHIP_REV)
444 strcpy(&fw_path[i+1], FW_BCM43241B4);
445 break;
446 case BCM4335_CHIP_ID:
447 if (chiprev == BCM4335A0_CHIP_REV)
448 strcpy(&fw_path[i+1], FW_BCM4339A0);
449 break;
450 case BCM4339_CHIP_ID:
451 if (chiprev == BCM4339A0_CHIP_REV)
452 strcpy(&fw_path[i+1], FW_BCM4339A0);
453 break;
454 case BCM4345_CHIP_ID:
455 case BCM43454_CHIP_ID:
456 if (chiprev == BCM43455C0_CHIP_REV)
457 strcpy(&fw_path[i+1], FW_BCM43455C0);
458 else if (chiprev == BCM43456C5_CHIP_REV)
459 strcpy(&fw_path[i+1], FW_BCM43456C5);
460 break;
461 case BCM4354_CHIP_ID:
462 if (chiprev == BCM4354A1_CHIP_REV)
463 strcpy(&fw_path[i+1], FW_BCM4354A1);
464 else if (chiprev == BCM4356A2_CHIP_REV)
465 strcpy(&fw_path[i+1], FW_BCM4356A2);
466 break;
467 case BCM4356_CHIP_ID:
468 case BCM4371_CHIP_ID:
469 if (chiprev == BCM4356A2_CHIP_REV)
470 strcpy(&fw_path[i+1], FW_BCM4356A2);
471 break;
472 case BCM43569_CHIP_ID:
473 if (chiprev == BCM4358A3_CHIP_REV)
474 strcpy(&fw_path[i+1], FW_BCM4358A3);
475 break;
476 case BCM4359_CHIP_ID:
477 if (chiprev == BCM4359B1_CHIP_REV)
478 strcpy(&fw_path[i+1], FW_BCM4359B1);
479 else if (chiprev == BCM4359C0_CHIP_REV)
480 strcpy(&fw_path[i+1], FW_BCM4359C0);
481 break;
482 #endif
483 #ifdef BCMPCIE
484 case BCM4354_CHIP_ID:
485 case BCM4356_CHIP_ID:
486 if (chiprev == BCM4356A2_CHIP_REV)
487 strcpy(&fw_path[i+1], FW_BCM4356A2);
488 break;
489 #endif
490 default:
491 strcpy(&fw_path[i+1], "fw_bcmdhd");
492 }
493 strcat(fw_path, fw_tail);
494
495 CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path));
496 }
497
498 void
499 dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
500 {
501 uint chip, chiprev;
502 int i;
503 char fw_tail[20];
504
505 chip = dhd->conf->chip;
506 chiprev = dhd->conf->chiprev;
507
508 if (clm_path[0] == '\0') {
509 printf("clm path is null\n");
510 return;
511 }
512
513 /* find out the last '/' */
514 i = strlen(clm_path);
515 while (i > 0) {
516 if (clm_path[i] == '/') break;
517 i--;
518 }
519
520 strcpy(fw_tail, ".blob");
521
522 switch (chip) {
523 #ifdef BCMSDIO
524 case BCM43012_CHIP_ID:
525 if (chiprev == BCM43012B0_CHIP_REV)
526 strcpy(&clm_path[i+1], CLM_BCM43012B0);
527 break;
528 #endif
529 default:
530 strcpy(&clm_path[i+1], "clm_bcmdhd");
531 }
532 strcat(clm_path, fw_tail);
533
534 CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_path));
535 }
536
537 void
538 dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)
539 {
540 int matched=-1;
541 uint chip, chiprev;
542 int i;
543
544 chip = dhd->conf->chip;
545 chiprev = dhd->conf->chiprev;
546
547 for (i=0; i<dhd->conf->nv_by_chip.count; i++) {
548 if (chip == dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip &&
549 chiprev == dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) {
550 matched = i;
551 break;
552 }
553 }
554 if (matched < 0)
555 return;
556
557 if (nv_path[0] == '\0') {
558 #ifdef CONFIG_BCMDHD_NVRAM_PATH
559 bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
560 if (nv_path[0] == '\0')
561 #endif
562 {
563 printf("nvram path is null\n");
564 return;
565 }
566 }
567
568 /* find out the last '/' */
569 i = strlen(nv_path);
570 while (i > 0) {
571 if (nv_path[i] == '/') break;
572 i--;
573 }
574
575 strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);
576
577 CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path));
578 }
579
580 void
581 dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path)
582 {
583 int i;
584
585 if (src_path[0] == '\0') {
586 printf("src_path is null\n");
587 return;
588 } else
589 strcpy(dst_path, src_path);
590
591 /* find out the last '/' */
592 i = strlen(dst_path);
593 while (i > 0) {
594 if (dst_path[i] == '/') break;
595 i--;
596 }
597 strcpy(&dst_path[i+1], dst_name);
598
599 CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));
600 }
601
602 #ifdef CONFIG_PATH_AUTO_SELECT
603 void
604 dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
605 {
606 uint chip, chiprev;
607 int i;
608
609 chip = dhd->conf->chip;
610 chiprev = dhd->conf->chiprev;
611
612 if (conf_path[0] == '\0') {
613 printf("config path is null\n");
614 return;
615 }
616
617 /* find out the last '/' */
618 i = strlen(conf_path);
619 while (i > 0) {
620 if (conf_path[i] == '/') break;
621 i--;
622 }
623
624 switch (chip) {
625 #ifdef BCMSDIO
626 case BCM4330_CHIP_ID:
627 if (chiprev == BCM4330B2_CHIP_REV)
628 strcpy(&conf_path[i+1], CONFIG_BCM4330B2);
629 break;
630 case BCM43362_CHIP_ID:
631 if (chiprev == BCM43362A0_CHIP_REV)
632 strcpy(&conf_path[i+1], CONFIG_BCM43362A0);
633 else
634 strcpy(&conf_path[i+1], CONFIG_BCM43362A2);
635 break;
636 case BCM43430_CHIP_ID:
637 if (chiprev == BCM43430A0_CHIP_REV)
638 strcpy(&conf_path[i+1], CONFIG_BCM43438A0);
639 else if (chiprev == BCM43430A1_CHIP_REV)
640 strcpy(&conf_path[i+1], CONFIG_BCM43438A1);
641 else if (chiprev == BCM43430A2_CHIP_REV)
642 strcpy(&conf_path[i+1], CONFIG_BCM43436B0);
643 break;
644 case BCM4334_CHIP_ID:
645 if (chiprev == BCM4334B1_CHIP_REV)
646 strcpy(&conf_path[i+1], CONFIG_BCM4334B1);
647 break;
648 case BCM43340_CHIP_ID:
649 case BCM43341_CHIP_ID:
650 if (chiprev == BCM43341B0_CHIP_REV)
651 strcpy(&conf_path[i+1], CONFIG_BCM43341B0);
652 break;
653 case BCM4324_CHIP_ID:
654 if (chiprev == BCM43241B4_CHIP_REV)
655 strcpy(&conf_path[i+1], CONFIG_BCM43241B4);
656 break;
657 case BCM4335_CHIP_ID:
658 if (chiprev == BCM4335A0_CHIP_REV)
659 strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
660 break;
661 case BCM43454_CHIP_ID:
662 if (chiprev == BCM43455C0_CHIP_REV)
663 strcpy(&conf_path[i+1], CONFIG_BCM43454C0);
664 break;
665 case BCM4345_CHIP_ID:
666 if (chiprev == BCM43455C0_CHIP_REV)
667 strcpy(&conf_path[i+1], CONFIG_BCM43455C0);
668 else if (chiprev == BCM43456C5_CHIP_REV)
669 strcpy(&conf_path[i+1], CONFIG_BCM43456C5);
670 break;
671 case BCM4339_CHIP_ID:
672 if (chiprev == BCM4339A0_CHIP_REV)
673 strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
674 break;
675 case BCM4354_CHIP_ID:
676 if (chiprev == BCM4354A1_CHIP_REV)
677 strcpy(&conf_path[i+1], CONFIG_BCM4354A1);
678 else if (chiprev == BCM4356A2_CHIP_REV)
679 strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
680 break;
681 case BCM4356_CHIP_ID:
682 case BCM4371_CHIP_ID:
683 if (chiprev == BCM4356A2_CHIP_REV)
684 strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
685 break;
686 case BCM43569_CHIP_ID:
687 if (chiprev == BCM4358A3_CHIP_REV)
688 strcpy(&conf_path[i+1], CONFIG_BCM4358A3);
689 break;
690 case BCM4359_CHIP_ID:
691 if (chiprev == BCM4359B1_CHIP_REV)
692 strcpy(&conf_path[i+1], CONFIG_BCM4359B1);
693 else if (chiprev == BCM4359C0_CHIP_REV)
694 strcpy(&conf_path[i+1], CONFIG_BCM4359C0);
695 break;
696 #endif
697 #ifdef BCMPCIE
698 case BCM4354_CHIP_ID:
699 case BCM4356_CHIP_ID:
700 if (chiprev == BCM4356A2_CHIP_REV)
701 strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
702 break;
703 #endif
704 }
705
706 CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path));
707 }
708 #endif
709
710 int
711 dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,
712 int def, bool down)
713 {
714 int ret = -1;
715 char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */
716
717 if (val >= def) {
718 if (down) {
719 if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
720 CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
721 }
722 if (cmd == WLC_SET_VAR) {
723 printf("%s: set %s %d\n", __FUNCTION__, name, val);
724 bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));
725 if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
726 CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
727 } else {
728 printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);
729 if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)
730 CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
731 }
732 }
733
734 return ret;
735 }
736
737 int
738 dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,
739 int len, bool down)
740 {
741 char iovbuf[WLC_IOCTL_SMLEN];
742 int ret = -1;
743
744 if (down) {
745 if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
746 CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
747 }
748
749 if (cmd == WLC_SET_VAR) {
750 bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));
751 if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
752 CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
753 } else {
754 if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0)
755 CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
756 }
757
758 return ret;
759 }
760
761 int
762 dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)
763 {
764 char iovbuf[WLC_IOCTL_SMLEN];
765 int ret = -1;
766
767 if (cmd == WLC_GET_VAR) {
768 if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
769 ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);
770 if (!ret) {
771 memcpy(buf, iovbuf, len);
772 } else {
773 CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
774 }
775 } else {
776 CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name));
777 }
778 } else {
779 ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);
780 if (ret < 0)
781 CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
782 }
783
784 return ret;
785 }
786
787 uint
788 dhd_conf_get_band(dhd_pub_t *dhd)
789 {
790 uint band = WLC_BAND_AUTO;
791
792 if (dhd && dhd->conf)
793 band = dhd->conf->band;
794 else
795 CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
796
797 return band;
798 }
799
800 int
801 dhd_conf_set_country(dhd_pub_t *dhd)
802 {
803 int bcmerror = -1;
804
805 memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
806 printf("%s: set country %s, revision %d\n", __FUNCTION__,
807 dhd->conf->cspec.ccode, dhd->conf->cspec.rev);
808 dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);
809
810 return bcmerror;
811 }
812
813 int
814 dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
815 {
816 int bcmerror = -1;
817
818 memset(cspec, 0, sizeof(wl_country_t));
819 bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t));
820 if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0)
821 CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror));
822 else
823 printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);
824
825 return bcmerror;
826 }
827
828 int
829 dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)
830 {
831 int bcmerror = -1, i;
832 struct dhd_conf *conf = dhd->conf;
833
834 for (i = 0; i < conf->country_list.count; i++) {
835 if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) {
836 memcpy(cspec->ccode,
837 conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ);
838 cspec->rev = conf->country_list.cspec[i].rev;
839 printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);
840 return 0;
841 }
842 }
843
844 return bcmerror;
845 }
846
847 int
848 dhd_conf_fix_country(dhd_pub_t *dhd)
849 {
850 int bcmerror = -1;
851 uint band;
852 wl_uint32_list_t *list;
853 u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
854
855 if (!(dhd && dhd->conf)) {
856 return bcmerror;
857 }
858
859 memset(valid_chan_list, 0, sizeof(valid_chan_list));
860 list = (wl_uint32_list_t *)(void *) valid_chan_list;
861 list->count = htod32(WL_NUMCHANNELS);
862 if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {
863 CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));
864 }
865
866 band = dhd_conf_get_band(dhd);
867
868 if (bcmerror || ((band == WLC_BAND_AUTO || band == WLC_BAND_2G) &&
869 dtoh32(list->count)<11)) {
870 CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",
871 __FUNCTION__, bcmerror, dtoh32(list->count)));
872 if ((bcmerror = dhd_conf_set_country(dhd)) < 0) {
873 strcpy(dhd->conf->cspec.country_abbrev, "US");
874 dhd->conf->cspec.rev = 0;
875 strcpy(dhd->conf->cspec.ccode, "US");
876 dhd_conf_set_country(dhd);
877 }
878 }
879
880 return bcmerror;
881 }
882
883 bool
884 dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel)
885 {
886 int i;
887 bool match = false;
888
889 if (dhd && dhd->conf) {
890 if (dhd->conf->channels.count == 0)
891 return true;
892 for (i=0; i<dhd->conf->channels.count; i++) {
893 if (channel == dhd->conf->channels.channel[i])
894 match = true;
895 }
896 } else {
897 match = true;
898 CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
899 }
900
901 return match;
902 }
903
904 int
905 dhd_conf_set_roam(dhd_pub_t *dhd)
906 {
907 int bcmerror = -1;
908 struct dhd_conf *conf = dhd->conf;
909
910 dhd_roam_disable = conf->roam_off;
911 dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);
912
913 if (!conf->roam_off || !conf->roam_off_suspend) {
914 printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]);
915 dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",
916 (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);
917
918 printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]);
919 dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",
920 (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);
921
922 printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]);
923 dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",
924 (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);
925
926 dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);
927 }
928
929 return bcmerror;
930 }
931
932 void
933 dhd_conf_set_bw_cap(dhd_pub_t *dhd)
934 {
935 struct {
936 u32 band;
937 u32 bw_cap;
938 } param = {0, 0};
939
940 if (dhd->conf->bw_cap_2g >= 0) {
941 param.band = WLC_BAND_2G;
942 param.bw_cap = (uint)dhd->conf->bw_cap_2g;
943 printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap);
944 dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
945 }
946
947 if (dhd->conf->bw_cap_5g >= 0) {
948 param.band = WLC_BAND_5G;
949 param.bw_cap = (uint)dhd->conf->bw_cap_5g;
950 printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap);
951 dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
952 }
953 }
954
955 void
956 dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp)
957 {
958 int bcmerror = -1;
959 char iovbuf[WLC_IOCTL_SMLEN];
960 edcf_acparam_t *acparam;
961
962 bzero(iovbuf, sizeof(iovbuf));
963
964 /*
965 * Get current acparams, using buf as an input buffer.
966 * Return data is array of 4 ACs of wme params.
967 */
968 if (mode == 0)
969 bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));
970 else
971 bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf));
972 if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {
973 CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror));
974 return;
975 }
976 memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);
977
978 acparam = &acp[AC_BK];
979 CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
980 __FUNCTION__,
981 acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
982 acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
983 acparam->TXOP));
984 acparam = &acp[AC_BE];
985 CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
986 __FUNCTION__,
987 acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
988 acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
989 acparam->TXOP));
990 acparam = &acp[AC_VI];
991 CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
992 __FUNCTION__,
993 acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
994 acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
995 acparam->TXOP));
996 acparam = &acp[AC_VO];
997 CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
998 __FUNCTION__,
999 acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
1000 acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
1001 acparam->TXOP));
1002
1003 return;
1004 }
1005
1006 void
1007 dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci)
1008 {
1009 int aifsn, ecwmin, ecwmax, txop;
1010 edcf_acparam_t *acp;
1011 struct dhd_conf *conf = dhd->conf;
1012 wme_param_t *wme;
1013
1014 if (mode == 0)
1015 wme = &conf->wme_sta;
1016 else
1017 wme = &conf->wme_ap;
1018
1019 /* Default value */
1020 aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;
1021 ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;
1022 ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;
1023 txop = acparam_cur->TXOP;
1024
1025 /* Modified value */
1026 if (wme->aifsn[aci] > 0)
1027 aifsn = wme->aifsn[aci];
1028 if (wme->ecwmin[aci] > 0)
1029 ecwmin = wme->ecwmin[aci];
1030 if (wme->ecwmax[aci] > 0)
1031 ecwmax = wme->ecwmax[aci];
1032 if (wme->txop[aci] > 0)
1033 txop = wme->txop[aci];
1034
1035 if (!(wme->aifsn[aci] || wme->ecwmin[aci] ||
1036 wme->ecwmax[aci] || wme->txop[aci]))
1037 return;
1038
1039 /* Update */
1040 acp = acparam_cur;
1041 acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);
1042 acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);
1043 acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));
1044 acp->TXOP = txop;
1045
1046 printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
1047 __FUNCTION__, mode?"ap":"sta",
1048 acp->ACI, acp->ACI&EDCF_AIFSN_MASK,
1049 acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
1050 acp->TXOP);
1051
1052 /*
1053 * Now use buf as an output buffer.
1054 * Put WME acparams after "wme_ac\0" in buf.
1055 * NOTE: only one of the four ACs can be set at a time.
1056 */
1057 if (mode == 0)
1058 dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);
1059 else
1060 dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE);
1061
1062 }
1063
1064 void
1065 dhd_conf_set_wme(dhd_pub_t *dhd, int mode)
1066 {
1067 edcf_acparam_t acparam_cur[AC_COUNT];
1068
1069 if (dhd && dhd->conf) {
1070 if (!dhd->conf->force_wme_ac) {
1071 CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n",
1072 __FUNCTION__, dhd->conf->force_wme_ac));
1073 return;
1074 }
1075
1076 CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__));
1077 dhd_conf_get_wme(dhd, mode, acparam_cur);
1078
1079 dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK);
1080 dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE);
1081 dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI);
1082 dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO);
1083
1084 CONFIG_TRACE(("%s: After change:\n", __FUNCTION__));
1085 dhd_conf_get_wme(dhd, mode, acparam_cur);
1086 } else {
1087 CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
1088 }
1089
1090 return;
1091 }
1092
1093 #ifdef PKT_FILTER_SUPPORT
1094 void
1095 dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
1096 {
1097 int i, j;
1098 char str[16];
1099 #define MACS "%02x%02x%02x%02x%02x%02x"
1100
1101 /*
1102 * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well.
1103 * 1) dhd_master_mode=0
1104 * 2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
1105 * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E)
1106 * 1) dhd_master_mode=1
1107 * 2) pkt_filter_del=100, 102, 103, 104, 105
1108 * 3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E
1109 * 3. magic pkt: magic_pkt_filter_add=141 0 1 12
1110 * 4. Filter out netbios pkt:
1111 * Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089
1112 */
1113 for(i=0; i<dhd->conf->pkt_filter_add.count; i++) {
1114 dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];
1115 printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]);
1116 }
1117 dhd->pktfilter_count += i;
1118
1119 if (dhd->conf->magic_pkt_filter_add) {
1120 strcat(dhd->conf->magic_pkt_filter_add, " 0x");
1121 strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
1122 for (j=0; j<16; j++)
1123 strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
1124 strcat(dhd->conf->magic_pkt_filter_add, " 0x");
1125 strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
1126 sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));
1127 for (j=0; j<16; j++)
1128 strncat(dhd->conf->magic_pkt_filter_add, str, 12);
1129 dhd->pktfilter[dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add;
1130 dhd->pktfilter_count += 1;
1131 }
1132 }
1133
1134 bool
1135 dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)
1136 {
1137 int i;
1138
1139 if (dhd && dhd->conf) {
1140 for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {
1141 if (id == dhd->conf->pkt_filter_del.id[i]) {
1142 printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]);
1143 return true;
1144 }
1145 }
1146 return false;
1147 }
1148 return false;
1149 }
1150
1151 void
1152 dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)
1153 {
1154 dhd->pktfilter_count = 6;
1155 dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;
1156 dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
1157 dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";
1158 dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";
1159 dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;
1160 /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/
1161 dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;
1162
1163 /* IPv4 broadcast address XXX.XXX.XXX.255 */
1164 dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";
1165 dhd->pktfilter_count++;
1166 /* discard IPv4 multicast address 224.0.0.0/4 */
1167 dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";
1168 dhd->pktfilter_count++;
1169 /* discard IPv6 multicast address FF00::/8 */
1170 dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";
1171 dhd->pktfilter_count++;
1172 /* discard Netbios pkt */
1173 dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";
1174 dhd->pktfilter_count++;
1175
1176 }
1177 #endif /* PKT_FILTER_SUPPORT */
1178
1179 int
1180 dhd_conf_get_pm(dhd_pub_t *dhd)
1181 {
1182 if (dhd && dhd->conf)
1183 return dhd->conf->pm;
1184 return -1;
1185 }
1186
1187 #define AP_IN_SUSPEND 1
1188 #define AP_DOWN_IN_SUSPEND 2
1189 int
1190 dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd)
1191 {
1192 int mode = 0;
1193
1194 /* returned ap_in_suspend value:
1195 * 0: nothing
1196 * 1: ap enabled in suspend
1197 * 2: ap enabled, but down in suspend
1198 */
1199 if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
1200 mode = dhd->conf->ap_in_suspend;
1201 }
1202
1203 return mode;
1204 }
1205
1206 int
1207 dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend)
1208 {
1209 int mode = 0;
1210 uint wl_down = 1;
1211
1212 mode = dhd_conf_get_ap_mode_in_suspend(dhd);
1213 if (mode)
1214 printf("%s: suspend %d, mode %d\n", __FUNCTION__, suspend, mode);
1215 if (suspend) {
1216 if (mode == AP_IN_SUSPEND) {
1217 #ifdef SUSPEND_EVENT
1218 if (dhd->conf->suspend_eventmask_enable) {
1219 char *eventmask = dhd->conf->suspend_eventmask;
1220 dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);
1221 }
1222 #endif
1223 } else if (mode == AP_DOWN_IN_SUSPEND)
1224 dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down, sizeof(wl_down), TRUE, 0);
1225 } else {
1226 if (mode == AP_IN_SUSPEND) {
1227 #ifdef SUSPEND_EVENT
1228 if (dhd->conf->suspend_eventmask_enable) {
1229 char *eventmask = dhd->conf->resume_eventmask;
1230 dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);
1231 }
1232 #endif
1233 } else if (mode == AP_DOWN_IN_SUSPEND) {
1234 wl_down = 0;
1235 dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down, sizeof(wl_down), TRUE, 0);
1236 }
1237 }
1238
1239 return mode;
1240 }
1241
1242 #ifdef PROP_TXSTATUS
1243 int
1244 dhd_conf_get_disable_proptx(dhd_pub_t *dhd)
1245 {
1246 struct dhd_conf *conf = dhd->conf;
1247 int disable_proptx = -1;
1248 int fw_proptx = 0;
1249
1250 /* check fw proptx priority:
1251 * 1st: check fw support by wl cap
1252 * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default
1253 * if you would like to disable it, please set disable_proptx=1 in config.txt
1254 * 3th: disable when proptxstatus not support in wl cap
1255 */
1256 if (FW_SUPPORTED(dhd, proptxstatus)) {
1257 fw_proptx = 1;
1258 } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||
1259 dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
1260 fw_proptx = 1;
1261 } else {
1262 fw_proptx = 0;
1263 }
1264
1265 /* returned disable_proptx value:
1266 * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled)
1267 * 0: depend on fw support
1268 * 1: always disable proptx
1269 */
1270 if (conf->disable_proptx == 0) {
1271 // check fw support as well
1272 if (fw_proptx)
1273 disable_proptx = 0;
1274 else
1275 disable_proptx = 1;
1276 } else if (conf->disable_proptx >= 1) {
1277 disable_proptx = 1;
1278 } else {
1279 // check fw support as well
1280 if (fw_proptx)
1281 disable_proptx = -1;
1282 else
1283 disable_proptx = 1;
1284 }
1285
1286 printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx);
1287
1288 return disable_proptx;
1289 }
1290 #endif
1291
1292 uint
1293 pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf)
1294 {
1295 bool findNewline, changenewline=FALSE, pick=FALSE;
1296 int column;
1297 uint n, pick_column=0;
1298
1299 findNewline = FALSE;
1300 column = 0;
1301
1302 if (start_pos >= len) {
1303 CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__));
1304 return 0;
1305 }
1306
1307 for (n = start_pos; n < len; n++) {
1308 if (varbuf[n] == '\r')
1309 continue;
1310 if ((findNewline || changenewline) && varbuf[n] != '\n')
1311 continue;
1312 findNewline = FALSE;
1313 if (varbuf[n] == '#') {
1314 findNewline = TRUE;
1315 continue;
1316 }
1317 if (varbuf[n] == '\\') {
1318 changenewline = TRUE;
1319 continue;
1320 }
1321 if (!changenewline && varbuf[n] == '\n') {
1322 if (column == 0)
1323 continue;
1324 column = 0;
1325 continue;
1326 }
1327 if (changenewline && varbuf[n] == '\n') {
1328 changenewline = FALSE;
1329 continue;
1330 }
1331
1332 if (column == 0 && !pick) { // start to pick
1333 pick = TRUE;
1334 column++;
1335 pick_column = 0;
1336 } else {
1337 if (pick && column == 0) { // stop to pick
1338 pick = FALSE;
1339 break;
1340 } else
1341 column++;
1342 }
1343 if (pick) {
1344 if (varbuf[n] == 0x9)
1345 continue;
1346 if (pick_column>0 && pickbuf[pick_column-1] == ' ' && varbuf[n] == ' ')
1347 continue;
1348 pickbuf[pick_column] = varbuf[n];
1349 pick_column++;
1350 }
1351 }
1352
1353 return n; // return current position
1354 }
1355
1356 bool
1357 dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param)
1358 {
1359 char *data = full_param+len_param;
1360
1361 if (!strncmp("dhd_msg_level=", full_param, len_param)) {
1362 dhd_msg_level = (int)simple_strtol(data, NULL, 0);
1363 printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level);
1364 }
1365 #ifdef BCMSDIO
1366 else if (!strncmp("sd_msglevel=", full_param, len_param)) {
1367 sd_msglevel = (int)simple_strtol(data, NULL, 0);
1368 printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel);
1369 }
1370 #endif
1371 else if (!strncmp("android_msg_level=", full_param, len_param)) {
1372 android_msg_level = (int)simple_strtol(data, NULL, 0);
1373 printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level);
1374 }
1375 else if (!strncmp("config_msg_level=", full_param, len_param)) {
1376 config_msg_level = (int)simple_strtol(data, NULL, 0);
1377 printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level);
1378 }
1379 #ifdef WL_CFG80211
1380 else if (!strncmp("wl_dbg_level=", full_param, len_param)) {
1381 wl_dbg_level = (int)simple_strtol(data, NULL, 0);
1382 printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level);
1383 }
1384 #endif
1385 #if defined(WL_WIRELESS_EXT)
1386 else if (!strncmp("iw_msg_level=", full_param, len_param)) {
1387 iw_msg_level = (int)simple_strtol(data, NULL, 0);
1388 printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level);
1389 }
1390 #endif
1391 #if defined(DHD_DEBUG)
1392 else if (!strncmp("dhd_console_ms=", full_param, len_param)) {
1393 dhd_console_ms = (int)simple_strtol(data, NULL, 0);
1394 printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);
1395 }
1396 #endif
1397 else
1398 return false;
1399
1400 return true;
1401 }
1402
1403 void
1404 dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val)
1405 {
1406 char *pick_tmp, *pch;
1407
1408 pick_tmp = pick;
1409 pch = bcmstrstr(pick_tmp, "aifsn ");
1410 if (pch) {
1411 wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);
1412 printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]);
1413 }
1414 pick_tmp = pick;
1415 pch = bcmstrstr(pick_tmp, "ecwmin ");
1416 if (pch) {
1417 wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);
1418 printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]);
1419 }
1420 pick_tmp = pick;
1421 pch = bcmstrstr(pick_tmp, "ecwmax ");
1422 if (pch) {
1423 wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);
1424 printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]);
1425 }
1426 pick_tmp = pick;
1427 pch = bcmstrstr(pick_tmp, "txop ");
1428 if (pch) {
1429 wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);
1430 printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]);
1431 }
1432
1433 }
1434
1435 bool
1436 dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param)
1437 {
1438 struct dhd_conf *conf = dhd->conf;
1439 char *data = full_param+len_param;
1440
1441 // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e
1442 // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e
1443
1444 if (!strncmp("force_wme_ac=", full_param, len_param)) {
1445 conf->force_wme_ac = (int)simple_strtol(data, NULL, 10);
1446 printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);
1447 }
1448 else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) {
1449 dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE);
1450 }
1451 else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) {
1452 dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK);
1453 }
1454 else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) {
1455 dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI);
1456 }
1457 else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) {
1458 dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO);
1459 }
1460 else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) {
1461 dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE);
1462 }
1463 else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) {
1464 dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK);
1465 }
1466 else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) {
1467 dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI);
1468 }
1469 else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) {
1470 dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO);
1471 }
1472 else
1473 return false;
1474
1475 return true;
1476 }
1477
1478 bool
1479 dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
1480 {
1481 int i, j;
1482 char *pch, *pick_tmp;
1483 wl_mac_list_t *mac_list;
1484 wl_mac_range_t *mac_range;
1485 struct dhd_conf *conf = dhd->conf;
1486 char *data = full_param+len_param;
1487
1488 /* Process fw_by_mac:
1489 * fw_by_mac=[fw_mac_num] \
1490 * [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \
1491 * [oui1-1] [nic_start1-1] [nic_end1-1]... \
1492 * [oui1-n] [nic_start1-n] [nic_end1-n] \
1493 * [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \
1494 * [oui2-1] [nic_start2-1] [nic_end2-1]... \
1495 * [oui2-n] [nic_start2-n] [nic_end2-n] \
1496 * Ex: fw_by_mac=2 \
1497 * fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
1498 * fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
1499 * 0x983B16 0x916157 0x916487
1500 */
1501
1502 if (!strncmp("fw_by_mac=", full_param, len_param)) {
1503 pick_tmp = data;
1504 pch = bcmstrtok(&pick_tmp, " ", 0);
1505 conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
1506 if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) {
1507 conf->fw_by_mac.count = 0;
1508 CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
1509 }
1510 printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count);
1511 conf->fw_by_mac.m_mac_list_head = mac_list;
1512 for (i=0; i<conf->fw_by_mac.count; i++) {
1513 pch = bcmstrtok(&pick_tmp, " ", 0);
1514 strcpy(mac_list[i].name, pch);
1515 pch = bcmstrtok(&pick_tmp, " ", 0);
1516 mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
1517 printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,
1518 mac_list[i].name, mac_list[i].count);
1519 if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {
1520 mac_list[i].count = 0;
1521 CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
1522 break;
1523 }
1524 mac_list[i].mac = mac_range;
1525 for (j=0; j<mac_list[i].count; j++) {
1526 pch = bcmstrtok(&pick_tmp, " ", 0);
1527 mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
1528 pch = bcmstrtok(&pick_tmp, " ", 0);
1529 mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
1530 pch = bcmstrtok(&pick_tmp, " ", 0);
1531 mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
1532 printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
1533 __FUNCTION__, mac_range[j].oui,
1534 mac_range[j].nic_start, mac_range[j].nic_end);
1535 }
1536 }
1537 }
1538 else
1539 return false;
1540
1541 return true;
1542 }
1543
1544 bool
1545 dhd_conf_read_nv_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
1546 {
1547 int i, j;
1548 char *pch, *pick_tmp;
1549 wl_mac_list_t *mac_list;
1550 wl_mac_range_t *mac_range;
1551 struct dhd_conf *conf = dhd->conf;
1552 char *data = full_param+len_param;
1553
1554 /* Process nv_by_mac:
1555 * [nv_by_mac]: The same format as fw_by_mac
1556 */
1557 if (!strncmp("nv_by_mac=", full_param, len_param)) {
1558 pick_tmp = data;
1559 pch = bcmstrtok(&pick_tmp, " ", 0);
1560 conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
1561 if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) {
1562 conf->nv_by_mac.count = 0;
1563 CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
1564 }
1565 printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count);
1566 conf->nv_by_mac.m_mac_list_head = mac_list;
1567 for (i=0; i<conf->nv_by_mac.count; i++) {
1568 pch = bcmstrtok(&pick_tmp, " ", 0);
1569 strcpy(mac_list[i].name, pch);
1570 pch = bcmstrtok(&pick_tmp, " ", 0);
1571 mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
1572 printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,
1573 mac_list[i].name, mac_list[i].count);
1574 if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {
1575 mac_list[i].count = 0;
1576 CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
1577 break;
1578 }
1579 mac_list[i].mac = mac_range;
1580 for (j=0; j<mac_list[i].count; j++) {
1581 pch = bcmstrtok(&pick_tmp, " ", 0);
1582 mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
1583 pch = bcmstrtok(&pick_tmp, " ", 0);
1584 mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
1585 pch = bcmstrtok(&pick_tmp, " ", 0);
1586 mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
1587 printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
1588 __FUNCTION__, mac_range[j].oui,
1589 mac_range[j].nic_start, mac_range[j].nic_end);
1590 }
1591 }
1592 }
1593 else
1594 return false;
1595
1596 return true;
1597 }
1598
1599 bool
1600 dhd_conf_read_nv_by_chip(dhd_pub_t *dhd, char *full_param, uint len_param)
1601 {
1602 int i;
1603 char *pch, *pick_tmp;
1604 wl_chip_nv_path_t *chip_nv_path;
1605 struct dhd_conf *conf = dhd->conf;
1606 char *data = full_param+len_param;
1607
1608 /* Process nv_by_chip:
1609 * nv_by_chip=[nv_chip_num] \
1610 * [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \
1611 * Ex: nv_by_chip=2 \
1612 * 43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \
1613 */
1614 if (!strncmp("nv_by_chip=", full_param, len_param)) {
1615 pick_tmp = data;
1616 pch = bcmstrtok(&pick_tmp, " ", 0);
1617 conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0);
1618 if (!(chip_nv_path = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_chip.count, GFP_KERNEL))) {
1619 conf->nv_by_chip.count = 0;
1620 CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
1621 }
1622 printf("%s: nv_by_chip_count=%d\n", __FUNCTION__, conf->nv_by_chip.count);
1623 conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path;
1624 for (i=0; i<conf->nv_by_chip.count; i++) {
1625 pch = bcmstrtok(&pick_tmp, " ", 0);
1626 chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0);
1627 pch = bcmstrtok(&pick_tmp, " ", 0);
1628 chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0);
1629 pch = bcmstrtok(&pick_tmp, " ", 0);
1630 strcpy(chip_nv_path[i].name, pch);
1631 printf("%s: chip=0x%x, chiprev=%d, name=%s\n", __FUNCTION__,
1632 chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name);
1633 }
1634 }
1635 else
1636 return false;
1637
1638 return true;
1639 }
1640
1641 bool
1642 dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param)
1643 {
1644 struct dhd_conf *conf = dhd->conf;
1645 char *data = full_param+len_param;
1646
1647 if (!strncmp("roam_off=", full_param, len_param)) {
1648 if (!strncmp(data, "0", 1))
1649 conf->roam_off = 0;
1650 else
1651 conf->roam_off = 1;
1652 printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off);
1653 }
1654 else if (!strncmp("roam_off_suspend=", full_param, len_param)) {
1655 if (!strncmp(data, "0", 1))
1656 conf->roam_off_suspend = 0;
1657 else
1658 conf->roam_off_suspend = 1;
1659 printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend);
1660 }
1661 else if (!strncmp("roam_trigger=", full_param, len_param)) {
1662 conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10);
1663 printf("%s: roam_trigger = %d\n", __FUNCTION__,
1664 conf->roam_trigger[0]);
1665 }
1666 else if (!strncmp("roam_scan_period=", full_param, len_param)) {
1667 conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10);
1668 printf("%s: roam_scan_period = %d\n", __FUNCTION__,
1669 conf->roam_scan_period[0]);
1670 }
1671 else if (!strncmp("roam_delta=", full_param, len_param)) {
1672 conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10);
1673 printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]);
1674 }
1675 else if (!strncmp("fullroamperiod=", full_param, len_param)) {
1676 conf->fullroamperiod = (int)simple_strtol(data, NULL, 10);
1677 printf("%s: fullroamperiod = %d\n", __FUNCTION__,
1678 conf->fullroamperiod);
1679 } else
1680 return false;
1681
1682 return true;
1683 }
1684
1685 bool
1686 dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
1687 {
1688 int i;
1689 char *pch, *pick_tmp;
1690 struct dhd_conf *conf = dhd->conf;
1691 char *data = full_param+len_param;
1692
1693 /* Process country_list:
1694 * country_list=[country1]:[ccode1]/[regrev1],
1695 * [country2]:[ccode2]/[regrev2] \
1696 * Ex: country_list=US:US/0, TW:TW/1
1697 */
1698 if (!strncmp("country_list=", full_param, len_param)) {
1699 pick_tmp = data;
1700 for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {
1701 /* Process country code */
1702 pch = bcmstrtok(&pick_tmp, ":", 0);
1703 if (!pch)
1704 break;
1705 strcpy(conf->country_list.cspec[i].country_abbrev, pch);
1706 pch = bcmstrtok(&pick_tmp, "/", 0);
1707 if (!pch)
1708 break;
1709 memcpy(conf->country_list.cspec[i].ccode, pch, 2);
1710 pch = bcmstrtok(&pick_tmp, ", ", 0);
1711 if (!pch)
1712 break;
1713 conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10);
1714 conf->country_list.count ++;
1715 CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,
1716 conf->country_list.cspec[i].country_abbrev,
1717 conf->country_list.cspec[i].ccode,
1718 conf->country_list.cspec[i].rev));
1719 }
1720 printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);
1721 }
1722 else
1723 return false;
1724
1725 return true;
1726 }
1727
1728 #ifdef PKT_FILTER_SUPPORT
1729 bool
1730 dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param)
1731 {
1732 struct dhd_conf *conf = dhd->conf;
1733 char *data = full_param+len_param;
1734 char *pch, *pick_tmp;
1735 int i;
1736
1737 /* Process pkt filter:
1738 * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
1739 * 2) pkt_filter_del=100, 102, 103, 104, 105
1740 * 3) magic_pkt_filter_add=141 0 1 12
1741 */
1742 if (!strncmp("dhd_master_mode=", full_param, len_param)) {
1743 if (!strncmp(data, "0", 1))
1744 dhd_master_mode = FALSE;
1745 else
1746 dhd_master_mode = TRUE;
1747 printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode);
1748 }
1749 else if (!strncmp("pkt_filter_add=", full_param, len_param)) {
1750 pick_tmp = data;
1751 pch = bcmstrtok(&pick_tmp, ",.-", 0);
1752 i=0;
1753 while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
1754 strcpy(&conf->pkt_filter_add.filter[i][0], pch);
1755 printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]);
1756 pch = bcmstrtok(&pick_tmp, ",.-", 0);
1757 i++;
1758 }
1759 conf->pkt_filter_add.count = i;
1760 }
1761 else if (!strncmp("pkt_filter_del=", full_param, len_param)) {
1762 pick_tmp = data;
1763 pch = bcmstrtok(&pick_tmp, " ,.-", 0);
1764 i=0;
1765 while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
1766 conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);
1767 pch = bcmstrtok(&pick_tmp, " ,.-", 0);
1768 i++;
1769 }
1770 conf->pkt_filter_del.count = i;
1771 printf("%s: pkt_filter_del id = ", __FUNCTION__);
1772 for (i=0; i<conf->pkt_filter_del.count; i++)
1773 printf("%d ", conf->pkt_filter_del.id[i]);
1774 printf("\n");
1775 }
1776 else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) {
1777 if (!(conf->magic_pkt_filter_add = kmalloc(MAGIC_PKT_FILTER_LEN, GFP_KERNEL))) {
1778 CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
1779 } else {
1780 strcpy(conf->magic_pkt_filter_add, data);
1781 printf("%s: magic_pkt_filter_add = %s\n", __FUNCTION__, conf->magic_pkt_filter_add);
1782 }
1783 }
1784 else
1785 return false;
1786
1787 return true;
1788 }
1789 #endif
1790
1791 #ifdef IAPSTA_PREINIT
1792 /*
1793 * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1]
1794 * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]
1795 hidden [y|n] maxassoc [x]
1796 amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]
1797 emode [none|wep|tkip|aes|tkipaes]
1798 key [xxxxx]
1799 * iapsta_enable=ifname [wlan0|wlan1]
1800 */
1801 bool
1802 dhd_conf_read_iapsta(dhd_pub_t *dhd, char *full_param, uint len_param)
1803 {
1804 struct dhd_conf *conf = dhd->conf;
1805 char *data = full_param+len_param;
1806
1807 if (!strncmp("iapsta_init=", full_param, len_param)) {
1808 sprintf(conf->iapsta_init, "iapsta_init %s", data);
1809 printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);
1810 }
1811 else if (!strncmp("iapsta_config=", full_param, len_param)) {
1812 sprintf(conf->iapsta_config, "iapsta_config %s", data);
1813 printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);
1814 }
1815 else if (!strncmp("iapsta_enable=", full_param, len_param)) {
1816 sprintf(conf->iapsta_enable, "iapsta_enable %s", data);
1817 printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);
1818 }
1819 else
1820 return false;
1821
1822 return true;
1823 }
1824 #endif
1825
1826 #ifdef IDHCP
1827 bool
1828 dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param)
1829 {
1830 struct dhd_conf *conf = dhd->conf;
1831 char *data = full_param+len_param;
1832 struct ipv4_addr ipa_set;
1833
1834 if (!strncmp("dhcpc_enable=", full_param, len_param)) {
1835 conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10);
1836 printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable);
1837 }
1838 else if (!strncmp("dhcpd_enable=", full_param, len_param)) {
1839 conf->dhcpd_enable = (int)simple_strtol(data, NULL, 10);
1840 printf("%s: dhcpd_enable = %d\n", __FUNCTION__, conf->dhcpd_enable);
1841 }
1842 else if (!strncmp("dhcpd_ip_addr=", full_param, len_param)) {
1843 if (!bcm_atoipv4(data, &ipa_set))
1844 printf("%s : dhcpd_ip_addr adress setting failed.\n", __FUNCTION__);
1845 conf->dhcpd_ip_addr = ipa_set;
1846 printf("%s: dhcpd_ip_addr = %s\n",__FUNCTION__, data);
1847 }
1848 else if (!strncmp("dhcpd_ip_mask=", full_param, len_param)) {
1849 if (!bcm_atoipv4(data, &ipa_set))
1850 printf("%s : dhcpd_ip_mask adress setting failed.\n", __FUNCTION__);
1851 conf->dhcpd_ip_mask = ipa_set;
1852 printf("%s: dhcpd_ip_mask = %s\n",__FUNCTION__, data);
1853 }
1854 else if (!strncmp("dhcpd_ip_start=", full_param, len_param)) {
1855 if (!bcm_atoipv4(data, &ipa_set))
1856 printf("%s : dhcpd_ip_start adress setting failed.\n", __FUNCTION__);
1857 conf->dhcpd_ip_start = ipa_set;
1858 printf("%s: dhcpd_ip_start = %s\n",__FUNCTION__, data);
1859 }
1860 else if (!strncmp("dhcpd_ip_end=", full_param, len_param)) {
1861 if (!bcm_atoipv4(data, &ipa_set))
1862 printf("%s : dhcpd_ip_end adress setting failed.\n", __FUNCTION__);
1863 conf->dhcpd_ip_end = ipa_set;
1864 printf("%s: dhcpd_ip_end = %s\n",__FUNCTION__, data);
1865 }
1866 else
1867 return false;
1868
1869 return true;
1870 }
1871 #endif
1872
1873 #ifdef BCMSDIO
1874 bool
1875 dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
1876 {
1877 struct dhd_conf *conf = dhd->conf;
1878 char *data = full_param+len_param;
1879
1880 if (!strncmp("dhd_doflow=", full_param, len_param)) {
1881 if (!strncmp(data, "0", 1))
1882 dhd_doflow = FALSE;
1883 else
1884 dhd_doflow = TRUE;
1885 printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow);
1886 }
1887 else if (!strncmp("dhd_slpauto=", full_param, len_param)) {
1888 if (!strncmp(data, "0", 1))
1889 dhd_slpauto = FALSE;
1890 else
1891 dhd_slpauto = TRUE;
1892 printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);
1893 }
1894 else if (!strncmp("kso_enable=", full_param, len_param)) {
1895 if (!strncmp(data, "0", 1))
1896 dhd_slpauto = FALSE;
1897 else
1898 dhd_slpauto = TRUE;
1899 printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);
1900 }
1901 else if (!strncmp("bus:txglom=", full_param, len_param)) {
1902 conf->bus_txglom = (int)simple_strtol(data, NULL, 10);
1903 printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);
1904 }
1905 else if (!strncmp("use_rxchain=", full_param, len_param)) {
1906 conf->use_rxchain = (int)simple_strtol(data, NULL, 10);
1907 printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain);
1908 }
1909 else if (!strncmp("dhd_txminmax=", full_param, len_param)) {
1910 conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10);
1911 printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax);
1912 }
1913 else if (!strncmp("txinrx_thres=", full_param, len_param)) {
1914 conf->txinrx_thres = (int)simple_strtol(data, NULL, 10);
1915 printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres);
1916 }
1917 else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) {
1918 conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10);
1919 printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize);
1920 }
1921 else if (!strncmp("oob_enabled_later=", full_param, len_param)) {
1922 if (!strncmp(data, "0", 1))
1923 conf->oob_enabled_later = FALSE;
1924 else
1925 conf->oob_enabled_later = TRUE;
1926 printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later);
1927 }
1928 else if (!strncmp("dpc_cpucore=", full_param, len_param)) {
1929 conf->dpc_cpucore = (int)simple_strtol(data, NULL, 10);
1930 printf("%s: dpc_cpucore = %d\n", __FUNCTION__, conf->dpc_cpucore);
1931 }
1932 else if (!strncmp("rxf_cpucore=", full_param, len_param)) {
1933 conf->rxf_cpucore = (int)simple_strtol(data, NULL, 10);
1934 printf("%s: rxf_cpucore = %d\n", __FUNCTION__, conf->rxf_cpucore);
1935 }
1936 #if defined(BCMSDIOH_TXGLOM)
1937 else if (!strncmp("txglomsize=", full_param, len_param)) {
1938 conf->txglomsize = (uint)simple_strtol(data, NULL, 10);
1939 if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
1940 conf->txglomsize = SDPCM_MAXGLOM_SIZE;
1941 printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize);
1942 }
1943 else if (!strncmp("swtxglom=", full_param, len_param)) {
1944 if (!strncmp(data, "0", 1))
1945 conf->swtxglom = FALSE;
1946 else
1947 conf->swtxglom = TRUE;
1948 printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom);
1949 }
1950 else if (!strncmp("txglom_ext=", full_param, len_param)) {
1951 if (!strncmp(data, "0", 1))
1952 conf->txglom_ext = FALSE;
1953 else
1954 conf->txglom_ext = TRUE;
1955 printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext);
1956 if (conf->txglom_ext) {
1957 if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID))
1958 conf->txglom_bucket_size = 1680;
1959 else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
1960 conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID)
1961 conf->txglom_bucket_size = 1684;
1962 }
1963 printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size);
1964 }
1965 else if (!strncmp("bus:rxglom=", full_param, len_param)) {
1966 if (!strncmp(data, "0", 1))
1967 conf->bus_rxglom = FALSE;
1968 else
1969 conf->bus_rxglom = TRUE;
1970 printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);
1971 }
1972 else if (!strncmp("dhd_poll=", full_param, len_param)) {
1973 if (!strncmp(data, "0", 1))
1974 conf->dhd_poll = 0;
1975 else
1976 conf->dhd_poll = 1;
1977 printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);
1978 }
1979 else if (!strncmp("deferred_tx_len=", full_param, len_param)) {
1980 conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10);
1981 printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);
1982 }
1983 else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) {
1984 if (!strncmp(data, "0", 1))
1985 conf->txctl_tmo_fix = FALSE;
1986 else
1987 conf->txctl_tmo_fix = TRUE;
1988 printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);
1989 }
1990 else if (!strncmp("tx_in_rx=", full_param, len_param)) {
1991 if (!strncmp(data, "0", 1))
1992 conf->tx_in_rx = FALSE;
1993 else
1994 conf->tx_in_rx = TRUE;
1995 printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);
1996 }
1997 else if (!strncmp("tx_max_offset=", full_param, len_param)) {
1998 conf->tx_max_offset = (int)simple_strtol(data, NULL, 10);
1999 printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);
2000 }
2001 else if (!strncmp("txglom_mode=", full_param, len_param)) {
2002 if (!strncmp(data, "0", 1))
2003 conf->txglom_mode = FALSE;
2004 else
2005 conf->txglom_mode = TRUE;
2006 printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode);
2007 }
2008 #endif
2009 else
2010 return false;
2011
2012 return true;
2013 }
2014 #endif
2015
2016 bool
2017 dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
2018 {
2019 struct dhd_conf *conf = dhd->conf;
2020 char *data = full_param+len_param;
2021
2022 if (!strncmp("lpc=", full_param, len_param)) {
2023 conf->lpc = (int)simple_strtol(data, NULL, 10);
2024 printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);
2025 }
2026 else if (!strncmp("deepsleep=", full_param, len_param)) {
2027 if (!strncmp(data, "1", 1))
2028 conf->deepsleep = TRUE;
2029 else
2030 conf->deepsleep = FALSE;
2031 printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);
2032 }
2033 else if (!strncmp("PM=", full_param, len_param)) {
2034 conf->pm = (int)simple_strtol(data, NULL, 10);
2035 printf("%s: PM = %d\n", __FUNCTION__, conf->pm);
2036 }
2037 else if (!strncmp("pm_in_suspend=", full_param, len_param)) {
2038 conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10);
2039 printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);
2040 }
2041 else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) {
2042 conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10);
2043 printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);
2044 }
2045 else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {
2046 if (!strncmp(data, "1", 1))
2047 conf->xmit_in_suspend = TRUE;
2048 else
2049 conf->xmit_in_suspend = FALSE;
2050 printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);
2051 }
2052 else if (!strncmp("ap_in_suspend=", full_param, len_param)) {
2053 conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10);
2054 printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);
2055 }
2056 else
2057 return false;
2058
2059 return true;
2060 }
2061
2062 bool
2063 dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
2064 {
2065 struct dhd_conf *conf = dhd->conf;
2066 char *data = full_param+len_param;
2067 uint len_data = strlen(data);
2068 char *pch, *pick_tmp;
2069 int i;
2070
2071 if (!strncmp("band=", full_param, len_param)) {
2072 /* Process band:
2073 * band=a for 5GHz only and band=b for 2.4GHz only
2074 */
2075 if (!strcmp(data, "b"))
2076 conf->band = WLC_BAND_2G;
2077 else if (!strcmp(data, "a"))
2078 conf->band = WLC_BAND_5G;
2079 else
2080 conf->band = WLC_BAND_AUTO;
2081 printf("%s: band = %d\n", __FUNCTION__, conf->band);
2082 }
2083 else if (!strncmp("mimo_bw_cap=", full_param, len_param)) {
2084 conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10);
2085 printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);
2086 }
2087 else if (!strncmp("bw_cap_2g=", full_param, len_param)) {
2088 conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0);
2089 printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);
2090 }
2091 else if (!strncmp("bw_cap_5g=", full_param, len_param)) {
2092 conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0);
2093 printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g);
2094 }
2095 else if (!strncmp("ccode=", full_param, len_param)) {
2096 memset(&conf->cspec, 0, sizeof(wl_country_t));
2097 memcpy(conf->cspec.country_abbrev, data, len_data);
2098 memcpy(conf->cspec.ccode, data, len_data);
2099 printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode);
2100 }
2101 else if (!strncmp("regrev=", full_param, len_param)) {
2102 conf->cspec.rev = (int32)simple_strtol(data, NULL, 10);
2103 printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev);
2104 }
2105 else if (!strncmp("channels=", full_param, len_param)) {
2106 pick_tmp = data;
2107 pch = bcmstrtok(&pick_tmp, " ,.-", 0);
2108 i=0;
2109 while (pch != NULL && i<WL_NUMCHANNELS) {
2110 conf->channels.channel[i] = (uint32)simple_strtol(pch, NULL, 10);
2111 pch = bcmstrtok(&pick_tmp, " ,.-", 0);
2112 i++;
2113 }
2114 conf->channels.count = i;
2115 printf("%s: channels = ", __FUNCTION__);
2116 for (i=0; i<conf->channels.count; i++)
2117 printf("%d ", conf->channels.channel[i]);
2118 printf("\n");
2119 }
2120 else if (!strncmp("keep_alive_period=", full_param, len_param)) {
2121 conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10);
2122 printf("%s: keep_alive_period = %d\n", __FUNCTION__,
2123 conf->keep_alive_period);
2124 }
2125 else if (!strncmp("stbc=", full_param, len_param)) {
2126 conf->stbc = (int)simple_strtol(data, NULL, 10);
2127 printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc);
2128 }
2129 else if (!strncmp("phy_oclscdenable=", full_param, len_param)) {
2130 conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10);
2131 printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable);
2132 }
2133 else if (!strncmp("srl=", full_param, len_param)) {
2134 conf->srl = (int)simple_strtol(data, NULL, 10);
2135 printf("%s: srl = %d\n", __FUNCTION__, conf->srl);
2136 }
2137 else if (!strncmp("lrl=", full_param, len_param)) {
2138 conf->lrl = (int)simple_strtol(data, NULL, 10);
2139 printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl);
2140 }
2141 else if (!strncmp("bcn_timeout=", full_param, len_param)) {
2142 conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10);
2143 printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);
2144 }
2145 else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) {
2146 conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10);
2147 printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);
2148 }
2149 else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) {
2150 conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10);
2151 printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);
2152 }
2153 else if (!strncmp("spect=", full_param, len_param)) {
2154 conf->spect = (int)simple_strtol(data, NULL, 10);
2155 printf("%s: spect = %d\n", __FUNCTION__, conf->spect);
2156 }
2157 else if (!strncmp("txbf=", full_param, len_param)) {
2158 conf->txbf = (int)simple_strtol(data, NULL, 10);
2159 printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf);
2160 }
2161 else if (!strncmp("frameburst=", full_param, len_param)) {
2162 conf->frameburst = (int)simple_strtol(data, NULL, 10);
2163 printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst);
2164 }
2165 else if (!strncmp("disable_proptx=", full_param, len_param)) {
2166 conf->disable_proptx = (int)simple_strtol(data, NULL, 10);
2167 printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx);
2168 }
2169 #ifdef DHDTCPACK_SUPPRESS
2170 else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) {
2171 conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10);
2172 printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode);
2173 }
2174 #endif
2175 else if (!strncmp("pktprio8021x=", full_param, len_param)) {
2176 conf->pktprio8021x = (int)simple_strtol(data, NULL, 10);
2177 printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);
2178 }
2179 else if (!strncmp("dhd_txbound=", full_param, len_param)) {
2180 dhd_txbound = (uint)simple_strtol(data, NULL, 10);
2181 printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound);
2182 }
2183 else if (!strncmp("dhd_rxbound=", full_param, len_param)) {
2184 dhd_rxbound = (uint)simple_strtol(data, NULL, 10);
2185 printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound);
2186 }
2187 else if (!strncmp("rsdb_mode=", full_param, len_param)) {
2188 conf->rsdb_mode = (int)simple_strtol(data, NULL, 10);
2189 printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode);
2190 }
2191 else if (!strncmp("vhtmode=", full_param, len_param)) {
2192 if (!strncmp(data, "0", 1))
2193 conf->vhtmode = 0;
2194 else
2195 conf->vhtmode = 1;
2196 printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);
2197 }
2198 else if (!strncmp("num_different_channels=", full_param, len_param)) {
2199 conf->num_different_channels = (int)simple_strtol(data, NULL, 10);
2200 printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);
2201 }
2202 else if (!strncmp("autocountry=", full_param, len_param)) {
2203 conf->autocountry = (int)simple_strtol(data, NULL, 10);
2204 printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry);
2205 }
2206 else if (!strncmp("tsq=", full_param, len_param)) {
2207 conf->tsq = (int)simple_strtol(data, NULL, 10);
2208 printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);
2209 }
2210 else
2211 return false;
2212
2213 return true;
2214 }
2215
2216 int
2217 dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
2218 {
2219 int bcmerror = -1;
2220 uint len, start_pos=0;
2221 void * image = NULL;
2222 char * memblock = NULL;
2223 char *bufp, *pick = NULL, *pch;
2224 bool conf_file_exists;
2225 uint len_param;
2226
2227 conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));
2228 if (!conf_file_exists) {
2229 printf("%s: config path %s\n", __FUNCTION__, conf_path);
2230 return (0);
2231 }
2232
2233 if (conf_file_exists) {
2234 image = dhd_os_open_image(conf_path);
2235 if (image == NULL) {
2236 printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path);
2237 goto err;
2238 }
2239 }
2240
2241 memblock = MALLOC(dhd->osh, MAXSZ_CONFIG);
2242 if (memblock == NULL) {
2243 CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
2244 __FUNCTION__, MAXSZ_CONFIG));
2245 goto err;
2246 }
2247
2248 pick = MALLOC(dhd->osh, MAXSZ_BUF);
2249 if (!pick) {
2250 CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
2251 __FUNCTION__, MAXSZ_BUF));
2252 goto err;
2253 }
2254
2255 /* Read variables */
2256 if (conf_file_exists) {
2257 len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image);
2258 }
2259 if (len > 0 && len < MAXSZ_CONFIG) {
2260 bufp = (char *)memblock;
2261 bufp[len] = 0;
2262
2263 while (start_pos < len) {
2264 memset(pick, 0, MAXSZ_BUF);
2265 start_pos = pick_config_vars(bufp, len, start_pos, pick);
2266 pch = strchr(pick, '=');
2267 if (pch != NULL) {
2268 len_param = pch-pick+1;
2269 if (len_param == strlen(pick)) {
2270 CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));
2271 continue;
2272 }
2273 } else {
2274 CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));
2275 continue;
2276 }
2277
2278 if (dhd_conf_read_log_level(dhd, pick, len_param))
2279 continue;
2280 else if (dhd_conf_read_roam_params(dhd, pick, len_param))
2281 continue;
2282 else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param))
2283 continue;
2284 else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param))
2285 continue;
2286 else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param))
2287 continue;
2288 else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param))
2289 continue;
2290 else if (dhd_conf_read_country_list(dhd, pick, len_param))
2291 continue;
2292 #ifdef PKT_FILTER_SUPPORT
2293 else if (dhd_conf_read_pkt_filter(dhd, pick, len_param))
2294 continue;
2295 #endif /* PKT_FILTER_SUPPORT */
2296 #ifdef IAPSTA_PREINIT
2297 else if (dhd_conf_read_iapsta(dhd, pick, len_param))
2298 continue;
2299 #endif /* IAPSTA_PREINIT */
2300 #ifdef IDHCP
2301 else if (dhd_conf_read_dhcp_params(dhd, pick, len_param))
2302 continue;
2303 #endif /* IDHCP */
2304 #ifdef BCMSDIO
2305 else if (dhd_conf_read_sdio_params(dhd, pick, len_param))
2306 continue;
2307 #endif /* BCMSDIO */
2308 else if (dhd_conf_read_pm_params(dhd, pick, len_param))
2309 continue;
2310 else if (dhd_conf_read_others(dhd, pick, len_param))
2311 continue;
2312 else
2313 continue;
2314 }
2315
2316 bcmerror = 0;
2317 } else {
2318 CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));
2319 bcmerror = BCME_SDIO_ERROR;
2320 }
2321
2322 err:
2323 if (pick)
2324 MFREE(dhd->osh, pick, MAXSZ_BUF);
2325
2326 if (memblock)
2327 MFREE(dhd->osh, memblock, MAXSZ_CONFIG);
2328
2329 if (image)
2330 dhd_os_close_image(image);
2331
2332 return bcmerror;
2333 }
2334
2335 int
2336 dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)
2337 {
2338 printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev);
2339 dhd->conf->chip = chip;
2340 dhd->conf->chiprev = chiprev;
2341 return 0;
2342 }
2343
2344 uint
2345 dhd_conf_get_chip(void *context)
2346 {
2347 dhd_pub_t *dhd = context;
2348
2349 if (dhd && dhd->conf)
2350 return dhd->conf->chip;
2351 return 0;
2352 }
2353
2354 uint
2355 dhd_conf_get_chiprev(void *context)
2356 {
2357 dhd_pub_t *dhd = context;
2358
2359 if (dhd && dhd->conf)
2360 return dhd->conf->chiprev;
2361 return 0;
2362 }
2363
2364 #ifdef BCMSDIO
2365 void
2366 dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)
2367 {
2368 struct dhd_conf *conf = dhd->conf;
2369
2370 if (enable) {
2371 #if defined(SWTXGLOM)
2372 if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
2373 conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
2374 conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
2375 // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom
2376 conf->swtxglom = TRUE;
2377 conf->txglom_ext = TRUE;
2378 }
2379 if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) {
2380 conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only
2381 }
2382 #elif defined(BCMSDIOH_TXGLOM_EXT)
2383 if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
2384 conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
2385 conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
2386 conf->txglom_mode = SDPCM_TXGLOM_CPY;
2387 }
2388 #endif
2389 // other parameters set in preinit or config.txt
2390 } else {
2391 // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt
2392 conf->txglom_ext = FALSE;
2393 conf->txglom_bucket_size = 0;
2394 conf->txglomsize = 0;
2395 conf->deferred_tx_len = 0;
2396 }
2397 printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__,
2398 conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size);
2399 printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__,
2400 conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom);
2401 printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__,
2402 conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax);
2403 printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__,
2404 conf->tx_max_offset, conf->txctl_tmo_fix);
2405
2406 }
2407 #endif
2408
2409 int
2410 dhd_conf_preinit(dhd_pub_t *dhd)
2411 {
2412 struct dhd_conf *conf = dhd->conf;
2413
2414 CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
2415
2416 #ifdef BCMSDIO
2417 dhd_conf_free_mac_list(&conf->fw_by_mac);
2418 dhd_conf_free_mac_list(&conf->nv_by_mac);
2419 dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);
2420 #endif
2421 if (conf->magic_pkt_filter_add)
2422 kfree(conf->magic_pkt_filter_add);
2423 memset(&conf->country_list, 0, sizeof(conf_country_list_t));
2424 conf->band = WLC_BAND_AUTO;
2425 conf->mimo_bw_cap = -1;
2426 conf->bw_cap_2g = -1;
2427 conf->bw_cap_5g = -1;
2428 if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {
2429 strcpy(conf->cspec.country_abbrev, "ALL");
2430 strcpy(conf->cspec.ccode, "ALL");
2431 conf->cspec.rev = 0;
2432 } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID ||
2433 conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
2434 conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID ||
2435 conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) {
2436 strcpy(conf->cspec.country_abbrev, "CN");
2437 strcpy(conf->cspec.ccode, "CN");
2438 conf->cspec.rev = 38;
2439 } else {
2440 strcpy(conf->cspec.country_abbrev, "CN");
2441 strcpy(conf->cspec.ccode, "CN");
2442 conf->cspec.rev = 0;
2443 }
2444 memset(&conf->channels, 0, sizeof(wl_channel_list_t));
2445 conf->roam_off = 1;
2446 conf->roam_off_suspend = 1;
2447 #ifdef CUSTOM_ROAM_TRIGGER_SETTING
2448 conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING;
2449 #else
2450 conf->roam_trigger[0] = -65;
2451 #endif
2452 conf->roam_trigger[1] = WLC_BAND_ALL;
2453 conf->roam_scan_period[0] = 10;
2454 conf->roam_scan_period[1] = WLC_BAND_ALL;
2455 #ifdef CUSTOM_ROAM_DELTA_SETTING
2456 conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING;
2457 #else
2458 conf->roam_delta[0] = 15;
2459 #endif
2460 conf->roam_delta[1] = WLC_BAND_ALL;
2461 #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
2462 conf->fullroamperiod = 60;
2463 #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
2464 conf->fullroamperiod = 120;
2465 #endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
2466 #ifdef CUSTOM_KEEP_ALIVE_SETTING
2467 conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING;
2468 #else
2469 conf->keep_alive_period = 28000;
2470 #endif
2471 conf->force_wme_ac = 0;
2472 memset(&conf->wme_sta, 0, sizeof(wme_param_t));
2473 memset(&conf->wme_ap, 0, sizeof(wme_param_t));
2474 conf->stbc = -1;
2475 conf->phy_oclscdenable = -1;
2476 #ifdef PKT_FILTER_SUPPORT
2477 memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));
2478 memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));
2479 #endif
2480 conf->srl = -1;
2481 conf->lrl = -1;
2482 conf->bcn_timeout = 15;
2483 conf->spect = -1;
2484 conf->txbf = -1;
2485 conf->lpc = -1;
2486 conf->disable_proptx = -1;
2487 #ifdef BCMSDIO
2488 conf->bus_txglom = -1;
2489 conf->use_rxchain = 0;
2490 conf->bus_rxglom = TRUE;
2491 conf->txglom_ext = FALSE;
2492 conf->tx_max_offset = 0;
2493 conf->txglomsize = SDPCM_DEFGLOM_SIZE;
2494 conf->dhd_poll = -1;
2495 conf->txctl_tmo_fix = FALSE;
2496 conf->tx_in_rx = TRUE;
2497 conf->txglom_mode = SDPCM_TXGLOM_MDESC;
2498 conf->deferred_tx_len = 0;
2499 conf->dhd_txminmax = 1;
2500 conf->txinrx_thres = -1;
2501 conf->sd_f2_blocksize = 0;
2502 conf->oob_enabled_later = FALSE;
2503 #endif
2504 conf->ampdu_ba_wsize = 0;
2505 conf->ampdu_hostreorder = -1;
2506 conf->dpc_cpucore = -1;
2507 conf->rxf_cpucore = -1;
2508 conf->frameburst = -1;
2509 conf->deepsleep = FALSE;
2510 conf->pm = -1;
2511 conf->pm_in_suspend = -1;
2512 conf->pm2_sleep_ret = -1;
2513 conf->num_different_channels = -1;
2514 conf->xmit_in_suspend = TRUE;
2515 conf->ap_in_suspend = 0;
2516 #ifdef IDHCP
2517 conf->dhcpc_enable = -1;
2518 conf->dhcpd_enable = -1;
2519 #endif
2520 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
2521 conf->tsq = 10;
2522 #else
2523 conf->tsq = 0;
2524 #endif
2525 #ifdef DHDTCPACK_SUPPRESS
2526 conf->tcpack_sup_mode = TCPACK_SUP_OFF;
2527 #endif
2528 conf->pktprio8021x = -1;
2529 conf->rsdb_mode = -2;
2530 conf->vhtmode = -1;
2531 conf->autocountry = -1;
2532 #ifdef IAPSTA_PREINIT
2533 memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init));
2534 memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config));
2535 memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable));
2536 #endif
2537 #ifdef CUSTOMER_HW_AMLOGIC
2538 dhd_slpauto = FALSE;
2539 #endif
2540 #ifdef BCMSDIO
2541 if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM43454_CHIP_ID ||
2542 conf->chip == BCM4345_CHIP_ID) {
2543 conf->txctl_tmo_fix = 1;
2544 }
2545 #endif
2546 if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
2547 conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID ||
2548 conf->chip == BCM4359_CHIP_ID) {
2549 #ifdef DHDTCPACK_SUPPRESS
2550 conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;
2551 #endif
2552 dhd_rxbound = 128;
2553 dhd_txbound = 64;
2554 conf->txbf = 1;
2555 conf->frameburst = 1;
2556 #ifdef BCMSDIO
2557 conf->dhd_txminmax = -1;
2558 conf->txinrx_thres = 128;
2559 conf->sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
2560 conf->oob_enabled_later = TRUE;
2561 #ifdef CUSTOMER_HW_AMLOGIC
2562 conf->rxf_cpucore = 2;
2563 #endif
2564 #endif
2565 }
2566
2567 #ifdef BCMSDIO
2568 #if defined(SWTXGLOM)
2569 if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
2570 conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
2571 conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
2572 conf->swtxglom = FALSE; // disabled by default
2573 conf->txglom_ext = TRUE; // enabled by default
2574 conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled
2575 conf->txglomsize = 16;
2576 } else {
2577 conf->swtxglom = FALSE; // use 1.201.59.x txglom by default
2578 conf->txglom_ext = FALSE;
2579 }
2580
2581 if (conf->chip == BCM43362_CHIP_ID) {
2582 conf->txglom_bucket_size = 1680; // fixed value, don't change
2583 conf->tx_in_rx = FALSE;
2584 conf->tx_max_offset = 1;
2585 }
2586 if (conf->chip == BCM4330_CHIP_ID) {
2587 conf->txglom_bucket_size = 1680; // fixed value, don't change
2588 conf->tx_in_rx = FALSE;
2589 conf->tx_max_offset = 0;
2590 }
2591 if (conf->chip == BCM4334_CHIP_ID) {
2592 conf->txglom_bucket_size = 1684; // fixed value, don't change
2593 conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
2594 conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110
2595 }
2596 if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) {
2597 conf->txglom_bucket_size = 1684; // fixed value, don't change
2598 conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
2599 conf->tx_max_offset = 1;
2600 }
2601 if (conf->chip == BCM4324_CHIP_ID) {
2602 conf->txglom_bucket_size = 1684; // fixed value, don't change
2603 conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
2604 conf->tx_max_offset = 0;
2605 }
2606 #endif
2607 #if defined(BCMSDIOH_TXGLOM_EXT)
2608 if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
2609 conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
2610 conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
2611 conf->txglom_ext = TRUE;
2612 conf->use_rxchain = 0;
2613 conf->tx_in_rx = TRUE;
2614 conf->tx_max_offset = 1;
2615 } else {
2616 conf->txglom_ext = FALSE;
2617 }
2618 if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {
2619 conf->txglom_bucket_size = 1680; // fixed value, don't change
2620 conf->txglomsize = 6;
2621 }
2622 if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||
2623 conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
2624 conf->txglom_bucket_size = 1684; // fixed value, don't change
2625 conf->txglomsize = 16;
2626 }
2627 #endif
2628 if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
2629 conf->txglomsize = SDPCM_MAXGLOM_SIZE;
2630 conf->deferred_tx_len = 0;
2631 #endif
2632
2633 return 0;
2634 }
2635
2636 int
2637 dhd_conf_reset(dhd_pub_t *dhd)
2638 {
2639 #ifdef BCMSDIO
2640 dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);
2641 dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
2642 dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
2643 #endif
2644 if (dhd->conf->magic_pkt_filter_add)
2645 kfree(dhd->conf->magic_pkt_filter_add);
2646 memset(dhd->conf, 0, sizeof(dhd_conf_t));
2647 return 0;
2648 }
2649
2650 int
2651 dhd_conf_attach(dhd_pub_t *dhd)
2652 {
2653 dhd_conf_t *conf;
2654
2655 CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
2656
2657 if (dhd->conf != NULL) {
2658 printf("%s: config is attached before!\n", __FUNCTION__);
2659 return 0;
2660 }
2661 /* Allocate private bus interface state */
2662 if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {
2663 CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__));
2664 goto fail;
2665 }
2666 memset(conf, 0, sizeof(dhd_conf_t));
2667
2668 dhd->conf = conf;
2669
2670 return 0;
2671
2672 fail:
2673 if (conf != NULL)
2674 MFREE(dhd->osh, conf, sizeof(dhd_conf_t));
2675 return BCME_NOMEM;
2676 }
2677
2678 void
2679 dhd_conf_detach(dhd_pub_t *dhd)
2680 {
2681 CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
2682
2683 if (dhd->conf) {
2684 #ifdef BCMSDIO
2685 dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);
2686 dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
2687 dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
2688 #endif
2689 if (dhd->conf->magic_pkt_filter_add)
2690 kfree(dhd->conf->magic_pkt_filter_add);
2691 MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));
2692 }
2693 dhd->conf = NULL;
2694 }