acx.c 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include "acx.h"
  3. #include <linux/module.h>
  4. #include <linux/slab.h>
  5. #include <linux/string.h>
  6. #include "wl1251.h"
  7. #include "reg.h"
  8. #include "cmd.h"
  9. #include "ps.h"
  10. int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
  11. u8 mgt_rate, u8 mgt_mod)
  12. {
  13. struct acx_fw_gen_frame_rates *rates;
  14. int ret;
  15. wl1251_debug(DEBUG_ACX, "acx frame rates");
  16. rates = kzalloc_obj(*rates);
  17. if (!rates)
  18. return -ENOMEM;
  19. rates->tx_ctrl_frame_rate = ctrl_rate;
  20. rates->tx_ctrl_frame_mod = ctrl_mod;
  21. rates->tx_mgt_frame_rate = mgt_rate;
  22. rates->tx_mgt_frame_mod = mgt_mod;
  23. ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
  24. rates, sizeof(*rates));
  25. if (ret < 0) {
  26. wl1251_error("Failed to set FW rates and modulation");
  27. goto out;
  28. }
  29. out:
  30. kfree(rates);
  31. return ret;
  32. }
  33. int wl1251_acx_station_id(struct wl1251 *wl)
  34. {
  35. struct acx_dot11_station_id *mac;
  36. int ret, i;
  37. wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
  38. mac = kzalloc_obj(*mac);
  39. if (!mac)
  40. return -ENOMEM;
  41. for (i = 0; i < ETH_ALEN; i++)
  42. mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
  43. ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
  44. kfree(mac);
  45. return ret;
  46. }
  47. int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
  48. {
  49. struct acx_dot11_default_key *default_key;
  50. int ret;
  51. wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
  52. default_key = kzalloc_obj(*default_key);
  53. if (!default_key)
  54. return -ENOMEM;
  55. default_key->id = key_id;
  56. ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
  57. default_key, sizeof(*default_key));
  58. if (ret < 0) {
  59. wl1251_error("Couldn't set default key");
  60. goto out;
  61. }
  62. wl->default_key = key_id;
  63. out:
  64. kfree(default_key);
  65. return ret;
  66. }
  67. int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
  68. u8 listen_interval)
  69. {
  70. struct acx_wake_up_condition *wake_up;
  71. int ret;
  72. wl1251_debug(DEBUG_ACX, "acx wake up conditions");
  73. wake_up = kzalloc_obj(*wake_up);
  74. if (!wake_up)
  75. return -ENOMEM;
  76. wake_up->wake_up_event = wake_up_event;
  77. wake_up->listen_interval = listen_interval;
  78. ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
  79. wake_up, sizeof(*wake_up));
  80. if (ret < 0) {
  81. wl1251_warning("could not set wake up conditions: %d", ret);
  82. goto out;
  83. }
  84. out:
  85. kfree(wake_up);
  86. return ret;
  87. }
  88. int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
  89. {
  90. struct acx_sleep_auth *auth;
  91. int ret;
  92. wl1251_debug(DEBUG_ACX, "acx sleep auth");
  93. auth = kzalloc_obj(*auth);
  94. if (!auth)
  95. return -ENOMEM;
  96. auth->sleep_auth = sleep_auth;
  97. ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
  98. kfree(auth);
  99. return ret;
  100. }
  101. int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
  102. {
  103. struct acx_revision *rev;
  104. int ret;
  105. wl1251_debug(DEBUG_ACX, "acx fw rev");
  106. rev = kzalloc_obj(*rev);
  107. if (!rev)
  108. return -ENOMEM;
  109. ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
  110. if (ret < 0) {
  111. wl1251_warning("ACX_FW_REV interrogate failed");
  112. goto out;
  113. }
  114. strscpy(buf, rev->fw_version, len);
  115. out:
  116. kfree(rev);
  117. return ret;
  118. }
  119. int wl1251_acx_tx_power(struct wl1251 *wl, int power)
  120. {
  121. struct acx_current_tx_power *acx;
  122. int ret;
  123. wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
  124. if (power < 0 || power > 25)
  125. return -EINVAL;
  126. acx = kzalloc_obj(*acx);
  127. if (!acx)
  128. return -ENOMEM;
  129. acx->current_tx_power = power * 10;
  130. ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
  131. if (ret < 0) {
  132. wl1251_warning("configure of tx power failed: %d", ret);
  133. goto out;
  134. }
  135. out:
  136. kfree(acx);
  137. return ret;
  138. }
  139. int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options)
  140. {
  141. struct acx_feature_config *feature;
  142. int ret;
  143. wl1251_debug(DEBUG_ACX, "acx feature cfg");
  144. feature = kzalloc_obj(*feature);
  145. if (!feature)
  146. return -ENOMEM;
  147. /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE can be set */
  148. feature->data_flow_options = data_flow_options;
  149. feature->options = 0;
  150. ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
  151. feature, sizeof(*feature));
  152. if (ret < 0) {
  153. wl1251_error("Couldn't set HW encryption");
  154. goto out;
  155. }
  156. out:
  157. kfree(feature);
  158. return ret;
  159. }
  160. int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
  161. size_t len)
  162. {
  163. int ret;
  164. wl1251_debug(DEBUG_ACX, "acx mem map");
  165. ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
  166. if (ret < 0)
  167. return ret;
  168. return 0;
  169. }
  170. int wl1251_acx_data_path_params(struct wl1251 *wl,
  171. struct acx_data_path_params_resp *resp)
  172. {
  173. struct acx_data_path_params *params;
  174. int ret;
  175. wl1251_debug(DEBUG_ACX, "acx data path params");
  176. params = kzalloc_obj(*params);
  177. if (!params)
  178. return -ENOMEM;
  179. params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
  180. params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
  181. params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
  182. params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
  183. params->tx_complete_threshold = 1;
  184. params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
  185. params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
  186. ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
  187. params, sizeof(*params));
  188. if (ret < 0)
  189. goto out;
  190. /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
  191. ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
  192. resp, sizeof(*resp));
  193. if (ret < 0) {
  194. wl1251_warning("failed to read data path parameters: %d", ret);
  195. goto out;
  196. } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
  197. wl1251_warning("data path parameter acx status failed");
  198. ret = -EIO;
  199. goto out;
  200. }
  201. out:
  202. kfree(params);
  203. return ret;
  204. }
  205. int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
  206. {
  207. struct acx_rx_msdu_lifetime *acx;
  208. int ret;
  209. wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
  210. acx = kzalloc_obj(*acx);
  211. if (!acx)
  212. return -ENOMEM;
  213. acx->lifetime = life_time;
  214. ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
  215. acx, sizeof(*acx));
  216. if (ret < 0) {
  217. wl1251_warning("failed to set rx msdu life time: %d", ret);
  218. goto out;
  219. }
  220. out:
  221. kfree(acx);
  222. return ret;
  223. }
  224. int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
  225. {
  226. struct acx_rx_config *rx_config;
  227. int ret;
  228. wl1251_debug(DEBUG_ACX, "acx rx config");
  229. rx_config = kzalloc_obj(*rx_config);
  230. if (!rx_config)
  231. return -ENOMEM;
  232. rx_config->config_options = config;
  233. rx_config->filter_options = filter;
  234. ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
  235. rx_config, sizeof(*rx_config));
  236. if (ret < 0) {
  237. wl1251_warning("failed to set rx config: %d", ret);
  238. goto out;
  239. }
  240. out:
  241. kfree(rx_config);
  242. return ret;
  243. }
  244. int wl1251_acx_pd_threshold(struct wl1251 *wl)
  245. {
  246. struct acx_packet_detection *pd;
  247. int ret;
  248. wl1251_debug(DEBUG_ACX, "acx data pd threshold");
  249. pd = kzalloc_obj(*pd);
  250. if (!pd)
  251. return -ENOMEM;
  252. /* FIXME: threshold value not set */
  253. ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
  254. if (ret < 0) {
  255. wl1251_warning("failed to set pd threshold: %d", ret);
  256. goto out;
  257. }
  258. out:
  259. kfree(pd);
  260. return ret;
  261. }
  262. int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
  263. {
  264. struct acx_slot *slot;
  265. int ret;
  266. wl1251_debug(DEBUG_ACX, "acx slot");
  267. slot = kzalloc_obj(*slot);
  268. if (!slot)
  269. return -ENOMEM;
  270. slot->wone_index = STATION_WONE_INDEX;
  271. slot->slot_time = slot_time;
  272. ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
  273. if (ret < 0) {
  274. wl1251_warning("failed to set slot time: %d", ret);
  275. goto out;
  276. }
  277. out:
  278. kfree(slot);
  279. return ret;
  280. }
  281. int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable,
  282. void *mc_list, u32 mc_list_len)
  283. {
  284. struct acx_dot11_grp_addr_tbl *acx;
  285. int ret;
  286. wl1251_debug(DEBUG_ACX, "acx group address tbl");
  287. acx = kzalloc_obj(*acx);
  288. if (!acx)
  289. return -ENOMEM;
  290. /* MAC filtering */
  291. acx->enabled = enable;
  292. acx->num_groups = mc_list_len;
  293. memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
  294. ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
  295. acx, sizeof(*acx));
  296. if (ret < 0) {
  297. wl1251_warning("failed to set group addr table: %d", ret);
  298. goto out;
  299. }
  300. out:
  301. kfree(acx);
  302. return ret;
  303. }
  304. int wl1251_acx_service_period_timeout(struct wl1251 *wl)
  305. {
  306. struct acx_rx_timeout *rx_timeout;
  307. int ret;
  308. rx_timeout = kzalloc_obj(*rx_timeout);
  309. if (!rx_timeout)
  310. return -ENOMEM;
  311. wl1251_debug(DEBUG_ACX, "acx service period timeout");
  312. rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
  313. rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
  314. ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
  315. rx_timeout, sizeof(*rx_timeout));
  316. if (ret < 0) {
  317. wl1251_warning("failed to set service period timeout: %d",
  318. ret);
  319. goto out;
  320. }
  321. out:
  322. kfree(rx_timeout);
  323. return ret;
  324. }
  325. int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
  326. {
  327. struct acx_rts_threshold *rts;
  328. int ret;
  329. wl1251_debug(DEBUG_ACX, "acx rts threshold");
  330. rts = kzalloc_obj(*rts);
  331. if (!rts)
  332. return -ENOMEM;
  333. rts->threshold = rts_threshold;
  334. ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
  335. if (ret < 0) {
  336. wl1251_warning("failed to set rts threshold: %d", ret);
  337. goto out;
  338. }
  339. out:
  340. kfree(rts);
  341. return ret;
  342. }
  343. int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
  344. {
  345. struct acx_beacon_filter_option *beacon_filter;
  346. int ret;
  347. wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
  348. beacon_filter = kzalloc_obj(*beacon_filter);
  349. if (!beacon_filter)
  350. return -ENOMEM;
  351. beacon_filter->enable = enable_filter;
  352. beacon_filter->max_num_beacons = 0;
  353. ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
  354. beacon_filter, sizeof(*beacon_filter));
  355. if (ret < 0) {
  356. wl1251_warning("failed to set beacon filter opt: %d", ret);
  357. goto out;
  358. }
  359. out:
  360. kfree(beacon_filter);
  361. return ret;
  362. }
  363. int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
  364. {
  365. struct acx_beacon_filter_ie_table *ie_table;
  366. int idx = 0;
  367. int ret;
  368. wl1251_debug(DEBUG_ACX, "acx beacon filter table");
  369. ie_table = kzalloc_obj(*ie_table);
  370. if (!ie_table)
  371. return -ENOMEM;
  372. /* configure default beacon pass-through rules */
  373. ie_table->num_ie = 1;
  374. ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
  375. ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
  376. ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
  377. ie_table, sizeof(*ie_table));
  378. if (ret < 0) {
  379. wl1251_warning("failed to set beacon filter table: %d", ret);
  380. goto out;
  381. }
  382. out:
  383. kfree(ie_table);
  384. return ret;
  385. }
  386. int wl1251_acx_conn_monit_params(struct wl1251 *wl)
  387. {
  388. struct acx_conn_monit_params *acx;
  389. int ret;
  390. wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
  391. acx = kzalloc_obj(*acx);
  392. if (!acx)
  393. return -ENOMEM;
  394. acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
  395. acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
  396. ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
  397. acx, sizeof(*acx));
  398. if (ret < 0) {
  399. wl1251_warning("failed to set connection monitor "
  400. "parameters: %d", ret);
  401. goto out;
  402. }
  403. out:
  404. kfree(acx);
  405. return ret;
  406. }
  407. int wl1251_acx_sg_enable(struct wl1251 *wl)
  408. {
  409. struct acx_bt_wlan_coex *pta;
  410. int ret;
  411. wl1251_debug(DEBUG_ACX, "acx sg enable");
  412. pta = kzalloc_obj(*pta);
  413. if (!pta)
  414. return -ENOMEM;
  415. pta->enable = SG_ENABLE;
  416. ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
  417. if (ret < 0) {
  418. wl1251_warning("failed to set softgemini enable: %d", ret);
  419. goto out;
  420. }
  421. out:
  422. kfree(pta);
  423. return ret;
  424. }
  425. int wl1251_acx_sg_cfg(struct wl1251 *wl)
  426. {
  427. struct acx_bt_wlan_coex_param *param;
  428. int ret;
  429. wl1251_debug(DEBUG_ACX, "acx sg cfg");
  430. param = kzalloc_obj(*param);
  431. if (!param)
  432. return -ENOMEM;
  433. /* BT-WLAN coext parameters */
  434. param->min_rate = RATE_INDEX_24MBPS;
  435. param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
  436. param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
  437. param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
  438. param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
  439. param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
  440. param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
  441. param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
  442. param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
  443. param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
  444. param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
  445. param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
  446. param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
  447. param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
  448. param->antenna_type = PTA_ANTENNA_TYPE_DEF;
  449. param->signal_type = PTA_SIGNALING_TYPE_DEF;
  450. param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
  451. param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
  452. param->max_cts = PTA_MAX_NUM_CTS_DEF;
  453. param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
  454. param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
  455. param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
  456. param->wlan_elp_hp = PTA_ELP_HP_DEF;
  457. param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
  458. param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
  459. param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
  460. param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
  461. param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
  462. ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
  463. if (ret < 0) {
  464. wl1251_warning("failed to set sg config: %d", ret);
  465. goto out;
  466. }
  467. out:
  468. kfree(param);
  469. return ret;
  470. }
  471. int wl1251_acx_cca_threshold(struct wl1251 *wl)
  472. {
  473. struct acx_energy_detection *detection;
  474. int ret;
  475. wl1251_debug(DEBUG_ACX, "acx cca threshold");
  476. detection = kzalloc_obj(*detection);
  477. if (!detection)
  478. return -ENOMEM;
  479. detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
  480. detection->tx_energy_detection = 0;
  481. ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
  482. detection, sizeof(*detection));
  483. if (ret < 0)
  484. wl1251_warning("failed to set cca threshold: %d", ret);
  485. kfree(detection);
  486. return ret;
  487. }
  488. int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
  489. {
  490. struct acx_beacon_broadcast *bb;
  491. int ret;
  492. wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
  493. bb = kzalloc_obj(*bb);
  494. if (!bb)
  495. return -ENOMEM;
  496. bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
  497. bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
  498. bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
  499. bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
  500. ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
  501. if (ret < 0) {
  502. wl1251_warning("failed to set rx config: %d", ret);
  503. goto out;
  504. }
  505. out:
  506. kfree(bb);
  507. return ret;
  508. }
  509. int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
  510. {
  511. struct acx_aid *acx_aid;
  512. int ret;
  513. wl1251_debug(DEBUG_ACX, "acx aid");
  514. acx_aid = kzalloc_obj(*acx_aid);
  515. if (!acx_aid)
  516. return -ENOMEM;
  517. acx_aid->aid = aid;
  518. ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
  519. if (ret < 0) {
  520. wl1251_warning("failed to set aid: %d", ret);
  521. goto out;
  522. }
  523. out:
  524. kfree(acx_aid);
  525. return ret;
  526. }
  527. int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
  528. {
  529. struct acx_event_mask *mask;
  530. int ret;
  531. wl1251_debug(DEBUG_ACX, "acx event mbox mask");
  532. mask = kzalloc_obj(*mask);
  533. if (!mask)
  534. return -ENOMEM;
  535. /* high event mask is unused */
  536. mask->high_event_mask = 0xffffffff;
  537. mask->event_mask = event_mask;
  538. ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
  539. mask, sizeof(*mask));
  540. if (ret < 0) {
  541. wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
  542. goto out;
  543. }
  544. out:
  545. kfree(mask);
  546. return ret;
  547. }
  548. int wl1251_acx_low_rssi(struct wl1251 *wl, s8 threshold, u8 weight,
  549. u8 depth, enum wl1251_acx_low_rssi_type type)
  550. {
  551. struct acx_low_rssi *rssi;
  552. int ret;
  553. wl1251_debug(DEBUG_ACX, "acx low rssi");
  554. rssi = kzalloc_obj(*rssi);
  555. if (!rssi)
  556. return -ENOMEM;
  557. rssi->threshold = threshold;
  558. rssi->weight = weight;
  559. rssi->depth = depth;
  560. rssi->type = type;
  561. ret = wl1251_cmd_configure(wl, ACX_LOW_RSSI, rssi, sizeof(*rssi));
  562. if (ret < 0)
  563. wl1251_warning("failed to set low rssi threshold: %d", ret);
  564. kfree(rssi);
  565. return ret;
  566. }
  567. int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
  568. {
  569. struct acx_preamble *acx;
  570. int ret;
  571. wl1251_debug(DEBUG_ACX, "acx_set_preamble");
  572. acx = kzalloc_obj(*acx);
  573. if (!acx)
  574. return -ENOMEM;
  575. acx->preamble = preamble;
  576. ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
  577. if (ret < 0) {
  578. wl1251_warning("Setting of preamble failed: %d", ret);
  579. goto out;
  580. }
  581. out:
  582. kfree(acx);
  583. return ret;
  584. }
  585. int wl1251_acx_cts_protect(struct wl1251 *wl,
  586. enum acx_ctsprotect_type ctsprotect)
  587. {
  588. struct acx_ctsprotect *acx;
  589. int ret;
  590. wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
  591. acx = kzalloc_obj(*acx);
  592. if (!acx)
  593. return -ENOMEM;
  594. acx->ctsprotect = ctsprotect;
  595. ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
  596. if (ret < 0) {
  597. wl1251_warning("Setting of ctsprotect failed: %d", ret);
  598. goto out;
  599. }
  600. out:
  601. kfree(acx);
  602. return ret;
  603. }
  604. int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
  605. {
  606. struct acx_tsf_info *tsf_info;
  607. int ret;
  608. tsf_info = kzalloc_obj(*tsf_info);
  609. if (!tsf_info)
  610. return -ENOMEM;
  611. ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
  612. tsf_info, sizeof(*tsf_info));
  613. if (ret < 0) {
  614. wl1251_warning("ACX_FW_REV interrogate failed");
  615. goto out;
  616. }
  617. *mactime = tsf_info->current_tsf_lsb |
  618. ((u64)tsf_info->current_tsf_msb << 32);
  619. out:
  620. kfree(tsf_info);
  621. return ret;
  622. }
  623. int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
  624. {
  625. int ret;
  626. wl1251_debug(DEBUG_ACX, "acx statistics");
  627. ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
  628. sizeof(*stats));
  629. if (ret < 0) {
  630. wl1251_warning("acx statistics failed: %d", ret);
  631. return -ENOMEM;
  632. }
  633. return 0;
  634. }
  635. int wl1251_acx_mem_cfg(struct wl1251 *wl)
  636. {
  637. struct wl1251_acx_config_memory *mem_conf;
  638. int ret, i;
  639. wl1251_debug(DEBUG_ACX, "acx mem cfg");
  640. mem_conf = kzalloc_obj(*mem_conf);
  641. if (!mem_conf)
  642. return -ENOMEM;
  643. /* memory config */
  644. mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
  645. mem_conf->mem_config.rx_mem_block_num = 35;
  646. mem_conf->mem_config.tx_min_mem_block_num = 64;
  647. mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
  648. mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
  649. mem_conf->mem_config.num_ssid_profiles = 1;
  650. mem_conf->mem_config.debug_buffer_size =
  651. cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
  652. /* RX queue config */
  653. mem_conf->rx_queue_config.dma_address = 0;
  654. mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
  655. mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
  656. mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
  657. /* TX queue config */
  658. for (i = 0; i < MAX_TX_QUEUES; i++) {
  659. mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
  660. mem_conf->tx_queue_config[i].attributes = i;
  661. }
  662. ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
  663. sizeof(*mem_conf));
  664. if (ret < 0) {
  665. wl1251_warning("wl1251 mem config failed: %d", ret);
  666. goto out;
  667. }
  668. out:
  669. kfree(mem_conf);
  670. return ret;
  671. }
  672. int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
  673. {
  674. struct wl1251_acx_wr_tbtt_and_dtim *acx;
  675. int ret;
  676. wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
  677. acx = kzalloc_obj(*acx);
  678. if (!acx)
  679. return -ENOMEM;
  680. acx->tbtt = tbtt;
  681. acx->dtim = dtim;
  682. ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
  683. acx, sizeof(*acx));
  684. if (ret < 0) {
  685. wl1251_warning("failed to set tbtt and dtim: %d", ret);
  686. goto out;
  687. }
  688. out:
  689. kfree(acx);
  690. return ret;
  691. }
  692. int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
  693. u8 max_consecutive)
  694. {
  695. struct wl1251_acx_bet_enable *acx;
  696. int ret;
  697. wl1251_debug(DEBUG_ACX, "acx bet enable");
  698. acx = kzalloc_obj(*acx);
  699. if (!acx)
  700. return -ENOMEM;
  701. acx->enable = mode;
  702. acx->max_consecutive = max_consecutive;
  703. ret = wl1251_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
  704. if (ret < 0) {
  705. wl1251_warning("wl1251 acx bet enable failed: %d", ret);
  706. goto out;
  707. }
  708. out:
  709. kfree(acx);
  710. return ret;
  711. }
  712. int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address)
  713. {
  714. struct wl1251_acx_arp_filter *acx;
  715. int ret;
  716. wl1251_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
  717. acx = kzalloc_obj(*acx);
  718. if (!acx)
  719. return -ENOMEM;
  720. acx->version = ACX_IPV4_VERSION;
  721. acx->enable = enable;
  722. if (enable)
  723. memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
  724. ret = wl1251_cmd_configure(wl, ACX_ARP_IP_FILTER,
  725. acx, sizeof(*acx));
  726. if (ret < 0)
  727. wl1251_warning("failed to set arp ip filter: %d", ret);
  728. kfree(acx);
  729. return ret;
  730. }
  731. int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
  732. u8 aifs, u16 txop)
  733. {
  734. struct wl1251_acx_ac_cfg *acx;
  735. int ret = 0;
  736. wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
  737. "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
  738. acx = kzalloc_obj(*acx);
  739. if (!acx)
  740. return -ENOMEM;
  741. acx->ac = ac;
  742. acx->cw_min = cw_min;
  743. acx->cw_max = cw_max;
  744. acx->aifsn = aifs;
  745. acx->txop_limit = txop;
  746. ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
  747. if (ret < 0) {
  748. wl1251_warning("acx ac cfg failed: %d", ret);
  749. goto out;
  750. }
  751. out:
  752. kfree(acx);
  753. return ret;
  754. }
  755. int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
  756. enum wl1251_acx_channel_type type,
  757. u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
  758. enum wl1251_acx_ack_policy ack_policy)
  759. {
  760. struct wl1251_acx_tid_cfg *acx;
  761. int ret = 0;
  762. wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
  763. "ps_scheme %d ack_policy %d", queue, type, tsid,
  764. ps_scheme, ack_policy);
  765. acx = kzalloc_obj(*acx);
  766. if (!acx)
  767. return -ENOMEM;
  768. acx->queue = queue;
  769. acx->type = type;
  770. acx->tsid = tsid;
  771. acx->ps_scheme = ps_scheme;
  772. acx->ack_policy = ack_policy;
  773. ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
  774. if (ret < 0) {
  775. wl1251_warning("acx tid cfg failed: %d", ret);
  776. goto out;
  777. }
  778. out:
  779. kfree(acx);
  780. return ret;
  781. }