PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/wilc1000/wilc_wlan_cfg.c

http://github.com/mirrors/linux-2.6
C | 553 lines | 433 code | 88 blank | 32 comment | 82 complexity | 39dca454fc8157aad3303faa80f26c50 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  1. /* ////////////////////////////////////////////////////////////////////////// */
  2. /* */
  3. /* Copyright (c) Atmel Corporation. All rights reserved. */
  4. /* */
  5. /* Module Name: wilc_wlan_cfg.c */
  6. /* */
  7. /* */
  8. /* ///////////////////////////////////////////////////////////////////////// */
  9. #include <linux/string.h>
  10. #include "wilc_wlan_if.h"
  11. #include "wilc_wlan.h"
  12. #include "wilc_wlan_cfg.h"
  13. #include "coreconfigurator.h"
  14. /********************************************
  15. *
  16. * Global Data
  17. *
  18. ********************************************/
  19. enum cfg_cmd_type {
  20. CFG_BYTE_CMD = 0,
  21. CFG_HWORD_CMD = 1,
  22. CFG_WORD_CMD = 2,
  23. CFG_STR_CMD = 3,
  24. CFG_BIN_CMD = 4
  25. };
  26. struct wilc_mac_cfg {
  27. int mac_status;
  28. u8 mac_address[7];
  29. u8 ip_address[5];
  30. u8 bssid[7];
  31. u8 ssid[34];
  32. u8 firmware_version[129];
  33. u8 supp_rate[24];
  34. u8 wep_key[28];
  35. u8 i_psk[66];
  36. u8 hw_product_version[33];
  37. u8 phyversion[17];
  38. u8 supp_username[21];
  39. u8 supp_password[64];
  40. u8 assoc_req[256];
  41. u8 assoc_rsp[256];
  42. u8 firmware_info[8];
  43. u8 scan_result[256];
  44. u8 scan_result1[256];
  45. };
  46. static struct wilc_mac_cfg g_mac;
  47. static struct wilc_cfg_byte g_cfg_byte[] = {
  48. {WID_BSS_TYPE, 0},
  49. {WID_CURRENT_TX_RATE, 0},
  50. {WID_CURRENT_CHANNEL, 0},
  51. {WID_PREAMBLE, 0},
  52. {WID_11G_OPERATING_MODE, 0},
  53. {WID_STATUS, 0},
  54. {WID_SCAN_TYPE, 0},
  55. {WID_KEY_ID, 0},
  56. {WID_QOS_ENABLE, 0},
  57. {WID_POWER_MANAGEMENT, 0},
  58. {WID_11I_MODE, 0},
  59. {WID_AUTH_TYPE, 0},
  60. {WID_SITE_SURVEY, 0},
  61. {WID_LISTEN_INTERVAL, 0},
  62. {WID_DTIM_PERIOD, 0},
  63. {WID_ACK_POLICY, 0},
  64. {WID_BCAST_SSID, 0},
  65. {WID_REKEY_POLICY, 0},
  66. {WID_SHORT_SLOT_ALLOWED, 0},
  67. {WID_START_SCAN_REQ, 0},
  68. {WID_RSSI, 0},
  69. {WID_LINKSPEED, 0},
  70. {WID_AUTO_RX_SENSITIVITY, 0},
  71. {WID_DATAFLOW_CONTROL, 0},
  72. {WID_SCAN_FILTER, 0},
  73. {WID_11N_PROT_MECH, 0},
  74. {WID_11N_ERP_PROT_TYPE, 0},
  75. {WID_11N_ENABLE, 0},
  76. {WID_11N_OPERATING_MODE, 0},
  77. {WID_11N_OBSS_NONHT_DETECTION, 0},
  78. {WID_11N_HT_PROT_TYPE, 0},
  79. {WID_11N_RIFS_PROT_ENABLE, 0},
  80. {WID_11N_SMPS_MODE, 0},
  81. {WID_11N_CURRENT_TX_MCS, 0},
  82. {WID_11N_SHORT_GI_ENABLE, 0},
  83. {WID_RIFS_MODE, 0},
  84. {WID_TX_ABORT_CONFIG, 0},
  85. {WID_11N_IMMEDIATE_BA_ENABLED, 0},
  86. {WID_11N_TXOP_PROT_DISABLE, 0},
  87. {WID_NIL, 0}
  88. };
  89. static struct wilc_cfg_hword g_cfg_hword[] = {
  90. {WID_LINK_LOSS_THRESHOLD, 0},
  91. {WID_RTS_THRESHOLD, 0},
  92. {WID_FRAG_THRESHOLD, 0},
  93. {WID_SHORT_RETRY_LIMIT, 0},
  94. {WID_LONG_RETRY_LIMIT, 0},
  95. {WID_BEACON_INTERVAL, 0},
  96. {WID_RX_SENSE, 0},
  97. {WID_ACTIVE_SCAN_TIME, 0},
  98. {WID_PASSIVE_SCAN_TIME, 0},
  99. {WID_SITE_SURVEY_SCAN_TIME, 0},
  100. {WID_JOIN_START_TIMEOUT, 0},
  101. {WID_AUTH_TIMEOUT, 0},
  102. {WID_ASOC_TIMEOUT, 0},
  103. {WID_11I_PROTOCOL_TIMEOUT, 0},
  104. {WID_EAPOL_RESPONSE_TIMEOUT, 0},
  105. {WID_11N_SIG_QUAL_VAL, 0},
  106. {WID_CCA_THRESHOLD, 0},
  107. {WID_NIL, 0}
  108. };
  109. static struct wilc_cfg_word g_cfg_word[] = {
  110. {WID_FAILED_COUNT, 0},
  111. {WID_RETRY_COUNT, 0},
  112. {WID_MULTIPLE_RETRY_COUNT, 0},
  113. {WID_FRAME_DUPLICATE_COUNT, 0},
  114. {WID_ACK_FAILURE_COUNT, 0},
  115. {WID_RECEIVED_FRAGMENT_COUNT, 0},
  116. {WID_MCAST_RECEIVED_FRAME_COUNT, 0},
  117. {WID_FCS_ERROR_COUNT, 0},
  118. {WID_SUCCESS_FRAME_COUNT, 0},
  119. {WID_TX_FRAGMENT_COUNT, 0},
  120. {WID_TX_MULTICAST_FRAME_COUNT, 0},
  121. {WID_RTS_SUCCESS_COUNT, 0},
  122. {WID_RTS_FAILURE_COUNT, 0},
  123. {WID_WEP_UNDECRYPTABLE_COUNT, 0},
  124. {WID_REKEY_PERIOD, 0},
  125. {WID_REKEY_PACKET_COUNT, 0},
  126. {WID_HW_RX_COUNT, 0},
  127. {WID_GET_INACTIVE_TIME, 0},
  128. {WID_NIL, 0}
  129. };
  130. static struct wilc_cfg_str g_cfg_str[] = {
  131. {WID_SSID, g_mac.ssid}, /* 33 + 1 bytes */
  132. {WID_FIRMWARE_VERSION, g_mac.firmware_version},
  133. {WID_OPERATIONAL_RATE_SET, g_mac.supp_rate},
  134. {WID_BSSID, g_mac.bssid}, /* 6 bytes */
  135. {WID_WEP_KEY_VALUE, g_mac.wep_key}, /* 27 bytes */
  136. {WID_11I_PSK, g_mac.i_psk}, /* 65 bytes */
  137. {WID_HARDWARE_VERSION, g_mac.hw_product_version},
  138. {WID_MAC_ADDR, g_mac.mac_address},
  139. {WID_PHY_VERSION, g_mac.phyversion},
  140. {WID_SUPP_USERNAME, g_mac.supp_username},
  141. {WID_SUPP_PASSWORD, g_mac.supp_password},
  142. {WID_SITE_SURVEY_RESULTS, g_mac.scan_result},
  143. {WID_SITE_SURVEY_RESULTS, g_mac.scan_result1},
  144. {WID_ASSOC_REQ_INFO, g_mac.assoc_req},
  145. {WID_ASSOC_RES_INFO, g_mac.assoc_rsp},
  146. {WID_FIRMWARE_INFO, g_mac.firmware_version},
  147. {WID_IP_ADDRESS, g_mac.ip_address},
  148. {WID_NIL, NULL}
  149. };
  150. /********************************************
  151. *
  152. * Configuration Functions
  153. *
  154. ********************************************/
  155. static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, u16 id, u8 val8)
  156. {
  157. u8 *buf;
  158. if ((offset + 4) >= MAX_CFG_FRAME_SIZE)
  159. return 0;
  160. buf = &frame[offset];
  161. buf[0] = (u8)id;
  162. buf[1] = (u8)(id >> 8);
  163. buf[2] = 1;
  164. buf[3] = val8;
  165. return 4;
  166. }
  167. static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16)
  168. {
  169. u8 *buf;
  170. if ((offset + 5) >= MAX_CFG_FRAME_SIZE)
  171. return 0;
  172. buf = &frame[offset];
  173. buf[0] = (u8)id;
  174. buf[1] = (u8)(id >> 8);
  175. buf[2] = 2;
  176. buf[3] = (u8)val16;
  177. buf[4] = (u8)(val16 >> 8);
  178. return 5;
  179. }
  180. static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32)
  181. {
  182. u8 *buf;
  183. if ((offset + 7) >= MAX_CFG_FRAME_SIZE)
  184. return 0;
  185. buf = &frame[offset];
  186. buf[0] = (u8)id;
  187. buf[1] = (u8)(id >> 8);
  188. buf[2] = 4;
  189. buf[3] = (u8)val32;
  190. buf[4] = (u8)(val32 >> 8);
  191. buf[5] = (u8)(val32 >> 16);
  192. buf[6] = (u8)(val32 >> 24);
  193. return 7;
  194. }
  195. static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, u32 size)
  196. {
  197. u8 *buf;
  198. if ((offset + size + 3) >= MAX_CFG_FRAME_SIZE)
  199. return 0;
  200. buf = &frame[offset];
  201. buf[0] = (u8)id;
  202. buf[1] = (u8)(id >> 8);
  203. buf[2] = (u8)size;
  204. if ((str) && (size != 0))
  205. memcpy(&buf[3], str, size);
  206. return (size + 3);
  207. }
  208. static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size)
  209. {
  210. u8 *buf;
  211. u32 i;
  212. u8 checksum = 0;
  213. if ((offset + size + 5) >= MAX_CFG_FRAME_SIZE)
  214. return 0;
  215. buf = &frame[offset];
  216. buf[0] = (u8)id;
  217. buf[1] = (u8)(id >> 8);
  218. buf[2] = (u8)size;
  219. buf[3] = (u8)(size >> 8);
  220. if ((b) && (size != 0)) {
  221. memcpy(&buf[4], b, size);
  222. for (i = 0; i < size; i++)
  223. checksum += buf[i + 4];
  224. }
  225. buf[size + 4] = checksum;
  226. return (size + 5);
  227. }
  228. /********************************************
  229. *
  230. * Configuration Response Functions
  231. *
  232. ********************************************/
  233. static void wilc_wlan_parse_response_frame(u8 *info, int size)
  234. {
  235. u32 wid, len = 0, i = 0;
  236. while (size > 0) {
  237. i = 0;
  238. wid = info[0] | (info[1] << 8);
  239. wid = cpu_to_le32(wid);
  240. switch ((wid >> 12) & 0x7) {
  241. case WID_CHAR:
  242. do {
  243. if (g_cfg_byte[i].id == WID_NIL)
  244. break;
  245. if (g_cfg_byte[i].id == wid) {
  246. g_cfg_byte[i].val = info[3];
  247. break;
  248. }
  249. i++;
  250. } while (1);
  251. len = 2;
  252. break;
  253. case WID_SHORT:
  254. do {
  255. if (g_cfg_hword[i].id == WID_NIL)
  256. break;
  257. if (g_cfg_hword[i].id == wid) {
  258. g_cfg_hword[i].val = cpu_to_le16(info[3] | (info[4] << 8));
  259. break;
  260. }
  261. i++;
  262. } while (1);
  263. len = 3;
  264. break;
  265. case WID_INT:
  266. do {
  267. if (g_cfg_word[i].id == WID_NIL)
  268. break;
  269. if (g_cfg_word[i].id == wid) {
  270. g_cfg_word[i].val = cpu_to_le32(info[3] | (info[4] << 8) | (info[5] << 16) | (info[6] << 24));
  271. break;
  272. }
  273. i++;
  274. } while (1);
  275. len = 5;
  276. break;
  277. case WID_STR:
  278. do {
  279. if (g_cfg_str[i].id == WID_NIL)
  280. break;
  281. if (g_cfg_str[i].id == wid) {
  282. if (wid == WID_SITE_SURVEY_RESULTS) {
  283. static int toggle;
  284. i += toggle;
  285. toggle ^= 1;
  286. }
  287. memcpy(g_cfg_str[i].str, &info[2], (info[2] + 1));
  288. break;
  289. }
  290. i++;
  291. } while (1);
  292. len = 1 + info[2];
  293. break;
  294. default:
  295. break;
  296. }
  297. size -= (2 + len);
  298. info += (2 + len);
  299. }
  300. }
  301. static int wilc_wlan_parse_info_frame(u8 *info, int size)
  302. {
  303. struct wilc_mac_cfg *pd = &g_mac;
  304. u32 wid, len;
  305. int type = WILC_CFG_RSP_STATUS;
  306. wid = info[0] | (info[1] << 8);
  307. len = info[2];
  308. if ((len == 1) && (wid == WID_STATUS)) {
  309. pd->mac_status = info[3];
  310. type = WILC_CFG_RSP_STATUS;
  311. }
  312. return type;
  313. }
  314. /********************************************
  315. *
  316. * Configuration Exported Functions
  317. *
  318. ********************************************/
  319. int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size)
  320. {
  321. u8 type = (id >> 12) & 0xf;
  322. int ret = 0;
  323. switch (type) {
  324. case CFG_BYTE_CMD:
  325. if (size >= 1)
  326. ret = wilc_wlan_cfg_set_byte(frame, offset, id, *buf);
  327. break;
  328. case CFG_HWORD_CMD:
  329. if (size >= 2)
  330. ret = wilc_wlan_cfg_set_hword(frame, offset, id,
  331. *((u16 *)buf));
  332. break;
  333. case CFG_WORD_CMD:
  334. if (size >= 4)
  335. ret = wilc_wlan_cfg_set_word(frame, offset, id,
  336. *((u32 *)buf));
  337. break;
  338. case CFG_STR_CMD:
  339. ret = wilc_wlan_cfg_set_str(frame, offset, id, buf, size);
  340. break;
  341. case CFG_BIN_CMD:
  342. ret = wilc_wlan_cfg_set_bin(frame, offset, id, buf, size);
  343. break;
  344. }
  345. return ret;
  346. }
  347. int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id)
  348. {
  349. u8 *buf;
  350. if ((offset + 2) >= MAX_CFG_FRAME_SIZE)
  351. return 0;
  352. buf = &frame[offset];
  353. buf[0] = (u8)id;
  354. buf[1] = (u8)(id >> 8);
  355. return 2;
  356. }
  357. int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
  358. {
  359. u32 type = (wid >> 12) & 0xf;
  360. int i, ret = 0;
  361. if (wid == WID_STATUS) {
  362. *((u32 *)buffer) = g_mac.mac_status;
  363. return 4;
  364. }
  365. i = 0;
  366. if (type == CFG_BYTE_CMD) {
  367. do {
  368. if (g_cfg_byte[i].id == WID_NIL)
  369. break;
  370. if (g_cfg_byte[i].id == wid) {
  371. memcpy(buffer, &g_cfg_byte[i].val, 1);
  372. ret = 1;
  373. break;
  374. }
  375. i++;
  376. } while (1);
  377. } else if (type == CFG_HWORD_CMD) {
  378. do {
  379. if (g_cfg_hword[i].id == WID_NIL)
  380. break;
  381. if (g_cfg_hword[i].id == wid) {
  382. memcpy(buffer, &g_cfg_hword[i].val, 2);
  383. ret = 2;
  384. break;
  385. }
  386. i++;
  387. } while (1);
  388. } else if (type == CFG_WORD_CMD) {
  389. do {
  390. if (g_cfg_word[i].id == WID_NIL)
  391. break;
  392. if (g_cfg_word[i].id == wid) {
  393. memcpy(buffer, &g_cfg_word[i].val, 4);
  394. ret = 4;
  395. break;
  396. }
  397. i++;
  398. } while (1);
  399. } else if (type == CFG_STR_CMD) {
  400. do {
  401. if (g_cfg_str[i].id == WID_NIL)
  402. break;
  403. if (g_cfg_str[i].id == wid) {
  404. u32 size = g_cfg_str[i].str[0];
  405. if (buffer_size >= size) {
  406. if (g_cfg_str[i].id == WID_SITE_SURVEY_RESULTS) {
  407. static int toggle;
  408. i += toggle;
  409. toggle ^= 1;
  410. }
  411. memcpy(buffer, &g_cfg_str[i].str[1], size);
  412. ret = size;
  413. }
  414. break;
  415. }
  416. i++;
  417. } while (1);
  418. }
  419. return ret;
  420. }
  421. int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
  422. struct wilc_cfg_rsp *rsp)
  423. {
  424. int ret = 1;
  425. u8 msg_type;
  426. u8 msg_id;
  427. msg_type = frame[0];
  428. msg_id = frame[1]; /* seq no */
  429. frame += 4;
  430. size -= 4;
  431. /**
  432. * The valid types of response messages are 'R' (Response), 'I' (Information), and 'N' (Network Information)
  433. **/
  434. switch (msg_type) {
  435. case 'R':
  436. wilc_wlan_parse_response_frame(frame, size);
  437. rsp->type = WILC_CFG_RSP;
  438. rsp->seq_no = msg_id;
  439. break;
  440. case 'I':
  441. rsp->type = wilc_wlan_parse_info_frame(frame, size);
  442. rsp->seq_no = msg_id;
  443. /*call host interface info parse as well*/
  444. wilc_gnrl_async_info_received(wilc, frame - 4, size + 4);
  445. break;
  446. case 'N':
  447. wilc_network_info_received(wilc, frame - 4, size + 4);
  448. rsp->type = 0;
  449. break;
  450. case 'S':
  451. wilc_scan_complete_received(wilc, frame - 4, size + 4);
  452. break;
  453. default:
  454. rsp->type = 0;
  455. rsp->seq_no = msg_id;
  456. ret = 0;
  457. break;
  458. }
  459. return ret;
  460. }
  461. int wilc_wlan_cfg_init(void)
  462. {
  463. memset((void *)&g_mac, 0, sizeof(struct wilc_mac_cfg));
  464. return 1;
  465. }