acx.c 23 KB

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