]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/wireless/ath5k/pcu.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / ath5k / pcu.c
1 /*
2  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4  * Copyright (c) 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
5  * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
6  * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
7  * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  */
22
23 /*********************************\
24 * Protocol Control Unit Functions *
25 \*********************************/
26
27 #include "ath5k.h"
28 #include "reg.h"
29 #include "debug.h"
30 #include "base.h"
31
32 /*******************\
33 * Generic functions *
34 \*******************/
35
36 /**
37  * ath5k_hw_set_opmode - Set PCU operating mode
38  *
39  * @ah: The &struct ath5k_hw
40  *
41  * Initialize PCU for the various operating modes (AP/STA etc)
42  *
43  * NOTE: ah->ah_op_mode must be set before calling this.
44  */
45 int ath5k_hw_set_opmode(struct ath5k_hw *ah)
46 {
47         u32 pcu_reg, beacon_reg, low_id, high_id;
48
49         pcu_reg = 0;
50         beacon_reg = 0;
51
52         ATH5K_TRACE(ah->ah_sc);
53
54         switch (ah->ah_op_mode) {
55         case NL80211_IFTYPE_ADHOC:
56                 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
57                         (ah->ah_version == AR5K_AR5210 ?
58                                 AR5K_STA_ID1_NO_PSPOLL : 0);
59                 beacon_reg |= AR5K_BCR_ADHOC;
60                 break;
61
62         case NL80211_IFTYPE_AP:
63         case NL80211_IFTYPE_MESH_POINT:
64                 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
65                         (ah->ah_version == AR5K_AR5210 ?
66                                 AR5K_STA_ID1_NO_PSPOLL : 0);
67                 beacon_reg |= AR5K_BCR_AP;
68                 break;
69
70         case NL80211_IFTYPE_STATION:
71                 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
72                         (ah->ah_version == AR5K_AR5210 ?
73                                 AR5K_STA_ID1_PWR_SV : 0);
74         case NL80211_IFTYPE_MONITOR:
75                 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
76                         (ah->ah_version == AR5K_AR5210 ?
77                                 AR5K_STA_ID1_NO_PSPOLL : 0);
78                 break;
79
80         default:
81                 return -EINVAL;
82         }
83
84         /*
85          * Set PCU registers
86          */
87         low_id = AR5K_LOW_ID(ah->ah_sta_id);
88         high_id = AR5K_HIGH_ID(ah->ah_sta_id);
89         ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
90         ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
91
92         /*
93          * Set Beacon Control Register on 5210
94          */
95         if (ah->ah_version == AR5K_AR5210)
96                 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
97
98         return 0;
99 }
100
101 /**
102  * ath5k_hw_update - Update mib counters (mac layer statistics)
103  *
104  * @ah: The &struct ath5k_hw
105  * @stats: The &struct ieee80211_low_level_stats we use to track
106  * statistics on the driver
107  *
108  * Reads MIB counters from PCU and updates sw statistics. Must be
109  * called after a MIB interrupt.
110  */
111 void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
112                 struct ieee80211_low_level_stats  *stats)
113 {
114         ATH5K_TRACE(ah->ah_sc);
115
116         /* Read-And-Clear */
117         stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
118         stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
119         stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
120         stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
121
122         /* XXX: Should we use this to track beacon count ?
123          * -we read it anyway to clear the register */
124         ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
125
126         /* Reset profile count registers on 5212*/
127         if (ah->ah_version == AR5K_AR5212) {
128                 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
129                 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
130                 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
131                 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
132         }
133 }
134
135 /**
136  * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
137  *
138  * @ah: The &struct ath5k_hw
139  * @high: Flag to determine if we want to use high transmition rate
140  * for ACKs or not
141  *
142  * If high flag is set, we tell hw to use a set of control rates based on
143  * the current transmition rate (check out control_rates array inside reset.c).
144  * If not hw just uses the lowest rate available for the current modulation
145  * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
146  */
147 void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
148 {
149         if (ah->ah_version != AR5K_AR5212)
150                 return;
151         else {
152                 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
153                 if (high)
154                         AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
155                 else
156                         AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
157         }
158 }
159
160
161 /******************\
162 * ACK/CTS Timeouts *
163 \******************/
164
165 /**
166  * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
167  *
168  * @ah: The &struct ath5k_hw
169  */
170 unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
171 {
172         ATH5K_TRACE(ah->ah_sc);
173
174         return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
175                         AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
176 }
177
178 /**
179  * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
180  *
181  * @ah: The &struct ath5k_hw
182  * @timeout: Timeout in usec
183  */
184 int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
185 {
186         ATH5K_TRACE(ah->ah_sc);
187         if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
188                         ah->ah_turbo) <= timeout)
189                 return -EINVAL;
190
191         AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
192                 ath5k_hw_htoclock(timeout, ah->ah_turbo));
193
194         return 0;
195 }
196
197 /**
198  * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
199  *
200  * @ah: The &struct ath5k_hw
201  */
202 unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
203 {
204         ATH5K_TRACE(ah->ah_sc);
205         return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
206                         AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
207 }
208
209 /**
210  * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
211  *
212  * @ah: The &struct ath5k_hw
213  * @timeout: Timeout in usec
214  */
215 int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
216 {
217         ATH5K_TRACE(ah->ah_sc);
218         if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
219                         ah->ah_turbo) <= timeout)
220                 return -EINVAL;
221
222         AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
223                         ath5k_hw_htoclock(timeout, ah->ah_turbo));
224
225         return 0;
226 }
227
228
229 /****************\
230 * BSSID handling *
231 \****************/
232
233 /**
234  * ath5k_hw_get_lladdr - Get station id
235  *
236  * @ah: The &struct ath5k_hw
237  * @mac: The card's mac address
238  *
239  * Initialize ah->ah_sta_id using the mac address provided
240  * (just a memcpy).
241  *
242  * TODO: Remove it once we merge ath5k_softc and ath5k_hw
243  */
244 void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
245 {
246         ATH5K_TRACE(ah->ah_sc);
247         memcpy(mac, ah->ah_sta_id, ETH_ALEN);
248 }
249
250 /**
251  * ath5k_hw_set_lladdr - Set station id
252  *
253  * @ah: The &struct ath5k_hw
254  * @mac: The card's mac address
255  *
256  * Set station id on hw using the provided mac address
257  */
258 int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
259 {
260         u32 low_id, high_id;
261
262         ATH5K_TRACE(ah->ah_sc);
263         /* Set new station ID */
264         memcpy(ah->ah_sta_id, mac, ETH_ALEN);
265
266         low_id = AR5K_LOW_ID(mac);
267         high_id = AR5K_HIGH_ID(mac);
268
269         ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
270         ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1);
271
272         return 0;
273 }
274
275 /**
276  * ath5k_hw_set_associd - Set BSSID for association
277  *
278  * @ah: The &struct ath5k_hw
279  * @bssid: BSSID
280  * @assoc_id: Assoc id
281  *
282  * Sets the BSSID which trigers the "SME Join" operation
283  */
284 void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
285 {
286         u32 low_id, high_id;
287         u16 tim_offset = 0;
288
289         /*
290          * Set simple BSSID mask on 5212
291          */
292         if (ah->ah_version == AR5K_AR5212) {
293                 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
294                 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
295         }
296
297         /*
298          * Set BSSID which triggers the "SME Join" operation
299          */
300         low_id = AR5K_LOW_ID(bssid);
301         high_id = AR5K_HIGH_ID(bssid);
302         ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
303         ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
304                                 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
305
306         if (assoc_id == 0) {
307                 ath5k_hw_disable_pspoll(ah);
308                 return;
309         }
310
311         AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
312                         tim_offset ? tim_offset + 4 : 0);
313
314         ath5k_hw_enable_pspoll(ah, NULL, 0);
315 }
316
317 /**
318  * ath5k_hw_set_bssid_mask - filter out bssids we listen
319  *
320  * @ah: the &struct ath5k_hw
321  * @mask: the bssid_mask, a u8 array of size ETH_ALEN
322  *
323  * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
324  * which bits of the interface's MAC address should be looked at when trying
325  * to decide which packets to ACK. In station mode and AP mode with a single
326  * BSS every bit matters since we lock to only one BSS. In AP mode with
327  * multiple BSSes (virtual interfaces) not every bit matters because hw must
328  * accept frames for all BSSes and so we tweak some bits of our mac address
329  * in order to have multiple BSSes.
330  *
331  * NOTE: This is a simple filter and does *not* filter out all
332  * relevant frames. Some frames that are not for us might get ACKed from us
333  * by PCU because they just match the mask.
334  *
335  * When handling multiple BSSes you can get the BSSID mask by computing the
336  * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
337  *
338  * When you do this you are essentially computing the common bits of all your
339  * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
340  * the MAC address to obtain the relevant bits and compare the result with
341  * (frame's BSSID & mask) to see if they match.
342  */
343 /*
344  * Simple example: on your card you have have two BSSes you have created with
345  * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
346  * There is another BSSID-03 but you are not part of it. For simplicity's sake,
347  * assuming only 4 bits for a mac address and for BSSIDs you can then have:
348  *
349  *                  \
350  * MAC:                0001 |
351  * BSSID-01:   0100 | --> Belongs to us
352  * BSSID-02:   1001 |
353  *                  /
354  * -------------------
355  * BSSID-03:   0110  | --> External
356  * -------------------
357  *
358  * Our bssid_mask would then be:
359  *
360  *             On loop iteration for BSSID-01:
361  *             ~(0001 ^ 0100)  -> ~(0101)
362  *                             ->   1010
363  *             bssid_mask      =    1010
364  *
365  *             On loop iteration for BSSID-02:
366  *             bssid_mask &= ~(0001   ^   1001)
367  *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
368  *             bssid_mask =   (1010)  & ~(1001)
369  *             bssid_mask =   (1010)  &  (0110)
370  *             bssid_mask =   0010
371  *
372  * A bssid_mask of 0010 means "only pay attention to the second least
373  * significant bit". This is because its the only bit common
374  * amongst the MAC and all BSSIDs we support. To findout what the real
375  * common bit is we can simply "&" the bssid_mask now with any BSSID we have
376  * or our MAC address (we assume the hardware uses the MAC address).
377  *
378  * Now, suppose there's an incoming frame for BSSID-03:
379  *
380  * IFRAME-01:  0110
381  *
382  * An easy eye-inspeciton of this already should tell you that this frame
383  * will not pass our check. This is beacuse the bssid_mask tells the
384  * hardware to only look at the second least significant bit and the
385  * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
386  * as 1, which does not match 0.
387  *
388  * So with IFRAME-01 we *assume* the hardware will do:
389  *
390  *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
391  *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
392  *  --> allow = (0010) == 0000 ? 1 : 0;
393  *  --> allow = 0
394  *
395  *  Lets now test a frame that should work:
396  *
397  * IFRAME-02:  0001 (we should allow)
398  *
399  *     allow = (0001 & 1010) == 1010
400  *
401  *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
402  *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
403  *  --> allow = (0010) == (0010)
404  *  --> allow = 1
405  *
406  * Other examples:
407  *
408  * IFRAME-03:  0100 --> allowed
409  * IFRAME-04:  1001 --> allowed
410  * IFRAME-05:  1101 --> allowed but its not for us!!!
411  *
412  */
413 int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
414 {
415         u32 low_id, high_id;
416         ATH5K_TRACE(ah->ah_sc);
417
418         if (ah->ah_version == AR5K_AR5212) {
419                 low_id = AR5K_LOW_ID(mask);
420                 high_id = AR5K_HIGH_ID(mask);
421
422                 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
423                 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
424
425                 return 0;
426         }
427
428         return -EIO;
429 }
430
431
432 /************\
433 * RX Control *
434 \************/
435
436 /**
437  * ath5k_hw_start_rx_pcu - Start RX engine
438  *
439  * @ah: The &struct ath5k_hw
440  *
441  * Starts RX engine on PCU so that hw can process RXed frames
442  * (ACK etc).
443  *
444  * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
445  * TODO: Init ANI here
446  */
447 void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
448 {
449         ATH5K_TRACE(ah->ah_sc);
450         AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
451 }
452
453 /**
454  * at5k_hw_stop_rx_pcu - Stop RX engine
455  *
456  * @ah: The &struct ath5k_hw
457  *
458  * Stops RX engine on PCU
459  *
460  * TODO: Detach ANI here
461  */
462 void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
463 {
464         ATH5K_TRACE(ah->ah_sc);
465         AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
466 }
467
468 /*
469  * Set multicast filter
470  */
471 void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
472 {
473         ATH5K_TRACE(ah->ah_sc);
474         /* Set the multicat filter */
475         ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
476         ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
477 }
478
479 /*
480  * Set multicast filter by index
481  */
482 int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
483 {
484
485         ATH5K_TRACE(ah->ah_sc);
486         if (index >= 64)
487                 return -EINVAL;
488         else if (index >= 32)
489                 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
490                                 (1 << (index - 32)));
491         else
492                 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
493
494         return 0;
495 }
496
497 /*
498  * Clear Multicast filter by index
499  */
500 int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
501 {
502
503         ATH5K_TRACE(ah->ah_sc);
504         if (index >= 64)
505                 return -EINVAL;
506         else if (index >= 32)
507                 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
508                                 (1 << (index - 32)));
509         else
510                 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
511
512         return 0;
513 }
514
515 /**
516  * ath5k_hw_get_rx_filter - Get current rx filter
517  *
518  * @ah: The &struct ath5k_hw
519  *
520  * Returns the RX filter by reading rx filter and
521  * phy error filter registers. RX filter is used
522  * to set the allowed frame types that PCU will accept
523  * and pass to the driver. For a list of frame types
524  * check out reg.h.
525  */
526 u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
527 {
528         u32 data, filter = 0;
529
530         ATH5K_TRACE(ah->ah_sc);
531         filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
532
533         /*Radar detection for 5212*/
534         if (ah->ah_version == AR5K_AR5212) {
535                 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
536
537                 if (data & AR5K_PHY_ERR_FIL_RADAR)
538                         filter |= AR5K_RX_FILTER_RADARERR;
539                 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
540                         filter |= AR5K_RX_FILTER_PHYERR;
541         }
542
543         return filter;
544 }
545
546 /**
547  * ath5k_hw_set_rx_filter - Set rx filter
548  *
549  * @ah: The &struct ath5k_hw
550  * @filter: RX filter mask (see reg.h)
551  *
552  * Sets RX filter register and also handles PHY error filter
553  * register on 5212 and newer chips so that we have proper PHY
554  * error reporting.
555  */
556 void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
557 {
558         u32 data = 0;
559
560         ATH5K_TRACE(ah->ah_sc);
561
562         /* Set PHY error filter register on 5212*/
563         if (ah->ah_version == AR5K_AR5212) {
564                 if (filter & AR5K_RX_FILTER_RADARERR)
565                         data |= AR5K_PHY_ERR_FIL_RADAR;
566                 if (filter & AR5K_RX_FILTER_PHYERR)
567                         data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
568         }
569
570         /*
571          * The AR5210 uses promiscous mode to detect radar activity
572          */
573         if (ah->ah_version == AR5K_AR5210 &&
574                         (filter & AR5K_RX_FILTER_RADARERR)) {
575                 filter &= ~AR5K_RX_FILTER_RADARERR;
576                 filter |= AR5K_RX_FILTER_PROM;
577         }
578
579         /*Zero length DMA*/
580         if (data)
581                 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
582         else
583                 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
584
585         /*Write RX Filter register*/
586         ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
587
588         /*Write PHY error filter register on 5212*/
589         if (ah->ah_version == AR5K_AR5212)
590                 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
591
592 }
593
594
595 /****************\
596 * Beacon control *
597 \****************/
598
599 /**
600  * ath5k_hw_get_tsf32 - Get a 32bit TSF
601  *
602  * @ah: The &struct ath5k_hw
603  *
604  * Returns lower 32 bits of current TSF
605  */
606 u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
607 {
608         ATH5K_TRACE(ah->ah_sc);
609         return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
610 }
611
612 /**
613  * ath5k_hw_get_tsf64 - Get the full 64bit TSF
614  *
615  * @ah: The &struct ath5k_hw
616  *
617  * Returns the current TSF
618  */
619 u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
620 {
621         u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
622         ATH5K_TRACE(ah->ah_sc);
623
624         return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
625 }
626
627 /**
628  * ath5k_hw_reset_tsf - Force a TSF reset
629  *
630  * @ah: The &struct ath5k_hw
631  *
632  * Forces a TSF reset on PCU
633  */
634 void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
635 {
636         u32 val;
637
638         ATH5K_TRACE(ah->ah_sc);
639
640         val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
641
642         /*
643          * Each write to the RESET_TSF bit toggles a hardware internal
644          * signal to reset TSF, but if left high it will cause a TSF reset
645          * on the next chip reset as well.  Thus we always write the value
646          * twice to clear the signal.
647          */
648         ath5k_hw_reg_write(ah, val, AR5K_BEACON);
649         ath5k_hw_reg_write(ah, val, AR5K_BEACON);
650 }
651
652 /*
653  * Initialize beacon timers
654  */
655 void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
656 {
657         u32 timer1, timer2, timer3;
658
659         ATH5K_TRACE(ah->ah_sc);
660         /*
661          * Set the additional timers by mode
662          */
663         switch (ah->ah_op_mode) {
664         case NL80211_IFTYPE_STATION:
665                 if (ah->ah_version == AR5K_AR5210) {
666                         timer1 = 0xffffffff;
667                         timer2 = 0xffffffff;
668                 } else {
669                         timer1 = 0x0000ffff;
670                         timer2 = 0x0007ffff;
671                 }
672                 break;
673
674         default:
675                 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
676                 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
677         }
678
679         timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
680
681         /*
682          * Set the beacon register and enable all timers.
683          * (next beacon, DMA beacon, software beacon, ATIM window time)
684          */
685         ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
686         ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
687         ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
688         ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
689
690         ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
691                         AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
692                 AR5K_BEACON);
693 }
694
695 #if 0
696 /*
697  * Set beacon timers
698  */
699 int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
700                 const struct ath5k_beacon_state *state)
701 {
702         u32 cfp_period, next_cfp, dtim, interval, next_beacon;
703
704         /*
705          * TODO: should be changed through *state
706          * review struct ath5k_beacon_state struct
707          *
708          * XXX: These are used for cfp period bellow, are they
709          * ok ? Is it O.K. for tsf here to be 0 or should we use
710          * get_tsf ?
711          */
712         u32 dtim_count = 0; /* XXX */
713         u32 cfp_count = 0; /* XXX */
714         u32 tsf = 0; /* XXX */
715
716         ATH5K_TRACE(ah->ah_sc);
717         /* Return on an invalid beacon state */
718         if (state->bs_interval < 1)
719                 return -EINVAL;
720
721         interval = state->bs_interval;
722         dtim = state->bs_dtim_period;
723
724         /*
725          * PCF support?
726          */
727         if (state->bs_cfp_period > 0) {
728                 /*
729                  * Enable PCF mode and set the CFP
730                  * (Contention Free Period) and timer registers
731                  */
732                 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
733                         state->bs_interval;
734                 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
735                         state->bs_interval;
736
737                 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
738                                 AR5K_STA_ID1_DEFAULT_ANTENNA |
739                                 AR5K_STA_ID1_PCF);
740                 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
741                 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
742                                 AR5K_CFP_DUR);
743                 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
744                                                 next_cfp)) << 3, AR5K_TIMER2);
745         } else {
746                 /* Disable PCF mode */
747                 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
748                                 AR5K_STA_ID1_DEFAULT_ANTENNA |
749                                 AR5K_STA_ID1_PCF);
750         }
751
752         /*
753          * Enable the beacon timer register
754          */
755         ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
756
757         /*
758          * Start the beacon timers
759          */
760         ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
761                 ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
762                 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
763                 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
764                 AR5K_BEACON_PERIOD), AR5K_BEACON);
765
766         /*
767          * Write new beacon miss threshold, if it appears to be valid
768          * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
769          * and return if its not in range. We can test this by reading value and
770          * setting value to a largest value and seeing which values register.
771          */
772
773         AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
774                         state->bs_bmiss_threshold);
775
776         /*
777          * Set sleep control register
778          * XXX: Didn't find this in 5210 code but since this register
779          * exists also in ar5k's 5210 headers i leave it as common code.
780          */
781         AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
782                         (state->bs_sleep_duration - 3) << 3);
783
784         /*
785          * Set enhanced sleep registers on 5212
786          */
787         if (ah->ah_version == AR5K_AR5212) {
788                 if (state->bs_sleep_duration > state->bs_interval &&
789                                 roundup(state->bs_sleep_duration, interval) ==
790                                 state->bs_sleep_duration)
791                         interval = state->bs_sleep_duration;
792
793                 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
794                                 roundup(state->bs_sleep_duration, dtim) ==
795                                 state->bs_sleep_duration))
796                         dtim = state->bs_sleep_duration;
797
798                 if (interval > dtim)
799                         return -EINVAL;
800
801                 next_beacon = interval == dtim ? state->bs_next_dtim :
802                         state->bs_next_beacon;
803
804                 ath5k_hw_reg_write(ah,
805                         AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
806                         AR5K_SLEEP0_NEXT_DTIM) |
807                         AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
808                         AR5K_SLEEP0_ENH_SLEEP_EN |
809                         AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
810
811                 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
812                         AR5K_SLEEP1_NEXT_TIM) |
813                         AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
814
815                 ath5k_hw_reg_write(ah,
816                         AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
817                         AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
818         }
819
820         return 0;
821 }
822
823 /*
824  * Reset beacon timers
825  */
826 void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
827 {
828         ATH5K_TRACE(ah->ah_sc);
829         /*
830          * Disable beacon timer
831          */
832         ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
833
834         /*
835          * Disable some beacon register values
836          */
837         AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
838                         AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
839         ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
840 }
841
842 /*
843  * Wait for beacon queue to finish
844  */
845 int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
846 {
847         unsigned int i;
848         int ret;
849
850         ATH5K_TRACE(ah->ah_sc);
851
852         /* 5210 doesn't have QCU*/
853         if (ah->ah_version == AR5K_AR5210) {
854                 /*
855                  * Wait for beaconn queue to finish by checking
856                  * Control Register and Beacon Status Register.
857                  */
858                 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
859                         if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
860                                         ||
861                             !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
862                                 break;
863                         udelay(10);
864                 }
865
866                 /* Timeout... */
867                 if (i <= 0) {
868                         /*
869                          * Re-schedule the beacon queue
870                          */
871                         ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
872                         ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
873                                         AR5K_BCR);
874
875                         return -EIO;
876                 }
877                 ret = 0;
878         } else {
879         /*5211/5212*/
880                 ret = ath5k_hw_register_timeout(ah,
881                         AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
882                         AR5K_QCU_STS_FRMPENDCNT, 0, false);
883
884                 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
885                         return -EIO;
886         }
887
888         return ret;
889 }
890 #endif
891
892
893 /*********************\
894 * Key table functions *
895 \*********************/
896
897 /*
898  * Reset a key entry on the table
899  */
900 int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
901 {
902         unsigned int i;
903
904         ATH5K_TRACE(ah->ah_sc);
905         AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
906
907         for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
908                 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
909
910         /*
911          * Set NULL encryption on AR5212+
912          *
913          * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
914          *       AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
915          *
916          * Note2: Windows driver (ndiswrapper) sets this to
917          *        0x00000714 instead of 0x00000007
918          */
919         if (ah->ah_version > AR5K_AR5211)
920                 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
921                                 AR5K_KEYTABLE_TYPE(entry));
922
923         return 0;
924 }
925
926 /*
927  * Check if a table entry is valid
928  */
929 int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
930 {
931         ATH5K_TRACE(ah->ah_sc);
932         AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
933
934         /* Check the validation flag at the end of the entry */
935         return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
936                 AR5K_KEYTABLE_VALID;
937 }
938
939 /*
940  * Set a key entry on the table
941  */
942 int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
943                 const struct ieee80211_key_conf *key, const u8 *mac)
944 {
945         unsigned int i;
946         __le32 key_v[5] = {};
947         u32 keytype;
948
949         ATH5K_TRACE(ah->ah_sc);
950
951         /* key->keylen comes in from mac80211 in bytes */
952
953         if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
954                 return -EOPNOTSUPP;
955
956         switch (key->keylen) {
957         /* WEP 40-bit   = 40-bit  entered key + 24 bit IV = 64-bit */
958         case 40 / 8:
959                 memcpy(&key_v[0], key->key, 5);
960                 keytype = AR5K_KEYTABLE_TYPE_40;
961                 break;
962
963         /* WEP 104-bit  = 104-bit entered key + 24-bit IV = 128-bit */
964         case 104 / 8:
965                 memcpy(&key_v[0], &key->key[0], 6);
966                 memcpy(&key_v[2], &key->key[6], 6);
967                 memcpy(&key_v[4], &key->key[12], 1);
968                 keytype = AR5K_KEYTABLE_TYPE_104;
969                 break;
970         /* WEP 128-bit  = 128-bit entered key + 24 bit IV = 152-bit */
971         case 128 / 8:
972                 memcpy(&key_v[0], &key->key[0], 6);
973                 memcpy(&key_v[2], &key->key[6], 6);
974                 memcpy(&key_v[4], &key->key[12], 4);
975                 keytype = AR5K_KEYTABLE_TYPE_128;
976                 break;
977
978         default:
979                 return -EINVAL; /* shouldn't happen */
980         }
981
982         for (i = 0; i < ARRAY_SIZE(key_v); i++)
983                 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
984                                 AR5K_KEYTABLE_OFF(entry, i));
985
986         ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
987
988         return ath5k_hw_set_key_lladdr(ah, entry, mac);
989 }
990
991 int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
992 {
993         u32 low_id, high_id;
994
995         ATH5K_TRACE(ah->ah_sc);
996          /* Invalid entry (key table overflow) */
997         AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
998
999         /* MAC may be NULL if it's a broadcast key. In this case no need to
1000          * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
1001         if (unlikely(mac == NULL)) {
1002                 low_id = 0xffffffff;
1003                 high_id = 0xffff | AR5K_KEYTABLE_VALID;
1004         } else {
1005                 low_id = AR5K_LOW_ID(mac);
1006                 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
1007         }
1008
1009         ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
1010         ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
1011
1012         return 0;
1013 }
1014