wl1271_acx.c 20 KB

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