coreconfigurator.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /*!
  2. * @file coreconfigurator.c
  3. * @brief
  4. * @author
  5. * @sa coreconfigurator.h
  6. * @date 1 Mar 2012
  7. * @version 1.0
  8. */
  9. #include "coreconfigurator.h"
  10. #include "wilc_wlan_if.h"
  11. #include "wilc_wlan.h"
  12. #include <linux/errno.h>
  13. #include <linux/slab.h>
  14. #define TAG_PARAM_OFFSET (MAC_HDR_LEN + TIME_STAMP_LEN + \
  15. BEACON_INTERVAL_LEN + CAP_INFO_LEN)
  16. /* Basic Frame Type Codes (2-bit) */
  17. enum basic_frame_type {
  18. FRAME_TYPE_CONTROL = 0x04,
  19. FRAME_TYPE_DATA = 0x08,
  20. FRAME_TYPE_MANAGEMENT = 0x00,
  21. FRAME_TYPE_RESERVED = 0x0C,
  22. FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF
  23. };
  24. /* Frame Type and Subtype Codes (6-bit) */
  25. enum sub_frame_type {
  26. ASSOC_REQ = 0x00,
  27. ASSOC_RSP = 0x10,
  28. REASSOC_REQ = 0x20,
  29. REASSOC_RSP = 0x30,
  30. PROBE_REQ = 0x40,
  31. PROBE_RSP = 0x50,
  32. BEACON = 0x80,
  33. ATIM = 0x90,
  34. DISASOC = 0xA0,
  35. AUTH = 0xB0,
  36. DEAUTH = 0xC0,
  37. ACTION = 0xD0,
  38. PS_POLL = 0xA4,
  39. RTS = 0xB4,
  40. CTS = 0xC4,
  41. ACK = 0xD4,
  42. CFEND = 0xE4,
  43. CFEND_ACK = 0xF4,
  44. DATA = 0x08,
  45. DATA_ACK = 0x18,
  46. DATA_POLL = 0x28,
  47. DATA_POLL_ACK = 0x38,
  48. NULL_FRAME = 0x48,
  49. CFACK = 0x58,
  50. CFPOLL = 0x68,
  51. CFPOLL_ACK = 0x78,
  52. QOS_DATA = 0x88,
  53. QOS_DATA_ACK = 0x98,
  54. QOS_DATA_POLL = 0xA8,
  55. QOS_DATA_POLL_ACK = 0xB8,
  56. QOS_NULL_FRAME = 0xC8,
  57. QOS_CFPOLL = 0xE8,
  58. QOS_CFPOLL_ACK = 0xF8,
  59. BLOCKACK_REQ = 0x84,
  60. BLOCKACK = 0x94,
  61. FRAME_SUBTYPE_FORCE_32BIT = 0xFFFFFFFF
  62. };
  63. /* Element ID of various Information Elements */
  64. enum info_element_id {
  65. ISSID = 0, /* Service Set Identifier */
  66. ISUPRATES = 1, /* Supported Rates */
  67. IFHPARMS = 2, /* FH parameter set */
  68. IDSPARMS = 3, /* DS parameter set */
  69. ICFPARMS = 4, /* CF parameter set */
  70. ITIM = 5, /* Traffic Information Map */
  71. IIBPARMS = 6, /* IBSS parameter set */
  72. ICOUNTRY = 7, /* Country element */
  73. IEDCAPARAMS = 12, /* EDCA parameter set */
  74. ITSPEC = 13, /* Traffic Specification */
  75. ITCLAS = 14, /* Traffic Classification */
  76. ISCHED = 15, /* Schedule */
  77. ICTEXT = 16, /* Challenge Text */
  78. IPOWERCONSTRAINT = 32, /* Power Constraint */
  79. IPOWERCAPABILITY = 33, /* Power Capability */
  80. ITPCREQUEST = 34, /* TPC Request */
  81. ITPCREPORT = 35, /* TPC Report */
  82. ISUPCHANNEL = 36, /* Supported channel list */
  83. ICHSWANNOUNC = 37, /* Channel Switch Announcement */
  84. IMEASUREMENTREQUEST = 38, /* Measurement request */
  85. IMEASUREMENTREPORT = 39, /* Measurement report */
  86. IQUIET = 40, /* Quiet element Info */
  87. IIBSSDFS = 41, /* IBSS DFS */
  88. IERPINFO = 42, /* ERP Information */
  89. ITSDELAY = 43, /* TS Delay */
  90. ITCLASPROCESS = 44, /* TCLAS Processing */
  91. IHTCAP = 45, /* HT Capabilities */
  92. IQOSCAP = 46, /* QoS Capability */
  93. IRSNELEMENT = 48, /* RSN Information Element */
  94. IEXSUPRATES = 50, /* Extended Supported Rates */
  95. IEXCHSWANNOUNC = 60, /* Extended Ch Switch Announcement*/
  96. IHTOPERATION = 61, /* HT Information */
  97. ISECCHOFF = 62, /* Secondary Channel Offeset */
  98. I2040COEX = 72, /* 20/40 Coexistence IE */
  99. I2040INTOLCHREPORT = 73, /* 20/40 Intolerant channel report*/
  100. IOBSSSCAN = 74, /* OBSS Scan parameters */
  101. IEXTCAP = 127, /* Extended capability */
  102. IWMM = 221, /* WMM parameters */
  103. IWPAELEMENT = 221, /* WPA Information Element */
  104. INFOELEM_ID_FORCE_32BIT = 0xFFFFFFFF
  105. };
  106. /* This function extracts the beacon period field from the beacon or probe */
  107. /* response frame. */
  108. static inline u16 get_beacon_period(u8 *data)
  109. {
  110. u16 bcn_per;
  111. bcn_per = data[0];
  112. bcn_per |= (data[1] << 8);
  113. return bcn_per;
  114. }
  115. static inline u32 get_beacon_timestamp_lo(u8 *data)
  116. {
  117. u32 time_stamp = 0;
  118. u32 index = MAC_HDR_LEN;
  119. time_stamp |= data[index++];
  120. time_stamp |= (data[index++] << 8);
  121. time_stamp |= (data[index++] << 16);
  122. time_stamp |= (data[index] << 24);
  123. return time_stamp;
  124. }
  125. static inline u32 get_beacon_timestamp_hi(u8 *data)
  126. {
  127. u32 time_stamp = 0;
  128. u32 index = (MAC_HDR_LEN + 4);
  129. time_stamp |= data[index++];
  130. time_stamp |= (data[index++] << 8);
  131. time_stamp |= (data[index++] << 16);
  132. time_stamp |= (data[index] << 24);
  133. return time_stamp;
  134. }
  135. /* This function extracts the 'frame type and sub type' bits from the MAC */
  136. /* header of the input frame. */
  137. /* Returns the value in the LSB of the returned value. */
  138. static inline enum sub_frame_type get_sub_type(u8 *header)
  139. {
  140. return ((enum sub_frame_type)(header[0] & 0xFC));
  141. }
  142. /* This function extracts the 'to ds' bit from the MAC header of the input */
  143. /* frame. */
  144. /* Returns the value in the LSB of the returned value. */
  145. static inline u8 get_to_ds(u8 *header)
  146. {
  147. return (header[1] & 0x01);
  148. }
  149. /* This function extracts the 'from ds' bit from the MAC header of the input */
  150. /* frame. */
  151. /* Returns the value in the LSB of the returned value. */
  152. static inline u8 get_from_ds(u8 *header)
  153. {
  154. return ((header[1] & 0x02) >> 1);
  155. }
  156. /* This function extracts the MAC Address in 'address1' field of the MAC */
  157. /* header and updates the MAC Address in the allocated 'addr' variable. */
  158. static inline void get_address1(u8 *pu8msa, u8 *addr)
  159. {
  160. memcpy(addr, pu8msa + 4, 6);
  161. }
  162. /* This function extracts the MAC Address in 'address2' field of the MAC */
  163. /* header and updates the MAC Address in the allocated 'addr' variable. */
  164. static inline void get_address2(u8 *pu8msa, u8 *addr)
  165. {
  166. memcpy(addr, pu8msa + 10, 6);
  167. }
  168. /* This function extracts the MAC Address in 'address3' field of the MAC */
  169. /* header and updates the MAC Address in the allocated 'addr' variable. */
  170. static inline void get_address3(u8 *pu8msa, u8 *addr)
  171. {
  172. memcpy(addr, pu8msa + 16, 6);
  173. }
  174. /* This function extracts the BSSID from the incoming WLAN packet based on */
  175. /* the 'from ds' bit, and updates the MAC Address in the allocated 'addr' */
  176. /* variable. */
  177. static inline void get_BSSID(u8 *data, u8 *bssid)
  178. {
  179. if (get_from_ds(data) == 1)
  180. get_address2(data, bssid);
  181. else if (get_to_ds(data) == 1)
  182. get_address1(data, bssid);
  183. else
  184. get_address3(data, bssid);
  185. }
  186. /* This function extracts the SSID from a beacon/probe response frame */
  187. static inline void get_ssid(u8 *data, u8 *ssid, u8 *p_ssid_len)
  188. {
  189. u8 len = 0;
  190. u8 i = 0;
  191. u8 j = 0;
  192. len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
  193. CAP_INFO_LEN + 1];
  194. j = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
  195. CAP_INFO_LEN + 2;
  196. /* If the SSID length field is set wrongly to a value greater than the */
  197. /* allowed maximum SSID length limit, reset the length to 0 */
  198. if (len >= MAX_SSID_LEN)
  199. len = 0;
  200. for (i = 0; i < len; i++, j++)
  201. ssid[i] = data[j];
  202. ssid[len] = '\0';
  203. *p_ssid_len = len;
  204. }
  205. /* This function extracts the capability info field from the beacon or probe */
  206. /* response frame. */
  207. static inline u16 get_cap_info(u8 *data)
  208. {
  209. u16 cap_info = 0;
  210. u16 index = MAC_HDR_LEN;
  211. enum sub_frame_type st;
  212. st = get_sub_type(data);
  213. /* Location of the Capability field is different for Beacon and */
  214. /* Association frames. */
  215. if ((st == BEACON) || (st == PROBE_RSP))
  216. index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN;
  217. cap_info = data[index];
  218. cap_info |= (data[index + 1] << 8);
  219. return cap_info;
  220. }
  221. /* This function extracts the capability info field from the Association */
  222. /* response frame. */
  223. static inline u16 get_assoc_resp_cap_info(u8 *data)
  224. {
  225. u16 cap_info;
  226. cap_info = data[0];
  227. cap_info |= (data[1] << 8);
  228. return cap_info;
  229. }
  230. /* This function extracts the association status code from the incoming */
  231. /* association response frame and returns association status code */
  232. static inline u16 get_asoc_status(u8 *data)
  233. {
  234. u16 asoc_status;
  235. asoc_status = data[3];
  236. asoc_status = (asoc_status << 8) | data[2];
  237. return asoc_status;
  238. }
  239. /* This function extracts association ID from the incoming association */
  240. /* response frame */
  241. static inline u16 get_asoc_id(u8 *data)
  242. {
  243. u16 asoc_id;
  244. asoc_id = data[4];
  245. asoc_id |= (data[5] << 8);
  246. return asoc_id;
  247. }
  248. u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset)
  249. {
  250. u16 u16index;
  251. /*************************************************************************/
  252. /* Beacon Frame - Frame Body */
  253. /* --------------------------------------------------------------------- */
  254. /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm | */
  255. /* --------------------------------------------------------------------- */
  256. /* |8 |2 |2 |2-34 |3-10 |3 |4-256 | */
  257. /* --------------------------------------------------------------------- */
  258. /* */
  259. /*************************************************************************/
  260. u16index = u16TagParamOffset;
  261. /* Search for the TIM Element Field and return if the element is found */
  262. while (u16index < (u16RxLen - FCS_LEN)) {
  263. if (pu8msa[u16index] == ITIM)
  264. return &pu8msa[u16index];
  265. u16index += (IE_HDR_LEN + pu8msa[u16index + 1]);
  266. }
  267. return NULL;
  268. }
  269. /* This function gets the current channel information from
  270. * the 802.11n beacon/probe response frame */
  271. u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen)
  272. {
  273. u16 index;
  274. index = TAG_PARAM_OFFSET;
  275. while (index < (u16RxLen - FCS_LEN)) {
  276. if (pu8msa[index] == IDSPARMS)
  277. return pu8msa[index + 2];
  278. /* Increment index by length information and header */
  279. index += pu8msa[index + 1] + IE_HDR_LEN;
  280. }
  281. /* Return current channel information from the MIB, if beacon/probe */
  282. /* response frame does not contain the DS parameter set IE */
  283. /* return (mget_CurrentChannel() + 1); */
  284. return 0; /* no MIB here */
  285. }
  286. /**
  287. * @brief parses the received 'N' message
  288. * @details
  289. * @param[in] pu8MsgBuffer The message to be parsed
  290. * @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info
  291. * @return Error code indicating success/failure
  292. * @note
  293. * @author mabubakr
  294. * @date 1 Mar 2012
  295. * @version 1.0
  296. */
  297. s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
  298. {
  299. tstrNetworkInfo *pstrNetworkInfo = NULL;
  300. u8 u8MsgType = 0;
  301. u8 u8MsgID = 0;
  302. u16 u16MsgLen = 0;
  303. u16 u16WidID = (u16)WID_NIL;
  304. u16 u16WidLen = 0;
  305. u8 *pu8WidVal = NULL;
  306. u8MsgType = pu8MsgBuffer[0];
  307. /* Check whether the received message type is 'N' */
  308. if ('N' != u8MsgType) {
  309. PRINT_ER("Received Message format incorrect.\n");
  310. return -EFAULT;
  311. }
  312. /* Extract message ID */
  313. u8MsgID = pu8MsgBuffer[1];
  314. /* Extract message Length */
  315. u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]);
  316. /* Extract WID ID */
  317. u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]);
  318. /* Extract WID Length */
  319. u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]);
  320. /* Assign a pointer to the WID value */
  321. pu8WidVal = &pu8MsgBuffer[8];
  322. /* parse the WID value of the WID "WID_NEWORK_INFO" */
  323. {
  324. u8 *pu8msa = NULL;
  325. u16 u16RxLen = 0;
  326. u8 *pu8TimElm = NULL;
  327. u8 *pu8IEs = NULL;
  328. u16 u16IEsLen = 0;
  329. u8 u8index = 0;
  330. u32 u32Tsf_Lo;
  331. u32 u32Tsf_Hi;
  332. pstrNetworkInfo = kzalloc(sizeof(tstrNetworkInfo), GFP_KERNEL);
  333. if (!pstrNetworkInfo)
  334. return -ENOMEM;
  335. pstrNetworkInfo->s8rssi = pu8WidVal[0];
  336. /* Assign a pointer to msa "Mac Header Start Address" */
  337. pu8msa = &pu8WidVal[1];
  338. u16RxLen = u16WidLen - 1;
  339. /* parse msa*/
  340. /* Get the cap_info */
  341. pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa);
  342. /* Get time-stamp [Low only 32 bit] */
  343. pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa);
  344. PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf);
  345. /* Get full time-stamp [Low and High 64 bit] */
  346. u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa);
  347. u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa);
  348. pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((u64)u32Tsf_Hi << 32);
  349. /* Get SSID */
  350. get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &pstrNetworkInfo->u8SsidLen);
  351. /* Get BSSID */
  352. get_BSSID(pu8msa, pstrNetworkInfo->au8bssid);
  353. /*
  354. * Extract current channel information from
  355. * the beacon/probe response frame
  356. */
  357. pstrNetworkInfo->u8channel = get_current_channel_802_11n(pu8msa,
  358. u16RxLen + FCS_LEN);
  359. /* Get beacon period */
  360. u8index = MAC_HDR_LEN + TIME_STAMP_LEN;
  361. pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index);
  362. u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN;
  363. /* Get DTIM Period */
  364. pu8TimElm = get_tim_elm(pu8msa, u16RxLen + FCS_LEN, u8index);
  365. if (pu8TimElm != NULL)
  366. pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3];
  367. pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN];
  368. u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN);
  369. if (u16IEsLen > 0) {
  370. pstrNetworkInfo->pu8IEs = kmemdup(pu8IEs, u16IEsLen,
  371. GFP_KERNEL);
  372. if (!pstrNetworkInfo->pu8IEs)
  373. return -ENOMEM;
  374. }
  375. pstrNetworkInfo->u16IEsLen = u16IEsLen;
  376. }
  377. *ppstrNetworkInfo = pstrNetworkInfo;
  378. return 0;
  379. }
  380. /**
  381. * @brief Deallocates the parsed Network Info
  382. * @details
  383. * @param[in] pstrNetworkInfo Network Info to be deallocated
  384. * @return Error code indicating success/failure
  385. * @note
  386. * @author mabubakr
  387. * @date 1 Mar 2012
  388. * @version 1.0
  389. */
  390. s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo)
  391. {
  392. s32 s32Error = 0;
  393. if (pstrNetworkInfo != NULL) {
  394. if (pstrNetworkInfo->pu8IEs != NULL) {
  395. kfree(pstrNetworkInfo->pu8IEs);
  396. pstrNetworkInfo->pu8IEs = NULL;
  397. } else {
  398. s32Error = -EFAULT;
  399. }
  400. kfree(pstrNetworkInfo);
  401. pstrNetworkInfo = NULL;
  402. } else {
  403. s32Error = -EFAULT;
  404. }
  405. return s32Error;
  406. }
  407. /**
  408. * @brief parses the received Association Response frame
  409. * @details
  410. * @param[in] pu8Buffer The Association Response frame to be parsed
  411. * @param[out] ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info
  412. * @return Error code indicating success/failure
  413. * @note
  414. * @author mabubakr
  415. * @date 2 Apr 2012
  416. * @version 1.0
  417. */
  418. s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen,
  419. tstrConnectRespInfo **ppstrConnectRespInfo)
  420. {
  421. s32 s32Error = 0;
  422. tstrConnectRespInfo *pstrConnectRespInfo = NULL;
  423. u16 u16AssocRespLen = 0;
  424. u8 *pu8IEs = NULL;
  425. u16 u16IEsLen = 0;
  426. pstrConnectRespInfo = kzalloc(sizeof(tstrConnectRespInfo), GFP_KERNEL);
  427. if (!pstrConnectRespInfo)
  428. return -ENOMEM;
  429. /* u16AssocRespLen = pu8Buffer[0]; */
  430. u16AssocRespLen = (u16)u32BufferLen;
  431. /* get the status code */
  432. pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer);
  433. if (pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
  434. /* get the capability */
  435. pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer);
  436. /* get the Association ID */
  437. pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer);
  438. /* get the Information Elements */
  439. pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN];
  440. u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN);
  441. pstrConnectRespInfo->pu8RespIEs = kmemdup(pu8IEs, u16IEsLen, GFP_KERNEL);
  442. if (!pstrConnectRespInfo->pu8RespIEs)
  443. return -ENOMEM;
  444. pstrConnectRespInfo->u16RespIEsLen = u16IEsLen;
  445. }
  446. *ppstrConnectRespInfo = pstrConnectRespInfo;
  447. return s32Error;
  448. }
  449. /**
  450. * @brief Deallocates the parsed Association Response Info
  451. * @details
  452. * @param[in] pstrNetworkInfo Network Info to be deallocated
  453. * @return Error code indicating success/failure
  454. * @note
  455. * @author mabubakr
  456. * @date 2 Apr 2012
  457. * @version 1.0
  458. */
  459. s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo)
  460. {
  461. s32 s32Error = 0;
  462. if (pstrConnectRespInfo != NULL) {
  463. if (pstrConnectRespInfo->pu8RespIEs != NULL) {
  464. kfree(pstrConnectRespInfo->pu8RespIEs);
  465. pstrConnectRespInfo->pu8RespIEs = NULL;
  466. } else {
  467. s32Error = -EFAULT;
  468. }
  469. kfree(pstrConnectRespInfo);
  470. pstrConnectRespInfo = NULL;
  471. } else {
  472. s32Error = -EFAULT;
  473. }
  474. return s32Error;
  475. }
  476. /**
  477. * @brief sends certain Configuration Packet based on the input WIDs pstrWIDs
  478. * using driver config layer
  479. *
  480. * @details
  481. * @param[in] pstrWIDs WIDs to be sent in the configuration packet
  482. * @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet
  483. * @param[out] pu8RxResp The received Packet Response
  484. * @param[out] ps32RxRespLen Length of the received Packet Response
  485. * @return Error code indicating success/failure
  486. * @note
  487. * @author mabubakr
  488. * @date 1 Mar 2012
  489. * @version 1.0
  490. */
  491. s32 send_config_pkt(u8 mode, struct wid *wids, u32 count, u32 drv)
  492. {
  493. s32 counter = 0, ret = 0;
  494. if (mode == GET_CFG) {
  495. for (counter = 0; counter < count; counter++) {
  496. PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter,
  497. (counter == count - 1));
  498. if (!wilc_wlan_cfg_get(!counter,
  499. wids[counter].id,
  500. (counter == count - 1),
  501. drv)) {
  502. ret = -1;
  503. printk("[Sendconfigpkt]Get Timed out\n");
  504. break;
  505. }
  506. }
  507. counter = 0;
  508. for (counter = 0; counter < count; counter++) {
  509. wids[counter].size = wilc_wlan_cfg_get_val(
  510. wids[counter].id,
  511. wids[counter].val,
  512. wids[counter].size);
  513. }
  514. } else if (mode == SET_CFG) {
  515. for (counter = 0; counter < count; counter++) {
  516. PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", wids[counter].id);
  517. if (!wilc_wlan_cfg_set(!counter,
  518. wids[counter].id,
  519. wids[counter].val,
  520. wids[counter].size,
  521. (counter == count - 1),
  522. drv)) {
  523. ret = -1;
  524. printk("[Sendconfigpkt]Set Timed out\n");
  525. break;
  526. }
  527. }
  528. }
  529. return ret;
  530. }