wl1271_acx.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  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)
  241. {
  242. struct acx_dot11_grp_addr_tbl *acx;
  243. int ret;
  244. wl1271_debug(DEBUG_ACX, "acx group address tbl");
  245. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  246. if (!acx) {
  247. ret = -ENOMEM;
  248. goto out;
  249. }
  250. /* MAC filtering */
  251. acx->enabled = 0;
  252. acx->num_groups = 0;
  253. memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
  254. ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
  255. acx, sizeof(*acx));
  256. if (ret < 0) {
  257. wl1271_warning("failed to set group addr table: %d", ret);
  258. goto out;
  259. }
  260. out:
  261. kfree(acx);
  262. return ret;
  263. }
  264. int wl1271_acx_service_period_timeout(struct wl1271 *wl)
  265. {
  266. struct acx_rx_timeout *rx_timeout;
  267. int ret;
  268. rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
  269. if (!rx_timeout) {
  270. ret = -ENOMEM;
  271. goto out;
  272. }
  273. wl1271_debug(DEBUG_ACX, "acx service period timeout");
  274. rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
  275. rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
  276. ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
  277. rx_timeout, sizeof(*rx_timeout));
  278. if (ret < 0) {
  279. wl1271_warning("failed to set service period timeout: %d",
  280. ret);
  281. goto out;
  282. }
  283. out:
  284. kfree(rx_timeout);
  285. return ret;
  286. }
  287. int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
  288. {
  289. struct acx_rts_threshold *rts;
  290. int ret;
  291. wl1271_debug(DEBUG_ACX, "acx rts threshold");
  292. rts = kzalloc(sizeof(*rts), GFP_KERNEL);
  293. if (!rts) {
  294. ret = -ENOMEM;
  295. goto out;
  296. }
  297. rts->threshold = rts_threshold;
  298. ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
  299. if (ret < 0) {
  300. wl1271_warning("failed to set rts threshold: %d", ret);
  301. goto out;
  302. }
  303. out:
  304. kfree(rts);
  305. return ret;
  306. }
  307. int wl1271_acx_beacon_filter_opt(struct wl1271 *wl)
  308. {
  309. struct acx_beacon_filter_option *beacon_filter;
  310. int ret;
  311. wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
  312. beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
  313. if (!beacon_filter) {
  314. ret = -ENOMEM;
  315. goto out;
  316. }
  317. beacon_filter->enable = 0;
  318. beacon_filter->max_num_beacons = 0;
  319. ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
  320. beacon_filter, sizeof(*beacon_filter));
  321. if (ret < 0) {
  322. wl1271_warning("failed to set beacon filter opt: %d", ret);
  323. goto out;
  324. }
  325. out:
  326. kfree(beacon_filter);
  327. return ret;
  328. }
  329. int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
  330. {
  331. struct acx_beacon_filter_ie_table *ie_table;
  332. int ret;
  333. wl1271_debug(DEBUG_ACX, "acx beacon filter table");
  334. ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
  335. if (!ie_table) {
  336. ret = -ENOMEM;
  337. goto out;
  338. }
  339. ie_table->num_ie = 0;
  340. memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
  341. ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
  342. ie_table, sizeof(*ie_table));
  343. if (ret < 0) {
  344. wl1271_warning("failed to set beacon filter table: %d", ret);
  345. goto out;
  346. }
  347. out:
  348. kfree(ie_table);
  349. return ret;
  350. }
  351. int wl1271_acx_sg_enable(struct wl1271 *wl)
  352. {
  353. struct acx_bt_wlan_coex *pta;
  354. int ret;
  355. wl1271_debug(DEBUG_ACX, "acx sg enable");
  356. pta = kzalloc(sizeof(*pta), GFP_KERNEL);
  357. if (!pta) {
  358. ret = -ENOMEM;
  359. goto out;
  360. }
  361. pta->enable = SG_ENABLE;
  362. ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
  363. if (ret < 0) {
  364. wl1271_warning("failed to set softgemini enable: %d", ret);
  365. goto out;
  366. }
  367. out:
  368. kfree(pta);
  369. return ret;
  370. }
  371. int wl1271_acx_sg_cfg(struct wl1271 *wl)
  372. {
  373. struct acx_bt_wlan_coex_param *param;
  374. int ret;
  375. wl1271_debug(DEBUG_ACX, "acx sg cfg");
  376. param = kzalloc(sizeof(*param), GFP_KERNEL);
  377. if (!param) {
  378. ret = -ENOMEM;
  379. goto out;
  380. }
  381. /* BT-WLAN coext parameters */
  382. param->min_rate = RATE_INDEX_24MBPS;
  383. param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
  384. param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
  385. param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
  386. param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
  387. param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
  388. param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
  389. param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
  390. param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
  391. param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
  392. param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
  393. param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
  394. param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
  395. param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
  396. param->antenna_type = PTA_ANTENNA_TYPE_DEF;
  397. param->signal_type = PTA_SIGNALING_TYPE_DEF;
  398. param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
  399. param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
  400. param->max_cts = PTA_MAX_NUM_CTS_DEF;
  401. param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
  402. param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
  403. param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
  404. param->wlan_elp_hp = PTA_ELP_HP_DEF;
  405. param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
  406. param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
  407. param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
  408. param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
  409. param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
  410. ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
  411. if (ret < 0) {
  412. wl1271_warning("failed to set sg config: %d", ret);
  413. goto out;
  414. }
  415. out:
  416. kfree(param);
  417. return ret;
  418. }
  419. int wl1271_acx_cca_threshold(struct wl1271 *wl)
  420. {
  421. struct acx_energy_detection *detection;
  422. int ret;
  423. wl1271_debug(DEBUG_ACX, "acx cca threshold");
  424. detection = kzalloc(sizeof(*detection), GFP_KERNEL);
  425. if (!detection) {
  426. ret = -ENOMEM;
  427. goto out;
  428. }
  429. detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
  430. detection->tx_energy_detection = 0;
  431. ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
  432. detection, sizeof(*detection));
  433. if (ret < 0) {
  434. wl1271_warning("failed to set cca threshold: %d", ret);
  435. return ret;
  436. }
  437. out:
  438. kfree(detection);
  439. return ret;
  440. }
  441. int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
  442. {
  443. struct acx_beacon_broadcast *bb;
  444. int ret;
  445. wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
  446. bb = kzalloc(sizeof(*bb), GFP_KERNEL);
  447. if (!bb) {
  448. ret = -ENOMEM;
  449. goto out;
  450. }
  451. bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
  452. bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
  453. bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
  454. bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
  455. ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
  456. if (ret < 0) {
  457. wl1271_warning("failed to set rx config: %d", ret);
  458. goto out;
  459. }
  460. out:
  461. kfree(bb);
  462. return ret;
  463. }
  464. int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
  465. {
  466. struct acx_aid *acx_aid;
  467. int ret;
  468. wl1271_debug(DEBUG_ACX, "acx aid");
  469. acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
  470. if (!acx_aid) {
  471. ret = -ENOMEM;
  472. goto out;
  473. }
  474. acx_aid->aid = aid;
  475. ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
  476. if (ret < 0) {
  477. wl1271_warning("failed to set aid: %d", ret);
  478. goto out;
  479. }
  480. out:
  481. kfree(acx_aid);
  482. return ret;
  483. }
  484. int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
  485. {
  486. struct acx_event_mask *mask;
  487. int ret;
  488. wl1271_debug(DEBUG_ACX, "acx event mbox mask");
  489. mask = kzalloc(sizeof(*mask), GFP_KERNEL);
  490. if (!mask) {
  491. ret = -ENOMEM;
  492. goto out;
  493. }
  494. /* high event mask is unused */
  495. mask->high_event_mask = 0xffffffff;
  496. mask->event_mask = event_mask;
  497. ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
  498. mask, sizeof(*mask));
  499. if (ret < 0) {
  500. wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
  501. goto out;
  502. }
  503. out:
  504. kfree(mask);
  505. return ret;
  506. }
  507. int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
  508. {
  509. struct acx_preamble *acx;
  510. int ret;
  511. wl1271_debug(DEBUG_ACX, "acx_set_preamble");
  512. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  513. if (!acx) {
  514. ret = -ENOMEM;
  515. goto out;
  516. }
  517. acx->preamble = preamble;
  518. ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
  519. if (ret < 0) {
  520. wl1271_warning("Setting of preamble failed: %d", ret);
  521. goto out;
  522. }
  523. out:
  524. kfree(acx);
  525. return ret;
  526. }
  527. int wl1271_acx_cts_protect(struct wl1271 *wl,
  528. enum acx_ctsprotect_type ctsprotect)
  529. {
  530. struct acx_ctsprotect *acx;
  531. int ret;
  532. wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
  533. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  534. if (!acx) {
  535. ret = -ENOMEM;
  536. goto out;
  537. }
  538. acx->ctsprotect = ctsprotect;
  539. ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
  540. if (ret < 0) {
  541. wl1271_warning("Setting of ctsprotect failed: %d", ret);
  542. goto out;
  543. }
  544. out:
  545. kfree(acx);
  546. return ret;
  547. }
  548. int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
  549. {
  550. int ret;
  551. wl1271_debug(DEBUG_ACX, "acx statistics");
  552. ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
  553. sizeof(*stats));
  554. if (ret < 0) {
  555. wl1271_warning("acx statistics failed: %d", ret);
  556. return -ENOMEM;
  557. }
  558. return 0;
  559. }
  560. int wl1271_acx_rate_policies(struct wl1271 *wl)
  561. {
  562. struct acx_rate_policy *acx;
  563. int ret = 0;
  564. wl1271_debug(DEBUG_ACX, "acx rate policies");
  565. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  566. if (!acx) {
  567. ret = -ENOMEM;
  568. goto out;
  569. }
  570. /* configure one default (one-size-fits-all) rate class */
  571. acx->rate_class_cnt = 1;
  572. acx->rate_class[0].enabled_rates = ACX_RATE_MASK_ALL;
  573. acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
  574. acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
  575. acx->rate_class[0].aflags = 0;
  576. ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
  577. if (ret < 0) {
  578. wl1271_warning("Setting of rate policies failed: %d", ret);
  579. goto out;
  580. }
  581. out:
  582. kfree(acx);
  583. return ret;
  584. }
  585. int wl1271_acx_ac_cfg(struct wl1271 *wl)
  586. {
  587. struct acx_ac_cfg *acx;
  588. int i, ret = 0;
  589. wl1271_debug(DEBUG_ACX, "acx access category config");
  590. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  591. if (!acx) {
  592. ret = -ENOMEM;
  593. goto out;
  594. }
  595. /*
  596. * FIXME: Configure each AC with appropriate values (most suitable
  597. * values will probably be different for each AC.
  598. */
  599. for (i = 0; i < WL1271_ACX_AC_COUNT; i++) {
  600. acx->ac = i;
  601. /*
  602. * FIXME: The following default values originate from
  603. * the TI reference driver. What do they mean?
  604. */
  605. acx->cw_min = 15;
  606. acx->cw_max = 63;
  607. acx->aifsn = 3;
  608. acx->reserved = 0;
  609. acx->tx_op_limit = 0;
  610. ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
  611. if (ret < 0) {
  612. wl1271_warning("Setting of access category "
  613. "config: %d", ret);
  614. goto out;
  615. }
  616. }
  617. out:
  618. kfree(acx);
  619. return ret;
  620. }
  621. int wl1271_acx_tid_cfg(struct wl1271 *wl)
  622. {
  623. struct acx_tid_config *acx;
  624. int i, ret = 0;
  625. wl1271_debug(DEBUG_ACX, "acx tid config");
  626. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  627. if (!acx) {
  628. ret = -ENOMEM;
  629. goto out;
  630. }
  631. /* FIXME: configure each TID with a different AC reference */
  632. for (i = 0; i < WL1271_ACX_TID_COUNT; i++) {
  633. acx->queue_id = i;
  634. acx->tsid = WL1271_ACX_AC_BE;
  635. acx->ps_scheme = WL1271_ACX_PS_SCHEME_LEGACY;
  636. acx->ack_policy = WL1271_ACX_ACK_POLICY_LEGACY;
  637. ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
  638. if (ret < 0) {
  639. wl1271_warning("Setting of tid config failed: %d", ret);
  640. goto out;
  641. }
  642. }
  643. out:
  644. kfree(acx);
  645. return ret;
  646. }
  647. int wl1271_acx_frag_threshold(struct wl1271 *wl)
  648. {
  649. struct acx_frag_threshold *acx;
  650. int ret = 0;
  651. wl1271_debug(DEBUG_ACX, "acx frag threshold");
  652. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  653. if (!acx) {
  654. ret = -ENOMEM;
  655. goto out;
  656. }
  657. acx->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
  658. ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
  659. if (ret < 0) {
  660. wl1271_warning("Setting of frag threshold failed: %d", ret);
  661. goto out;
  662. }
  663. out:
  664. kfree(acx);
  665. return ret;
  666. }
  667. int wl1271_acx_tx_config_options(struct wl1271 *wl)
  668. {
  669. struct acx_tx_config_options *acx;
  670. int ret = 0;
  671. wl1271_debug(DEBUG_ACX, "acx tx config options");
  672. acx = kzalloc(sizeof(*acx), GFP_KERNEL);
  673. if (!acx) {
  674. ret = -ENOMEM;
  675. goto out;
  676. }
  677. acx->tx_compl_timeout = WL1271_ACX_TX_COMPL_TIMEOUT;
  678. acx->tx_compl_threshold = WL1271_ACX_TX_COMPL_THRESHOLD;
  679. ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
  680. if (ret < 0) {
  681. wl1271_warning("Setting of tx options failed: %d", ret);
  682. goto out;
  683. }
  684. out:
  685. kfree(acx);
  686. return ret;
  687. }
  688. int wl1271_acx_mem_cfg(struct wl1271 *wl)
  689. {
  690. struct wl1271_acx_config_memory *mem_conf;
  691. int ret;
  692. wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
  693. mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
  694. if (!mem_conf) {
  695. ret = -ENOMEM;
  696. goto out;
  697. }
  698. /* memory config */
  699. mem_conf->num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
  700. mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
  701. mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
  702. mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
  703. mem_conf->total_tx_descriptors = ACX_TX_DESCRIPTORS;
  704. ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
  705. sizeof(*mem_conf));
  706. if (ret < 0) {
  707. wl1271_warning("wl1271 mem config failed: %d", ret);
  708. goto out;
  709. }
  710. out:
  711. kfree(mem_conf);
  712. return ret;
  713. }
  714. int wl1271_acx_init_mem_config(struct wl1271 *wl)
  715. {
  716. int ret;
  717. ret = wl1271_acx_mem_cfg(wl);
  718. if (ret < 0)
  719. return ret;
  720. wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
  721. GFP_KERNEL);
  722. if (!wl->target_mem_map) {
  723. wl1271_error("couldn't allocate target memory map");
  724. return -ENOMEM;
  725. }
  726. /* we now ask for the firmware built memory map */
  727. ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
  728. sizeof(struct wl1271_acx_mem_map));
  729. if (ret < 0) {
  730. wl1271_error("couldn't retrieve firmware memory map");
  731. kfree(wl->target_mem_map);
  732. wl->target_mem_map = NULL;
  733. return ret;
  734. }
  735. /* initialize TX block book keeping */
  736. wl->tx_blocks_available = wl->target_mem_map->num_tx_mem_blocks;
  737. wl1271_debug(DEBUG_TX, "available tx blocks: %d",
  738. wl->tx_blocks_available);
  739. return 0;
  740. }
  741. int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
  742. {
  743. struct wl1271_acx_rx_config_opt *rx_conf;
  744. int ret;
  745. wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
  746. rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
  747. if (!rx_conf) {
  748. ret = -ENOMEM;
  749. goto out;
  750. }
  751. rx_conf->threshold = WL1271_RX_INTR_THRESHOLD_DEF;
  752. rx_conf->timeout = WL1271_RX_INTR_TIMEOUT_DEF;
  753. rx_conf->mblk_threshold = USHORT_MAX; /* Disabled */
  754. rx_conf->queue_type = RX_QUEUE_TYPE_RX_LOW_PRIORITY;
  755. ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
  756. sizeof(*rx_conf));
  757. if (ret < 0) {
  758. wl1271_warning("wl1271 rx config opt failed: %d", ret);
  759. goto out;
  760. }
  761. out:
  762. kfree(rx_conf);
  763. return ret;
  764. }