hif.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
  4. * All rights reserved.
  5. */
  6. #include "netdev.h"
  7. #define WILC_HIF_SCAN_TIMEOUT_MS 5000
  8. #define WILC_HIF_CONNECT_TIMEOUT_MS 9500
  9. #define WILC_FALSE_FRMWR_CHANNEL 100
  10. #define WILC_SCAN_WID_LIST_SIZE 6
  11. struct wilc_rcvd_mac_info {
  12. u8 status;
  13. };
  14. struct wilc_set_multicast {
  15. u32 enabled;
  16. u32 cnt;
  17. u8 *mc_list;
  18. };
  19. struct host_if_wowlan_trigger {
  20. u8 wowlan_trigger;
  21. };
  22. struct wilc_del_all_sta {
  23. u8 assoc_sta;
  24. u8 mac[WILC_MAX_NUM_STA][ETH_ALEN];
  25. };
  26. union wilc_message_body {
  27. struct wilc_rcvd_net_info net_info;
  28. struct wilc_rcvd_mac_info mac_info;
  29. struct wilc_set_multicast mc_info;
  30. struct wilc_remain_ch remain_on_ch;
  31. char *data;
  32. struct host_if_wowlan_trigger wow_trigger;
  33. };
  34. struct host_if_msg {
  35. union wilc_message_body body;
  36. struct wilc_vif *vif;
  37. struct work_struct work;
  38. void (*fn)(struct work_struct *ws);
  39. struct completion work_comp;
  40. bool is_sync;
  41. };
  42. /* 'msg' should be free by the caller for syc */
  43. static struct host_if_msg*
  44. wilc_alloc_work(struct wilc_vif *vif, void (*work_fun)(struct work_struct *),
  45. bool is_sync)
  46. {
  47. struct host_if_msg *msg;
  48. if (!work_fun)
  49. return ERR_PTR(-EINVAL);
  50. msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
  51. if (!msg)
  52. return ERR_PTR(-ENOMEM);
  53. msg->fn = work_fun;
  54. msg->vif = vif;
  55. msg->is_sync = is_sync;
  56. if (is_sync)
  57. init_completion(&msg->work_comp);
  58. return msg;
  59. }
  60. static int wilc_enqueue_work(struct host_if_msg *msg)
  61. {
  62. INIT_WORK(&msg->work, msg->fn);
  63. if (!msg->vif || !msg->vif->wilc || !msg->vif->wilc->hif_workqueue)
  64. return -EINVAL;
  65. if (!queue_work(msg->vif->wilc->hif_workqueue, &msg->work))
  66. return -EINVAL;
  67. return 0;
  68. }
  69. /* The idx starts from 0 to (NUM_CONCURRENT_IFC - 1), but 0 index used as
  70. * special purpose in wilc device, so we add 1 to the index to starts from 1.
  71. * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
  72. */
  73. int wilc_get_vif_idx(struct wilc_vif *vif)
  74. {
  75. return vif->idx + 1;
  76. }
  77. /* We need to minus 1 from idx which is from wilc device to get real index
  78. * of wilc->vif[], because we add 1 when pass to wilc device in the function
  79. * wilc_get_vif_idx.
  80. * As a result, the index should be between 0 and (NUM_CONCURRENT_IFC - 1).
  81. */
  82. static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
  83. {
  84. int index = idx - 1;
  85. struct wilc_vif *vif;
  86. if (index < 0 || index >= WILC_NUM_CONCURRENT_IFC)
  87. return NULL;
  88. list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
  89. if (vif->idx == index)
  90. return vif;
  91. }
  92. return NULL;
  93. }
  94. static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
  95. {
  96. int result = 0;
  97. u8 abort_running_scan;
  98. struct wid wid;
  99. struct host_if_drv *hif_drv = vif->hif_drv;
  100. struct wilc_user_scan_req *scan_req;
  101. if (evt == SCAN_EVENT_ABORTED) {
  102. abort_running_scan = 1;
  103. wid.id = WID_ABORT_RUNNING_SCAN;
  104. wid.type = WID_CHAR;
  105. wid.val = (s8 *)&abort_running_scan;
  106. wid.size = sizeof(char);
  107. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  108. if (result) {
  109. netdev_err(vif->ndev, "Failed to set abort running\n");
  110. result = -EFAULT;
  111. }
  112. }
  113. if (!hif_drv) {
  114. netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
  115. return result;
  116. }
  117. scan_req = &hif_drv->usr_scan_req;
  118. if (scan_req->scan_result) {
  119. scan_req->scan_result(evt, NULL, scan_req->arg);
  120. scan_req->scan_result = NULL;
  121. }
  122. return result;
  123. }
  124. int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
  125. u8 *ch_freq_list, u8 ch_list_len,
  126. void (*scan_result_fn)(enum scan_event,
  127. struct wilc_rcvd_net_info *, void *),
  128. void *user_arg, struct cfg80211_scan_request *request)
  129. {
  130. int result = 0;
  131. struct wid wid_list[WILC_SCAN_WID_LIST_SIZE];
  132. u32 index = 0;
  133. u32 i, scan_timeout;
  134. u8 *buffer;
  135. u8 valuesize = 0;
  136. u8 *search_ssid_vals = NULL;
  137. struct host_if_drv *hif_drv = vif->hif_drv;
  138. if (hif_drv->hif_state >= HOST_IF_SCANNING &&
  139. hif_drv->hif_state < HOST_IF_CONNECTED) {
  140. netdev_err(vif->ndev, "Already scan\n");
  141. result = -EBUSY;
  142. goto error;
  143. }
  144. if (vif->connecting) {
  145. netdev_err(vif->ndev, "Don't do obss scan\n");
  146. result = -EBUSY;
  147. goto error;
  148. }
  149. hif_drv->usr_scan_req.ch_cnt = 0;
  150. if (request->n_ssids) {
  151. for (i = 0; i < request->n_ssids; i++)
  152. valuesize += ((request->ssids[i].ssid_len) + 1);
  153. search_ssid_vals = kmalloc(valuesize + 1, GFP_KERNEL);
  154. if (search_ssid_vals) {
  155. wid_list[index].id = WID_SSID_PROBE_REQ;
  156. wid_list[index].type = WID_STR;
  157. wid_list[index].val = search_ssid_vals;
  158. buffer = wid_list[index].val;
  159. *buffer++ = request->n_ssids;
  160. for (i = 0; i < request->n_ssids; i++) {
  161. *buffer++ = request->ssids[i].ssid_len;
  162. memcpy(buffer, request->ssids[i].ssid,
  163. request->ssids[i].ssid_len);
  164. buffer += request->ssids[i].ssid_len;
  165. }
  166. wid_list[index].size = (s32)(valuesize + 1);
  167. index++;
  168. }
  169. }
  170. wid_list[index].id = WID_INFO_ELEMENT_PROBE;
  171. wid_list[index].type = WID_BIN_DATA;
  172. wid_list[index].val = (s8 *)request->ie;
  173. wid_list[index].size = request->ie_len;
  174. index++;
  175. wid_list[index].id = WID_SCAN_TYPE;
  176. wid_list[index].type = WID_CHAR;
  177. wid_list[index].size = sizeof(char);
  178. wid_list[index].val = (s8 *)&scan_type;
  179. index++;
  180. if (scan_type == WILC_FW_PASSIVE_SCAN && request->duration) {
  181. wid_list[index].id = WID_PASSIVE_SCAN_TIME;
  182. wid_list[index].type = WID_SHORT;
  183. wid_list[index].size = sizeof(u16);
  184. wid_list[index].val = (s8 *)&request->duration;
  185. index++;
  186. scan_timeout = (request->duration * ch_list_len) + 500;
  187. } else {
  188. scan_timeout = WILC_HIF_SCAN_TIMEOUT_MS;
  189. }
  190. wid_list[index].id = WID_SCAN_CHANNEL_LIST;
  191. wid_list[index].type = WID_BIN_DATA;
  192. if (ch_freq_list && ch_list_len > 0) {
  193. for (i = 0; i < ch_list_len; i++) {
  194. if (ch_freq_list[i] > 0)
  195. ch_freq_list[i] -= 1;
  196. }
  197. }
  198. wid_list[index].val = ch_freq_list;
  199. wid_list[index].size = ch_list_len;
  200. index++;
  201. wid_list[index].id = WID_START_SCAN_REQ;
  202. wid_list[index].type = WID_CHAR;
  203. wid_list[index].size = sizeof(char);
  204. wid_list[index].val = (s8 *)&scan_source;
  205. index++;
  206. hif_drv->usr_scan_req.scan_result = scan_result_fn;
  207. hif_drv->usr_scan_req.arg = user_arg;
  208. result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, index);
  209. if (result) {
  210. netdev_err(vif->ndev, "Failed to send scan parameters\n");
  211. goto error;
  212. }
  213. hif_drv->scan_timer_vif = vif;
  214. mod_timer(&hif_drv->scan_timer,
  215. jiffies + msecs_to_jiffies(scan_timeout));
  216. error:
  217. kfree(search_ssid_vals);
  218. return result;
  219. }
  220. static int wilc_send_connect_wid(struct wilc_vif *vif)
  221. {
  222. int result = 0;
  223. struct wid wid_list[5];
  224. u32 wid_cnt = 0;
  225. struct host_if_drv *hif_drv = vif->hif_drv;
  226. struct wilc_conn_info *conn_attr = &hif_drv->conn_info;
  227. struct wilc_join_bss_param *bss_param = conn_attr->param;
  228. wid_list[wid_cnt].id = WID_SET_MFP;
  229. wid_list[wid_cnt].type = WID_CHAR;
  230. wid_list[wid_cnt].size = sizeof(char);
  231. wid_list[wid_cnt].val = (s8 *)&conn_attr->mfp_type;
  232. wid_cnt++;
  233. wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE;
  234. wid_list[wid_cnt].type = WID_BIN_DATA;
  235. wid_list[wid_cnt].val = conn_attr->req_ies;
  236. wid_list[wid_cnt].size = conn_attr->req_ies_len;
  237. wid_cnt++;
  238. wid_list[wid_cnt].id = WID_11I_MODE;
  239. wid_list[wid_cnt].type = WID_CHAR;
  240. wid_list[wid_cnt].size = sizeof(char);
  241. wid_list[wid_cnt].val = (s8 *)&conn_attr->security;
  242. wid_cnt++;
  243. wid_list[wid_cnt].id = WID_AUTH_TYPE;
  244. wid_list[wid_cnt].type = WID_CHAR;
  245. wid_list[wid_cnt].size = sizeof(char);
  246. wid_list[wid_cnt].val = (s8 *)&conn_attr->auth_type;
  247. wid_cnt++;
  248. wid_list[wid_cnt].id = WID_JOIN_REQ_EXTENDED;
  249. wid_list[wid_cnt].type = WID_STR;
  250. wid_list[wid_cnt].size = sizeof(*bss_param);
  251. wid_list[wid_cnt].val = (u8 *)bss_param;
  252. wid_cnt++;
  253. result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, wid_cnt);
  254. if (result) {
  255. netdev_err(vif->ndev, "failed to send config packet\n");
  256. goto error;
  257. } else {
  258. if (conn_attr->auth_type == WILC_FW_AUTH_SAE)
  259. hif_drv->hif_state = HOST_IF_EXTERNAL_AUTH;
  260. else
  261. hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
  262. }
  263. return 0;
  264. error:
  265. kfree(conn_attr->req_ies);
  266. conn_attr->req_ies = NULL;
  267. return result;
  268. }
  269. static void handle_connect_timeout(struct work_struct *work)
  270. {
  271. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  272. struct wilc_vif *vif = msg->vif;
  273. int result;
  274. struct wid wid;
  275. u16 dummy_reason_code = 0;
  276. struct host_if_drv *hif_drv = vif->hif_drv;
  277. if (!hif_drv) {
  278. netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
  279. goto out;
  280. }
  281. hif_drv->hif_state = HOST_IF_IDLE;
  282. if (hif_drv->conn_info.conn_result) {
  283. hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
  284. WILC_MAC_STATUS_DISCONNECTED,
  285. hif_drv->conn_info.arg);
  286. } else {
  287. netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
  288. }
  289. wid.id = WID_DISCONNECT;
  290. wid.type = WID_CHAR;
  291. wid.val = (s8 *)&dummy_reason_code;
  292. wid.size = sizeof(char);
  293. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  294. if (result)
  295. netdev_err(vif->ndev, "Failed to send disconnect\n");
  296. hif_drv->conn_info.req_ies_len = 0;
  297. kfree(hif_drv->conn_info.req_ies);
  298. hif_drv->conn_info.req_ies = NULL;
  299. out:
  300. kfree(msg);
  301. }
  302. void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
  303. struct cfg80211_crypto_settings *crypto)
  304. {
  305. struct wilc_join_bss_param *param;
  306. struct ieee80211_p2p_noa_attr noa_attr;
  307. u8 rates_len = 0;
  308. const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie;
  309. const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie;
  310. int ret;
  311. const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies);
  312. param = kzalloc(sizeof(*param), GFP_KERNEL);
  313. if (!param)
  314. return NULL;
  315. param->beacon_period = cpu_to_le16(bss->beacon_interval);
  316. param->cap_info = cpu_to_le16(bss->capability);
  317. param->bss_type = WILC_FW_BSS_TYPE_INFRA;
  318. param->ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
  319. ether_addr_copy(param->bssid, bss->bssid);
  320. ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
  321. if (ssid_elm) {
  322. if (ssid_elm[1] <= IEEE80211_MAX_SSID_LEN)
  323. memcpy(param->ssid, ssid_elm + 2, ssid_elm[1]);
  324. }
  325. tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len);
  326. if (tim_elm && tim_elm[1] >= 2)
  327. param->dtim_period = tim_elm[3];
  328. memset(param->p_suites, 0xFF, 3);
  329. memset(param->akm_suites, 0xFF, 3);
  330. rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies->data, ies->len);
  331. if (rates_ie) {
  332. rates_len = rates_ie[1];
  333. if (rates_len > WILC_MAX_RATES_SUPPORTED)
  334. rates_len = WILC_MAX_RATES_SUPPORTED;
  335. param->supp_rates[0] = rates_len;
  336. memcpy(&param->supp_rates[1], rates_ie + 2, rates_len);
  337. }
  338. if (rates_len < WILC_MAX_RATES_SUPPORTED) {
  339. supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES,
  340. ies->data, ies->len);
  341. if (supp_rates_ie) {
  342. u8 ext_rates = supp_rates_ie[1];
  343. if (ext_rates > (WILC_MAX_RATES_SUPPORTED - rates_len))
  344. param->supp_rates[0] = WILC_MAX_RATES_SUPPORTED;
  345. else
  346. param->supp_rates[0] += ext_rates;
  347. memcpy(&param->supp_rates[rates_len + 1],
  348. supp_rates_ie + 2,
  349. (param->supp_rates[0] - rates_len));
  350. }
  351. }
  352. ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies->data, ies->len);
  353. if (ht_ie)
  354. param->ht_capable = true;
  355. ret = cfg80211_get_p2p_attr(ies->data, ies->len,
  356. IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
  357. (u8 *)&noa_attr, sizeof(noa_attr));
  358. if (ret > 0) {
  359. param->tsf_lo = cpu_to_le32(ies->tsf);
  360. param->noa_enabled = 1;
  361. param->idx = noa_attr.index;
  362. if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) {
  363. param->opp_enabled = 1;
  364. param->opp_en.ct_window = noa_attr.oppps_ctwindow;
  365. param->opp_en.cnt = noa_attr.desc[0].count;
  366. param->opp_en.duration = noa_attr.desc[0].duration;
  367. param->opp_en.interval = noa_attr.desc[0].interval;
  368. param->opp_en.start_time = noa_attr.desc[0].start_time;
  369. } else {
  370. param->opp_enabled = 0;
  371. param->opp_dis.cnt = noa_attr.desc[0].count;
  372. param->opp_dis.duration = noa_attr.desc[0].duration;
  373. param->opp_dis.interval = noa_attr.desc[0].interval;
  374. param->opp_dis.start_time = noa_attr.desc[0].start_time;
  375. }
  376. }
  377. wmm_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
  378. WLAN_OUI_TYPE_MICROSOFT_WMM,
  379. ies->data, ies->len);
  380. if (wmm_ie) {
  381. struct ieee80211_wmm_param_ie *ie;
  382. ie = (struct ieee80211_wmm_param_ie *)wmm_ie;
  383. if ((ie->oui_subtype == 0 || ie->oui_subtype == 1) &&
  384. ie->version == 1) {
  385. param->wmm_cap = true;
  386. if (ie->qos_info & BIT(7))
  387. param->uapsd_cap = true;
  388. }
  389. }
  390. wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
  391. WLAN_OUI_TYPE_MICROSOFT_WPA,
  392. ies->data, ies->len);
  393. if (wpa_ie) {
  394. param->mode_802_11i = 1;
  395. param->rsn_found = true;
  396. }
  397. rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
  398. if (rsn_ie) {
  399. int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
  400. int offset = 8;
  401. param->mode_802_11i = 2;
  402. param->rsn_found = true;
  403. /* extract RSN capabilities */
  404. if (offset < rsn_ie_len) {
  405. /* skip over pairwise suites */
  406. offset += (rsn_ie[offset] * 4) + 2;
  407. if (offset < rsn_ie_len) {
  408. /* skip over authentication suites */
  409. offset += (rsn_ie[offset] * 4) + 2;
  410. if (offset + 1 < rsn_ie_len)
  411. memcpy(param->rsn_cap, &rsn_ie[offset], 2);
  412. }
  413. }
  414. }
  415. if (param->rsn_found) {
  416. int i;
  417. param->rsn_grp_policy = crypto->cipher_group & 0xFF;
  418. for (i = 0; i < crypto->n_ciphers_pairwise && i < 3; i++)
  419. param->p_suites[i] = crypto->ciphers_pairwise[i] & 0xFF;
  420. for (i = 0; i < crypto->n_akm_suites && i < 3; i++)
  421. param->akm_suites[i] = crypto->akm_suites[i] & 0xFF;
  422. }
  423. return (void *)param;
  424. }
  425. static void handle_rcvd_ntwrk_info(struct work_struct *work)
  426. {
  427. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  428. struct wilc_rcvd_net_info *rcvd_info = &msg->body.net_info;
  429. struct wilc_user_scan_req *scan_req = &msg->vif->hif_drv->usr_scan_req;
  430. const u8 *ch_elm;
  431. u8 *ies;
  432. int ies_len;
  433. size_t offset;
  434. if (ieee80211_is_probe_resp(rcvd_info->mgmt->frame_control))
  435. offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
  436. else if (ieee80211_is_beacon(rcvd_info->mgmt->frame_control))
  437. offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
  438. else
  439. goto done;
  440. ies = rcvd_info->mgmt->u.beacon.variable;
  441. ies_len = rcvd_info->frame_len - offset;
  442. if (ies_len <= 0)
  443. goto done;
  444. ch_elm = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ies, ies_len);
  445. if (ch_elm && ch_elm[1] > 0)
  446. rcvd_info->ch = ch_elm[2];
  447. if (scan_req->scan_result)
  448. scan_req->scan_result(SCAN_EVENT_NETWORK_FOUND, rcvd_info,
  449. scan_req->arg);
  450. done:
  451. kfree(rcvd_info->mgmt);
  452. kfree(msg);
  453. }
  454. static void host_int_get_assoc_res_info(struct wilc_vif *vif,
  455. u8 *assoc_resp_info,
  456. u32 max_assoc_resp_info_len,
  457. u32 *rcvd_assoc_resp_info_len)
  458. {
  459. int result;
  460. struct wid wid;
  461. wid.id = WID_ASSOC_RES_INFO;
  462. wid.type = WID_STR;
  463. wid.val = assoc_resp_info;
  464. wid.size = max_assoc_resp_info_len;
  465. result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
  466. if (result) {
  467. *rcvd_assoc_resp_info_len = 0;
  468. netdev_err(vif->ndev, "Failed to send association response\n");
  469. return;
  470. }
  471. *rcvd_assoc_resp_info_len = wid.size;
  472. }
  473. static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len,
  474. struct wilc_conn_info *ret_conn_info)
  475. {
  476. u8 *ies;
  477. u16 ies_len;
  478. struct wilc_assoc_resp *res = (struct wilc_assoc_resp *)buffer;
  479. ret_conn_info->status = le16_to_cpu(res->status_code);
  480. if (ret_conn_info->status == WLAN_STATUS_SUCCESS) {
  481. ies = &buffer[sizeof(*res)];
  482. ies_len = buffer_len - sizeof(*res);
  483. ret_conn_info->resp_ies = kmemdup(ies, ies_len, GFP_KERNEL);
  484. if (!ret_conn_info->resp_ies)
  485. return -ENOMEM;
  486. ret_conn_info->resp_ies_len = ies_len;
  487. }
  488. return 0;
  489. }
  490. static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
  491. u8 mac_status)
  492. {
  493. struct host_if_drv *hif_drv = vif->hif_drv;
  494. struct wilc_conn_info *conn_info = &hif_drv->conn_info;
  495. if (mac_status == WILC_MAC_STATUS_CONNECTED) {
  496. u32 assoc_resp_info_len;
  497. memset(hif_drv->assoc_resp, 0, WILC_MAX_ASSOC_RESP_FRAME_SIZE);
  498. host_int_get_assoc_res_info(vif, hif_drv->assoc_resp,
  499. WILC_MAX_ASSOC_RESP_FRAME_SIZE,
  500. &assoc_resp_info_len);
  501. if (assoc_resp_info_len != 0) {
  502. s32 err = 0;
  503. err = wilc_parse_assoc_resp_info(hif_drv->assoc_resp,
  504. assoc_resp_info_len,
  505. conn_info);
  506. if (err)
  507. netdev_err(vif->ndev,
  508. "wilc_parse_assoc_resp_info() returned error %d\n",
  509. err);
  510. }
  511. }
  512. del_timer(&hif_drv->connect_timer);
  513. conn_info->conn_result(CONN_DISCONN_EVENT_CONN_RESP, mac_status,
  514. hif_drv->conn_info.arg);
  515. if (mac_status == WILC_MAC_STATUS_CONNECTED &&
  516. conn_info->status == WLAN_STATUS_SUCCESS) {
  517. ether_addr_copy(hif_drv->assoc_bssid, conn_info->bssid);
  518. hif_drv->hif_state = HOST_IF_CONNECTED;
  519. } else {
  520. hif_drv->hif_state = HOST_IF_IDLE;
  521. }
  522. kfree(conn_info->resp_ies);
  523. conn_info->resp_ies = NULL;
  524. conn_info->resp_ies_len = 0;
  525. kfree(conn_info->req_ies);
  526. conn_info->req_ies = NULL;
  527. conn_info->req_ies_len = 0;
  528. }
  529. void wilc_handle_disconnect(struct wilc_vif *vif)
  530. {
  531. struct host_if_drv *hif_drv = vif->hif_drv;
  532. if (hif_drv->usr_scan_req.scan_result) {
  533. del_timer(&hif_drv->scan_timer);
  534. handle_scan_done(vif, SCAN_EVENT_ABORTED);
  535. }
  536. if (hif_drv->conn_info.conn_result)
  537. hif_drv->conn_info.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
  538. 0, hif_drv->conn_info.arg);
  539. eth_zero_addr(hif_drv->assoc_bssid);
  540. hif_drv->conn_info.req_ies_len = 0;
  541. kfree(hif_drv->conn_info.req_ies);
  542. hif_drv->conn_info.req_ies = NULL;
  543. hif_drv->hif_state = HOST_IF_IDLE;
  544. }
  545. static void handle_rcvd_gnrl_async_info(struct work_struct *work)
  546. {
  547. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  548. struct wilc_vif *vif = msg->vif;
  549. struct wilc_rcvd_mac_info *mac_info = &msg->body.mac_info;
  550. struct host_if_drv *hif_drv = vif->hif_drv;
  551. if (!hif_drv) {
  552. netdev_err(vif->ndev, "%s: hif driver is NULL\n", __func__);
  553. goto free_msg;
  554. }
  555. if (!hif_drv->conn_info.conn_result) {
  556. netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
  557. goto free_msg;
  558. }
  559. if (hif_drv->hif_state == HOST_IF_EXTERNAL_AUTH) {
  560. cfg80211_external_auth_request(vif->ndev, &vif->auth,
  561. GFP_KERNEL);
  562. hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
  563. } else if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
  564. host_int_parse_assoc_resp_info(vif, mac_info->status);
  565. } else if (mac_info->status == WILC_MAC_STATUS_DISCONNECTED) {
  566. if (hif_drv->hif_state == HOST_IF_CONNECTED) {
  567. wilc_handle_disconnect(vif);
  568. } else if (hif_drv->usr_scan_req.scan_result) {
  569. del_timer(&hif_drv->scan_timer);
  570. handle_scan_done(vif, SCAN_EVENT_ABORTED);
  571. }
  572. }
  573. free_msg:
  574. kfree(msg);
  575. }
  576. int wilc_disconnect(struct wilc_vif *vif)
  577. {
  578. struct wid wid;
  579. struct host_if_drv *hif_drv = vif->hif_drv;
  580. struct wilc_user_scan_req *scan_req;
  581. struct wilc_conn_info *conn_info;
  582. int result;
  583. u16 dummy_reason_code = 0;
  584. wid.id = WID_DISCONNECT;
  585. wid.type = WID_CHAR;
  586. wid.val = (s8 *)&dummy_reason_code;
  587. wid.size = sizeof(char);
  588. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  589. if (result) {
  590. netdev_err(vif->ndev, "Failed to send disconnect\n");
  591. return result;
  592. }
  593. scan_req = &hif_drv->usr_scan_req;
  594. conn_info = &hif_drv->conn_info;
  595. if (scan_req->scan_result) {
  596. del_timer(&hif_drv->scan_timer);
  597. scan_req->scan_result(SCAN_EVENT_ABORTED, NULL, scan_req->arg);
  598. scan_req->scan_result = NULL;
  599. }
  600. if (conn_info->conn_result) {
  601. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP ||
  602. hif_drv->hif_state == HOST_IF_EXTERNAL_AUTH)
  603. del_timer(&hif_drv->connect_timer);
  604. conn_info->conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, 0,
  605. conn_info->arg);
  606. } else {
  607. netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
  608. }
  609. hif_drv->hif_state = HOST_IF_IDLE;
  610. eth_zero_addr(hif_drv->assoc_bssid);
  611. conn_info->req_ies_len = 0;
  612. kfree(conn_info->req_ies);
  613. conn_info->req_ies = NULL;
  614. return 0;
  615. }
  616. int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
  617. {
  618. struct wid wid_list[5];
  619. u32 wid_cnt = 0, result;
  620. wid_list[wid_cnt].id = WID_LINKSPEED;
  621. wid_list[wid_cnt].type = WID_CHAR;
  622. wid_list[wid_cnt].size = sizeof(char);
  623. wid_list[wid_cnt].val = (s8 *)&stats->link_speed;
  624. wid_cnt++;
  625. wid_list[wid_cnt].id = WID_RSSI;
  626. wid_list[wid_cnt].type = WID_CHAR;
  627. wid_list[wid_cnt].size = sizeof(char);
  628. wid_list[wid_cnt].val = (s8 *)&stats->rssi;
  629. wid_cnt++;
  630. wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
  631. wid_list[wid_cnt].type = WID_INT;
  632. wid_list[wid_cnt].size = sizeof(u32);
  633. wid_list[wid_cnt].val = (s8 *)&stats->tx_cnt;
  634. wid_cnt++;
  635. wid_list[wid_cnt].id = WID_RECEIVED_FRAGMENT_COUNT;
  636. wid_list[wid_cnt].type = WID_INT;
  637. wid_list[wid_cnt].size = sizeof(u32);
  638. wid_list[wid_cnt].val = (s8 *)&stats->rx_cnt;
  639. wid_cnt++;
  640. wid_list[wid_cnt].id = WID_FAILED_COUNT;
  641. wid_list[wid_cnt].type = WID_INT;
  642. wid_list[wid_cnt].size = sizeof(u32);
  643. wid_list[wid_cnt].val = (s8 *)&stats->tx_fail_cnt;
  644. wid_cnt++;
  645. result = wilc_send_config_pkt(vif, WILC_GET_CFG, wid_list, wid_cnt);
  646. if (result) {
  647. netdev_err(vif->ndev, "Failed to send scan parameters\n");
  648. return result;
  649. }
  650. if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
  651. stats->link_speed != DEFAULT_LINK_SPEED)
  652. wilc_enable_tcp_ack_filter(vif, true);
  653. else if (stats->link_speed != DEFAULT_LINK_SPEED)
  654. wilc_enable_tcp_ack_filter(vif, false);
  655. return result;
  656. }
  657. static void handle_get_statistics(struct work_struct *work)
  658. {
  659. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  660. struct wilc_vif *vif = msg->vif;
  661. struct rf_info *stats = (struct rf_info *)msg->body.data;
  662. wilc_get_statistics(vif, stats);
  663. kfree(msg);
  664. }
  665. static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac,
  666. struct station_parameters *params)
  667. {
  668. ether_addr_copy(cur_byte, mac);
  669. cur_byte += ETH_ALEN;
  670. put_unaligned_le16(params->aid, cur_byte);
  671. cur_byte += 2;
  672. *cur_byte++ = params->link_sta_params.supported_rates_len;
  673. if (params->link_sta_params.supported_rates_len > 0)
  674. memcpy(cur_byte, params->link_sta_params.supported_rates,
  675. params->link_sta_params.supported_rates_len);
  676. cur_byte += params->link_sta_params.supported_rates_len;
  677. if (params->link_sta_params.ht_capa) {
  678. *cur_byte++ = true;
  679. memcpy(cur_byte, params->link_sta_params.ht_capa,
  680. sizeof(struct ieee80211_ht_cap));
  681. } else {
  682. *cur_byte++ = false;
  683. }
  684. cur_byte += sizeof(struct ieee80211_ht_cap);
  685. put_unaligned_le16(params->sta_flags_mask, cur_byte);
  686. cur_byte += 2;
  687. put_unaligned_le16(params->sta_flags_set, cur_byte);
  688. }
  689. static int handle_remain_on_chan(struct wilc_vif *vif,
  690. struct wilc_remain_ch *hif_remain_ch)
  691. {
  692. int result;
  693. u8 remain_on_chan_flag;
  694. struct wid wid;
  695. struct host_if_drv *hif_drv = vif->hif_drv;
  696. if (hif_drv->usr_scan_req.scan_result)
  697. return -EBUSY;
  698. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
  699. return -EBUSY;
  700. if (vif->connecting)
  701. return -EBUSY;
  702. remain_on_chan_flag = true;
  703. wid.id = WID_REMAIN_ON_CHAN;
  704. wid.type = WID_STR;
  705. wid.size = 2;
  706. wid.val = kmalloc(wid.size, GFP_KERNEL);
  707. if (!wid.val)
  708. return -ENOMEM;
  709. wid.val[0] = remain_on_chan_flag;
  710. wid.val[1] = (s8)hif_remain_ch->ch;
  711. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  712. kfree(wid.val);
  713. if (result)
  714. return -EBUSY;
  715. hif_drv->remain_on_ch.arg = hif_remain_ch->arg;
  716. hif_drv->remain_on_ch.expired = hif_remain_ch->expired;
  717. hif_drv->remain_on_ch.ch = hif_remain_ch->ch;
  718. hif_drv->remain_on_ch.cookie = hif_remain_ch->cookie;
  719. hif_drv->remain_on_ch_timer_vif = vif;
  720. return 0;
  721. }
  722. static int wilc_handle_roc_expired(struct wilc_vif *vif, u64 cookie)
  723. {
  724. u8 remain_on_chan_flag;
  725. struct wid wid;
  726. int result;
  727. struct host_if_drv *hif_drv = vif->hif_drv;
  728. if (vif->priv.p2p_listen_state) {
  729. remain_on_chan_flag = false;
  730. wid.id = WID_REMAIN_ON_CHAN;
  731. wid.type = WID_STR;
  732. wid.size = 2;
  733. wid.val = kmalloc(wid.size, GFP_KERNEL);
  734. if (!wid.val)
  735. return -ENOMEM;
  736. wid.val[0] = remain_on_chan_flag;
  737. wid.val[1] = WILC_FALSE_FRMWR_CHANNEL;
  738. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  739. kfree(wid.val);
  740. if (result != 0) {
  741. netdev_err(vif->ndev, "Failed to set remain channel\n");
  742. return -EINVAL;
  743. }
  744. if (hif_drv->remain_on_ch.expired) {
  745. hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
  746. cookie);
  747. }
  748. } else {
  749. netdev_dbg(vif->ndev, "Not in listen state\n");
  750. }
  751. return 0;
  752. }
  753. static void wilc_handle_listen_state_expired(struct work_struct *work)
  754. {
  755. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  756. wilc_handle_roc_expired(msg->vif, msg->body.remain_on_ch.cookie);
  757. kfree(msg);
  758. }
  759. static void listen_timer_cb(struct timer_list *t)
  760. {
  761. struct host_if_drv *hif_drv = from_timer(hif_drv, t,
  762. remain_on_ch_timer);
  763. struct wilc_vif *vif = hif_drv->remain_on_ch_timer_vif;
  764. int result;
  765. struct host_if_msg *msg;
  766. del_timer(&vif->hif_drv->remain_on_ch_timer);
  767. msg = wilc_alloc_work(vif, wilc_handle_listen_state_expired, false);
  768. if (IS_ERR(msg))
  769. return;
  770. msg->body.remain_on_ch.cookie = vif->hif_drv->remain_on_ch.cookie;
  771. result = wilc_enqueue_work(msg);
  772. if (result) {
  773. netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
  774. kfree(msg);
  775. }
  776. }
  777. static void handle_set_mcast_filter(struct work_struct *work)
  778. {
  779. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  780. struct wilc_vif *vif = msg->vif;
  781. struct wilc_set_multicast *set_mc = &msg->body.mc_info;
  782. int result;
  783. struct wid wid;
  784. u8 *cur_byte;
  785. wid.id = WID_SETUP_MULTICAST_FILTER;
  786. wid.type = WID_BIN;
  787. wid.size = sizeof(struct wilc_set_multicast) + (set_mc->cnt * ETH_ALEN);
  788. wid.val = kmalloc(wid.size, GFP_KERNEL);
  789. if (!wid.val)
  790. goto error;
  791. cur_byte = wid.val;
  792. put_unaligned_le32(set_mc->enabled, cur_byte);
  793. cur_byte += 4;
  794. put_unaligned_le32(set_mc->cnt, cur_byte);
  795. cur_byte += 4;
  796. if (set_mc->cnt > 0 && set_mc->mc_list)
  797. memcpy(cur_byte, set_mc->mc_list, set_mc->cnt * ETH_ALEN);
  798. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  799. if (result)
  800. netdev_err(vif->ndev, "Failed to send setup multicast\n");
  801. error:
  802. kfree(set_mc->mc_list);
  803. kfree(wid.val);
  804. kfree(msg);
  805. }
  806. void wilc_set_wowlan_trigger(struct wilc_vif *vif, bool enabled)
  807. {
  808. int ret;
  809. struct wid wid;
  810. u8 wowlan_trigger = 0;
  811. if (enabled)
  812. wowlan_trigger = 1;
  813. wid.id = WID_WOWLAN_TRIGGER;
  814. wid.type = WID_CHAR;
  815. wid.val = &wowlan_trigger;
  816. wid.size = sizeof(char);
  817. ret = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  818. if (ret)
  819. pr_err("Failed to send wowlan trigger config packet\n");
  820. }
  821. int wilc_set_external_auth_param(struct wilc_vif *vif,
  822. struct cfg80211_external_auth_params *auth)
  823. {
  824. int ret;
  825. struct wid wid;
  826. struct wilc_external_auth_param *param;
  827. wid.id = WID_EXTERNAL_AUTH_PARAM;
  828. wid.type = WID_BIN_DATA;
  829. wid.size = sizeof(*param);
  830. param = kzalloc(sizeof(*param), GFP_KERNEL);
  831. if (!param)
  832. return -EINVAL;
  833. wid.val = (u8 *)param;
  834. param->action = auth->action;
  835. ether_addr_copy(param->bssid, auth->bssid);
  836. memcpy(param->ssid, auth->ssid.ssid, auth->ssid.ssid_len);
  837. param->ssid_len = auth->ssid.ssid_len;
  838. ret = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  839. kfree(param);
  840. return ret;
  841. }
  842. static void handle_scan_timer(struct work_struct *work)
  843. {
  844. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  845. handle_scan_done(msg->vif, SCAN_EVENT_ABORTED);
  846. kfree(msg);
  847. }
  848. static void handle_scan_complete(struct work_struct *work)
  849. {
  850. struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
  851. del_timer(&msg->vif->hif_drv->scan_timer);
  852. handle_scan_done(msg->vif, SCAN_EVENT_DONE);
  853. kfree(msg);
  854. }
  855. static void timer_scan_cb(struct timer_list *t)
  856. {
  857. struct host_if_drv *hif_drv = from_timer(hif_drv, t, scan_timer);
  858. struct wilc_vif *vif = hif_drv->scan_timer_vif;
  859. struct host_if_msg *msg;
  860. int result;
  861. msg = wilc_alloc_work(vif, handle_scan_timer, false);
  862. if (IS_ERR(msg))
  863. return;
  864. result = wilc_enqueue_work(msg);
  865. if (result)
  866. kfree(msg);
  867. }
  868. static void timer_connect_cb(struct timer_list *t)
  869. {
  870. struct host_if_drv *hif_drv = from_timer(hif_drv, t,
  871. connect_timer);
  872. struct wilc_vif *vif = hif_drv->connect_timer_vif;
  873. struct host_if_msg *msg;
  874. int result;
  875. msg = wilc_alloc_work(vif, handle_connect_timeout, false);
  876. if (IS_ERR(msg))
  877. return;
  878. result = wilc_enqueue_work(msg);
  879. if (result)
  880. kfree(msg);
  881. }
  882. int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
  883. const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
  884. u8 mode, u8 cipher_mode, u8 index)
  885. {
  886. int result = 0;
  887. u8 t_key_len = ptk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN;
  888. if (mode == WILC_AP_MODE) {
  889. struct wid wid_list[2];
  890. struct wilc_ap_wpa_ptk *key_buf;
  891. wid_list[0].id = WID_11I_MODE;
  892. wid_list[0].type = WID_CHAR;
  893. wid_list[0].size = sizeof(char);
  894. wid_list[0].val = (s8 *)&cipher_mode;
  895. key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
  896. if (!key_buf)
  897. return -ENOMEM;
  898. ether_addr_copy(key_buf->mac_addr, mac_addr);
  899. key_buf->index = index;
  900. key_buf->key_len = t_key_len;
  901. memcpy(&key_buf->key[0], ptk, ptk_key_len);
  902. if (rx_mic)
  903. memcpy(&key_buf->key[ptk_key_len], rx_mic,
  904. WILC_RX_MIC_KEY_LEN);
  905. if (tx_mic)
  906. memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN],
  907. tx_mic, WILC_TX_MIC_KEY_LEN);
  908. wid_list[1].id = WID_ADD_PTK;
  909. wid_list[1].type = WID_STR;
  910. wid_list[1].size = sizeof(*key_buf) + t_key_len;
  911. wid_list[1].val = (u8 *)key_buf;
  912. result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
  913. ARRAY_SIZE(wid_list));
  914. kfree(key_buf);
  915. } else if (mode == WILC_STATION_MODE) {
  916. struct wid wid;
  917. struct wilc_sta_wpa_ptk *key_buf;
  918. key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
  919. if (!key_buf)
  920. return -ENOMEM;
  921. ether_addr_copy(key_buf->mac_addr, mac_addr);
  922. key_buf->key_len = t_key_len;
  923. memcpy(&key_buf->key[0], ptk, ptk_key_len);
  924. if (rx_mic)
  925. memcpy(&key_buf->key[ptk_key_len], rx_mic,
  926. WILC_RX_MIC_KEY_LEN);
  927. if (tx_mic)
  928. memcpy(&key_buf->key[ptk_key_len + WILC_RX_MIC_KEY_LEN],
  929. tx_mic, WILC_TX_MIC_KEY_LEN);
  930. wid.id = WID_ADD_PTK;
  931. wid.type = WID_STR;
  932. wid.size = sizeof(*key_buf) + t_key_len;
  933. wid.val = (s8 *)key_buf;
  934. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  935. kfree(key_buf);
  936. }
  937. return result;
  938. }
  939. int wilc_add_igtk(struct wilc_vif *vif, const u8 *igtk, u8 igtk_key_len,
  940. const u8 *pn, u8 pn_len, const u8 *mac_addr, u8 mode, u8 index)
  941. {
  942. int result = 0;
  943. u8 t_key_len = igtk_key_len;
  944. struct wid wid;
  945. struct wilc_wpa_igtk *key_buf;
  946. key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
  947. if (!key_buf)
  948. return -ENOMEM;
  949. key_buf->index = index;
  950. memcpy(&key_buf->pn[0], pn, pn_len);
  951. key_buf->pn_len = pn_len;
  952. memcpy(&key_buf->key[0], igtk, igtk_key_len);
  953. key_buf->key_len = t_key_len;
  954. wid.id = WID_ADD_IGTK;
  955. wid.type = WID_STR;
  956. wid.size = sizeof(*key_buf) + t_key_len;
  957. wid.val = (s8 *)key_buf;
  958. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  959. kfree(key_buf);
  960. return result;
  961. }
  962. int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
  963. u8 index, u32 key_rsc_len, const u8 *key_rsc,
  964. const u8 *rx_mic, const u8 *tx_mic, u8 mode,
  965. u8 cipher_mode)
  966. {
  967. int result = 0;
  968. struct wilc_gtk_key *gtk_key;
  969. int t_key_len = gtk_key_len + WILC_RX_MIC_KEY_LEN + WILC_TX_MIC_KEY_LEN;
  970. gtk_key = kzalloc(sizeof(*gtk_key) + t_key_len, GFP_KERNEL);
  971. if (!gtk_key)
  972. return -ENOMEM;
  973. /* fill bssid value only in station mode */
  974. if (mode == WILC_STATION_MODE &&
  975. vif->hif_drv->hif_state == HOST_IF_CONNECTED)
  976. memcpy(gtk_key->mac_addr, vif->hif_drv->assoc_bssid, ETH_ALEN);
  977. if (key_rsc)
  978. memcpy(gtk_key->rsc, key_rsc, 8);
  979. gtk_key->index = index;
  980. gtk_key->key_len = t_key_len;
  981. memcpy(&gtk_key->key[0], rx_gtk, gtk_key_len);
  982. if (rx_mic)
  983. memcpy(&gtk_key->key[gtk_key_len], rx_mic, WILC_RX_MIC_KEY_LEN);
  984. if (tx_mic)
  985. memcpy(&gtk_key->key[gtk_key_len + WILC_RX_MIC_KEY_LEN],
  986. tx_mic, WILC_TX_MIC_KEY_LEN);
  987. if (mode == WILC_AP_MODE) {
  988. struct wid wid_list[2];
  989. wid_list[0].id = WID_11I_MODE;
  990. wid_list[0].type = WID_CHAR;
  991. wid_list[0].size = sizeof(char);
  992. wid_list[0].val = (s8 *)&cipher_mode;
  993. wid_list[1].id = WID_ADD_RX_GTK;
  994. wid_list[1].type = WID_STR;
  995. wid_list[1].size = sizeof(*gtk_key) + t_key_len;
  996. wid_list[1].val = (u8 *)gtk_key;
  997. result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
  998. ARRAY_SIZE(wid_list));
  999. } else if (mode == WILC_STATION_MODE) {
  1000. struct wid wid;
  1001. wid.id = WID_ADD_RX_GTK;
  1002. wid.type = WID_STR;
  1003. wid.size = sizeof(*gtk_key) + t_key_len;
  1004. wid.val = (u8 *)gtk_key;
  1005. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1006. }
  1007. kfree(gtk_key);
  1008. return result;
  1009. }
  1010. int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid)
  1011. {
  1012. struct wid wid;
  1013. wid.id = WID_PMKID_INFO;
  1014. wid.type = WID_STR;
  1015. wid.size = (pmkid->numpmkid * sizeof(struct wilc_pmkid)) + 1;
  1016. wid.val = (u8 *)pmkid;
  1017. return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1018. }
  1019. int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
  1020. {
  1021. int result;
  1022. struct wid wid;
  1023. wid.id = WID_MAC_ADDR;
  1024. wid.type = WID_STR;
  1025. wid.size = ETH_ALEN;
  1026. wid.val = mac_addr;
  1027. result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
  1028. if (result)
  1029. netdev_err(vif->ndev, "Failed to get mac address\n");
  1030. return result;
  1031. }
  1032. int wilc_set_mac_address(struct wilc_vif *vif, u8 *mac_addr)
  1033. {
  1034. struct wid wid;
  1035. int result;
  1036. wid.id = WID_MAC_ADDR;
  1037. wid.type = WID_STR;
  1038. wid.size = ETH_ALEN;
  1039. wid.val = mac_addr;
  1040. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1041. if (result)
  1042. netdev_err(vif->ndev, "Failed to set mac address\n");
  1043. return result;
  1044. }
  1045. int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ies,
  1046. size_t ies_len)
  1047. {
  1048. int result;
  1049. struct host_if_drv *hif_drv = vif->hif_drv;
  1050. struct wilc_conn_info *conn_info = &hif_drv->conn_info;
  1051. if (bssid)
  1052. ether_addr_copy(conn_info->bssid, bssid);
  1053. if (ies) {
  1054. conn_info->req_ies_len = ies_len;
  1055. conn_info->req_ies = kmemdup(ies, ies_len, GFP_KERNEL);
  1056. if (!conn_info->req_ies)
  1057. return -ENOMEM;
  1058. }
  1059. result = wilc_send_connect_wid(vif);
  1060. if (result)
  1061. goto free_ies;
  1062. hif_drv->connect_timer_vif = vif;
  1063. mod_timer(&hif_drv->connect_timer,
  1064. jiffies + msecs_to_jiffies(WILC_HIF_CONNECT_TIMEOUT_MS));
  1065. return 0;
  1066. free_ies:
  1067. kfree(conn_info->req_ies);
  1068. return result;
  1069. }
  1070. int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
  1071. {
  1072. struct wid wid;
  1073. int result;
  1074. wid.id = WID_CURRENT_CHANNEL;
  1075. wid.type = WID_CHAR;
  1076. wid.size = sizeof(char);
  1077. wid.val = &channel;
  1078. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1079. if (result)
  1080. netdev_err(vif->ndev, "Failed to set channel\n");
  1081. return result;
  1082. }
  1083. int wilc_set_operation_mode(struct wilc_vif *vif, int index, u8 mode,
  1084. u8 ifc_id)
  1085. {
  1086. struct wid wid;
  1087. int result;
  1088. struct wilc_drv_handler drv;
  1089. wid.id = WID_SET_OPERATION_MODE;
  1090. wid.type = WID_STR;
  1091. wid.size = sizeof(drv);
  1092. wid.val = (u8 *)&drv;
  1093. drv.handler = cpu_to_le32(index);
  1094. drv.mode = (ifc_id | (mode << 1));
  1095. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1096. if (result)
  1097. netdev_err(vif->ndev, "Failed to set driver handler\n");
  1098. return result;
  1099. }
  1100. s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
  1101. {
  1102. struct wid wid;
  1103. s32 result;
  1104. wid.id = WID_SET_STA_MAC_INACTIVE_TIME;
  1105. wid.type = WID_STR;
  1106. wid.size = ETH_ALEN;
  1107. wid.val = kzalloc(wid.size, GFP_KERNEL);
  1108. if (!wid.val)
  1109. return -ENOMEM;
  1110. ether_addr_copy(wid.val, mac);
  1111. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1112. kfree(wid.val);
  1113. if (result) {
  1114. netdev_err(vif->ndev, "Failed to set inactive mac\n");
  1115. return result;
  1116. }
  1117. wid.id = WID_GET_INACTIVE_TIME;
  1118. wid.type = WID_INT;
  1119. wid.val = (s8 *)out_val;
  1120. wid.size = sizeof(u32);
  1121. result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
  1122. if (result)
  1123. netdev_err(vif->ndev, "Failed to get inactive time\n");
  1124. return result;
  1125. }
  1126. int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
  1127. {
  1128. struct wid wid;
  1129. int result;
  1130. if (!rssi_level) {
  1131. netdev_err(vif->ndev, "%s: RSSI level is NULL\n", __func__);
  1132. return -EFAULT;
  1133. }
  1134. wid.id = WID_RSSI;
  1135. wid.type = WID_CHAR;
  1136. wid.size = sizeof(char);
  1137. wid.val = rssi_level;
  1138. result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
  1139. if (result)
  1140. netdev_err(vif->ndev, "Failed to get RSSI value\n");
  1141. return result;
  1142. }
  1143. static int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats)
  1144. {
  1145. int result;
  1146. struct host_if_msg *msg;
  1147. msg = wilc_alloc_work(vif, handle_get_statistics, false);
  1148. if (IS_ERR(msg))
  1149. return PTR_ERR(msg);
  1150. msg->body.data = (char *)stats;
  1151. result = wilc_enqueue_work(msg);
  1152. if (result) {
  1153. netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
  1154. kfree(msg);
  1155. return result;
  1156. }
  1157. return result;
  1158. }
  1159. int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *param)
  1160. {
  1161. struct wid wid_list[4];
  1162. int i = 0;
  1163. if (param->flag & WILC_CFG_PARAM_RETRY_SHORT) {
  1164. wid_list[i].id = WID_SHORT_RETRY_LIMIT;
  1165. wid_list[i].val = (s8 *)&param->short_retry_limit;
  1166. wid_list[i].type = WID_SHORT;
  1167. wid_list[i].size = sizeof(u16);
  1168. i++;
  1169. }
  1170. if (param->flag & WILC_CFG_PARAM_RETRY_LONG) {
  1171. wid_list[i].id = WID_LONG_RETRY_LIMIT;
  1172. wid_list[i].val = (s8 *)&param->long_retry_limit;
  1173. wid_list[i].type = WID_SHORT;
  1174. wid_list[i].size = sizeof(u16);
  1175. i++;
  1176. }
  1177. if (param->flag & WILC_CFG_PARAM_FRAG_THRESHOLD) {
  1178. wid_list[i].id = WID_FRAG_THRESHOLD;
  1179. wid_list[i].val = (s8 *)&param->frag_threshold;
  1180. wid_list[i].type = WID_SHORT;
  1181. wid_list[i].size = sizeof(u16);
  1182. i++;
  1183. }
  1184. if (param->flag & WILC_CFG_PARAM_RTS_THRESHOLD) {
  1185. wid_list[i].id = WID_RTS_THRESHOLD;
  1186. wid_list[i].val = (s8 *)&param->rts_threshold;
  1187. wid_list[i].type = WID_SHORT;
  1188. wid_list[i].size = sizeof(u16);
  1189. i++;
  1190. }
  1191. return wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, i);
  1192. }
  1193. static void get_periodic_rssi(struct timer_list *t)
  1194. {
  1195. struct wilc_vif *vif = from_timer(vif, t, periodic_rssi);
  1196. if (!vif->hif_drv) {
  1197. netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
  1198. return;
  1199. }
  1200. if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
  1201. wilc_get_stats_async(vif, &vif->periodic_stat);
  1202. mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
  1203. }
  1204. int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
  1205. {
  1206. struct host_if_drv *hif_drv;
  1207. struct wilc_vif *vif = netdev_priv(dev);
  1208. hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
  1209. if (!hif_drv)
  1210. return -ENOMEM;
  1211. *hif_drv_handler = hif_drv;
  1212. vif->hif_drv = hif_drv;
  1213. timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0);
  1214. mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
  1215. timer_setup(&hif_drv->scan_timer, timer_scan_cb, 0);
  1216. timer_setup(&hif_drv->connect_timer, timer_connect_cb, 0);
  1217. timer_setup(&hif_drv->remain_on_ch_timer, listen_timer_cb, 0);
  1218. hif_drv->hif_state = HOST_IF_IDLE;
  1219. hif_drv->p2p_timeout = 0;
  1220. return 0;
  1221. }
  1222. int wilc_deinit(struct wilc_vif *vif)
  1223. {
  1224. int result = 0;
  1225. struct host_if_drv *hif_drv = vif->hif_drv;
  1226. if (!hif_drv) {
  1227. netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
  1228. return -EFAULT;
  1229. }
  1230. mutex_lock(&vif->wilc->deinit_lock);
  1231. del_timer_sync(&hif_drv->scan_timer);
  1232. del_timer_sync(&hif_drv->connect_timer);
  1233. del_timer_sync(&vif->periodic_rssi);
  1234. del_timer_sync(&hif_drv->remain_on_ch_timer);
  1235. if (hif_drv->usr_scan_req.scan_result) {
  1236. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
  1237. hif_drv->usr_scan_req.arg);
  1238. hif_drv->usr_scan_req.scan_result = NULL;
  1239. }
  1240. hif_drv->hif_state = HOST_IF_IDLE;
  1241. kfree(hif_drv);
  1242. vif->hif_drv = NULL;
  1243. mutex_unlock(&vif->wilc->deinit_lock);
  1244. return result;
  1245. }
  1246. void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
  1247. {
  1248. int result;
  1249. struct host_if_msg *msg;
  1250. int id;
  1251. struct host_if_drv *hif_drv;
  1252. struct wilc_vif *vif;
  1253. id = get_unaligned_le32(&buffer[length - 4]);
  1254. vif = wilc_get_vif_from_idx(wilc, id);
  1255. if (!vif)
  1256. return;
  1257. hif_drv = vif->hif_drv;
  1258. if (!hif_drv) {
  1259. netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
  1260. return;
  1261. }
  1262. msg = wilc_alloc_work(vif, handle_rcvd_ntwrk_info, false);
  1263. if (IS_ERR(msg))
  1264. return;
  1265. msg->body.net_info.frame_len = get_unaligned_le16(&buffer[6]) - 1;
  1266. msg->body.net_info.rssi = buffer[8];
  1267. msg->body.net_info.mgmt = kmemdup(&buffer[9],
  1268. msg->body.net_info.frame_len,
  1269. GFP_KERNEL);
  1270. if (!msg->body.net_info.mgmt) {
  1271. kfree(msg);
  1272. return;
  1273. }
  1274. result = wilc_enqueue_work(msg);
  1275. if (result) {
  1276. netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
  1277. kfree(msg->body.net_info.mgmt);
  1278. kfree(msg);
  1279. }
  1280. }
  1281. void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length)
  1282. {
  1283. int result;
  1284. struct host_if_msg *msg;
  1285. int id;
  1286. struct host_if_drv *hif_drv;
  1287. struct wilc_vif *vif;
  1288. mutex_lock(&wilc->deinit_lock);
  1289. id = get_unaligned_le32(&buffer[length - 4]);
  1290. vif = wilc_get_vif_from_idx(wilc, id);
  1291. if (!vif) {
  1292. mutex_unlock(&wilc->deinit_lock);
  1293. return;
  1294. }
  1295. hif_drv = vif->hif_drv;
  1296. if (!hif_drv) {
  1297. mutex_unlock(&wilc->deinit_lock);
  1298. return;
  1299. }
  1300. if (!hif_drv->conn_info.conn_result) {
  1301. netdev_err(vif->ndev, "%s: conn_result is NULL\n", __func__);
  1302. mutex_unlock(&wilc->deinit_lock);
  1303. return;
  1304. }
  1305. msg = wilc_alloc_work(vif, handle_rcvd_gnrl_async_info, false);
  1306. if (IS_ERR(msg)) {
  1307. mutex_unlock(&wilc->deinit_lock);
  1308. return;
  1309. }
  1310. msg->body.mac_info.status = buffer[7];
  1311. result = wilc_enqueue_work(msg);
  1312. if (result) {
  1313. netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
  1314. kfree(msg);
  1315. }
  1316. mutex_unlock(&wilc->deinit_lock);
  1317. }
  1318. void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
  1319. {
  1320. int result;
  1321. int id;
  1322. struct host_if_drv *hif_drv;
  1323. struct wilc_vif *vif;
  1324. id = get_unaligned_le32(&buffer[length - 4]);
  1325. vif = wilc_get_vif_from_idx(wilc, id);
  1326. if (!vif)
  1327. return;
  1328. hif_drv = vif->hif_drv;
  1329. if (!hif_drv)
  1330. return;
  1331. if (hif_drv->usr_scan_req.scan_result) {
  1332. struct host_if_msg *msg;
  1333. msg = wilc_alloc_work(vif, handle_scan_complete, false);
  1334. if (IS_ERR(msg))
  1335. return;
  1336. result = wilc_enqueue_work(msg);
  1337. if (result) {
  1338. netdev_err(vif->ndev, "%s: enqueue work failed\n",
  1339. __func__);
  1340. kfree(msg);
  1341. }
  1342. }
  1343. }
  1344. int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
  1345. u32 duration, u16 chan,
  1346. void (*expired)(void *, u64),
  1347. void *user_arg)
  1348. {
  1349. struct wilc_remain_ch roc;
  1350. int result;
  1351. roc.ch = chan;
  1352. roc.expired = expired;
  1353. roc.arg = user_arg;
  1354. roc.duration = duration;
  1355. roc.cookie = cookie;
  1356. result = handle_remain_on_chan(vif, &roc);
  1357. if (result)
  1358. netdev_err(vif->ndev, "%s: failed to set remain on channel\n",
  1359. __func__);
  1360. return result;
  1361. }
  1362. int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie)
  1363. {
  1364. if (!vif->hif_drv) {
  1365. netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
  1366. return -EFAULT;
  1367. }
  1368. del_timer(&vif->hif_drv->remain_on_ch_timer);
  1369. return wilc_handle_roc_expired(vif, cookie);
  1370. }
  1371. void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
  1372. {
  1373. struct wid wid;
  1374. int result;
  1375. struct wilc_reg_frame reg_frame;
  1376. wid.id = WID_REGISTER_FRAME;
  1377. wid.type = WID_STR;
  1378. wid.size = sizeof(reg_frame);
  1379. wid.val = (u8 *)&reg_frame;
  1380. memset(&reg_frame, 0x0, sizeof(reg_frame));
  1381. if (reg)
  1382. reg_frame.reg = 1;
  1383. switch (frame_type) {
  1384. case IEEE80211_STYPE_ACTION:
  1385. reg_frame.reg_id = WILC_FW_ACTION_FRM_IDX;
  1386. break;
  1387. case IEEE80211_STYPE_PROBE_REQ:
  1388. reg_frame.reg_id = WILC_FW_PROBE_REQ_IDX;
  1389. break;
  1390. case IEEE80211_STYPE_AUTH:
  1391. reg_frame.reg_id = WILC_FW_AUTH_REQ_IDX;
  1392. break;
  1393. default:
  1394. break;
  1395. }
  1396. reg_frame.frame_type = cpu_to_le16(frame_type);
  1397. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1398. if (result)
  1399. netdev_err(vif->ndev, "Failed to frame register\n");
  1400. }
  1401. int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
  1402. struct cfg80211_beacon_data *params)
  1403. {
  1404. struct wid wid;
  1405. int result;
  1406. u8 *cur_byte;
  1407. wid.id = WID_ADD_BEACON;
  1408. wid.type = WID_BIN;
  1409. wid.size = params->head_len + params->tail_len + 16;
  1410. wid.val = kzalloc(wid.size, GFP_KERNEL);
  1411. if (!wid.val)
  1412. return -ENOMEM;
  1413. cur_byte = wid.val;
  1414. put_unaligned_le32(interval, cur_byte);
  1415. cur_byte += 4;
  1416. put_unaligned_le32(dtim_period, cur_byte);
  1417. cur_byte += 4;
  1418. put_unaligned_le32(params->head_len, cur_byte);
  1419. cur_byte += 4;
  1420. if (params->head_len > 0)
  1421. memcpy(cur_byte, params->head, params->head_len);
  1422. cur_byte += params->head_len;
  1423. put_unaligned_le32(params->tail_len, cur_byte);
  1424. cur_byte += 4;
  1425. if (params->tail_len > 0)
  1426. memcpy(cur_byte, params->tail, params->tail_len);
  1427. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1428. if (result)
  1429. netdev_err(vif->ndev, "Failed to send add beacon\n");
  1430. kfree(wid.val);
  1431. return result;
  1432. }
  1433. int wilc_del_beacon(struct wilc_vif *vif)
  1434. {
  1435. int result;
  1436. struct wid wid;
  1437. u8 del_beacon = 0;
  1438. wid.id = WID_DEL_BEACON;
  1439. wid.type = WID_CHAR;
  1440. wid.size = sizeof(char);
  1441. wid.val = &del_beacon;
  1442. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1443. if (result)
  1444. netdev_err(vif->ndev, "Failed to send delete beacon\n");
  1445. return result;
  1446. }
  1447. int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
  1448. struct station_parameters *params)
  1449. {
  1450. struct wid wid;
  1451. int result;
  1452. u8 *cur_byte;
  1453. wid.id = WID_ADD_STA;
  1454. wid.type = WID_BIN;
  1455. wid.size = WILC_ADD_STA_LENGTH +
  1456. params->link_sta_params.supported_rates_len;
  1457. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1458. if (!wid.val)
  1459. return -ENOMEM;
  1460. cur_byte = wid.val;
  1461. wilc_hif_pack_sta_param(cur_byte, mac, params);
  1462. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1463. if (result != 0)
  1464. netdev_err(vif->ndev, "Failed to send add station\n");
  1465. kfree(wid.val);
  1466. return result;
  1467. }
  1468. int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
  1469. {
  1470. struct wid wid;
  1471. int result;
  1472. wid.id = WID_REMOVE_STA;
  1473. wid.type = WID_BIN;
  1474. wid.size = ETH_ALEN;
  1475. wid.val = kzalloc(wid.size, GFP_KERNEL);
  1476. if (!wid.val)
  1477. return -ENOMEM;
  1478. if (!mac_addr)
  1479. eth_broadcast_addr(wid.val);
  1480. else
  1481. ether_addr_copy(wid.val, mac_addr);
  1482. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1483. if (result)
  1484. netdev_err(vif->ndev, "Failed to del station\n");
  1485. kfree(wid.val);
  1486. return result;
  1487. }
  1488. int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
  1489. {
  1490. struct wid wid;
  1491. int result;
  1492. int i;
  1493. u8 assoc_sta = 0;
  1494. struct wilc_del_all_sta del_sta;
  1495. memset(&del_sta, 0x0, sizeof(del_sta));
  1496. for (i = 0; i < WILC_MAX_NUM_STA; i++) {
  1497. if (!is_zero_ether_addr(mac_addr[i])) {
  1498. assoc_sta++;
  1499. ether_addr_copy(del_sta.mac[i], mac_addr[i]);
  1500. }
  1501. }
  1502. if (!assoc_sta)
  1503. return 0;
  1504. del_sta.assoc_sta = assoc_sta;
  1505. wid.id = WID_DEL_ALL_STA;
  1506. wid.type = WID_STR;
  1507. wid.size = (assoc_sta * ETH_ALEN) + 1;
  1508. wid.val = (u8 *)&del_sta;
  1509. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1510. if (result)
  1511. netdev_err(vif->ndev, "Failed to send delete all station\n");
  1512. return result;
  1513. }
  1514. int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
  1515. struct station_parameters *params)
  1516. {
  1517. struct wid wid;
  1518. int result;
  1519. u8 *cur_byte;
  1520. wid.id = WID_EDIT_STA;
  1521. wid.type = WID_BIN;
  1522. wid.size = WILC_ADD_STA_LENGTH +
  1523. params->link_sta_params.supported_rates_len;
  1524. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1525. if (!wid.val)
  1526. return -ENOMEM;
  1527. cur_byte = wid.val;
  1528. wilc_hif_pack_sta_param(cur_byte, mac, params);
  1529. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1530. if (result)
  1531. netdev_err(vif->ndev, "Failed to send edit station\n");
  1532. kfree(wid.val);
  1533. return result;
  1534. }
  1535. int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
  1536. {
  1537. struct wilc *wilc = vif->wilc;
  1538. struct wid wid;
  1539. int result;
  1540. s8 power_mode;
  1541. if (enabled)
  1542. power_mode = WILC_FW_MIN_FAST_PS;
  1543. else
  1544. power_mode = WILC_FW_NO_POWERSAVE;
  1545. wid.id = WID_POWER_MANAGEMENT;
  1546. wid.val = &power_mode;
  1547. wid.size = sizeof(char);
  1548. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1549. if (result)
  1550. netdev_err(vif->ndev, "Failed to send power management\n");
  1551. else
  1552. wilc->power_save_mode = enabled;
  1553. return result;
  1554. }
  1555. int wilc_setup_multicast_filter(struct wilc_vif *vif, u32 enabled, u32 count,
  1556. u8 *mc_list)
  1557. {
  1558. int result;
  1559. struct host_if_msg *msg;
  1560. msg = wilc_alloc_work(vif, handle_set_mcast_filter, false);
  1561. if (IS_ERR(msg))
  1562. return PTR_ERR(msg);
  1563. msg->body.mc_info.enabled = enabled;
  1564. msg->body.mc_info.cnt = count;
  1565. msg->body.mc_info.mc_list = mc_list;
  1566. result = wilc_enqueue_work(msg);
  1567. if (result) {
  1568. netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
  1569. kfree(msg);
  1570. }
  1571. return result;
  1572. }
  1573. int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
  1574. {
  1575. struct wid wid;
  1576. wid.id = WID_TX_POWER;
  1577. wid.type = WID_CHAR;
  1578. wid.val = &tx_power;
  1579. wid.size = sizeof(char);
  1580. return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1581. }
  1582. int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
  1583. {
  1584. struct wid wid;
  1585. wid.id = WID_TX_POWER;
  1586. wid.type = WID_CHAR;
  1587. wid.val = tx_power;
  1588. wid.size = sizeof(char);
  1589. return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
  1590. }
  1591. int wilc_set_default_mgmt_key_index(struct wilc_vif *vif, u8 index)
  1592. {
  1593. struct wid wid;
  1594. int result;
  1595. wid.id = WID_DEFAULT_MGMT_KEY_ID;
  1596. wid.type = WID_CHAR;
  1597. wid.size = sizeof(char);
  1598. wid.val = &index;
  1599. result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
  1600. if (result)
  1601. netdev_err(vif->ndev,
  1602. "Failed to send default mgmt key index\n");
  1603. return result;
  1604. }