Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mac.c
Go to the documentation of this file.
1 /*
2  * Atheros CARL9170 driver
3  *
4  * MAC programming
5  *
6  * Copyright 2008, Johannes Berg <[email protected]>
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 
39 #include <asm/unaligned.h>
40 
41 #include "carl9170.h"
42 #include "cmd.h"
43 
45 {
46  u32 val;
47 
48  if (conf_is_ht40(&ar->hw->conf))
49  val = 0x010a;
50  else {
51  if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
52  val = 0x105;
53  else
54  val = 0x104;
55  }
56 
58 }
59 
61 {
62  u32 rts_rate, cts_rate;
63 
64  if (conf_is_ht(&ar->hw->conf)) {
65  /* 12 mbit OFDM */
66  rts_rate = 0x1da;
67  cts_rate = 0x10a;
68  } else {
69  if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
70  /* 11 mbit CCK */
71  rts_rate = 033;
72  cts_rate = 003;
73  } else {
74  /* 6 mbit OFDM */
75  rts_rate = 0x1bb;
76  cts_rate = 0x10b;
77  }
78  }
79 
81  rts_rate | (cts_rate) << 16);
82 }
83 
85 {
86  struct ieee80211_vif *vif;
87  u32 slottime = 20;
88 
89  rcu_read_lock();
90  vif = carl9170_get_main_vif(ar);
91  if (!vif) {
92  rcu_read_unlock();
93  return 0;
94  }
95 
96  if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
97  vif->bss_conf.use_short_slot)
98  slottime = 9;
99 
100  rcu_read_unlock();
101 
103  slottime << 10);
104 }
105 
107 {
108  struct ieee80211_vif *vif;
109  u32 basic, mandatory;
110 
111  rcu_read_lock();
112  vif = carl9170_get_main_vif(ar);
113 
114  if (!vif) {
115  rcu_read_unlock();
116  return 0;
117  }
118 
119  basic = (vif->bss_conf.basic_rates & 0xf);
120  basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
121  rcu_read_unlock();
122 
123  if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
124  mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
125  else
126  mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
127 
132 
133  return carl9170_regwrite_result();
134 }
135 
137 {
139 
141  (ar->edcf[0].cw_max << 16));
143  (ar->edcf[1].cw_max << 16));
145  (ar->edcf[2].cw_max << 16));
147  (ar->edcf[3].cw_max << 16));
149  (ar->edcf[4].cw_max << 16));
150 
152  ((ar->edcf[0].aifs * 9 + 10)) |
153  ((ar->edcf[1].aifs * 9 + 10) << 12) |
154  ((ar->edcf[2].aifs * 9 + 10) << 24));
156  ((ar->edcf[2].aifs * 9 + 10) >> 8) |
157  ((ar->edcf[3].aifs * 9 + 10) << 4) |
158  ((ar->edcf[4].aifs * 9 + 10) << 16));
159 
161  ar->edcf[0].txop | ar->edcf[1].txop << 16);
163  ar->edcf[2].txop | ar->edcf[3].txop << 16 |
164  ar->edcf[4].txop << 24);
165 
167 
168  return carl9170_regwrite_result();
169 }
170 
172 {
174 
175  /* switch MAC to OTUS interface */
176  carl9170_regwrite(0x1c3600, 0x3);
177 
179 
181 
184 
185  /* enable MMIC */
188 
190 
194 
195  /* CF-END & CF-ACK rate => 24M OFDM */
197 
198  /* NAV protects ACK only (in TXOP) */
200 
201  /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
202  /* OTUS set AM to 0x1 */
204 
206 
207  /* Aggregation MAX number and timeout */
210 
213 
217 
218  /* rate sets */
222 
223  /* MIMO response control */
225 
227 
228  /* set PHY register read timeout (??) */
230 
231  /* Disable Rx TimeOut, workaround for BB. */
233 
234  /* Set WLAN DMA interrupt mode: generate int per packet */
236 
239 
240  /* Disables the CF_END frame, undocumented register */
242  0x141e0f48);
243 
244  /* reset group hash table */
247 
248  /* disable PRETBTT interrupt */
251 
253 
254  return carl9170_regwrite_result();
255 }
256 
257 static int carl9170_set_mac_reg(struct ar9170 *ar,
258  const u32 reg, const u8 *mac)
259 {
260  static const u8 zero[ETH_ALEN] = { 0 };
261 
262  if (!mac)
263  mac = zero;
264 
266 
268  carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
269 
271 
272  return carl9170_regwrite_result();
273 }
274 
275 int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
276  const u8 *mac)
277 {
278  if (WARN_ON(id >= ar->fw.vif_num))
279  return -EINVAL;
280 
281  return carl9170_set_mac_reg(ar,
282  AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
283 }
284 
285 int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
286 {
287  int err;
288 
293  err = carl9170_regwrite_result();
294  if (err)
295  return err;
296 
297  ar->cur_mc_hash = mc_hash;
298  return 0;
299 }
300 
302 {
303  struct ieee80211_vif *vif;
304  struct ath_common *common = &ar->common;
305  u8 *mac_addr, *bssid;
306  u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
309  u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
312  int err = 0;
313 
314  rcu_read_lock();
315  vif = carl9170_get_main_vif(ar);
316 
317  if (vif) {
318  mac_addr = common->macaddr;
319  bssid = common->curbssid;
320 
321  switch (vif->type) {
323  cam_mode |= AR9170_MAC_CAM_IBSS;
324  break;
326  case NL80211_IFTYPE_AP:
327  cam_mode |= AR9170_MAC_CAM_AP;
328 
329  /* iwlagn 802.11n STA Workaround */
331  break;
332  case NL80211_IFTYPE_WDS:
333  cam_mode |= AR9170_MAC_CAM_AP_WDS;
335  break;
337  cam_mode |= AR9170_MAC_CAM_STA;
339  break;
340  default:
341  WARN(1, "Unsupported operation mode %x\n", vif->type);
342  err = -EOPNOTSUPP;
343  break;
344  }
345  } else {
346  mac_addr = NULL;
347  bssid = NULL;
348  }
349  rcu_read_unlock();
350 
351  if (err)
352  return err;
353 
354  if (ar->rx_software_decryption)
356 
357  if (ar->sniffer_enabled) {
361  }
362 
363  err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
364  if (err)
365  return err;
366 
367  err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
368  if (err)
369  return err;
370 
377 
378  return carl9170_regwrite_result();
379 }
380 
381 int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
382 {
383  u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
384 
386 }
387 
389 {
390  struct ieee80211_vif *vif;
391  u32 v = 0;
392  u32 pretbtt = 0;
393 
394  rcu_read_lock();
395  vif = carl9170_get_main_vif(ar);
396 
397  if (vif) {
398  struct carl9170_vif_info *mvif;
399  mvif = (void *) vif->drv_priv;
400 
401  if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
402  ar->global_beacon_int = vif->bss_conf.beacon_int /
403  ar->beacon_enabled;
404 
406  vif->bss_conf.dtim_period);
407 
408  switch (vif->type) {
412  break;
413  case NL80211_IFTYPE_AP:
415  break;
416  default:
417  WARN_ON_ONCE(1);
418  break;
419  }
420  } else if (vif->type == NL80211_IFTYPE_STATION) {
421  ar->global_beacon_int = vif->bss_conf.beacon_int;
422 
424  ar->hw->conf.ps_dtim_period);
425 
426  v |= AR9170_MAC_BCN_STA_PS |
428  }
429 
430  if (ar->global_beacon_int) {
431  if (ar->global_beacon_int < 15) {
432  rcu_read_unlock();
433  return -ERANGE;
434  }
435 
438  } else {
439  ar->global_pretbtt = 0;
440  }
441  } else {
442  ar->global_beacon_int = 0;
443  ar->global_pretbtt = 0;
444  }
445 
446  rcu_read_unlock();
447 
451 
456  return carl9170_regwrite_result();
457 }
458 
459 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
460  const u8 ktype, const u8 keyidx, const u8 *keydata,
461  const int keylen)
462 {
463  struct carl9170_set_key_cmd key = { };
464  static const u8 bcast[ETH_ALEN] = {
465  0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
466 
467  mac = mac ? : bcast;
468 
469  key.user = cpu_to_le16(id);
470  key.keyId = cpu_to_le16(keyidx);
471  key.type = cpu_to_le16(ktype);
472  memcpy(&key.macAddr, mac, ETH_ALEN);
473  if (keydata)
474  memcpy(&key.key, keydata, keylen);
475 
477  sizeof(key), (u8 *)&key, 0, NULL);
478 }
479 
480 int carl9170_disable_key(struct ar9170 *ar, const u8 id)
481 {
482  struct carl9170_disable_key_cmd key = { };
483 
484  key.user = cpu_to_le16(id);
485 
487  sizeof(key), (u8 *)&key, 0, NULL);
488 }
489 
491 {
492  unsigned int power, chains;
493 
494  if (ar->eeprom.tx_mask != 1)
495  chains = AR9170_TX_PHY_TXCHAIN_2;
496  else
497  chains = AR9170_TX_PHY_TXCHAIN_1;
498 
499  switch (channel->band) {
500  case IEEE80211_BAND_2GHZ:
501  power = ar->power_2G_ofdm[0] & 0x3f;
502  break;
503  case IEEE80211_BAND_5GHZ:
504  power = ar->power_5G_leg[0] & 0x3f;
505  break;
506  default:
507  BUG_ON(1);
508  }
509 
510  power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
511 
514  0x3c1e | power << 20 | chains << 26);
516  power << 5 | chains << 11 |
517  power << 21 | chains << 27);
519  power << 5 | chains << 11 |
520  power << 21 | chains << 27);
522  return carl9170_regwrite_result();
523 }