Commit | Line | Data |
---|---|---|
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 | ||
22 | uint 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 | |
72 | const 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 | |
80 | const 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 | |
88 | const 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 | |
96 | const 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 | |
104 | const 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 | |
112 | const 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 | |
120 | const 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 | |
128 | const 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 | |
136 | const 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 | |
144 | const 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 | |
152 | const 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 | |
160 | const 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 | |
168 | const 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 | |
176 | const 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 | |
184 | const 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 | |
193 | const 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 | |
210 | void\r | |
211 | dhd_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 | |
229 | void\r | |
230 | dhd_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 | |
242 | void\r | |
243 | dhd_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 | |
260 | int\r | |
261 | dhd_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 | |
341 | void\r | |
342 | dhd_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 | |
402 | void\r | |
403 | dhd_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 | |
451 | void\r | |
452 | dhd_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 | |
571 | void\r | |
572 | dhd_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 | |
614 | void\r | |
615 | dhd_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 | |
643 | void\r | |
644 | dhd_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 | |
738 | int\r | |
739 | dhd_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 | |
756 | int\r | |
757 | dhd_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 | |
772 | int\r | |
773 | dhd_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 | |
792 | int\r | |
793 | dhd_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 | |
810 | uint\r | |
811 | dhd_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 | |
823 | int\r | |
824 | dhd_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 | |
836 | int\r | |
837 | dhd_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 | |
851 | int\r | |
852 | dhd_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 | |
870 | int\r | |
871 | dhd_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 | |
906 | bool\r | |
907 | dhd_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 | |
927 | int\r | |
928 | dhd_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 | |
955 | void\r | |
956 | dhd_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 *)¶m, 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 *)¶m, sizeof(param), TRUE);\r | |
975 | }\r | |
976 | }\r | |
977 | \r | |
978 | void\r | |
979 | dhd_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 | |
1026 | void\r | |
1027 | dhd_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 | |
1075 | void\r | |
1076 | dhd_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 | |
1105 | void\r | |
1106 | dhd_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 | |
1135 | bool\r | |
1136 | dhd_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 | |
1152 | void\r | |
1153 | dhd_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 | |
1180 | void\r | |
1181 | dhd_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 | |
1187 | int\r | |
1188 | dhd_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 | |
1195 | unsigned int\r | |
1196 | process_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 | |
1253 | void\r | |
1254 | dhd_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 | ||
1329 | void\r | |
1330 | dhd_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 | ||
1365 | void\r | |
1366 | dhd_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 | |
1418 | void\r | |
1419 | dhd_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 | |
1492 | void\r | |
1493 | dhd_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 | |
1556 | void\r | |
1557 | dhd_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 | |
1607 | void\r | |
1608 | dhd_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 | |
1677 | void\r | |
1678 | dhd_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 | |
1728 | int\r | |
1729 | dhd_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 | |
2269 | err:\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 | |
2282 | int\r | |
2283 | dhd_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 | |
2291 | uint\r | |
2292 | dhd_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 | |
2301 | uint\r | |
2302 | dhd_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 | |
2312 | void\r | |
2313 | dhd_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 | |
2355 | int\r | |
2356 | dhd_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 | |
2545 | int\r | |
2546 | dhd_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 | |
2557 | int\r | |
2558 | dhd_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 | |
2579 | fail:\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 | |
2585 | void\r | |
2586 | dhd_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 |