wl1271_acx.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. /*
  2. * This file is part of wl1271
  3. *
  4. * Copyright (C) 2008-2009 Nokia Corporation
  5. *
  6. * Contact: Luciano Coelho <luciano.coelho@nokia.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * version 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA
  21. *
  22. */
  23. #include "wl1271_acx.h"
  24. #include <linux/module.h>
  25. #include <linux/platform_device.h>
  26. #include <linux/crc7.h>
  27. #include <linux/spi/spi.h>
  28. #include "wl1271.h"
  29. #include "wl12xx_80211.h"
  30. #include "wl1271_reg.h"
  31. #include "wl1271_spi.h"
  32. #include "wl1271_ps.h"
  33. int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
  34. u8 listen_interval)
  35. {
  36. struct acx_wake_up_condition *wake_up;
  37. int ret;
  38. wl1271_debug(DEBUG_ACX, "acx wake up conditions");
  39. wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
  40. if (!wake_up) {
  41. ret = -ENOMEM;
  42. goto out;
  43. }
  44. wake_up->wake_up_event = wake_up_event;
  45. wake_up->listen_interval = listen_interval;
  46. ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
  47. wake_up, sizeof(*wake_up));
  48. if (ret < 0) {
  49. wl1271_warning("could not set wake up conditions: %d", ret);
  50. goto out;
  51. }
  52. out:
  53. kfree(wake_up);
  54. return ret;
  55. }
  56. int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
  57. {
  58. struct acx_sleep_auth *auth;
  59. int ret;
  60. wl1271_debug(DEBUG_ACX, "acx sleep auth");
  61. auth = kzalloc(sizeof(*auth), GFP_KERNEL);
  62. if (!auth) {
  63. ret = -ENOMEM;
  64. goto out;
  65. }
  66. auth->sleep_auth = sleep_auth;
  67. ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
  68. if (ret < 0)
  69. return ret;
  70. out:
  71. kfree(auth);
  72. return ret;
  73. }
  74. int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
  75. {
  76. struct acx_revision *rev;
  77. int ret;
  78. wl1271_debug(DEBUG_ACX, "acx fw rev");
  79. rev = kzalloc(sizeof(*rev), GFP_KERNEL);
  80. if (!rev) {
  81. ret = -ENOMEM;
  82. goto out;
  83. }
  84. ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
  85. if (ret < 0) {
  86. wl1271_warning("ACX_FW_REV interrogate failed");
  87. goto out;
  88. }
  89. /* be careful with the buffer sizes */
  90. strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
  91. /*
  92. * if the firmware version string is exactly
  93. * sizeof(rev->fw_version) long or fw_len is less than
  94. * sizeof(rev->fw_version) it won't be null terminated
  95. */
  96. buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
  97. out:
  98. kfree(rev);
  99. return ret;
  100. }
  101. int wl1271_acx_tx_power(struct wl1271 *wl, int power)
  102. {
  103. struct acx_current_tx_power *acx;
  104. int ret;
  105. wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
  106. if (power < 0 || power > 25)
  107. return -EINVAL;
  108. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  109. if (!acx) {
  110. ret = -ENOMEM;
  111. goto out;
  112. }
  113. acx->current_tx_power = power * 10;
  114. ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
  115. if (ret < 0) {
  116. wl1271_warning("configure of tx power failed: %d", ret);
  117. goto out;
  118. }
  119. out:
  120. kfree(acx);
  121. return ret;
  122. }
  123. int wl1271_acx_feature_cfg(struct wl1271 *wl)
  124. {
  125. struct acx_feature_config *feature;
  126. int ret;
  127. wl1271_debug(DEBUG_ACX, "acx feature cfg");
  128. feature = kzalloc(sizeof(*feature), GFP_KERNEL);
  129. if (!feature) {
  130. ret = -ENOMEM;
  131. goto out;
  132. }
  133. /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
  134. feature->data_flow_options = 0;
  135. feature->options = 0;
  136. ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
  137. feature, sizeof(*feature));
  138. if (ret < 0) {
  139. wl1271_error("Couldnt set HW encryption");
  140. goto out;
  141. }
  142. out:
  143. kfree(feature);
  144. return ret;
  145. }
  146. int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
  147. size_t len)
  148. {
  149. int ret;
  150. wl1271_debug(DEBUG_ACX, "acx mem map");
  151. ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
  152. if (ret < 0)
  153. return ret;
  154. return 0;
  155. }
  156. int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time)
  157. {
  158. struct acx_rx_msdu_lifetime *acx;
  159. int ret;
  160. wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
  161. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  162. if (!acx) {
  163. ret = -ENOMEM;
  164. goto out;
  165. }
  166. acx->lifetime = life_time;
  167. ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
  168. acx, sizeof(*acx));
  169. if (ret < 0) {
  170. wl1271_warning("failed to set rx msdu life time: %d", ret);
  171. goto out;
  172. }
  173. out:
  174. kfree(acx);
  175. return ret;
  176. }
  177. int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter)
  178. {
  179. struct acx_rx_config *rx_config;
  180. int ret;
  181. wl1271_debug(DEBUG_ACX, "acx rx config");
  182. rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
  183. if (!rx_config) {
  184. ret = -ENOMEM;
  185. goto out;
  186. }
  187. rx_config->config_options = config;
  188. rx_config->filter_options = filter;
  189. ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
  190. rx_config, sizeof(*rx_config));
  191. if (ret < 0) {
  192. wl1271_warning("failed to set rx config: %d", ret);
  193. goto out;
  194. }
  195. out:
  196. kfree(rx_config);
  197. return ret;
  198. }
  199. int wl1271_acx_pd_threshold(struct wl1271 *wl)
  200. {
  201. struct acx_packet_detection *pd;
  202. int ret;
  203. wl1271_debug(DEBUG_ACX, "acx data pd threshold");
  204. pd = kzalloc(sizeof(*pd), GFP_KERNEL);
  205. if (!pd) {
  206. ret = -ENOMEM;
  207. goto out;
  208. }
  209. /* FIXME: threshold value not set */
  210. ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
  211. if (ret < 0) {
  212. wl1271_warning("failed to set pd threshold: %d", ret);
  213. goto out;
  214. }
  215. out:
  216. kfree(pd);
  217. return 0;
  218. }
  219. int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
  220. {
  221. struct acx_slot *slot;
  222. int ret;
  223. wl1271_debug(DEBUG_ACX, "acx slot");
  224. slot = kzalloc(sizeof(*slot), GFP_KERNEL);
  225. if (!slot) {
  226. ret = -ENOMEM;
  227. goto out;
  228. }
  229. slot->wone_index = STATION_WONE_INDEX;
  230. slot->slot_time = slot_time;
  231. ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
  232. if (ret < 0) {
  233. wl1271_warning("failed to set slot time: %d", ret);
  234. goto out;
  235. }
  236. out:
  237. kfree(slot);
  238. return ret;
  239. }
  240. int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
  241. void *mc_list, u32 mc_list_len)
  242. {
  243. struct acx_dot11_grp_addr_tbl *acx;
  244. int ret;
  245. wl1271_debug(DEBUG_ACX, "acx group address tbl");
  246. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  247. if (!acx) {
  248. ret = -ENOMEM;
  249. goto out;
  250. }
  251. /* MAC filtering */
  252. acx->enabled = enable;
  253. acx->num_groups = mc_list_len;
  254. memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
  255. ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
  256. acx, sizeof(*acx));
  257. if (ret < 0) {
  258. wl1271_warning("failed to set group addr table: %d", ret);
  259. goto out;
  260. }
  261. out:
  262. kfree(acx);
  263. return ret;
  264. }
  265. int wl1271_acx_service_period_timeout(struct wl1271 *wl)
  266. {
  267. struct acx_rx_timeout *rx_timeout;
  268. int ret;
  269. rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
  270. if (!rx_timeout) {
  271. ret = -ENOMEM;
  272. goto out;
  273. }
  274. wl1271_debug(DEBUG_ACX, "acx service period timeout");
  275. rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
  276. rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
  277. ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
  278. rx_timeout, sizeof(*rx_timeout));
  279. if (ret < 0) {
  280. wl1271_warning("failed to set service period timeout: %d",
  281. ret);
  282. goto out;
  283. }
  284. out:
  285. kfree(rx_timeout);
  286. return ret;
  287. }
  288. int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
  289. {
  290. struct acx_rts_threshold *rts;
  291. int ret;
  292. wl1271_debug(DEBUG_ACX, "acx rts threshold");
  293. rts = kzalloc(sizeof(*rts), GFP_KERNEL);
  294. if (!rts) {
  295. ret = -ENOMEM;
  296. goto out;
  297. }
  298. rts->threshold = rts_threshold;
  299. ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
  300. if (ret < 0) {
  301. wl1271_warning("failed to set rts threshold: %d", ret);
  302. goto out;
  303. }
  304. out:
  305. kfree(rts);
  306. return ret;
  307. }
  308. int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
  309. {
  310. struct acx_beacon_filter_option *beacon_filter;
  311. int ret;
  312. wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
  313. beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
  314. if (!beacon_filter) {
  315. ret = -ENOMEM;
  316. goto out;
  317. }
  318. beacon_filter->enable = enable_filter;
  319. beacon_filter->max_num_beacons = 0;
  320. ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
  321. beacon_filter, sizeof(*beacon_filter));
  322. if (ret < 0) {
  323. wl1271_warning("failed to set beacon filter opt: %d", ret);
  324. goto out;
  325. }
  326. out:
  327. kfree(beacon_filter);
  328. return ret;
  329. }
  330. int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
  331. {
  332. struct acx_beacon_filter_ie_table *ie_table;
  333. int idx = 0;
  334. int ret;
  335. wl1271_debug(DEBUG_ACX, "acx beacon filter table");
  336. ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
  337. if (!ie_table) {
  338. ret = -ENOMEM;
  339. goto out;
  340. }
  341. /* configure default beacon pass-through rules */
  342. ie_table->num_ie = 1;
  343. ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
  344. ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
  345. ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
  346. ie_table, sizeof(*ie_table));
  347. if (ret < 0) {
  348. wl1271_warning("failed to set beacon filter table: %d", ret);
  349. goto out;
  350. }
  351. out:
  352. kfree(ie_table);
  353. return ret;
  354. }
  355. int wl1271_acx_conn_monit_params(struct wl1271 *wl)
  356. {
  357. struct acx_conn_monit_params *acx;
  358. int ret;
  359. wl1271_debug(DEBUG_ACX, "acx connection monitor parameters");
  360. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  361. if (!acx) {
  362. ret = -ENOMEM;
  363. goto out;
  364. }
  365. acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
  366. acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
  367. ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
  368. acx, sizeof(*acx));
  369. if (ret < 0) {
  370. wl1271_warning("failed to set connection monitor "
  371. "parameters: %d", ret);
  372. goto out;
  373. }
  374. out:
  375. kfree(acx);
  376. return ret;
  377. }
  378. int wl1271_acx_sg_enable(struct wl1271 *wl)
  379. {
  380. struct acx_bt_wlan_coex *pta;
  381. int ret;
  382. wl1271_debug(DEBUG_ACX, "acx sg enable");
  383. pta = kzalloc(sizeof(*pta), GFP_KERNEL);
  384. if (!pta) {
  385. ret = -ENOMEM;
  386. goto out;
  387. }
  388. pta->enable = SG_ENABLE;
  389. ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
  390. if (ret < 0) {
  391. wl1271_warning("failed to set softgemini enable: %d", ret);
  392. goto out;
  393. }
  394. out:
  395. kfree(pta);
  396. return ret;
  397. }
  398. int wl1271_acx_sg_cfg(struct wl1271 *wl)
  399. {
  400. struct acx_bt_wlan_coex_param *param;
  401. int ret;
  402. wl1271_debug(DEBUG_ACX, "acx sg cfg");
  403. param = kzalloc(sizeof(*param), GFP_KERNEL);
  404. if (!param) {
  405. ret = -ENOMEM;
  406. goto out;
  407. }
  408. /* BT-WLAN coext parameters */
  409. param->min_rate = RATE_INDEX_24MBPS;
  410. param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
  411. param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
  412. param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
  413. param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
  414. param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
  415. param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
  416. param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
  417. param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
  418. param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
  419. param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
  420. param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
  421. param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
  422. param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
  423. param->antenna_type = PTA_ANTENNA_TYPE_DEF;
  424. param->signal_type = PTA_SIGNALING_TYPE_DEF;
  425. param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
  426. param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
  427. param->max_cts = PTA_MAX_NUM_CTS_DEF;
  428. param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
  429. param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
  430. param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
  431. param->wlan_elp_hp = PTA_ELP_HP_DEF;
  432. param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
  433. param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
  434. param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
  435. param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
  436. param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
  437. ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
  438. if (ret < 0) {
  439. wl1271_warning("failed to set sg config: %d", ret);
  440. goto out;
  441. }
  442. out:
  443. kfree(param);
  444. return ret;
  445. }
  446. int wl1271_acx_cca_threshold(struct wl1271 *wl)
  447. {
  448. struct acx_energy_detection *detection;
  449. int ret;
  450. wl1271_debug(DEBUG_ACX, "acx cca threshold");
  451. detection = kzalloc(sizeof(*detection), GFP_KERNEL);
  452. if (!detection) {
  453. ret = -ENOMEM;
  454. goto out;
  455. }
  456. detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
  457. detection->tx_energy_detection = 0;
  458. ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
  459. detection, sizeof(*detection));
  460. if (ret < 0) {
  461. wl1271_warning("failed to set cca threshold: %d", ret);
  462. return ret;
  463. }
  464. out:
  465. kfree(detection);
  466. return ret;
  467. }
  468. int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
  469. {
  470. struct acx_beacon_broadcast *bb;
  471. int ret;
  472. wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
  473. bb = kzalloc(sizeof(*bb), GFP_KERNEL);
  474. if (!bb) {
  475. ret = -ENOMEM;
  476. goto out;
  477. }
  478. bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
  479. bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
  480. bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
  481. bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
  482. ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
  483. if (ret < 0) {
  484. wl1271_warning("failed to set rx config: %d", ret);
  485. goto out;
  486. }
  487. out:
  488. kfree(bb);
  489. return ret;
  490. }
  491. int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
  492. {
  493. struct acx_aid *acx_aid;
  494. int ret;
  495. wl1271_debug(DEBUG_ACX, "acx aid");
  496. acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
  497. if (!acx_aid) {
  498. ret = -ENOMEM;
  499. goto out;
  500. }
  501. acx_aid->aid = aid;
  502. ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
  503. if (ret < 0) {
  504. wl1271_warning("failed to set aid: %d", ret);
  505. goto out;
  506. }
  507. out:
  508. kfree(acx_aid);
  509. return ret;
  510. }
  511. int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
  512. {
  513. struct acx_event_mask *mask;
  514. int ret;
  515. wl1271_debug(DEBUG_ACX, "acx event mbox mask");
  516. mask = kzalloc(sizeof(*mask), GFP_KERNEL);
  517. if (!mask) {
  518. ret = -ENOMEM;
  519. goto out;
  520. }
  521. /* high event mask is unused */
  522. mask->high_event_mask = 0xffffffff;
  523. mask->event_mask = event_mask;
  524. ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
  525. mask, sizeof(*mask));
  526. if (ret < 0) {
  527. wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
  528. goto out;
  529. }
  530. out:
  531. kfree(mask);
  532. return ret;
  533. }
  534. int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
  535. {
  536. struct acx_preamble *acx;
  537. int ret;
  538. wl1271_debug(DEBUG_ACX, "acx_set_preamble");
  539. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  540. if (!acx) {
  541. ret = -ENOMEM;
  542. goto out;
  543. }
  544. acx->preamble = preamble;
  545. ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
  546. if (ret < 0) {
  547. wl1271_warning("Setting of preamble failed: %d", ret);
  548. goto out;
  549. }
  550. out:
  551. kfree(acx);
  552. return ret;
  553. }
  554. int wl1271_acx_cts_protect(struct wl1271 *wl,
  555. enum acx_ctsprotect_type ctsprotect)
  556. {
  557. struct acx_ctsprotect *acx;
  558. int ret;
  559. wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
  560. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  561. if (!acx) {
  562. ret = -ENOMEM;
  563. goto out;
  564. }
  565. acx->ctsprotect = ctsprotect;
  566. ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
  567. if (ret < 0) {
  568. wl1271_warning("Setting of ctsprotect failed: %d", ret);
  569. goto out;
  570. }
  571. out:
  572. kfree(acx);
  573. return ret;
  574. }
  575. int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
  576. {
  577. int ret;
  578. wl1271_debug(DEBUG_ACX, "acx statistics");
  579. ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
  580. sizeof(*stats));
  581. if (ret < 0) {
  582. wl1271_warning("acx statistics failed: %d", ret);
  583. return -ENOMEM;
  584. }
  585. return 0;
  586. }
  587. int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates)
  588. {
  589. struct acx_rate_policy *acx;
  590. int ret = 0;
  591. wl1271_debug(DEBUG_ACX, "acx rate policies");
  592. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  593. if (!acx) {
  594. ret = -ENOMEM;
  595. goto out;
  596. }
  597. /* configure one default (one-size-fits-all) rate class */
  598. acx->rate_class_cnt = 1;
  599. acx->rate_class[0].enabled_rates = enabled_rates;
  600. acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
  601. acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
  602. acx->rate_class[0].aflags = 0;
  603. ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
  604. if (ret < 0) {
  605. wl1271_warning("Setting of rate policies failed: %d", ret);
  606. goto out;
  607. }
  608. out:
  609. kfree(acx);
  610. return ret;
  611. }
  612. int wl1271_acx_ac_cfg(struct wl1271 *wl)
  613. {
  614. struct acx_ac_cfg *acx;
  615. int i, ret = 0;
  616. wl1271_debug(DEBUG_ACX, "acx access category config");
  617. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  618. if (!acx) {
  619. ret = -ENOMEM;
  620. goto out;
  621. }
  622. /*
  623. * FIXME: Configure each AC with appropriate values (most suitable
  624. * values will probably be different for each AC.
  625. */
  626. for (i = 0; i < WL1271_ACX_AC_COUNT; i++) {
  627. acx->ac = i;
  628. /*
  629. * FIXME: The following default values originate from
  630. * the TI reference driver. What do they mean?
  631. */
  632. acx->cw_min = 15;
  633. acx->cw_max = 63;
  634. acx->aifsn = 3;
  635. acx->reserved = 0;
  636. acx->tx_op_limit = 0;
  637. ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
  638. if (ret < 0) {
  639. wl1271_warning("Setting of access category "
  640. "config: %d", ret);
  641. goto out;
  642. }
  643. }
  644. out:
  645. kfree(acx);
  646. return ret;
  647. }
  648. int wl1271_acx_tid_cfg(struct wl1271 *wl)
  649. {
  650. struct acx_tid_config *acx;
  651. int i, ret = 0;
  652. wl1271_debug(DEBUG_ACX, "acx tid config");
  653. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  654. if (!acx) {
  655. ret = -ENOMEM;
  656. goto out;
  657. }
  658. /* FIXME: configure each TID with a different AC reference */
  659. for (i = 0; i < WL1271_ACX_TID_COUNT; i++) {
  660. acx->queue_id = i;
  661. acx->tsid = WL1271_ACX_AC_BE;
  662. acx->ps_scheme = WL1271_ACX_PS_SCHEME_LEGACY;
  663. acx->ack_policy = WL1271_ACX_ACK_POLICY_LEGACY;
  664. ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
  665. if (ret < 0) {
  666. wl1271_warning("Setting of tid config failed: %d", ret);
  667. goto out;
  668. }
  669. }
  670. out:
  671. kfree(acx);
  672. return ret;
  673. }
  674. int wl1271_acx_frag_threshold(struct wl1271 *wl)
  675. {
  676. struct acx_frag_threshold *acx;
  677. int ret = 0;
  678. wl1271_debug(DEBUG_ACX, "acx frag threshold");
  679. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  680. if (!acx) {
  681. ret = -ENOMEM;
  682. goto out;
  683. }
  684. acx->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
  685. ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
  686. if (ret < 0) {
  687. wl1271_warning("Setting of frag threshold failed: %d", ret);
  688. goto out;
  689. }
  690. out:
  691. kfree(acx);
  692. return ret;
  693. }
  694. int wl1271_acx_tx_config_options(struct wl1271 *wl)
  695. {
  696. struct acx_tx_config_options *acx;
  697. int ret = 0;
  698. wl1271_debug(DEBUG_ACX, "acx tx config options");
  699. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  700. if (!acx) {
  701. ret = -ENOMEM;
  702. goto out;
  703. }
  704. acx->tx_compl_timeout = WL1271_ACX_TX_COMPL_TIMEOUT;
  705. acx->tx_compl_threshold = WL1271_ACX_TX_COMPL_THRESHOLD;
  706. ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
  707. if (ret < 0) {
  708. wl1271_warning("Setting of tx options failed: %d", ret);
  709. goto out;
  710. }
  711. out:
  712. kfree(acx);
  713. return ret;
  714. }
  715. int wl1271_acx_mem_cfg(struct wl1271 *wl)
  716. {
  717. struct wl1271_acx_config_memory *mem_conf;
  718. int ret;
  719. wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
  720. mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
  721. if (!mem_conf) {
  722. ret = -ENOMEM;
  723. goto out;
  724. }
  725. /* memory config */
  726. mem_conf->num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
  727. mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
  728. mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
  729. mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
  730. mem_conf->total_tx_descriptors = ACX_TX_DESCRIPTORS;
  731. ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
  732. sizeof(*mem_conf));
  733. if (ret < 0) {
  734. wl1271_warning("wl1271 mem config failed: %d", ret);
  735. goto out;
  736. }
  737. out:
  738. kfree(mem_conf);
  739. return ret;
  740. }
  741. int wl1271_acx_init_mem_config(struct wl1271 *wl)
  742. {
  743. int ret;
  744. ret = wl1271_acx_mem_cfg(wl);
  745. if (ret < 0)
  746. return ret;
  747. wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
  748. GFP_KERNEL);
  749. if (!wl->target_mem_map) {
  750. wl1271_error("couldn't allocate target memory map");
  751. return -ENOMEM;
  752. }
  753. /* we now ask for the firmware built memory map */
  754. ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
  755. sizeof(struct wl1271_acx_mem_map));
  756. if (ret < 0) {
  757. wl1271_error("couldn't retrieve firmware memory map");
  758. kfree(wl->target_mem_map);
  759. wl->target_mem_map = NULL;
  760. return ret;
  761. }
  762. /* initialize TX block book keeping */
  763. wl->tx_blocks_available = wl->target_mem_map->num_tx_mem_blocks;
  764. wl1271_debug(DEBUG_TX, "available tx blocks: %d",
  765. wl->tx_blocks_available);
  766. return 0;
  767. }
  768. int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
  769. {
  770. struct wl1271_acx_rx_config_opt *rx_conf;
  771. int ret;
  772. wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
  773. rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
  774. if (!rx_conf) {
  775. ret = -ENOMEM;
  776. goto out;
  777. }
  778. rx_conf->threshold = WL1271_RX_INTR_THRESHOLD_DEF;
  779. rx_conf->timeout = WL1271_RX_INTR_TIMEOUT_DEF;
  780. rx_conf->mblk_threshold = USHORT_MAX; /* Disabled */
  781. rx_conf->queue_type = RX_QUEUE_TYPE_RX_LOW_PRIORITY;
  782. ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
  783. sizeof(*rx_conf));
  784. if (ret < 0) {
  785. wl1271_warning("wl1271 rx config opt failed: %d", ret);
  786. goto out;
  787. }
  788. out:
  789. kfree(rx_conf);
  790. return ret;
  791. }