mac.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /*
  2. * Atheros CARL9170 driver
  3. *
  4. * MAC programming
  5. *
  6. * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; see the file COPYING. If not, see
  20. * http://www.gnu.org/licenses/.
  21. *
  22. * This file incorporates work covered by the following copyright and
  23. * permission notice:
  24. * Copyright (c) 2007-2008 Atheros Communications, Inc.
  25. *
  26. * Permission to use, copy, modify, and/or distribute this software for any
  27. * purpose with or without fee is hereby granted, provided that the above
  28. * copyright notice and this permission notice appear in all copies.
  29. *
  30. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  31. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  32. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  33. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  34. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  35. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  36. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  37. */
  38. #include <asm/unaligned.h>
  39. #include "carl9170.h"
  40. #include "cmd.h"
  41. int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
  42. {
  43. u32 val;
  44. if (conf_is_ht40(&ar->hw->conf))
  45. val = 0x010a;
  46. else {
  47. if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
  48. val = 0x105;
  49. else
  50. val = 0x104;
  51. }
  52. return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
  53. }
  54. int carl9170_set_rts_cts_rate(struct ar9170 *ar)
  55. {
  56. u32 rts_rate, cts_rate;
  57. if (conf_is_ht(&ar->hw->conf)) {
  58. /* 12 mbit OFDM */
  59. rts_rate = 0x1da;
  60. cts_rate = 0x10a;
  61. } else {
  62. if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
  63. /* 11 mbit CCK */
  64. rts_rate = 033;
  65. cts_rate = 003;
  66. } else {
  67. /* 6 mbit OFDM */
  68. rts_rate = 0x1bb;
  69. cts_rate = 0x10b;
  70. }
  71. }
  72. return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE,
  73. rts_rate | (cts_rate) << 16);
  74. }
  75. int carl9170_set_slot_time(struct ar9170 *ar)
  76. {
  77. struct ieee80211_vif *vif;
  78. u32 slottime = 20;
  79. rcu_read_lock();
  80. vif = carl9170_get_main_vif(ar);
  81. if (!vif) {
  82. rcu_read_unlock();
  83. return 0;
  84. }
  85. if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
  86. vif->bss_conf.use_short_slot)
  87. slottime = 9;
  88. rcu_read_unlock();
  89. return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
  90. slottime << 10);
  91. }
  92. int carl9170_set_mac_rates(struct ar9170 *ar)
  93. {
  94. struct ieee80211_vif *vif;
  95. u32 basic, mandatory;
  96. rcu_read_lock();
  97. vif = carl9170_get_main_vif(ar);
  98. if (!vif) {
  99. rcu_read_unlock();
  100. return 0;
  101. }
  102. basic = (vif->bss_conf.basic_rates & 0xf);
  103. basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
  104. rcu_read_unlock();
  105. if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
  106. mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
  107. else
  108. mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
  109. carl9170_regwrite_begin(ar);
  110. carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic);
  111. carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory);
  112. carl9170_regwrite_finish();
  113. return carl9170_regwrite_result();
  114. }
  115. int carl9170_set_qos(struct ar9170 *ar)
  116. {
  117. carl9170_regwrite_begin(ar);
  118. carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
  119. (ar->edcf[0].cw_max << 16));
  120. carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
  121. (ar->edcf[1].cw_max << 16));
  122. carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
  123. (ar->edcf[2].cw_max << 16));
  124. carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
  125. (ar->edcf[3].cw_max << 16));
  126. carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
  127. (ar->edcf[4].cw_max << 16));
  128. carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS,
  129. ((ar->edcf[0].aifs * 9 + 10)) |
  130. ((ar->edcf[1].aifs * 9 + 10) << 12) |
  131. ((ar->edcf[2].aifs * 9 + 10) << 24));
  132. carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS,
  133. ((ar->edcf[2].aifs * 9 + 10) >> 8) |
  134. ((ar->edcf[3].aifs * 9 + 10) << 4) |
  135. ((ar->edcf[4].aifs * 9 + 10) << 16));
  136. carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
  137. ar->edcf[0].txop | ar->edcf[1].txop << 16);
  138. carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
  139. ar->edcf[2].txop | ar->edcf[3].txop << 16 |
  140. ar->edcf[4].txop << 24);
  141. carl9170_regwrite_finish();
  142. return carl9170_regwrite_result();
  143. }
  144. int carl9170_init_mac(struct ar9170 *ar)
  145. {
  146. carl9170_regwrite_begin(ar);
  147. /* switch MAC to OTUS interface */
  148. carl9170_regwrite(0x1c3600, 0x3);
  149. carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
  150. carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0);
  151. carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
  152. AR9170_MAC_FTF_MONITOR);
  153. /* enable MMIC */
  154. carl9170_regwrite(AR9170_MAC_REG_SNIFFER,
  155. AR9170_MAC_SNIFFER_DEFAULTS);
  156. carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
  157. carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
  158. carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
  159. carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
  160. /* CF-END & CF-ACK rate => 24M OFDM */
  161. carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000);
  162. /* NAV protects ACK only (in TXOP) */
  163. carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201);
  164. /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
  165. /* OTUS set AM to 0x1 */
  166. carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
  167. carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
  168. /* Aggregation MAX number and timeout */
  169. carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
  170. carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
  171. carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
  172. AR9170_MAC_FTF_DEFAULTS);
  173. carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL,
  174. AR9170_MAC_RX_CTRL_DEAGG |
  175. AR9170_MAC_RX_CTRL_SHORT_FILTER);
  176. /* rate sets */
  177. carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
  178. carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
  179. carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033);
  180. /* MIMO response control */
  181. carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e);
  182. carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
  183. /* set PHY register read timeout (??) */
  184. carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
  185. /* Disable Rx TimeOut, workaround for BB. */
  186. carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
  187. /* Set WLAN DMA interrupt mode: generate int per packet */
  188. carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
  189. carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
  190. AR9170_MAC_FCS_FIFO_PROT);
  191. /* Disables the CF_END frame, undocumented register */
  192. carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
  193. 0x141e0f48);
  194. /* reset group hash table */
  195. carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff);
  196. carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff);
  197. /* disable PRETBTT interrupt */
  198. carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0);
  199. carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0);
  200. carl9170_regwrite_finish();
  201. return carl9170_regwrite_result();
  202. }
  203. static int carl9170_set_mac_reg(struct ar9170 *ar,
  204. const u32 reg, const u8 *mac)
  205. {
  206. static const u8 zero[ETH_ALEN] = { 0 };
  207. if (!mac)
  208. mac = zero;
  209. carl9170_regwrite_begin(ar);
  210. carl9170_regwrite(reg, get_unaligned_le32(mac));
  211. carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
  212. carl9170_regwrite_finish();
  213. return carl9170_regwrite_result();
  214. }
  215. int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
  216. const u8 *mac)
  217. {
  218. if (WARN_ON(id >= ar->fw.vif_num))
  219. return -EINVAL;
  220. return carl9170_set_mac_reg(ar,
  221. AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
  222. }
  223. int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
  224. {
  225. int err;
  226. carl9170_regwrite_begin(ar);
  227. carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
  228. carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
  229. carl9170_regwrite_finish();
  230. err = carl9170_regwrite_result();
  231. if (err)
  232. return err;
  233. ar->cur_mc_hash = mc_hash;
  234. return 0;
  235. }
  236. int carl9170_set_operating_mode(struct ar9170 *ar)
  237. {
  238. struct ieee80211_vif *vif;
  239. struct ath_common *common = &ar->common;
  240. u8 *mac_addr, *bssid;
  241. u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
  242. u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS;
  243. u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
  244. AR9170_MAC_RX_CTRL_SHORT_FILTER;
  245. u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS;
  246. int err = 0;
  247. rcu_read_lock();
  248. vif = carl9170_get_main_vif(ar);
  249. if (vif) {
  250. mac_addr = common->macaddr;
  251. bssid = common->curbssid;
  252. switch (vif->type) {
  253. case NL80211_IFTYPE_MESH_POINT:
  254. case NL80211_IFTYPE_ADHOC:
  255. cam_mode |= AR9170_MAC_CAM_IBSS;
  256. break;
  257. case NL80211_IFTYPE_AP:
  258. cam_mode |= AR9170_MAC_CAM_AP;
  259. /* iwlagn 802.11n STA Workaround */
  260. rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
  261. break;
  262. case NL80211_IFTYPE_WDS:
  263. cam_mode |= AR9170_MAC_CAM_AP_WDS;
  264. rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
  265. break;
  266. case NL80211_IFTYPE_STATION:
  267. cam_mode |= AR9170_MAC_CAM_STA;
  268. rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
  269. break;
  270. default:
  271. WARN(1, "Unsupported operation mode %x\n", vif->type);
  272. err = -EOPNOTSUPP;
  273. break;
  274. }
  275. } else {
  276. mac_addr = NULL;
  277. bssid = NULL;
  278. }
  279. rcu_read_unlock();
  280. if (err)
  281. return err;
  282. if (ar->rx_software_decryption)
  283. enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
  284. if (ar->sniffer_enabled) {
  285. rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER;
  286. sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC;
  287. enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
  288. }
  289. err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
  290. if (err)
  291. return err;
  292. err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
  293. if (err)
  294. return err;
  295. carl9170_regwrite_begin(ar);
  296. carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
  297. carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode);
  298. carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode);
  299. carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl);
  300. carl9170_regwrite_finish();
  301. return carl9170_regwrite_result();
  302. }
  303. int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
  304. {
  305. u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
  306. return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
  307. }
  308. int carl9170_set_beacon_timers(struct ar9170 *ar)
  309. {
  310. struct ieee80211_vif *vif;
  311. u32 v = 0;
  312. u32 pretbtt = 0;
  313. rcu_read_lock();
  314. vif = carl9170_get_main_vif(ar);
  315. if (vif) {
  316. struct carl9170_vif_info *mvif;
  317. mvif = (void *) vif->drv_priv;
  318. if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
  319. ar->global_beacon_int = vif->bss_conf.beacon_int /
  320. ar->beacon_enabled;
  321. SET_VAL(AR9170_MAC_BCN_DTIM, v,
  322. vif->bss_conf.dtim_period);
  323. switch (vif->type) {
  324. case NL80211_IFTYPE_MESH_POINT:
  325. case NL80211_IFTYPE_ADHOC:
  326. v |= AR9170_MAC_BCN_IBSS_MODE;
  327. break;
  328. case NL80211_IFTYPE_AP:
  329. v |= AR9170_MAC_BCN_AP_MODE;
  330. break;
  331. default:
  332. WARN_ON_ONCE(1);
  333. break;
  334. }
  335. } else if (vif->type == NL80211_IFTYPE_STATION) {
  336. ar->global_beacon_int = vif->bss_conf.beacon_int;
  337. SET_VAL(AR9170_MAC_BCN_DTIM, v,
  338. ar->hw->conf.ps_dtim_period);
  339. v |= AR9170_MAC_BCN_STA_PS |
  340. AR9170_MAC_BCN_PWR_MGT;
  341. }
  342. if (ar->global_beacon_int) {
  343. if (ar->global_beacon_int < 15) {
  344. rcu_read_unlock();
  345. return -ERANGE;
  346. }
  347. ar->global_pretbtt = ar->global_beacon_int -
  348. CARL9170_PRETBTT_KUS;
  349. } else {
  350. ar->global_pretbtt = 0;
  351. }
  352. } else {
  353. ar->global_beacon_int = 0;
  354. ar->global_pretbtt = 0;
  355. }
  356. rcu_read_unlock();
  357. SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int);
  358. SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt);
  359. SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt);
  360. carl9170_regwrite_begin(ar);
  361. carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
  362. carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
  363. carl9170_regwrite_finish();
  364. return carl9170_regwrite_result();
  365. }
  366. int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
  367. {
  368. struct sk_buff *skb = NULL;
  369. struct carl9170_vif_info *cvif;
  370. struct ieee80211_tx_info *txinfo;
  371. __le32 *data, *old = NULL;
  372. u32 word, off, addr, len;
  373. int i = 0, err = 0;
  374. rcu_read_lock();
  375. cvif = rcu_dereference(ar->beacon_iter);
  376. retry:
  377. if (ar->vifs == 0 || !cvif)
  378. goto out_unlock;
  379. list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
  380. if (cvif->active && cvif->enable_beacon)
  381. goto found;
  382. }
  383. if (!ar->beacon_enabled || i++)
  384. goto out_unlock;
  385. goto retry;
  386. found:
  387. rcu_assign_pointer(ar->beacon_iter, cvif);
  388. skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
  389. NULL, NULL);
  390. if (!skb) {
  391. err = -ENOMEM;
  392. goto err_free;
  393. }
  394. txinfo = IEEE80211_SKB_CB(skb);
  395. if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
  396. err = -EINVAL;
  397. goto err_free;
  398. }
  399. spin_lock_bh(&ar->beacon_lock);
  400. data = (__le32 *)skb->data;
  401. if (cvif->beacon)
  402. old = (__le32 *)cvif->beacon->data;
  403. off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
  404. addr = ar->fw.beacon_addr + off;
  405. len = roundup(skb->len + FCS_LEN, 4);
  406. if ((off + len) > ar->fw.beacon_max_len) {
  407. if (net_ratelimit()) {
  408. wiphy_err(ar->hw->wiphy, "beacon does not "
  409. "fit into device memory!\n");
  410. }
  411. err = -EINVAL;
  412. goto err_unlock;
  413. }
  414. if (len > AR9170_MAC_BCN_LENGTH_MAX) {
  415. if (net_ratelimit()) {
  416. wiphy_err(ar->hw->wiphy, "no support for beacons "
  417. "bigger than %d (yours:%d).\n",
  418. AR9170_MAC_BCN_LENGTH_MAX, len);
  419. }
  420. err = -EMSGSIZE;
  421. goto err_unlock;
  422. }
  423. i = txinfo->control.rates[0].idx;
  424. if (txinfo->band != IEEE80211_BAND_2GHZ)
  425. i += 4;
  426. word = __carl9170_ratetable[i].hw_value & 0xf;
  427. if (i < 4)
  428. word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
  429. else
  430. word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
  431. carl9170_async_regwrite_begin(ar);
  432. carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
  433. for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
  434. /*
  435. * XXX: This accesses beyond skb data for up
  436. * to the last 3 bytes!!
  437. */
  438. if (old && (data[i] == old[i]))
  439. continue;
  440. word = le32_to_cpu(data[i]);
  441. carl9170_async_regwrite(addr + 4 * i, word);
  442. }
  443. carl9170_async_regwrite_finish();
  444. dev_kfree_skb_any(cvif->beacon);
  445. cvif->beacon = NULL;
  446. err = carl9170_async_regwrite_result();
  447. if (!err)
  448. cvif->beacon = skb;
  449. spin_unlock_bh(&ar->beacon_lock);
  450. if (err)
  451. goto err_free;
  452. if (submit) {
  453. err = carl9170_bcn_ctrl(ar, cvif->id,
  454. CARL9170_BCN_CTRL_CAB_TRIGGER,
  455. addr, skb->len + FCS_LEN);
  456. if (err)
  457. goto err_free;
  458. }
  459. out_unlock:
  460. rcu_read_unlock();
  461. return 0;
  462. err_unlock:
  463. spin_unlock_bh(&ar->beacon_lock);
  464. err_free:
  465. rcu_read_unlock();
  466. dev_kfree_skb_any(skb);
  467. return err;
  468. }
  469. int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
  470. const u8 ktype, const u8 keyidx, const u8 *keydata,
  471. const int keylen)
  472. {
  473. struct carl9170_set_key_cmd key = { };
  474. static const u8 bcast[ETH_ALEN] = {
  475. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  476. mac = mac ? : bcast;
  477. key.user = cpu_to_le16(id);
  478. key.keyId = cpu_to_le16(keyidx);
  479. key.type = cpu_to_le16(ktype);
  480. memcpy(&key.macAddr, mac, ETH_ALEN);
  481. if (keydata)
  482. memcpy(&key.key, keydata, keylen);
  483. return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY,
  484. sizeof(key), (u8 *)&key, 0, NULL);
  485. }
  486. int carl9170_disable_key(struct ar9170 *ar, const u8 id)
  487. {
  488. struct carl9170_disable_key_cmd key = { };
  489. key.user = cpu_to_le16(id);
  490. return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
  491. sizeof(key), (u8 *)&key, 0, NULL);
  492. }