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