dhd_custom_sec.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659
  1. /*
  2. * Customer HW 4 dependant file
  3. *
  4. * Copyright (C) 1999-2014, Broadcom Corporation
  5. *
  6. * Unless you and Broadcom execute a separate written software license
  7. * agreement governing use of this software, this software is licensed to you
  8. * under the terms of the GNU General Public License version 2 (the "GPL"),
  9. * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  10. * following added to such license:
  11. *
  12. * As a special exception, the copyright holders of this software give you
  13. * permission to link this software with independent modules, and to copy and
  14. * distribute the resulting executable under terms of your choice, provided that
  15. * you also meet, for each linked independent module, the terms and conditions of
  16. * the license of that module. An independent module is a module which is not
  17. * derived from this software. The special exception does not apply to any
  18. * modifications of the software.
  19. *
  20. * Notwithstanding the above, under no circumstances may you combine this
  21. * software in any way with any other Broadcom software provided under a license
  22. * other than the GPL, without Broadcom's express prior written consent.
  23. *
  24. * $Id: dhd_custom_sec.c 334946 2012-05-24 20:38:00Z $
  25. */
  26. #ifdef CUSTOMER_HW4
  27. #include <typedefs.h>
  28. #include <linuxver.h>
  29. #include <osl.h>
  30. #include <proto/ethernet.h>
  31. #include <dngl_stats.h>
  32. #include <bcmutils.h>
  33. #include <dhd.h>
  34. #include <dhd_dbg.h>
  35. #include <dhd_linux.h>
  36. #include <bcmdevs.h>
  37. #include <linux/fcntl.h>
  38. #include <linux/fs.h>
  39. struct dhd_info;
  40. extern int _dhd_set_mac_address(struct dhd_info *dhd,
  41. int ifidx, struct ether_addr *addr);
  42. struct cntry_locales_custom {
  43. char iso_abbrev[WLC_CNTRY_BUF_SZ]; /* ISO 3166-1 country abbreviation */
  44. char custom_locale[WLC_CNTRY_BUF_SZ]; /* Custom firmware locale */
  45. int32 custom_locale_rev; /* Custom local revisin default -1 */
  46. };
  47. /* Locale table for sec */
  48. const struct cntry_locales_custom translate_custom_table[] = {
  49. #if defined(BCM4330_CHIP) || defined(BCM4334_CHIP) || defined(BCM43241_CHIP)
  50. /* 4330/4334/43241 */
  51. {"AR", "AR", 1},
  52. {"AT", "AT", 1},
  53. {"AU", "AU", 2},
  54. {"BE", "BE", 1},
  55. {"BG", "BG", 1},
  56. {"BN", "BN", 1},
  57. {"CA", "CA", 2},
  58. {"CH", "CH", 1},
  59. {"CY", "CY", 1},
  60. {"CZ", "CZ", 1},
  61. {"DE", "DE", 3},
  62. {"DK", "DK", 1},
  63. {"EE", "EE", 1},
  64. {"ES", "ES", 1},
  65. {"FI", "FI", 1},
  66. {"FR", "FR", 1},
  67. {"GB", "GB", 1},
  68. {"GR", "GR", 1},
  69. {"HR", "HR", 1},
  70. {"HU", "HU", 1},
  71. {"IE", "IE", 1},
  72. {"IS", "IS", 1},
  73. {"IT", "IT", 1},
  74. {"JP", "JP", 5},
  75. {"KR", "KR", 24},
  76. {"KW", "KW", 1},
  77. {"LI", "LI", 1},
  78. {"LT", "LT", 1},
  79. {"LU", "LU", 1},
  80. {"LV", "LV", 1},
  81. {"MT", "MT", 1},
  82. {"NL", "NL", 1},
  83. {"NO", "NO", 1},
  84. {"PL", "PL", 1},
  85. {"PT", "PT", 1},
  86. {"PY", "PY", 1},
  87. {"RO", "RO", 1},
  88. {"RU", "RU", 13},
  89. {"SE", "SE", 1},
  90. {"SI", "SI", 1},
  91. {"SK", "SK", 1},
  92. {"TW", "TW", 2},
  93. #ifdef BCM4330_CHIP
  94. {"", "XZ", 1}, /* Universal if Country code is unknown or empty */
  95. {"IR", "XZ", 1}, /* Universal if Country code is IRAN, (ISLAMIC REPUBLIC OF) */
  96. {"SD", "XZ", 1}, /* Universal if Country code is SUDAN */
  97. {"SY", "XZ", 1}, /* Universal if Country code is SYRIAN ARAB REPUBLIC */
  98. {"GL", "XZ", 1}, /* Universal if Country code is GREENLAND */
  99. {"PS", "XZ", 1}, /* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
  100. {"TL", "XZ", 1}, /* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
  101. {"MH", "XZ", 1}, /* Universal if Country code is MARSHALL ISLANDS */
  102. {"JO", "XZ", 1}, /* Universal if Country code is Jordan */
  103. {"PG", "XZ", 1}, /* Universal if Country code is Papua New Guinea */
  104. {"SA", "XZ", 1}, /* Universal if Country code is Saudi Arabia */
  105. {"AF", "XZ", 1}, /* Universal if Country code is Afghanistan */
  106. {"US", "US", 5},
  107. {"UA", "UY", 0},
  108. {"AD", "AL", 0},
  109. {"CX", "AU", 2},
  110. {"GE", "GB", 1},
  111. {"ID", "MW", 0},
  112. {"KI", "AU", 2},
  113. {"NP", "SA", 0},
  114. {"WS", "SA", 0},
  115. {"LR", "BR", 0},
  116. {"ZM", "IN", 0},
  117. {"AN", "AG", 0},
  118. {"AI", "AS", 0},
  119. {"BM", "AS", 0},
  120. {"DZ", "GB", 1},
  121. {"LC", "AG", 0},
  122. {"MF", "BY", 0},
  123. {"GY", "CU", 0},
  124. {"LA", "GB", 1},
  125. {"LB", "BR", 0},
  126. {"MA", "IL", 0},
  127. {"MO", "BD", 0},
  128. {"MW", "BD", 0},
  129. {"QA", "BD", 0},
  130. {"TR", "GB", 1},
  131. {"TZ", "BF", 0},
  132. {"VN", "BR", 0},
  133. {"AE", "AZ", 0},
  134. {"IQ", "GB", 1},
  135. {"CN", "CL", 0},
  136. {"MX", "MX", 1},
  137. #else
  138. /* 4334/43241 */
  139. {"", "XZ", 11}, /* Universal if Country code is unknown or empty */
  140. {"IR", "XZ", 11}, /* Universal if Country code is IRAN, (ISLAMIC REPUBLIC OF) */
  141. {"SD", "XZ", 11}, /* Universal if Country code is SUDAN */
  142. {"SY", "XZ", 11}, /* Universal if Country code is SYRIAN ARAB REPUBLIC */
  143. {"GL", "XZ", 11}, /* Universal if Country code is GREENLAND */
  144. {"PS", "XZ", 11}, /* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
  145. {"TL", "XZ", 11}, /* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
  146. {"MH", "XZ", 11}, /* Universal if Country code is MARSHALL ISLANDS */
  147. {"US", "US", 46},
  148. {"UA", "UA", 8},
  149. {"CO", "CO", 4},
  150. {"ID", "ID", 1},
  151. {"LA", "LA", 1},
  152. {"LB", "LB", 2},
  153. {"VN", "VN", 4},
  154. {"MA", "MA", 1},
  155. {"TR", "TR", 7},
  156. #endif /* defined(BCM4330_CHIP) */
  157. #ifdef BCM4334_CHIP
  158. {"AE", "AE", 1},
  159. {"MX", "MX", 1},
  160. #endif /* defined(BCM4334_CHIP) */
  161. #ifdef BCM43241_CHIP
  162. {"AE", "AE", 6},
  163. {"BD", "BD", 2},
  164. {"CN", "CN", 38},
  165. {"MX", "MX", 20},
  166. #endif /* defined(BCM43241_CHIP) */
  167. #else /* defined(BCM4330_CHIP) || defined(BCM4334_CHIP) || defined(BCM43241_CHIP) */
  168. /* default ccode/regrev */
  169. {"", "XZ", 11}, /* Universal if Country code is unknown or empty */
  170. {"IR", "XZ", 11}, /* Universal if Country code is IRAN, (ISLAMIC REPUBLIC OF) */
  171. {"SD", "XZ", 11}, /* Universal if Country code is SUDAN */
  172. {"SY", "XZ", 11}, /* Universal if Country code is SYRIAN ARAB REPUBLIC */
  173. {"GL", "XZ", 11}, /* Universal if Country code is GREENLAND */
  174. {"PS", "XZ", 11}, /* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
  175. {"TL", "XZ", 11}, /* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
  176. {"MH", "XZ", 11}, /* Universal if Country code is MARSHALL ISLANDS */
  177. {"AL", "AL", 2},
  178. {"DZ", "GB", 6},
  179. {"AS", "AS", 12},
  180. {"AI", "AI", 1},
  181. {"AF", "AD", 0},
  182. {"AG", "AG", 2},
  183. {"AR", "AU", 6},
  184. {"AW", "AW", 2},
  185. {"AU", "AU", 6},
  186. {"AT", "AT", 4},
  187. {"AZ", "AZ", 2},
  188. {"BS", "BS", 2},
  189. {"BH", "BH", 4},
  190. {"BD", "AO", 0},
  191. {"BY", "BY", 3},
  192. {"BE", "BE", 4},
  193. {"BM", "BM", 12},
  194. {"BA", "BA", 2},
  195. {"BR", "BR", 4},
  196. {"VG", "VG", 2},
  197. {"BN", "BN", 4},
  198. {"BG", "BG", 4},
  199. {"KH", "KH", 2},
  200. {"CA", "US", 0},
  201. {"KY", "KY", 3},
  202. {"CN", "CN", 38},
  203. {"CO", "CO", 17},
  204. {"CR", "CR", 17},
  205. {"HR", "HR", 4},
  206. {"CY", "CY", 4},
  207. {"CZ", "CZ", 4},
  208. {"DK", "DK", 4},
  209. {"EE", "EE", 4},
  210. {"ET", "ET", 2},
  211. {"FI", "FI", 4},
  212. {"FR", "FR", 5},
  213. {"GF", "GF", 2},
  214. {"DE", "DE", 7},
  215. {"GR", "GR", 4},
  216. {"GD", "GD", 2},
  217. {"GP", "GP", 2},
  218. {"GU", "GU", 12},
  219. {"HK", "HK", 2},
  220. {"HU", "HU", 4},
  221. {"IS", "IS", 4},
  222. {"IN", "IN", 3},
  223. {"ID", "ID", 1},
  224. {"IE", "IE", 5},
  225. {"IL", "IL", 7},
  226. {"IT", "IT", 4},
  227. {"JP", "JP", 45},
  228. {"JO", "JO", 3},
  229. {"KE", "SA", 0},
  230. {"KW", "KW", 5},
  231. {"LA", "LA", 2},
  232. {"LV", "LV", 4},
  233. {"LB", "LB", 5},
  234. {"LS", "LS", 2},
  235. {"LI", "LI", 4},
  236. {"LT", "LT", 4},
  237. {"LU", "LU", 3},
  238. {"MO", "MO", 2},
  239. {"MK", "MK", 2},
  240. {"MW", "MW", 1},
  241. {"MY", "MY", 3},
  242. {"MV", "MV", 3},
  243. {"MT", "MT", 4},
  244. {"MQ", "MQ", 2},
  245. {"MR", "MR", 2},
  246. {"MU", "MU", 2},
  247. {"YT", "YT", 2},
  248. {"MX", "MX", 20},
  249. {"MD", "MD", 2},
  250. {"MC", "MC", 1},
  251. {"ME", "ME", 2},
  252. {"MA", "MA", 2},
  253. {"NP", "ID", 5},
  254. {"NL", "NL", 4},
  255. {"AN", "GD", 2},
  256. {"NZ", "NZ", 4},
  257. {"NO", "NO", 4},
  258. {"OM", "OM", 4},
  259. {"PA", "PA", 17},
  260. {"PG", "AU", 6},
  261. {"PY", "PY", 2},
  262. {"PE", "PE", 20},
  263. {"PH", "PH", 5},
  264. {"PL", "PL", 4},
  265. {"PT", "PT", 4},
  266. {"PR", "PR", 20},
  267. {"RE", "RE", 2},
  268. {"RO", "RO", 4},
  269. {"SN", "MA", 2},
  270. {"RS", "RS", 2},
  271. {"SK", "SK", 4},
  272. {"SI", "SI", 4},
  273. {"ES", "ES", 4},
  274. {"LK", "LK", 1},
  275. {"SE", "SE", 4},
  276. {"CH", "CH", 4},
  277. {"TW", "TW", 1},
  278. {"TH", "TH", 5},
  279. {"TT", "TT", 3},
  280. {"TR", "TR", 7},
  281. {"AE", "AE", 6},
  282. {"UG", "UG", 2},
  283. {"GB", "GB", 6},
  284. {"UY", "UY", 1},
  285. {"VI", "VI", 13},
  286. {"VA", "VA", 2},
  287. {"VE", "VE", 3},
  288. {"VN", "VN", 4},
  289. {"ZM", "LA", 2},
  290. {"EC", "EC", 21},
  291. {"SV", "SV", 25},
  292. {"KR", "KR", 48},
  293. {"RU", "RU", 13},
  294. {"UA", "UA", 8},
  295. {"GT", "GT", 1},
  296. {"FR", "FR", 5},
  297. {"MN", "MN", 1},
  298. {"NI", "NI", 2},
  299. {"UZ", "MA", 2},
  300. {"ZA", "ZA", 6},
  301. {"EG", "EG", 13},
  302. {"TN", "TN", 1},
  303. #endif /* default ccode/regrev */
  304. };
  305. /* Customized Locale convertor
  306. * input : ISO 3166-1 country abbreviation
  307. * output: customized cspec
  308. */
  309. void get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec)
  310. {
  311. int size, i;
  312. size = ARRAYSIZE(translate_custom_table);
  313. if (cspec == 0)
  314. return;
  315. if (size == 0)
  316. return;
  317. for (i = 0; i < size; i++) {
  318. if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) {
  319. memcpy(cspec->ccode,
  320. translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ);
  321. cspec->rev = translate_custom_table[i].custom_locale_rev;
  322. return;
  323. }
  324. }
  325. return;
  326. }
  327. #ifdef PLATFORM_SLP
  328. #define CIDINFO "/opt/etc/.cid.info"
  329. #define PSMINFO "/opt/etc/.psm.info"
  330. #define MACINFO "/opt/etc/.mac.info"
  331. #define MACINFO_EFS NULL
  332. #define REVINFO "/opt/etc/.rev"
  333. #define WIFIVERINFO "/opt/etc/.wifiver.info"
  334. #define ANTINFO "/opt/etc/.ant.info"
  335. #define WRMAC_BUF_SIZE 19
  336. #else
  337. #define MACINFO "/data/.mac.info"
  338. #define MACINFO_EFS "/efs/wifi/.mac.info"
  339. #define NVMACINFO "/data/.nvmac.info"
  340. #define REVINFO "/data/.rev"
  341. #define CIDINFO "/data/.cid.info"
  342. #define PSMINFO "/data/.psm.info"
  343. #define WIFIVERINFO "/data/.wifiver.info"
  344. #define ANTINFO "/data/.ant.info"
  345. #define WRMAC_BUF_SIZE 18
  346. #endif /* PLATFORM_SLP */
  347. #ifdef BCM4330_CHIP
  348. #define CIS_BUF_SIZE 128
  349. #elif defined(BCM4334_CHIP)
  350. #define CIS_BUF_SIZE 256
  351. #else
  352. #define CIS_BUF_SIZE 512
  353. #endif /* BCM4330_CHIP */
  354. #define CIS_TUPLE_TAG_START 0x80
  355. #define CIS_TUPLE_TAG_VENDOR 0x81
  356. #define CIS_TUPLE_TAG_MACADDR 0x19
  357. #define CIS_TUPLE_TAG_MACADDR_OFF ((TLV_BODY_OFF) + (1))
  358. #ifdef READ_MACADDR
  359. int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
  360. {
  361. struct file *fp = NULL;
  362. char macbuffer[18] = {0};
  363. mm_segment_t oldfs = {0};
  364. char randommac[3] = {0};
  365. char buf[18] = {0};
  366. char *filepath_efs = MACINFO_EFS;
  367. int ret = 0;
  368. fp = filp_open(filepath_efs, O_RDONLY, 0);
  369. if (IS_ERR(fp)) {
  370. start_readmac:
  371. /* File Doesn't Exist. Create and write mac addr. */
  372. fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
  373. if (IS_ERR(fp)) {
  374. DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_efs));
  375. return -1;
  376. }
  377. oldfs = get_fs();
  378. set_fs(get_ds());
  379. /* Generating the Random Bytes for 3 last octects of the MAC address */
  380. get_random_bytes(randommac, 3);
  381. sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  382. 0x00, 0x12, 0x34, randommac[0], randommac[1], randommac[2]);
  383. DHD_ERROR(("[WIFI_SEC] The Random Generated MAC ID: %s\n", macbuffer));
  384. if (fp->f_mode & FMODE_WRITE) {
  385. ret = fp->f_op->write(fp, (const char *)macbuffer,
  386. sizeof(macbuffer), &fp->f_pos);
  387. if (ret < 0)
  388. DHD_ERROR(("[WIFI_SEC] MAC address [%s] Failed to write into File:"
  389. " %s\n", macbuffer, filepath_efs));
  390. else
  391. DHD_ERROR(("[WIFI_SEC] MAC address [%s] written into File: %s\n",
  392. macbuffer, filepath_efs));
  393. }
  394. set_fs(oldfs);
  395. /* Reading the MAC Address from .mac.info file
  396. ( the existed file or just created file)
  397. */
  398. ret = kernel_read(fp, 0, buf, 18);
  399. } else {
  400. /* Reading the MAC Address from
  401. .mac.info file( the existed file or just created file)
  402. */
  403. ret = kernel_read(fp, 0, buf, 18);
  404. /* to prevent abnormal string display
  405. * when mac address is displayed on the screen.
  406. */
  407. buf[17] = '\0';
  408. if (strncmp(buf, "00:00:00:00:00:00", 17) < 1) {
  409. DHD_ERROR(("[WIFI_SEC] goto start_readmac \r\n"));
  410. filp_close(fp, NULL);
  411. goto start_readmac;
  412. }
  413. }
  414. if (ret)
  415. sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
  416. (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]),
  417. (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]),
  418. (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5]));
  419. else
  420. DHD_ERROR(("[WIFI_SEC] dhd_bus_start: Reading from the '%s' returns 0 bytes\n",
  421. filepath_efs));
  422. if (fp)
  423. filp_close(fp, NULL);
  424. /* Writing Newly generated MAC ID to the Dongle */
  425. if (_dhd_set_mac_address(dhd, 0, mac) == 0)
  426. DHD_INFO(("[WIFI_SEC] dhd_bus_start: MACID is overwritten\n"));
  427. else
  428. DHD_ERROR(("[WIFI_SEC] dhd_bus_start: _dhd_set_mac_address() failed\n"));
  429. return 0;
  430. }
  431. #endif /* READ_MACADDR */
  432. #ifdef RDWR_MACADDR
  433. static int g_imac_flag;
  434. enum {
  435. MACADDR_NONE = 0,
  436. MACADDR_MOD,
  437. MACADDR_MOD_RANDOM,
  438. MACADDR_MOD_NONE,
  439. MACADDR_COB,
  440. MACADDR_COB_RANDOM
  441. };
  442. int dhd_write_rdwr_macaddr(struct ether_addr *mac)
  443. {
  444. char *filepath_data = MACINFO;
  445. char *filepath_efs = MACINFO_EFS;
  446. struct file *fp_mac = NULL;
  447. char buf[18] = {0};
  448. mm_segment_t oldfs = {0};
  449. int ret = -1;
  450. if ((g_imac_flag != MACADDR_COB) && (g_imac_flag != MACADDR_MOD))
  451. return 0;
  452. sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  453. mac->octet[0], mac->octet[1], mac->octet[2],
  454. mac->octet[3], mac->octet[4], mac->octet[5]);
  455. /* /efs/wifi/.mac.info will be created */
  456. fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
  457. if (IS_ERR(fp_mac)) {
  458. DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_data));
  459. return -1;
  460. } else {
  461. oldfs = get_fs();
  462. set_fs(get_ds());
  463. if (fp_mac->f_mode & FMODE_WRITE) {
  464. ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
  465. sizeof(buf), &fp_mac->f_pos);
  466. if (ret < 0)
  467. DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed"
  468. " to write into File: %s\n", buf, filepath_data));
  469. else
  470. DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
  471. " into File: %s\n", buf, filepath_data));
  472. }
  473. set_fs(oldfs);
  474. filp_close(fp_mac, NULL);
  475. }
  476. /* /data/.mac.info will be created */
  477. fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);
  478. if (IS_ERR(fp_mac)) {
  479. DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_efs));
  480. return -1;
  481. } else {
  482. oldfs = get_fs();
  483. set_fs(get_ds());
  484. if (fp_mac->f_mode & FMODE_WRITE) {
  485. ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
  486. sizeof(buf), &fp_mac->f_pos);
  487. if (ret < 0)
  488. DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed"
  489. " to write into File: %s\n", buf, filepath_efs));
  490. else
  491. DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
  492. " into File: %s\n", buf, filepath_efs));
  493. }
  494. set_fs(oldfs);
  495. filp_close(fp_mac, NULL);
  496. }
  497. return 0;
  498. }
  499. int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
  500. struct ether_addr *mac)
  501. {
  502. struct file *fp_mac = NULL;
  503. struct file *fp_nvm = NULL;
  504. char macbuffer[18] = {0};
  505. char randommac[3] = {0};
  506. char buf[18] = {0};
  507. char *filepath_data = MACINFO;
  508. char *filepath_efs = MACINFO_EFS;
  509. #ifdef CONFIG_TARGET_LOCALE_NA
  510. char *nvfilepath = "/data/misc/wifi/.nvmac.info";
  511. #else
  512. char *nvfilepath = "/efs/wifi/.nvmac.info";
  513. #endif
  514. char cur_mac[128] = {0};
  515. char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38};
  516. char cur_macbuffer[18] = {0};
  517. int ret = -1;
  518. g_imac_flag = MACADDR_NONE;
  519. fp_nvm = filp_open(nvfilepath, O_RDONLY, 0);
  520. if (IS_ERR(fp_nvm)) { /* file does not exist */
  521. /* read MAC Address */
  522. strcpy(cur_mac, "cur_etheraddr");
  523. ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, cur_mac,
  524. sizeof(cur_mac), 0, 0);
  525. if (ret < 0) {
  526. DHD_ERROR(("[WIFI_SEC] Current READ MAC error \r\n"));
  527. memset(cur_mac, 0, ETHER_ADDR_LEN);
  528. return -1;
  529. } else {
  530. DHD_ERROR(("[WIFI_SEC] MAC (OTP) : "
  531. "[%02X:%02X:%02X:%02X:%02X:%02X] \r\n",
  532. cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3],
  533. cur_mac[4], cur_mac[5]));
  534. }
  535. sprintf(cur_macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  536. cur_mac[0], cur_mac[1], cur_mac[2],
  537. cur_mac[3], cur_mac[4], cur_mac[5]);
  538. fp_mac = filp_open(filepath_data, O_RDONLY, 0);
  539. if (IS_ERR(fp_mac)) { /* file does not exist */
  540. /* read mac is the dummy mac (00:90:4C:C5:12:38) */
  541. if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
  542. g_imac_flag = MACADDR_MOD_RANDOM;
  543. else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0)
  544. g_imac_flag = MACADDR_MOD_RANDOM;
  545. else
  546. g_imac_flag = MACADDR_MOD;
  547. } else {
  548. int is_zeromac;
  549. ret = kernel_read(fp_mac, 0, buf, 18);
  550. filp_close(fp_mac, NULL);
  551. buf[17] = '\0';
  552. is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
  553. DHD_ERROR(("[WIFI_SEC] MAC (FILE): [%s] [%d] \r\n",
  554. buf, is_zeromac));
  555. if (is_zeromac == 0) {
  556. DHD_ERROR(("[WIFI_SEC] Zero MAC detected."
  557. " Trying Random MAC.\n"));
  558. g_imac_flag = MACADDR_MOD_RANDOM;
  559. } else {
  560. sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
  561. (unsigned int *)&(mac->octet[0]),
  562. (unsigned int *)&(mac->octet[1]),
  563. (unsigned int *)&(mac->octet[2]),
  564. (unsigned int *)&(mac->octet[3]),
  565. (unsigned int *)&(mac->octet[4]),
  566. (unsigned int *)&(mac->octet[5]));
  567. /* current MAC address is same as previous one */
  568. if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
  569. g_imac_flag = MACADDR_NONE;
  570. } else { /* change MAC address */
  571. if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
  572. DHD_INFO(("[WIFI_SEC] %s: MACID is"
  573. " overwritten\n", __FUNCTION__));
  574. g_imac_flag = MACADDR_MOD;
  575. } else {
  576. DHD_ERROR(("[WIFI_SEC] %s: "
  577. "_dhd_set_mac_address()"
  578. " failed\n", __FUNCTION__));
  579. g_imac_flag = MACADDR_NONE;
  580. }
  581. }
  582. }
  583. }
  584. fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
  585. if (IS_ERR(fp_mac)) { /* file does not exist */
  586. /* read mac is the dummy mac (00:90:4C:C5:12:38) */
  587. if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
  588. g_imac_flag = MACADDR_MOD_RANDOM;
  589. else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0)
  590. g_imac_flag = MACADDR_MOD_RANDOM;
  591. else
  592. g_imac_flag = MACADDR_MOD;
  593. } else {
  594. int is_zeromac;
  595. ret = kernel_read(fp_mac, 0, buf, 18);
  596. filp_close(fp_mac, NULL);
  597. buf[17] = '\0';
  598. is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
  599. DHD_ERROR(("[WIFI_SEC] MAC (FILE): [%s] [%d] \r\n",
  600. buf, is_zeromac));
  601. if (is_zeromac == 0) {
  602. DHD_ERROR(("[WIFI_SEC] Zero MAC detected."
  603. " Trying Random MAC.\n"));
  604. g_imac_flag = MACADDR_MOD_RANDOM;
  605. } else {
  606. sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
  607. (unsigned int *)&(mac->octet[0]),
  608. (unsigned int *)&(mac->octet[1]),
  609. (unsigned int *)&(mac->octet[2]),
  610. (unsigned int *)&(mac->octet[3]),
  611. (unsigned int *)&(mac->octet[4]),
  612. (unsigned int *)&(mac->octet[5]));
  613. /* current MAC address is same as previous one */
  614. if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
  615. g_imac_flag = MACADDR_NONE;
  616. } else { /* change MAC address */
  617. if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
  618. DHD_INFO(("[WIFI_SEC] %s: MACID is"
  619. " overwritten\n", __FUNCTION__));
  620. g_imac_flag = MACADDR_MOD;
  621. } else {
  622. DHD_ERROR(("[WIFI_SEC] %s: "
  623. "_dhd_set_mac_address()"
  624. " failed\n", __FUNCTION__));
  625. g_imac_flag = MACADDR_NONE;
  626. }
  627. }
  628. }
  629. }
  630. } else {
  631. /* COB type. only COB. */
  632. /* Reading the MAC Address from .nvmac.info file
  633. * (the existed file or just created file)
  634. */
  635. ret = kernel_read(fp_nvm, 0, buf, 18);
  636. /* to prevent abnormal string display when mac address
  637. * is displayed on the screen.
  638. */
  639. buf[17] = '\0';
  640. DHD_ERROR(("[WIFI_SEC] Read MAC : [%s] [%d] \r\n", buf,
  641. strncmp(buf, "00:00:00:00:00:00", 17)));
  642. if ((buf[0] == '\0') ||
  643. (strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
  644. g_imac_flag = MACADDR_COB_RANDOM;
  645. } else {
  646. sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
  647. (unsigned int *)&(mac->octet[0]),
  648. (unsigned int *)&(mac->octet[1]),
  649. (unsigned int *)&(mac->octet[2]),
  650. (unsigned int *)&(mac->octet[3]),
  651. (unsigned int *)&(mac->octet[4]),
  652. (unsigned int *)&(mac->octet[5]));
  653. /* Writing Newly generated MAC ID to the Dongle */
  654. if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
  655. DHD_INFO(("[WIFI_SEC] %s: MACID is overwritten\n",
  656. __FUNCTION__));
  657. g_imac_flag = MACADDR_COB;
  658. } else {
  659. DHD_ERROR(("[WIFI_SEC] %s: _dhd_set_mac_address()"
  660. " failed\n", __FUNCTION__));
  661. }
  662. }
  663. filp_close(fp_nvm, NULL);
  664. }
  665. if ((g_imac_flag == MACADDR_COB_RANDOM) ||
  666. (g_imac_flag == MACADDR_MOD_RANDOM)) {
  667. get_random_bytes(randommac, 3);
  668. sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  669. 0x60, 0xd0, 0xa9, randommac[0], randommac[1],
  670. randommac[2]);
  671. DHD_ERROR(("[WIFI_SEC] The Random Generated MAC ID : %s\n",
  672. macbuffer));
  673. sscanf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X",
  674. (unsigned int *)&(mac->octet[0]),
  675. (unsigned int *)&(mac->octet[1]),
  676. (unsigned int *)&(mac->octet[2]),
  677. (unsigned int *)&(mac->octet[3]),
  678. (unsigned int *)&(mac->octet[4]),
  679. (unsigned int *)&(mac->octet[5]));
  680. if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
  681. DHD_INFO(("[WIFI_SEC] %s: MACID is overwritten\n", __FUNCTION__));
  682. g_imac_flag = MACADDR_COB;
  683. } else {
  684. DHD_ERROR(("[WIFI_SEC] %s: _dhd_set_mac_address() failed\n",
  685. __FUNCTION__));
  686. }
  687. }
  688. return 0;
  689. }
  690. #endif /* RDWR_MACADDR */
  691. #ifdef RDWR_KORICS_MACADDR
  692. int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
  693. {
  694. struct file *fp = NULL;
  695. char macbuffer[18] = {0};
  696. mm_segment_t oldfs = {0};
  697. char randommac[3] = {0};
  698. char buf[18] = {0};
  699. char *filepath_efs = MACINFO_EFS;
  700. int is_zeromac = 0;
  701. int ret = 0;
  702. /* MAC address copied from efs/wifi.mac.info */
  703. fp = filp_open(filepath_efs, O_RDONLY, 0);
  704. if (IS_ERR(fp)) {
  705. /* File Doesn't Exist. Create and write mac addr. */
  706. fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
  707. if (IS_ERR(fp)) {
  708. DHD_ERROR(("[WIFI_SEC] %s: File open error\n",
  709. filepath_efs));
  710. return -1;
  711. }
  712. oldfs = get_fs();
  713. set_fs(get_ds());
  714. /* Generating the Random Bytes for
  715. * 3 last octects of the MAC address
  716. */
  717. get_random_bytes(randommac, 3);
  718. sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  719. 0x60, 0xd0, 0xa9, randommac[0],
  720. randommac[1], randommac[2]);
  721. DHD_ERROR(("[WIFI_SEC] The Random Generated MAC ID : %s\n",
  722. macbuffer));
  723. if (fp->f_mode & FMODE_WRITE) {
  724. ret = fp->f_op->write(fp,
  725. (const char *)macbuffer,
  726. sizeof(macbuffer), &fp->f_pos);
  727. if (ret < 0)
  728. DHD_ERROR(("[WIFI_SEC] Mac address [%s]"
  729. " Failed to write into File:"
  730. " %s\n", macbuffer, filepath_efs));
  731. else
  732. DHD_ERROR(("[WIFI_SEC] Mac address [%s]"
  733. " written into File: %s\n",
  734. macbuffer, filepath_efs));
  735. }
  736. set_fs(oldfs);
  737. } else {
  738. /* Reading the MAC Address from .mac.info file
  739. * (the existed file or just created file)
  740. */
  741. ret = kernel_read(fp, 0, buf, 18);
  742. /* to prevent abnormal string display when mac address
  743. * is displayed on the screen.
  744. */
  745. buf[17] = '\0';
  746. /* Remove security log */
  747. /* DHD_ERROR(("Read MAC : [%s] [%d] \r\n", buf,
  748. * strncmp(buf, "00:00:00:00:00:00", 17)));
  749. */
  750. if ((buf[0] == '\0') ||
  751. (strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
  752. is_zeromac = 1;
  753. }
  754. }
  755. if (ret)
  756. sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
  757. (unsigned int *)&(mac->octet[0]),
  758. (unsigned int *)&(mac->octet[1]),
  759. (unsigned int *)&(mac->octet[2]),
  760. (unsigned int *)&(mac->octet[3]),
  761. (unsigned int *)&(mac->octet[4]),
  762. (unsigned int *)&(mac->octet[5]));
  763. else
  764. DHD_INFO(("[WIFI_SEC] dhd_bus_start: Reading from the"
  765. " '%s' returns 0 bytes\n", filepath_efs));
  766. if (fp)
  767. filp_close(fp, NULL);
  768. if (!is_zeromac) {
  769. /* Writing Newly generated MAC ID to the Dongle */
  770. if (_dhd_set_mac_address(dhd, 0, mac) == 0)
  771. DHD_INFO(("[WIFI_SEC] dhd_bus_start: MACID is overwritten\n"));
  772. else
  773. DHD_ERROR(("[WIFI_SEC] dhd_bus_start: _dhd_set_mac_address() "
  774. "failed\n"));
  775. } else {
  776. DHD_ERROR(("[WIFI_SEC] dhd_bus_start:Is ZeroMAC BypassWrite.mac.info!\n"));
  777. }
  778. return 0;
  779. }
  780. #endif /* RDWR_KORICS_MACADDR */
  781. #ifdef USE_CID_CHECK
  782. static int dhd_write_cid_file(const char *filepath_cid, const char *buf, int buf_len)
  783. {
  784. struct file *fp = NULL;
  785. mm_segment_t oldfs = {0};
  786. int ret = 0;
  787. /* File is always created. */
  788. fp = filp_open(filepath_cid, O_RDWR | O_CREAT, 0666);
  789. if (IS_ERR(fp)) {
  790. DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_cid));
  791. return -1;
  792. } else {
  793. oldfs = get_fs();
  794. set_fs(get_ds());
  795. if (fp->f_mode & FMODE_WRITE) {
  796. ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos);
  797. if (ret < 0)
  798. DHD_ERROR(("[WIFI_SEC] Failed to write CIS[%s]"
  799. " into '%s'\n", buf, filepath_cid));
  800. else
  801. DHD_ERROR(("[WIFI_SEC] CID [%s] written into"
  802. " '%s'\n", buf, filepath_cid));
  803. }
  804. set_fs(oldfs);
  805. }
  806. filp_close(fp, NULL);
  807. return 0;
  808. }
  809. #ifdef DUMP_CIS
  810. static void dhd_dump_cis(const unsigned char *buf, int size)
  811. {
  812. int i;
  813. for (i = 0; i < size; i++) {
  814. DHD_ERROR(("%02X ", buf[i]));
  815. if ((i % 15) == 15) DHD_ERROR(("\n"));
  816. }
  817. DHD_ERROR(("\n"));
  818. }
  819. #endif /* DUMP_CIS */
  820. #define MAX_VID_LEN 8
  821. #define MAX_VNAME_LEN 16
  822. typedef struct {
  823. uint8 vid_length;
  824. unsigned char vid[MAX_VID_LEN];
  825. char vname[MAX_VNAME_LEN];
  826. } vid_info_t;
  827. #if defined(BCM4330_CHIP)
  828. vid_info_t vid_info[] = {
  829. { 6, { 0x00, 0x20, 0xc7, 0x00, 0x00, }, { "murata" } },
  830. { 2, { 0x99, }, { "semcove" } },
  831. { 0, { 0x00, }, { "samsung" } }
  832. };
  833. #elif defined(BCM4334_CHIP)
  834. vid_info_t vid_info[] = {
  835. { 6, { 0x00, 0x00, 0x00, 0x33, 0x33, }, { "semco" } },
  836. { 6, { 0x00, 0x00, 0x00, 0xfb, 0x50, }, { "semcosh" } },
  837. { 6, { 0x00, 0x20, 0xc7, 0x00, 0x00, }, { "murata" } },
  838. { 0, { 0x00, }, { "murata" } }
  839. };
  840. #elif defined(BCM4335_CHIP)
  841. vid_info_t vid_info[] = {
  842. { 3, { 0x33, 0x66, }, { "semcosh" } }, /* B0 Sharp 5G-FEM */
  843. { 3, { 0x33, 0x33, }, { "semco" } }, /* B0 Skyworks 5G-FEM and A0 chip */
  844. { 3, { 0x33, 0x88, }, { "semco3rd" } }, /* B0 Syri 5G-FEM */
  845. { 3, { 0x00, 0x11, }, { "muratafem1" } }, /* B0 ANADIGICS 5G-FEM */
  846. { 3, { 0x00, 0x22, }, { "muratafem2" } }, /* B0 TriQuint 5G-FEM */
  847. { 3, { 0x00, 0x33, }, { "muratafem3" } }, /* 3rd FEM: Reserved */
  848. { 0, { 0x00, }, { "murata" } } /* Default: for Murata A0 module */
  849. };
  850. #elif defined(BCM4339_CHIP) || defined(BCM4354_CHIP)
  851. vid_info_t vid_info[] = { /* 4339:2G FEM+5G FEM ,4354: 2G FEM+5G FEM */
  852. { 3, { 0x33, 0x33, }, { "semco" } }, /* 4339:Skyworks+sharp,4354:Panasonic+Panasonic */
  853. { 3, { 0x33, 0x66, }, { "semco" } }, /* 4339: , 4354:Panasonic+SEMCO */
  854. { 3, { 0x33, 0x88, }, { "semco3rd" } }, /* 4339: , 4354:SEMCO+SEMCO */
  855. { 3, { 0x90, 0x01, }, { "wisol" } }, /* 4339: , 4354:Microsemi+Panasonic */
  856. { 3, { 0x90, 0x02, }, { "wisolfem1" } }, /* 4339: , 4354:Panasonic+Panasonic */
  857. { 3, { 0x90, 0x03, }, { "wisolfem2" } }, /* 4354:Murata+Panasonic */
  858. { 3, { 0x00, 0x11, }, { "muratafem1" } }, /* 4339: , 4354:Murata+Anadigics */
  859. { 3, { 0x00, 0x22, }, { "muratafem2"} }, /* 4339: , 4354:Murata+Triquint */
  860. { 0, { 0x00, }, { "samsung" } } /* Default: Not specified yet */
  861. };
  862. #else
  863. vid_info_t vid_info[] = {
  864. { 0, { 0x00, }, { "samsung" } } /* Default: Not specified yet */
  865. };
  866. #endif /* BCM_CHIP_ID */
  867. int dhd_check_module_cid(dhd_pub_t *dhd)
  868. {
  869. int ret = -1;
  870. unsigned char cis_buf[CIS_BUF_SIZE] = {0};
  871. const char *cidfilepath = CIDINFO;
  872. cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
  873. int idx, max;
  874. vid_info_t *cur_info;
  875. unsigned char *vid_start;
  876. unsigned char vid_length;
  877. #if defined(BCM4334_CHIP) || defined(BCM4335_CHIP)
  878. const char *revfilepath = REVINFO;
  879. #ifdef BCM4334_CHIP
  880. int flag_b3;
  881. #else
  882. char rev_str[10] = {0};
  883. #endif /* BCM4334_CHIP */
  884. #endif /* BCM4334_CHIP || BCM4335_CHIP */
  885. /* Try reading out from CIS */
  886. cish->source = 0;
  887. cish->byteoff = 0;
  888. cish->nbytes = sizeof(cis_buf);
  889. strcpy(cis_buf, "cisdump");
  890. ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
  891. sizeof(cis_buf), 0, 0);
  892. if (ret < 0) {
  893. DHD_ERROR(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n",
  894. __FUNCTION__, ret));
  895. return ret;
  896. }
  897. DHD_ERROR(("[WIFI_SEC] %s: CIS reading success, ret=%d\n",
  898. __FUNCTION__, ret));
  899. #ifdef DUMP_CIS
  900. dhd_dump_cis(cis_buf, 48);
  901. #endif
  902. max = sizeof(cis_buf) - 4;
  903. for (idx = 0; idx < max; idx++) {
  904. if (cis_buf[idx] == CIS_TUPLE_TAG_START) {
  905. if (cis_buf[idx + 2] == CIS_TUPLE_TAG_VENDOR) {
  906. vid_length = cis_buf[idx + 1];
  907. vid_start = &cis_buf[idx + 3];
  908. /* found CIS tuple */
  909. break;
  910. } else {
  911. /* Go to next tuple if tuple value is not vendor type */
  912. idx += (cis_buf[idx + 1] + 1);
  913. }
  914. }
  915. }
  916. if (idx < max) {
  917. max = sizeof(vid_info) / sizeof(vid_info_t);
  918. for (idx = 0; idx < max; idx++) {
  919. cur_info = &vid_info[idx];
  920. if ((cur_info->vid_length == vid_length) &&
  921. (cur_info->vid_length != 0) &&
  922. (memcmp(cur_info->vid, vid_start, cur_info->vid_length - 1) == 0))
  923. goto write_cid;
  924. }
  925. }
  926. /* find default nvram, if exist */
  927. DHD_ERROR(("[WIFI_SEC] %s: cannot find CIS TUPLE set as default\n", __FUNCTION__));
  928. max = sizeof(vid_info) / sizeof(vid_info_t);
  929. for (idx = 0; idx < max; idx++) {
  930. cur_info = &vid_info[idx];
  931. if (cur_info->vid_length == 0)
  932. goto write_cid;
  933. }
  934. DHD_ERROR(("[WIFI_SEC] %s: cannot find default CID\n", __FUNCTION__));
  935. return -1;
  936. write_cid:
  937. DHD_ERROR(("[WIFI_SEC] CIS MATCH FOUND : %s\n", cur_info->vname));
  938. dhd_write_cid_file(cidfilepath, cur_info->vname, strlen(cur_info->vname)+1);
  939. #if defined(BCM4334_CHIP)
  940. /* Try reading out from OTP to distinguish B2 or B3 */
  941. memset(cis_buf, 0, sizeof(cis_buf));
  942. cish = (cis_rw_t *)&cis_buf[8];
  943. cish->source = 0;
  944. cish->byteoff = 0;
  945. cish->nbytes = sizeof(cis_buf);
  946. strcpy(cis_buf, "otpdump");
  947. ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
  948. sizeof(cis_buf), 0, 0);
  949. if (ret < 0) {
  950. DHD_ERROR(("[WIFI_SEC] %s: OTP reading failed, err=%d\n",
  951. __FUNCTION__, ret));
  952. return ret;
  953. }
  954. /* otp 33th character is identifier for 4334B3 */
  955. cis_buf[34] = '\0';
  956. flag_b3 = bcm_atoi(&cis_buf[33]);
  957. if (flag_b3 & 0x1) {
  958. DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4334B3, %c\n", cis_buf[33]));
  959. dhd_write_cid_file(revfilepath, "4334B3", 6);
  960. }
  961. #endif /* BCM4334_CHIP */
  962. #if defined(BCM4335_CHIP)
  963. DHD_TRACE(("[WIFI_SEC] %s: BCM4335 Multiple Revision Check\n", __FUNCTION__));
  964. if (concate_revision(dhd->bus, rev_str, sizeof(rev_str),
  965. rev_str, sizeof(rev_str)) < 0) {
  966. DHD_ERROR(("[WIFI_SEC] %s: fail to concate revision\n", __FUNCTION__));
  967. ret = -1;
  968. } else {
  969. if (strstr(rev_str, "_a0")) {
  970. DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4335A0\n"));
  971. dhd_write_cid_file(revfilepath, "BCM4335A0", 9);
  972. } else {
  973. DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4335B0\n"));
  974. dhd_write_cid_file(revfilepath, "BCM4335B0", 9);
  975. }
  976. }
  977. #endif /* BCM4335_CHIP */
  978. return ret;
  979. }
  980. #endif /* USE_CID_CHECK */
  981. #ifdef GET_MAC_FROM_OTP
  982. static int dhd_write_mac_file(const char *filepath, const char *buf, int buf_len)
  983. {
  984. struct file *fp = NULL;
  985. mm_segment_t oldfs = {0};
  986. int ret = 0;
  987. fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
  988. /* File is always created. */
  989. if (IS_ERR(fp)) {
  990. DHD_ERROR(("[WIFI_SEC] File open error\n"));
  991. return -1;
  992. } else {
  993. oldfs = get_fs();
  994. set_fs(get_ds());
  995. if (fp->f_mode & FMODE_WRITE) {
  996. ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos);
  997. if (ret < 0)
  998. DHD_ERROR(("[WIFI_SEC] Failed to write CIS. \n"));
  999. else
  1000. DHD_ERROR(("[WIFI_SEC] MAC written. \n"));
  1001. }
  1002. set_fs(oldfs);
  1003. }
  1004. filp_close(fp, NULL);
  1005. return 0;
  1006. }
  1007. int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
  1008. {
  1009. int ret = -1;
  1010. unsigned char cis_buf[CIS_BUF_SIZE] = {0};
  1011. unsigned char mac_buf[20] = {0};
  1012. unsigned char otp_mac_buf[20] = {0};
  1013. const char *macfilepath = MACINFO_EFS;
  1014. /* Try reading out from CIS */
  1015. cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
  1016. struct file *fp_mac = NULL;
  1017. cish->source = 0;
  1018. cish->byteoff = 0;
  1019. cish->nbytes = sizeof(cis_buf);
  1020. strcpy(cis_buf, "cisdump");
  1021. ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
  1022. sizeof(cis_buf), 0, 0);
  1023. if (ret < 0) {
  1024. DHD_TRACE(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n", __func__,
  1025. ret));
  1026. sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  1027. mac->octet[0], mac->octet[1], mac->octet[2],
  1028. mac->octet[3], mac->octet[4], mac->octet[5]);
  1029. DHD_ERROR(("[WIFI_SEC] %s: Check module mac by legacy FW : " MACDBG "\n",
  1030. __FUNCTION__, MAC2STRDBG(mac->octet)));
  1031. } else {
  1032. bcm_tlv_t *elt = NULL;
  1033. int remained_len = sizeof(cis_buf);
  1034. int index = 0;
  1035. uint8 *mac_addr = NULL;
  1036. #ifdef DUMP_CIS
  1037. dhd_dump_cis(cis_buf, 48);
  1038. #endif
  1039. /* Find a new tuple tag */
  1040. while (index < remained_len) {
  1041. if (cis_buf[index] == CIS_TUPLE_TAG_START) {
  1042. remained_len -= index;
  1043. if (remained_len >= sizeof(bcm_tlv_t)) {
  1044. elt = (bcm_tlv_t *)&cis_buf[index];
  1045. }
  1046. break;
  1047. } else {
  1048. index++;
  1049. }
  1050. }
  1051. /* Find a MAC address tuple */
  1052. while (elt && remained_len >= TLV_HDR_LEN) {
  1053. int body_len = (int)elt->len;
  1054. if ((elt->id == CIS_TUPLE_TAG_START) &&
  1055. (remained_len >= (body_len + TLV_HDR_LEN)) &&
  1056. (*elt->data == CIS_TUPLE_TAG_MACADDR)) {
  1057. /* found MAC Address tuple and
  1058. * get the MAC Address data
  1059. */
  1060. mac_addr = (uint8 *)elt + CIS_TUPLE_TAG_MACADDR_OFF;
  1061. break;
  1062. }
  1063. /* Go to next tuple if tuple value
  1064. * is not MAC address type
  1065. */
  1066. elt = (bcm_tlv_t *)((uint8 *)elt + (body_len + TLV_HDR_LEN));
  1067. remained_len -= (body_len + TLV_HDR_LEN);
  1068. }
  1069. if (mac_addr) {
  1070. sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  1071. mac_addr[0], mac_addr[1], mac_addr[2],
  1072. mac_addr[3], mac_addr[4], mac_addr[5]);
  1073. DHD_ERROR(("[WIFI_SEC] MAC address is taken from OTP\n"));
  1074. } else {
  1075. sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  1076. mac->octet[0], mac->octet[1], mac->octet[2],
  1077. mac->octet[3], mac->octet[4], mac->octet[5]);
  1078. DHD_ERROR(("[WIFI_SEC] %s: Cannot find MAC address info from OTP,"
  1079. " Check module mac by initial value: " MACDBG "\n",
  1080. __FUNCTION__, MAC2STRDBG(mac->octet)));
  1081. }
  1082. }
  1083. fp_mac = filp_open(macfilepath, O_RDONLY, 0);
  1084. if (!IS_ERR(fp_mac)) {
  1085. DHD_ERROR(("[WIFI_SEC] Check Mac address in .mac.info \n"));
  1086. kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
  1087. filp_close(fp_mac, NULL);
  1088. if (strncmp(mac_buf, otp_mac_buf, 17) != 0) {
  1089. DHD_ERROR(("[WIFI_SEC] file MAC is wrong. Write OTP MAC in .mac.info \n"));
  1090. dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
  1091. }
  1092. }
  1093. return ret;
  1094. }
  1095. #endif /* GET_MAC_FROM_OTP */
  1096. #ifdef WRITE_MACADDR
  1097. int dhd_write_macaddr(struct ether_addr *mac)
  1098. {
  1099. char *filepath_data = MACINFO;
  1100. char *filepath_efs = MACINFO_EFS;
  1101. struct file *fp_mac = NULL;
  1102. char buf[WRMAC_BUF_SIZE] = {0};
  1103. mm_segment_t oldfs = {0};
  1104. int ret = -1;
  1105. int retry_count = 0;
  1106. startwrite:
  1107. sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
  1108. mac->octet[0], mac->octet[1], mac->octet[2],
  1109. mac->octet[3], mac->octet[4], mac->octet[5]);
  1110. /* File will be created /data/.mac.info. */
  1111. fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);
  1112. if (IS_ERR(fp_mac)) {
  1113. DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_data));
  1114. return -1;
  1115. } else {
  1116. oldfs = get_fs();
  1117. set_fs(get_ds());
  1118. if (fp_mac->f_mode & FMODE_WRITE) {
  1119. ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
  1120. sizeof(buf), &fp_mac->f_pos);
  1121. if (ret < 0)
  1122. DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed to"
  1123. " write into File: %s\n", buf, filepath_data));
  1124. else
  1125. DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
  1126. " into File: %s\n", buf, filepath_data));
  1127. }
  1128. set_fs(oldfs);
  1129. filp_close(fp_mac, NULL);
  1130. }
  1131. /* check .mac.info file is 0 byte */
  1132. fp_mac = filp_open(filepath_data, O_RDONLY, 0);
  1133. ret = kernel_read(fp_mac, 0, buf, 18);
  1134. if ((ret == 0) && (retry_count++ < 3)) {
  1135. filp_close(fp_mac, NULL);
  1136. goto startwrite;
  1137. }
  1138. filp_close(fp_mac, NULL);
  1139. /* end of /data/.mac.info */
  1140. if (filepath_efs == NULL) {
  1141. DHD_ERROR(("[WIFI_SEC] %s : no efs filepath", __func__));
  1142. return 0;
  1143. }
  1144. /* File will be created /efs/wifi/.mac.info. */
  1145. fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
  1146. if (IS_ERR(fp_mac)) {
  1147. DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_efs));
  1148. return -1;
  1149. } else {
  1150. oldfs = get_fs();
  1151. set_fs(get_ds());
  1152. if (fp_mac->f_mode & FMODE_WRITE) {
  1153. ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
  1154. sizeof(buf), &fp_mac->f_pos);
  1155. if (ret < 0)
  1156. DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed to"
  1157. " write into File: %s\n", buf, filepath_efs));
  1158. else
  1159. DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
  1160. " into File: %s\n", buf, filepath_efs));
  1161. }
  1162. set_fs(oldfs);
  1163. filp_close(fp_mac, NULL);
  1164. }
  1165. /* check .mac.info file is 0 byte */
  1166. fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
  1167. ret = kernel_read(fp_mac, 0, buf, 18);
  1168. if ((ret == 0) && (retry_count++ < 3)) {
  1169. filp_close(fp_mac, NULL);
  1170. goto startwrite;
  1171. }
  1172. filp_close(fp_mac, NULL);
  1173. return 0;
  1174. }
  1175. #endif /* WRITE_MACADDR */
  1176. #ifdef CONFIG_CONTROL_PM
  1177. extern bool g_pm_control;
  1178. void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
  1179. {
  1180. struct file *fp = NULL;
  1181. char *filepath = PSMINFO;
  1182. char power_val = 0;
  1183. char iovbuf[WL_EVENTING_MASK_LEN + 12];
  1184. #ifdef DHD_ENABLE_LPC
  1185. int ret = 0;
  1186. uint32 lpc = 0;
  1187. #endif /* DHD_ENABLE_LPC */
  1188. g_pm_control = FALSE;
  1189. fp = filp_open(filepath, O_RDONLY, 0);
  1190. if (IS_ERR(fp) || (fp == NULL)) {
  1191. /* Enable PowerSave Mode */
  1192. dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
  1193. sizeof(uint), TRUE, 0);
  1194. DHD_ERROR(("[WIFI_SEC] %s: /data/.psm.info open failed,"
  1195. " so set PM to %d\n",
  1196. __FUNCTION__, *power_mode));
  1197. return;
  1198. } else {
  1199. kernel_read(fp, fp->f_pos, &power_val, 1);
  1200. DHD_ERROR(("[WIFI_SEC] %s: POWER_VAL = %c \r\n", __FUNCTION__, power_val));
  1201. if (power_val == '0') {
  1202. #ifdef ROAM_ENABLE
  1203. uint roamvar = 1;
  1204. #endif
  1205. *power_mode = PM_OFF;
  1206. /* Disable PowerSave Mode */
  1207. dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
  1208. sizeof(uint), TRUE, 0);
  1209. /* Turn off MPC in AP mode */
  1210. bcm_mkiovar("mpc", (char *)power_mode, 4,
  1211. iovbuf, sizeof(iovbuf));
  1212. dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
  1213. sizeof(iovbuf), TRUE, 0);
  1214. g_pm_control = TRUE;
  1215. #ifdef ROAM_ENABLE
  1216. /* Roaming off of dongle */
  1217. bcm_mkiovar("roam_off", (char *)&roamvar, 4,
  1218. iovbuf, sizeof(iovbuf));
  1219. dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
  1220. sizeof(iovbuf), TRUE, 0);
  1221. #endif
  1222. #ifdef DHD_ENABLE_LPC
  1223. /* Set lpc 0 */
  1224. bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf));
  1225. if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
  1226. sizeof(iovbuf), TRUE, 0)) < 0) {
  1227. DHD_ERROR(("[WIFI_SEC] %s: Set lpc failed %d\n",
  1228. __FUNCTION__, ret));
  1229. }
  1230. #endif /* DHD_ENABLE_LPC */
  1231. } else {
  1232. dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
  1233. sizeof(uint), TRUE, 0);
  1234. }
  1235. }
  1236. if (fp)
  1237. filp_close(fp, NULL);
  1238. }
  1239. #endif /* CONFIG_CONTROL_PM */
  1240. #ifdef MIMO_ANT_SETTING
  1241. int dhd_sel_ant_from_file(dhd_pub_t *dhd)
  1242. {
  1243. struct file *fp = NULL;
  1244. int ret = -1;
  1245. uint32 ant_val = 0;
  1246. uint32 btc_mode = 0;
  1247. char *filepath = ANTINFO;
  1248. char iovbuf[WLC_IOCTL_SMLEN];
  1249. uint chip_id = dhd_bus_chip_id(dhd);
  1250. /* Check if this chip can support MIMO */
  1251. if (chip_id != BCM4324_CHIP_ID &&
  1252. chip_id != BCM4350_CHIP_ID &&
  1253. chip_id != BCM4356_CHIP_ID &&
  1254. chip_id != BCM4354_CHIP_ID) {
  1255. DHD_ERROR(("[WIFI_SEC] %s: This chipset does not support MIMO\n",
  1256. __FUNCTION__));
  1257. return ret;
  1258. }
  1259. /* Read antenna settings from the file */
  1260. fp = filp_open(filepath, O_RDONLY, 0);
  1261. if (IS_ERR(fp)) {
  1262. DHD_ERROR(("[WIFI_SEC] %s: File [%s] open error\n", __FUNCTION__, filepath));
  1263. return ret;
  1264. } else {
  1265. ret = kernel_read(fp, 0, (char *)&ant_val, 4);
  1266. if (ret < 0) {
  1267. DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
  1268. filp_close(fp, NULL);
  1269. return ret;
  1270. }
  1271. ant_val = bcm_atoi((char *)&ant_val);
  1272. DHD_ERROR(("[WIFI_SEC]%s: ANT val = %d\n", __FUNCTION__, ant_val));
  1273. filp_close(fp, NULL);
  1274. /* Check value from the file */
  1275. if (ant_val < 1 || ant_val > 3) {
  1276. DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
  1277. __FUNCTION__, ant_val, filepath));
  1278. return -1;
  1279. }
  1280. }
  1281. /* bt coex mode off */
  1282. if (dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) {
  1283. bcm_mkiovar("btc_mode", (char *)&btc_mode, 4, iovbuf, sizeof(iovbuf));
  1284. ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
  1285. if (ret) {
  1286. DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
  1287. "btc_mode, ret=%d\n",
  1288. __FUNCTION__, ret));
  1289. return ret;
  1290. }
  1291. }
  1292. /* Select Antenna */
  1293. bcm_mkiovar("txchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
  1294. ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
  1295. if (ret) {
  1296. DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
  1297. __FUNCTION__, ret));
  1298. return ret;
  1299. }
  1300. bcm_mkiovar("rxchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
  1301. ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
  1302. if (ret) {
  1303. DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
  1304. __FUNCTION__, ret));
  1305. return ret;
  1306. }
  1307. return 0;
  1308. }
  1309. #endif /* MIMO_ANTENNA_SETTING */
  1310. #ifdef USE_WFA_CERT_CONF
  1311. int sec_get_param(dhd_pub_t *dhd, int mode)
  1312. {
  1313. struct file *fp = NULL;
  1314. char *filepath = NULL;
  1315. int val, ret = 0;
  1316. if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
  1317. (mode >= PARAM_LAST_VALUE)) {
  1318. DHD_ERROR(("[WIFI_SEC] %s: invalid argument\n", __FUNCTION__));
  1319. return -EINVAL;
  1320. }
  1321. switch (mode) {
  1322. case SET_PARAM_BUS_TXGLOM_MODE:
  1323. filepath = "/data/.bustxglom.info";
  1324. break;
  1325. case SET_PARAM_ROAMOFF:
  1326. filepath = "/data/.roamoff.info";
  1327. break;
  1328. #ifdef USE_WL_FRAMEBURST
  1329. case SET_PARAM_FRAMEBURST:
  1330. filepath = "/data/.frameburst.info";
  1331. break;
  1332. #endif /* USE_WL_FRAMEBURST */
  1333. #ifdef USE_WL_TXBF
  1334. case SET_PARAM_TXBF:
  1335. filepath = "/data/.txbf.info";
  1336. break;
  1337. #endif /* USE_WL_TXBF */
  1338. default:
  1339. return -EINVAL;
  1340. }
  1341. fp = filp_open(filepath, O_RDONLY, 0);
  1342. if (IS_ERR(fp) || (fp == NULL)) {
  1343. ret = -EIO;
  1344. } else {
  1345. ret = kernel_read(fp, fp->f_pos, (char *)&val, 4);
  1346. filp_close(fp, NULL);
  1347. }
  1348. if (ret < 0) {
  1349. /* File operation is failed so we will return default value */
  1350. switch (mode) {
  1351. case SET_PARAM_BUS_TXGLOM_MODE:
  1352. val = CUSTOM_GLOM_SETTING;
  1353. break;
  1354. case SET_PARAM_ROAMOFF:
  1355. #ifdef ROAM_ENABLE
  1356. val = 0;
  1357. #elif defined(DISABLE_BUILTIN_ROAM)
  1358. val = 1;
  1359. #else
  1360. val = 0;
  1361. #endif /* ROAM_ENABLE */
  1362. break;
  1363. #ifdef USE_WL_FRAMEBURST
  1364. case SET_PARAM_FRAMEBURST:
  1365. val = 1;
  1366. break;
  1367. #endif /* USE_WL_FRAMEBURST */
  1368. #ifdef USE_WL_TXBF
  1369. case SET_PARAM_TXBF:
  1370. val = 1;
  1371. break;
  1372. #endif /* USE_WL_TXBF */
  1373. }
  1374. DHD_INFO(("[WIFI_SEC] %s: File open failed, file path=%s,"
  1375. " default value=%d\n",
  1376. __FUNCTION__, filepath, val));
  1377. return val;
  1378. }
  1379. val = bcm_atoi((char *)&val);
  1380. DHD_INFO(("[WIFI_SEC] %s: %s = %d\n", __FUNCTION__, filepath, val));
  1381. switch (mode) {
  1382. case SET_PARAM_ROAMOFF:
  1383. #ifdef USE_WL_FRAMEBURST
  1384. case SET_PARAM_FRAMEBURST:
  1385. #endif /* USE_WL_FRAMEBURST */
  1386. #ifdef USE_WL_TXBF
  1387. case SET_PARAM_TXBF:
  1388. #endif /* USE_WL_TXBF */
  1389. val = val ? 1 : 0;
  1390. break;
  1391. }
  1392. return val;
  1393. }
  1394. #endif /* USE_WFA_CERT_CONF */
  1395. #ifdef WRITE_WLANINFO
  1396. #define FIRM_PREFIX "Firm_ver:"
  1397. #define DHD_PREFIX "DHD_ver:"
  1398. #define NV_PREFIX "Nv_info:"
  1399. #define max_len(a, b) ((sizeof(a)/(2)) - (strlen(b)) - (3))
  1400. #define tstr_len(a, b) ((strlen(a)) + (strlen(b)) + (3))
  1401. char version_info[512];
  1402. char version_old_info[512];
  1403. int write_filesystem(struct file *file, unsigned long long offset,
  1404. unsigned char* data, unsigned int size)
  1405. {
  1406. mm_segment_t oldfs;
  1407. int ret;
  1408. oldfs = get_fs();
  1409. set_fs(get_ds());
  1410. ret = vfs_write(file, data, size, &offset);
  1411. set_fs(oldfs);
  1412. return ret;
  1413. }
  1414. uint32 sec_save_wlinfo(char *firm_ver, char *dhd_ver, char *nvram_p)
  1415. {
  1416. struct file *fp = NULL;
  1417. struct file *nvfp = NULL;
  1418. char *filepath = WIFIVERINFO;
  1419. int min_len, str_len = 0;
  1420. int ret = 0;
  1421. char* nvram_buf;
  1422. char temp_buf[256];
  1423. DHD_TRACE(("[WIFI_SEC] %s: Entered.\n", __FUNCTION__));
  1424. DHD_INFO(("[WIFI_SEC] firmware version : %s\n", firm_ver));
  1425. DHD_INFO(("[WIFI_SEC] dhd driver version : %s\n", dhd_ver));
  1426. DHD_INFO(("[WIFI_SEC] nvram path : %s\n", nvram_p));
  1427. memset(version_info, 0, sizeof(version_info));
  1428. if (strlen(dhd_ver)) {
  1429. min_len = min(strlen(dhd_ver), max_len(temp_buf, DHD_PREFIX));
  1430. min_len += strlen(DHD_PREFIX) + 3;
  1431. DHD_INFO(("[WIFI_SEC] DHD ver length : %d\n", min_len));
  1432. snprintf(version_info+str_len, min_len, DHD_PREFIX " %s\n", dhd_ver);
  1433. str_len = strlen(version_info);
  1434. DHD_INFO(("[WIFI_SEC] Driver version_info len : %d\n", str_len));
  1435. DHD_INFO(("[WIFI_SEC] Driver version_info : %s\n", version_info));
  1436. } else {
  1437. DHD_ERROR(("[WIFI_SEC] Driver version is missing.\n"));
  1438. }
  1439. if (strlen(firm_ver)) {
  1440. min_len = min(strlen(firm_ver), max_len(temp_buf, FIRM_PREFIX));
  1441. min_len += strlen(FIRM_PREFIX) + 3;
  1442. DHD_INFO(("[WIFI_SEC] firmware ver length : %d\n", min_len));
  1443. snprintf(version_info+str_len, min_len, FIRM_PREFIX " %s\n", firm_ver);
  1444. str_len = strlen(version_info);
  1445. DHD_INFO(("[WIFI_SEC] Firmware version_info len : %d\n", str_len));
  1446. DHD_INFO(("[WIFI_SEC] Firmware version_info : %s\n", version_info));
  1447. } else {
  1448. DHD_ERROR(("[WIFI_SEC] Firmware version is missing.\n"));
  1449. }
  1450. if (nvram_p) {
  1451. memset(temp_buf, 0, sizeof(temp_buf));
  1452. nvfp = filp_open(nvram_p, O_RDONLY, 0);
  1453. if (IS_ERR(nvfp) || (nvfp == NULL)) {
  1454. DHD_ERROR(("[WIFI_SEC] %s: Nvarm File open failed.\n", __FUNCTION__));
  1455. return -1;
  1456. } else {
  1457. ret = kernel_read(nvfp, nvfp->f_pos, temp_buf, sizeof(temp_buf));
  1458. filp_close(nvfp, NULL);
  1459. }
  1460. if (strlen(temp_buf)) {
  1461. nvram_buf = temp_buf;
  1462. bcmstrtok(&nvram_buf, "\n", 0);
  1463. DHD_INFO(("[WIFI_SEC] nvram tolkening : %s(%d) \n",
  1464. temp_buf, strlen(temp_buf)));
  1465. snprintf(version_info+str_len, tstr_len(temp_buf, NV_PREFIX),
  1466. NV_PREFIX " %s\n", temp_buf);
  1467. str_len = strlen(version_info);
  1468. DHD_INFO(("[WIFI_SEC] NVRAM version_info : %s\n", version_info));
  1469. DHD_INFO(("[WIFI_SEC] NVRAM version_info len : %d, nvram len : %d\n",
  1470. str_len, strlen(temp_buf)));
  1471. } else {
  1472. DHD_ERROR(("[WIFI_SEC] NVRAM info is missing.\n"));
  1473. }
  1474. } else {
  1475. DHD_ERROR(("[WIFI_SEC] Not exist nvram path\n"));
  1476. }
  1477. DHD_INFO(("[WIFI_SEC] version_info : %s, strlen : %d\n",
  1478. version_info, strlen(version_info)));
  1479. fp = filp_open(filepath, O_RDONLY, 0);
  1480. if (IS_ERR(fp) || (fp == NULL)) {
  1481. DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n", __FUNCTION__));
  1482. } else {
  1483. memset(version_old_info, 0, sizeof(version_old_info));
  1484. ret = kernel_read(fp, fp->f_pos, version_old_info, sizeof(version_info));
  1485. filp_close(fp, NULL);
  1486. DHD_INFO(("[WIFI_SEC] kernel_read ret : %d.\n", ret));
  1487. if (strcmp(version_info, version_old_info) == 0) {
  1488. DHD_ERROR(("[WIFI_SEC] .wifiver.info already saved.\n"));
  1489. return 0;
  1490. }
  1491. }
  1492. fp = filp_open(filepath, O_RDWR | O_CREAT, 0664);
  1493. if (IS_ERR(fp) || (fp == NULL)) {
  1494. DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n",
  1495. __FUNCTION__));
  1496. } else {
  1497. ret = write_filesystem(fp, fp->f_pos, version_info, sizeof(version_info));
  1498. DHD_INFO(("[WIFI_SEC] sec_save_wlinfo done. ret : %d\n", ret));
  1499. DHD_ERROR(("[WIFI_SEC] save .wifiver.info file.\n"));
  1500. filp_close(fp, NULL);
  1501. }
  1502. return ret;
  1503. }
  1504. #endif /* WRITE_WLANINFO */
  1505. #endif /* CUSTOMER_HW4 */