]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
MFS r365608:
[FreeBSD/FreeBSD.git] / sys / contrib / dev / ath / ath_hal / ar9300 / ar9300_freebsd.c
1 /*
2  * Copyright (c) 2012, 2013 Adrian Chadd <adrian@FreeBSD.org>.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include "opt_ah.h"
18
19 #include "ah.h"
20 #include "ah_internal.h"
21 #include "ah_devid.h"
22 #include "ah_desc.h"
23
24 #include "ar9300.h"
25 #include "ar9300reg.h"
26 #include "ar9300phy.h"
27 #include "ar9300desc.h"
28
29 #include "ar9300_freebsd.h"
30
31 #include "ar9300_stub.h"
32 #include "ar9300_stub_funcs.h"
33
34 #define FIX_NOISE_FLOOR     1
35 #define NEXT_TBTT_NOW      5 
36 static HAL_BOOL ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix);
37 static HAL_BOOL ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix);
38
39 static void ar9300_beacon_set_beacon_timers(struct ath_hal *ah,
40     const HAL_BEACON_TIMERS *bt);
41
42 static void
43 ar9300SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask,
44     uint32_t rx_chainmask)
45 {
46
47         AH9300(ah)->ah_tx_chainmask =
48             tx_chainmask & AH_PRIVATE(ah)->ah_caps.halTxChainMask;
49         AH9300(ah)->ah_rx_chainmask =
50             rx_chainmask & AH_PRIVATE(ah)->ah_caps.halRxChainMask;
51 }
52
53 static u_int
54 ar9300GetSlotTime(struct ath_hal *ah)
55 {
56         u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
57         return (ath_hal_mac_usec(ah, clks));    /* convert from system clocks */
58 }
59
60 static HAL_BOOL
61 ar9300_freebsd_set_tx_power_limit(struct ath_hal *ah, uint32_t limit)
62 {
63         return (ar9300_set_tx_power_limit(ah, limit, 0, 0));
64 }
65
66 static uint64_t
67 ar9300_get_next_tbtt(struct ath_hal *ah)
68 {
69         return (OS_REG_READ(ah, AR_NEXT_TBTT_TIMER));
70 }
71
72
73 /*
74  * TODO: implement the antenna diversity control for AR9485 and
75  * other LNA mixing based NICs.
76  *
77  * For now we'll just go with the HAL default and make these no-ops.
78  */
79 static HAL_ANT_SETTING
80 ar9300_freebsd_get_antenna_switch(struct ath_hal *ah)
81 {
82
83         return (HAL_ANT_VARIABLE);
84 }
85
86 static HAL_BOOL
87 ar9300_freebsd_set_antenna_switch(struct ath_hal *ah, HAL_ANT_SETTING setting)
88 {
89
90         return (AH_TRUE);
91 }
92
93 static u_int
94 ar9300_freebsd_get_cts_timeout(struct ath_hal *ah)
95 {
96     u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
97     return ath_hal_mac_usec(ah, clks);      /* convert from system clocks */
98 }
99
100 static void
101 ar9300_freebsd_set_tsf64(struct ath_hal *ah, uint64_t tsf64)
102 {
103
104         /*
105          * XXX TODO: read ar5416SetTsf64() - we should wait before we do
106          * this.
107          */
108         OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
109         OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
110 }
111
112 /* Flags for pulse_bw_info */
113 #define PRI_CH_RADAR_FOUND              0x01
114 #define EXT_CH_RADAR_FOUND              0x02
115 #define EXT_CH_RADAR_EARLY_FOUND        0x04
116
117 static HAL_BOOL
118 ar9300_freebsd_proc_radar_event(struct ath_hal *ah, struct ath_rx_status *rxs,
119     uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
120 {
121         HAL_BOOL doDfsExtCh;
122         HAL_BOOL doDfsEnhanced;
123         HAL_BOOL doDfsCombinedRssi;
124
125         uint8_t rssi = 0, ext_rssi = 0;
126         uint8_t pulse_bw_info = 0, pulse_length_ext = 0, pulse_length_pri = 0;
127         uint32_t dur = 0;
128         int pri_found = 1, ext_found = 0;
129         int early_ext = 0;
130         int is_dc = 0;
131         uint16_t datalen;               /* length from the RX status field */
132
133         /* Check whether the given phy error is a radar event */
134         if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
135             (rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT)) {
136                 return AH_FALSE;
137         }
138
139         /* Grab copies of the capabilities; just to make the code clearer */
140         doDfsExtCh = AH_PRIVATE(ah)->ah_caps.halExtChanDfsSupport;
141         doDfsEnhanced = AH_PRIVATE(ah)->ah_caps.halEnhancedDfsSupport;
142         doDfsCombinedRssi = AH_PRIVATE(ah)->ah_caps.halUseCombinedRadarRssi;
143
144         datalen = rxs->rs_datalen;
145
146         /* If hardware supports it, use combined RSSI, else use chain 0 RSSI */
147         if (doDfsCombinedRssi)
148                 rssi = (uint8_t) rxs->rs_rssi;
149         else            
150                 rssi = (uint8_t) rxs->rs_rssi_ctl[0];
151
152         /* Set this; but only use it if doDfsExtCh is set */
153         ext_rssi = (uint8_t) rxs->rs_rssi_ext[0];
154
155         /* Cap it at 0 if the RSSI is a negative number */
156         if (rssi & 0x80)
157                 rssi = 0;
158
159         if (ext_rssi & 0x80)
160                 ext_rssi = 0;
161
162         /*
163          * Fetch the relevant data from the frame
164          */
165         if (doDfsExtCh) {
166                 if (datalen < 3)
167                         return AH_FALSE;
168
169                 /* Last three bytes of the frame are of interest */
170                 pulse_length_pri = *(buf + datalen - 3);
171                 pulse_length_ext = *(buf + datalen - 2);
172                 pulse_bw_info = *(buf + datalen - 1);
173                 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, ext_rssi=%d, pulse_length_pri=%d,"
174                     " pulse_length_ext=%d, pulse_bw_info=%x\n",
175                     __func__, rssi, ext_rssi, pulse_length_pri, pulse_length_ext,
176                     pulse_bw_info);
177         } else {
178                 /* The pulse width is byte 0 of the data */
179                 if (datalen >= 1)
180                         dur = ((uint8_t) buf[0]) & 0xff;
181                 else
182                         dur = 0;
183
184                 if (dur == 0 && rssi == 0) {
185                         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: dur and rssi are 0\n", __func__);
186                         return AH_FALSE;
187                 }
188
189                 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n", __func__, rssi, dur);
190
191                 /* Single-channel only */
192                 pri_found = 1;
193                 ext_found = 0;
194         }
195
196         /*
197          * If doing extended channel data, pulse_bw_info must
198          * have one of the flags set.
199          */
200         if (doDfsExtCh && pulse_bw_info == 0x0)
201                 return AH_FALSE;
202                 
203         /*
204          * If the extended channel data is available, calculate
205          * which to pay attention to.
206          */
207         if (doDfsExtCh) {
208                 /* If pulse is on DC, take the larger duration of the two */
209                 if ((pulse_bw_info & EXT_CH_RADAR_FOUND) &&
210                     (pulse_bw_info & PRI_CH_RADAR_FOUND)) {
211                         is_dc = 1;
212                         if (pulse_length_ext > pulse_length_pri) {
213                                 dur = pulse_length_ext;
214                                 pri_found = 0;
215                                 ext_found = 1;
216                         } else {
217                                 dur = pulse_length_pri;
218                                 pri_found = 1;
219                                 ext_found = 0;
220                         }
221                 } else if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) {
222                         dur = pulse_length_ext;
223                         pri_found = 0;
224                         ext_found = 1;
225                         early_ext = 1;
226                 } else if (pulse_bw_info & PRI_CH_RADAR_FOUND) {
227                         dur = pulse_length_pri;
228                         pri_found = 1;
229                         ext_found = 0;
230                 } else if (pulse_bw_info & EXT_CH_RADAR_FOUND) {
231                         dur = pulse_length_ext;
232                         pri_found = 0;
233                         ext_found = 1;
234                 }
235                 
236         }
237
238         /*
239          * For enhanced DFS (Merlin and later), pulse_bw_info has
240          * implications for selecting the correct RSSI value.
241          */
242         if (doDfsEnhanced) {
243                 switch (pulse_bw_info & 0x03) {
244                 case 0:
245                         /* No radar? */
246                         rssi = 0;
247                         break;
248                 case PRI_CH_RADAR_FOUND:
249                         /* Radar in primary channel */
250                         /* Cannot use ctrl channel RSSI if ext channel is stronger */
251                         if (ext_rssi >= (rssi + 3)) {
252                                 rssi = 0;
253                         }
254                         break;
255                 case EXT_CH_RADAR_FOUND:
256                         /* Radar in extended channel */
257                         /* Cannot use ext channel RSSI if ctrl channel is stronger */
258                         if (rssi >= (ext_rssi + 12)) {
259                                 rssi = 0;
260                         } else {
261                                 rssi = ext_rssi;
262                         }
263                         break;
264                 case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND):
265                         /* When both are present, use stronger one */
266                         if (rssi < ext_rssi)
267                                 rssi = ext_rssi;
268                         break;
269                 }
270         }
271
272         /*
273          * If not doing enhanced DFS, choose the ext channel if
274          * it is stronger than the main channel
275          */
276         if (doDfsExtCh && !doDfsEnhanced) {
277                 if ((ext_rssi > rssi) && (ext_rssi < 128))
278                         rssi = ext_rssi;
279         }
280
281         /*
282          * XXX what happens if the above code decides the RSSI
283          * XXX wasn't valid, an sets it to 0?
284          */
285
286         /*
287          * Fill out dfs_event structure.
288          */
289         event->re_full_ts = fulltsf;
290         event->re_ts = rxs->rs_tstamp;
291         event->re_rssi = rssi;
292         event->re_dur = dur;
293
294         event->re_flags = 0;
295         if (pri_found)
296                 event->re_flags |= HAL_DFS_EVENT_PRICH;
297         if (ext_found)
298                 event->re_flags |= HAL_DFS_EVENT_EXTCH;
299         if (early_ext)
300                 event->re_flags |= HAL_DFS_EVENT_EXTEARLY;
301         if (is_dc)
302                 event->re_flags |= HAL_DFS_EVENT_ISDC;
303
304         return AH_TRUE;
305 }
306
307 void
308 ar9300_attach_freebsd_ops(struct ath_hal *ah)
309 {
310
311         /* Global functions */
312         ah->ah_detach           = ar9300_detach;
313         ah->ah_getRateTable             = ar9300_get_rate_table;
314
315         /* Reset functions */
316         ah->ah_reset            = ar9300_reset_freebsd;
317         ah->ah_phyDisable               = ar9300_phy_disable;
318         ah->ah_disable          = ar9300_disable;
319         ah->ah_configPCIE               = ar9300_config_pcie_freebsd;
320 //      ah->ah_disablePCIE              = ar9300_disable_pcie_phy;
321         ah->ah_setPCUConfig             = ar9300_set_pcu_config;
322         // perCalibration
323         ah->ah_perCalibrationN  = ar9300_per_calibration_freebsd;
324         ah->ah_resetCalValid    = ar9300_reset_cal_valid_freebsd;
325         ah->ah_setTxPowerLimit  = ar9300_freebsd_set_tx_power_limit;
326         ah->ah_getChanNoise             = ath_hal_getChanNoise;
327
328         /* Transmit functions */
329         ah->ah_setupTxQueue             = ar9300_setup_tx_queue;
330         ah->ah_setTxQueueProps  = ar9300_set_tx_queue_props;
331         ah->ah_getTxQueueProps  = ar9300_get_tx_queue_props;
332         ah->ah_releaseTxQueue   = ar9300_release_tx_queue;
333         ah->ah_resetTxQueue             = ar9300_reset_tx_queue;
334         ah->ah_getTxDP          = ar9300_get_tx_dp;
335         ah->ah_setTxDP          = ar9300_set_tx_dp;
336         ah->ah_numTxPending             = ar9300_num_tx_pending;
337         ah->ah_startTxDma               = ar9300_start_tx_dma;
338         ah->ah_stopTxDma                = ar9300_stop_tx_dma_freebsd;
339         ah->ah_setupTxDesc              = ar9300_freebsd_setup_tx_desc;
340         ah->ah_setupXTxDesc             = ar9300_freebsd_setup_x_tx_desc;
341         ah->ah_fillTxDesc               = ar9300_freebsd_fill_tx_desc;
342         ah->ah_procTxDesc               = ar9300_freebsd_proc_tx_desc;
343         ah->ah_getTxIntrQueue   = ar9300_get_tx_intr_queue;
344         // reqTxIntrDesc
345         ah->ah_getTxCompletionRates     = ar9300_freebsd_get_tx_completion_rates;
346         ah->ah_setTxDescLink    = ar9300_set_desc_link;
347         ah->ah_getTxDescLink    = ar9300_freebsd_get_desc_link;
348         ah->ah_getTxDescLinkPtr = ar9300_get_desc_link_ptr;
349         ah->ah_setupTxStatusRing        = ar9300_setup_tx_status_ring;
350         ah->ah_getTxRawTxDesc    = ar9300_get_raw_tx_desc;
351         ah->ah_updateTxTrigLevel        = ar9300_update_tx_trig_level;
352
353         /* RX functions */
354         ah->ah_getRxDP          = ar9300_get_rx_dp;
355         ah->ah_setRxDP          = ar9300_set_rx_dp;
356         ah->ah_enableReceive    = ar9300_enable_receive;
357         ah->ah_stopDmaReceive   = ar9300_stop_dma_receive_freebsd;
358         ah->ah_startPcuReceive  = ar9300_start_pcu_receive;
359         ah->ah_stopPcuReceive   = ar9300_stop_pcu_receive;
360         ah->ah_setMulticastFilter       = ar9300_set_multicast_filter;
361         ah->ah_setMulticastFilterIndex = ar9300SetMulticastFilterIndex;
362         ah->ah_clrMulticastFilterIndex = ar9300ClrMulticastFilterIndex;
363         ah->ah_getRxFilter              = ar9300_get_rx_filter;
364         ah->ah_setRxFilter              = ar9300_set_rx_filter;
365         /* setupRxDesc */
366         ah->ah_procRxDesc               = ar9300_proc_rx_desc_freebsd;
367         ah->ah_rxMonitor                = ar9300_ani_rxmonitor_freebsd;
368         ah->ah_aniPoll          = ar9300_ani_poll_freebsd;
369         ah->ah_procMibEvent             = ar9300_process_mib_intr;
370
371         /* Misc functions */
372         ah->ah_getCapability    = ar9300_get_capability;
373         ah->ah_setCapability    = ar9300_set_capability;
374         ah->ah_getDiagState             = ar9300_get_diag_state;
375         ah->ah_getMacAddress    = ar9300_get_mac_address;
376         ah->ah_setMacAddress    = ar9300_set_mac_address;
377         ah->ah_getBssIdMask             = ar9300_get_bss_id_mask;
378         ah->ah_setBssIdMask             = ar9300_set_bss_id_mask;
379         ah->ah_setRegulatoryDomain      = ar9300_set_regulatory_domain;
380         ah->ah_setLedState              = ar9300_set_led_state;
381         ah->ah_writeAssocid             = ar9300_write_associd;
382         ah->ah_gpioCfgInput             = ar9300_gpio_cfg_input;
383         ah->ah_gpioCfgOutput    = ar9300_gpio_cfg_output;
384         ah->ah_gpioGet          = ar9300_gpio_get;
385         ah->ah_gpioSet          = ar9300_gpio_set;
386         ah->ah_gpioSetIntr              = ar9300_gpio_set_intr;
387         /* polarity */
388         /* mask */
389         ah->ah_getTsf32         = ar9300_get_tsf32;
390         ah->ah_getTsf64         = ar9300_get_tsf64;
391         ah->ah_resetTsf         = ar9300_reset_tsf;
392         ah->ah_setTsf64         = ar9300_freebsd_set_tsf64;
393         ah->ah_detectCardPresent        = ar9300_detect_card_present;
394         // ah->ah_updateMibCounters     = ar9300_update_mib_counters;
395         ah->ah_getRfGain                = ar9300_get_rfgain;
396         ah->ah_getDefAntenna    = ar9300_get_def_antenna;
397         ah->ah_setDefAntenna    = ar9300_set_def_antenna;
398         ah->ah_getAntennaSwitch = ar9300_freebsd_get_antenna_switch;
399         ah->ah_setAntennaSwitch = ar9300_freebsd_set_antenna_switch;
400         // ah->ah_setSifsTime           = ar9300_set_sifs_time;
401         // ah->ah_getSifsTime           = ar9300_get_sifs_time;
402         ah->ah_setSlotTime              = ar9300_set_slot_time;
403         ah->ah_getSlotTime              = ar9300GetSlotTime;
404         ah->ah_getAckTimeout    = ar9300_get_ack_timeout;
405         ah->ah_setAckTimeout    = ar9300_set_ack_timeout;
406         // XXX ack/ctsrate
407         // XXX CTS timeout
408         ah->ah_getCTSTimeout = ar9300_freebsd_get_cts_timeout;
409         // XXX decompmask
410         // coverageclass
411         ah->ah_setQuiet         = ar9300_set_quiet;
412         ah->ah_getMibCycleCounts        = ar9300_freebsd_get_mib_cycle_counts;
413
414         /* DFS functions */
415         ah->ah_enableDfs                = ar9300_enable_dfs;
416         ah->ah_getDfsThresh             = ar9300_get_dfs_thresh;
417         ah->ah_getDfsDefaultThresh      = ar9300_get_default_dfs_thresh;
418         ah->ah_procRadarEvent           = ar9300_freebsd_proc_radar_event;
419         ah->ah_isFastClockEnabled       = ar9300_is_fast_clock_enabled;
420         ah->ah_get11nExtBusy            = ar9300_get_11n_ext_busy;
421         ah->ah_setDfsCacTxQuiet         = ar9300_cac_tx_quiet;
422
423         /* Spectral Scan Functions */
424         ah->ah_spectralConfigure        = ar9300_configure_spectral_scan;
425         ah->ah_spectralGetConfig        = ar9300_get_spectral_params;
426         ah->ah_spectralStart            = ar9300_start_spectral_scan;
427         ah->ah_spectralStop             = ar9300_stop_spectral_scan;
428         ah->ah_spectralIsEnabled        = ar9300_is_spectral_enabled;
429         ah->ah_spectralIsActive         = ar9300_is_spectral_active;
430
431         /* Key cache functions */
432         ah->ah_getKeyCacheSize  = ar9300_get_key_cache_size;
433         ah->ah_resetKeyCacheEntry       = ar9300_reset_key_cache_entry;
434         ah->ah_isKeyCacheEntryValid     = ar9300_is_key_cache_entry_valid;
435         ah->ah_setKeyCacheEntry = ar9300_set_key_cache_entry;
436         ah->ah_setKeyCacheEntryMac      = ar9300_set_key_cache_entry_mac;
437
438         /* Power management functions */
439         ah->ah_setPowerMode             = ar9300_set_power_mode;
440         ah->ah_getPowerMode             = ar9300_get_power_mode;
441
442         /* Beacon functions */
443         /* ah_setBeaconTimers */
444         ah->ah_beaconInit               = ar9300_freebsd_beacon_init;
445         ah->ah_setBeaconTimers          = ar9300_beacon_set_beacon_timers;
446         ah->ah_setStationBeaconTimers = ar9300_set_sta_beacon_timers;
447         /* ah_resetStationBeaconTimers */
448         ah->ah_getNextTBTT = ar9300_get_next_tbtt;
449
450         /* Interrupt functions */
451         ah->ah_isInterruptPending       = ar9300_is_interrupt_pending;
452         ah->ah_getPendingInterrupts     = ar9300_get_pending_interrupts_freebsd;
453         ah->ah_getInterrupts =  ar9300_get_interrupts;
454         ah->ah_setInterrupts =  ar9300_set_interrupts_freebsd;
455
456         /* Regulatory/internal functions */
457         //    AH_PRIVATE(ah)->ah_getNfAdjust = ar9300_get_nf_adjust;
458         AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
459         //    AH_PRIVATE(ah)->ah_getChipPowerLimits = ar9300_get_chip_power_limits;
460         AH_PRIVATE(ah)->ah_getWirelessModes = ar9300_get_wireless_modes;
461         AH_PRIVATE(ah)->ah_getChannelEdges = ar9300_get_channel_edges;
462
463         AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
464         /* XXX ah_eeprom */
465         /* XXX ah_eeversion */
466         /* XXX ah_eepromDetach */
467         /* XXX ah_eepromGet */
468         AH_PRIVATE(ah)->ah_eepromGet = ar9300_eeprom_get_freebsd;
469         /* XXX ah_eepromSet */
470         /* XXX ah_getSpurChan */
471         /* XXX ah_eepromDiag */
472
473         /* 802.11n functions */
474         ah->ah_chainTxDesc = ar9300_freebsd_chain_tx_desc;
475         ah->ah_setupFirstTxDesc= ar9300_freebsd_setup_first_tx_desc;
476         ah->ah_setupLastTxDesc = ar9300_freebsd_setup_last_tx_desc;
477         ah->ah_set11nRateScenario = ar9300_freebsd_set_11n_rate_scenario;
478         ah->ah_set11nTxDesc = ar9300_freebsd_setup_11n_desc;
479         ah->ah_set11nAggrFirst = ar9300_set_11n_aggr_first;
480         ah->ah_set11nAggrMiddle = ar9300_set_11n_aggr_middle;
481         ah->ah_set11nAggrLast = ar9300_set_11n_aggr_last;
482         ah->ah_clr11nAggr = ar9300_clr_11n_aggr;
483         ah->ah_set11nBurstDuration = ar9300_set_11n_burst_duration;
484         /* ah_get11nExtBusy */
485         ah->ah_set11nMac2040 = ar9300_set_11n_mac2040;
486         ah->ah_setChainMasks = ar9300SetChainMasks;
487         /* ah_get11nRxClear */
488         /* ah_set11nRxClear */
489
490         /* bluetooth coexistence functions */
491         ah->ah_btCoexSetInfo            = ar9300_set_bt_coex_info;
492         ah->ah_btCoexSetConfig          = ar9300_bt_coex_config;
493         ah->ah_btCoexSetQcuThresh       = ar9300_bt_coex_set_qcu_thresh;
494         ah->ah_btCoexSetWeights         = ar9300_bt_coex_set_weights;
495         ah->ah_btCoexSetBmissThresh     = ar9300_bt_coex_setup_bmiss_thresh;
496         ah->ah_btCoexSetParameter       = ar9300_bt_coex_set_parameter;
497         ah->ah_btCoexDisable            = ar9300_bt_coex_disable;
498         ah->ah_btCoexEnable             = ar9300_bt_coex_enable;
499
500         /* MCI bluetooth functions */
501         if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
502                 /*
503                  * Note: these are done in attach too for now, because
504                  * at this point we haven't yet setup the mac/bb revision
505                  * values, so this code is effectively NULL.
506                  * However, I'm leaving this here so people digging
507                  * into the code (a) see the MCI bits here, and (b)
508                  * are now told they should look elsewhere for
509                  * these methods.
510                  */
511                 ah->ah_btCoexSetWeights = ar9300_mci_bt_coex_set_weights;
512                 ah->ah_btCoexDisable = ar9300_mci_bt_coex_disable;
513                 ah->ah_btCoexEnable = ar9300_mci_bt_coex_enable;
514         }
515         ah->ah_btMciSetup               = ar9300_mci_setup;
516         ah->ah_btMciSendMessage         = ar9300_mci_send_message;
517         ah->ah_btMciGetInterrupt        = ar9300_mci_get_interrupt;
518         ah->ah_btMciState               = ar9300_mci_state;
519         ah->ah_btMciDetach              = ar9300_mci_detach;
520
521         /* LNA diversity functions */
522         ah->ah_divLnaConfGet = ar9300_ant_div_comb_get_config;
523         ah->ah_divLnaConfSet = ar9300_ant_div_comb_set_config;
524 }
525
526 HAL_BOOL
527 ar9300_reset_freebsd(struct ath_hal *ah, HAL_OPMODE opmode,
528     struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
529     HAL_RESET_TYPE resetType,
530     HAL_STATUS *status)
531 {
532         HAL_BOOL r;
533         HAL_HT_MACMODE macmode;
534         struct ath_hal_private  *ap  = AH_PRIVATE(ah);
535
536         macmode =
537             IEEE80211_IS_CHAN_HT40(chan) ?
538                 HAL_HT_MACMODE_2040 : HAL_HT_MACMODE_20;
539
540         r = ar9300_reset(ah, opmode, chan, macmode,
541             ap->ah_caps.halTxChainMask,
542             ap->ah_caps.halRxChainMask,
543             HAL_HT_EXTPROTSPACING_20, /* always 20Mhz channel spacing */
544             bChannelChange,
545             status,
546             resetType,
547             AH_FALSE);       /* XXX should really extend ath_hal_reset() */
548
549         return (r);
550 }
551
552 void
553 ar9300_config_pcie_freebsd(struct ath_hal *ah, HAL_BOOL restore,
554     HAL_BOOL powerOff)
555 {
556
557         ar9300_config_pci_power_save(ah, restore ? 1 : 0, powerOff ? 1 : 0);
558 }
559
560 /*
561  * This is a copy from ar9300_eeprom_get(), purely because the FreeBSD
562  * API is very silly and inconsistent.
563  *
564  * The AR93xx HAL doesn't call the eepromGetFlag() function, so this
565  * only occurs for FreeBSD code.
566  *
567  * When I fix this particular API, I'll undo this.
568  */
569 HAL_STATUS
570 ar9300_eeprom_get_freebsd(struct ath_hal *ah, int param, void *val)
571 {
572
573         switch (param) {
574         case AR_EEP_FSTCLK_5G:
575                 return HAL_OK;
576         default:
577                 ath_hal_printf(ah, "%s: called, param=%d\n",
578                     __func__, param);
579                 return HAL_EIO;
580         }
581 }
582
583 HAL_BOOL
584 ar9300_stop_tx_dma_freebsd(struct ath_hal *ah, u_int q)
585 {
586
587         return ar9300_stop_tx_dma(ah, q, 1000);
588 }
589
590 void
591 ar9300_ani_poll_freebsd(struct ath_hal *ah,
592     const struct ieee80211_channel *chan)
593 {
594
595         HAL_NODE_STATS stats;
596         HAL_ANISTATS anistats;
597         HAL_SURVEY_SAMPLE survey;
598
599         OS_MEMZERO(&stats, sizeof(stats));
600         OS_MEMZERO(&anistats, sizeof(anistats));
601         OS_MEMZERO(&survey, sizeof(survey));
602
603         ar9300_ani_ar_poll(ah, &stats, chan, &anistats);
604
605         /*
606          * If ANI stats are valid, use them to update the
607          * channel survey.
608          */
609         if (anistats.valid) {
610                 survey.cycle_count = anistats.cyclecnt_diff;
611                 survey.chan_busy = anistats.rxclr_cnt;
612                 survey.ext_chan_busy = anistats.extrxclr_cnt;
613                 survey.tx_busy = anistats.txframecnt_diff;
614                 survey.rx_busy = anistats.rxframecnt_diff;
615                 ath_hal_survey_add_sample(ah, &survey);
616         }
617 }
618
619 /*
620  * Setup the configuration parameters in the style the AR9300 HAL
621  * wants.
622  */
623 void
624 ar9300_config_defaults_freebsd(struct ath_hal *ah, HAL_OPS_CONFIG *ah_config)
625 {
626
627         /* Until FreeBSD's HAL does this by default - just copy */
628         OS_MEMCPY(&ah->ah_config, ah_config, sizeof(HAL_OPS_CONFIG));
629         ah->ah_config.ath_hal_enable_ani = AH_TRUE;
630 }
631
632 HAL_BOOL
633 ar9300_stop_dma_receive_freebsd(struct ath_hal *ah)
634 {
635
636         return ar9300_stop_dma_receive(ah, 1000);
637 }
638
639 HAL_BOOL
640 ar9300_get_pending_interrupts_freebsd(struct ath_hal *ah, HAL_INT *masked)
641 {
642
643         /* Non-MSI, so no MSI vector; and 'nortc' = 0 */
644         return ar9300_get_pending_interrupts(ah, masked, HAL_INT_LINE, 0, 0);
645 }
646
647 HAL_INT
648 ar9300_set_interrupts_freebsd(struct ath_hal *ah, HAL_INT ints)
649 {
650
651         /* nortc = 0 */
652         return ar9300_set_interrupts(ah, ints, 0);
653 }
654
655 HAL_BOOL
656 ar9300_per_calibration_freebsd(struct ath_hal *ah,
657     struct ieee80211_channel *chan, u_int rxchainmask, HAL_BOOL long_cal,
658     HAL_BOOL *isCalDone)
659 {
660         /* XXX fake scheduled calibrations for now */
661         u_int32_t sched_cals = 0xfffffff;
662
663         return ar9300_calibration(ah, chan,
664             AH_PRIVATE(ah)->ah_caps.halRxChainMask,
665             long_cal,
666             isCalDone,
667             0,                  /* is_scan */
668             &sched_cals);
669 }
670
671 HAL_BOOL
672 ar9300_reset_cal_valid_freebsd(struct ath_hal *ah,
673     const struct ieee80211_channel *chan)
674 {
675
676         HAL_BOOL is_cal_done = AH_TRUE;
677         
678         ar9300_reset_cal_valid(ah, chan, &is_cal_done, 0xffffffff);
679         return (is_cal_done);
680 }
681
682
683 /*
684  * FreeBSD will just pass in the descriptor value as 'pa'.
685  * The Atheros HAL treats 'pa' as the physical address of the RX
686  * descriptor and 'bufaddr' as the physical address of the RX buffer.
687  * I'm not sure why they didn't collapse them - the AR9300 RX descriptor
688  * routine doesn't check 'pa'.
689  */
690 HAL_STATUS
691 ar9300_proc_rx_desc_freebsd(struct ath_hal *ah, struct ath_desc *ds,
692     uint32_t pa, struct ath_desc *ds_next, uint64_t tsf,
693     struct ath_rx_status *rxs)
694 {
695
696         return (ar9300_proc_rx_desc_fast(ah, ds, 0, ds_next, rxs,
697             (void *) ds));
698 }
699
700 /*
701  * This is the primary way the ANI code gets the node statistics per packet.
702  */
703 void
704 ar9300_ani_rxmonitor_freebsd(struct ath_hal *ah, const HAL_NODE_STATS *stats,
705     const struct ieee80211_channel *chan)
706 {
707         struct ath_hal_9300 *ahp = AH9300(ah);
708
709         ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
710 }
711
712 void
713 ar9300_freebsd_get_desc_link(struct ath_hal *ah, void *ds, uint32_t *link)
714 {
715         struct ar9300_txc *ads = AR9300TXC(ds);
716
717         (*link) = ads->ds_link;
718 }
719
720 /*
721  * TX descriptor field setting wrappers - eek.
722  */
723
724
725 HAL_BOOL
726 ar9300_freebsd_setup_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
727     u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower,
728     u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags,
729     u_int rtsctsRate, u_int rtsCtsDuration, u_int compicvLen,
730     u_int compivLen, u_int comp)
731 {
732         struct ath_hal_9300 *ahp = AH9300(ah);
733
734         HAL_KEY_TYPE keyType = 0;       /* XXX No padding */
735
736         if (keyIx != HAL_TXKEYIX_INVALID)
737                 keyType = ahp->ah_keytype[keyIx];
738
739         /* XXX bounds check keyix */
740         ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
741             keyType, flags);
742
743         return AH_TRUE;
744 }
745
746 HAL_BOOL
747 ar9300_freebsd_setup_x_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
748     u_int txRate1, u_int txTries1,
749     u_int txRate2, u_int txTries2,
750     u_int txRate3, u_int txTries3)
751 {
752
753 #if 0
754         ath_hal_printf(ah, "%s: called, 0x%x/%d, 0x%x/%d, 0x%x/%d\n",
755             __func__,
756             txRate1, txTries1,
757             txRate2, txTries2,
758             txRate3, txTries3);
759 #endif
760
761         /* XXX should only be called during probe */
762         return (AH_TRUE);
763 }
764
765 HAL_BOOL
766 ar9300_freebsd_fill_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
767     HAL_DMA_ADDR *bufListPtr, uint32_t *segLenPtr, u_int descId, u_int qid,
768     HAL_BOOL firstSeg, HAL_BOOL lastSeg,
769     const struct ath_desc *ds0)
770 {
771         HAL_KEY_TYPE keyType = 0;
772         const struct ar9300_txc *ads = AR9300TXC_CONST(ds0);
773
774         /*
775          * FreeBSD's HAL doesn't pass the keytype to fill_tx_desc();
776          * it's copied as part of the descriptor chaining.
777          *
778          * So, extract it from ds0.
779          */
780         keyType = MS(ads->ds_ctl17, AR_encr_type);
781
782         return ar9300_fill_tx_desc(ah, ds, bufListPtr, segLenPtr, descId,
783             qid, keyType, firstSeg, lastSeg, ds0);
784 }
785
786 HAL_BOOL
787 ar9300_freebsd_get_tx_completion_rates(struct ath_hal *ah,
788     const struct ath_desc *ds0, int *rates, int *tries)
789 {
790
791         ath_hal_printf(ah, "%s: called\n", __func__);
792         return AH_FALSE;        /* XXX for now */
793 }
794
795
796 /*
797  * 802.11n TX descriptor wrappers
798  */
799 void
800 ar9300_freebsd_set_11n_rate_scenario(struct ath_hal *ah, struct ath_desc *ds,
801     u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[],
802     u_int nseries, u_int flags)
803 {
804
805         /* lastds=NULL, rtscts_duration is 0, smart antenna is 0 */
806         ar9300_set_11n_rate_scenario(ah, (void *) ds, (void *)ds, durUpdateEn,
807             rtsctsRate, 0, series, nseries, flags, 0);
808 }
809
810 /* chaintxdesc */
811 HAL_BOOL
812 ar9300_freebsd_chain_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
813     HAL_DMA_ADDR *bufLenList, uint32_t *segLenList,
814     u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int keyIx,
815     HAL_CIPHER cipher, uint8_t numDelims,
816     HAL_BOOL firstSeg, HAL_BOOL lastSeg, HAL_BOOL lastAggr)
817 {
818
819         ath_hal_printf(ah, "%s: called\n", __func__);
820         return AH_FALSE;
821 }
822
823 /* setupfirsttxdesc */
824 HAL_BOOL
825 ar9300_freebsd_setup_first_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
826     u_int aggrLen, u_int flags, u_int txPower, u_int txRate0,
827     u_int txTries0, u_int antMode, u_int rtsctsRate, u_int rtsctsDuration)
828 {
829
830         ath_hal_printf(ah, "%s: called\n", __func__);
831         return AH_FALSE;
832 }
833
834 /* setuplasttxdesc */
835 /*
836  * This gets called but for now let's not log anything;
837  * it's only used to update the rate control information.
838  */
839 HAL_BOOL
840 ar9300_freebsd_setup_last_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
841     const struct ath_desc *ds0)
842 {
843
844 //      ath_hal_printf(ah, "%s: called\n", __func__);
845         return AH_FALSE;
846 }
847
848 void
849 ar9300_freebsd_setup_11n_desc(struct ath_hal *ah, void *ds, u_int pktLen,
850     HAL_PKT_TYPE type, u_int txPower, u_int keyIx, u_int flags)
851 {
852         ath_hal_printf(ah, "%s: called\n", __func__);
853 #if 0
854         struct ath_hal_9300 *ahp = AH9300(ah);
855
856         HAL_KEY_TYPE keyType = 0;       /* XXX No padding */
857
858         if (keyIx != HAL_TXKEYIX_INVALID)
859                 keyType = ahp->ah_keytype[keyIx];
860
861         /* XXX bounds check keyix */
862         ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
863             keyType, flags);
864 #endif
865 }
866
867 HAL_STATUS
868 ar9300_freebsd_proc_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
869     struct ath_tx_status *ts)
870 {
871
872         return ar9300_proc_tx_desc(ah, ts);
873 }
874
875 void
876 ar9300_freebsd_beacon_init(struct ath_hal *ah, uint32_t next_beacon,
877     uint32_t beacon_period)
878 {
879
880         ar9300_beacon_init(ah, next_beacon, beacon_period, 0,
881             AH_PRIVATE(ah)->ah_opmode);
882 }
883
884 HAL_BOOL
885 ar9300_freebsd_get_mib_cycle_counts(struct ath_hal *ah,
886     HAL_SURVEY_SAMPLE *hs)
887
888 {
889
890         return (AH_FALSE);
891 }
892
893 /*
894  * Clear multicast filter by index - from FreeBSD ar5212_recv.c
895  */
896 static HAL_BOOL
897 ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
898 {
899         uint32_t val;
900
901         if (ix >= 64)
902                 return (AH_FALSE);
903         if (ix >= 32) {
904                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
905                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32))));
906         } else {
907                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
908                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<<ix)));
909         }
910         return AH_TRUE;
911 }
912
913 /*
914  * Set multicast filter by index - from FreeBSD ar5212_recv.c
915  */
916 static HAL_BOOL
917 ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
918 {
919         uint32_t val;
920
921         if (ix >= 64)
922                 return (AH_FALSE);
923         if (ix >= 32) {
924                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
925                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32))));
926         } else {
927                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
928                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<<ix)));
929         }
930         return (AH_TRUE);
931 }
932
933 #define TU_TO_USEC(_tu) ((_tu) << 10)
934 #define ONE_EIGHTH_TU_TO_USEC(_tu8) ((_tu8) << 7)
935
936 /*
937  * Initializes all of the hardware registers used to
938  * send beacons.  Note that for station operation the
939  * driver calls ar9300_set_sta_beacon_timers instead.
940  */
941 static void
942 ar9300_beacon_set_beacon_timers(struct ath_hal *ah,
943     const HAL_BEACON_TIMERS *bt)
944 {
945         uint32_t bperiod;
946
947 #if 0
948     HALASSERT(opmode == HAL_M_IBSS || opmode == HAL_M_HOSTAP);
949     if (opmode == HAL_M_IBSS) {
950         OS_REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
951     }
952 #endif
953
954         /* XXX TODO: should migrate the HAL code to always use ONE_EIGHTH_TU */
955         OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bt->bt_nexttbtt));
956         OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextdba));
957         OS_REG_WRITE(ah, AR_NEXT_SWBA, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextswba));
958         OS_REG_WRITE(ah, AR_NEXT_NDP_TIMER, TU_TO_USEC(bt->bt_nextatim));
959
960         bperiod = TU_TO_USEC(bt->bt_intval & HAL_BEACON_PERIOD);
961         AH9300(ah)->ah_beaconInterval = bt->bt_intval & HAL_BEACON_PERIOD;
962         OS_REG_WRITE(ah, AR_BEACON_PERIOD, bperiod);
963         OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bperiod);
964         OS_REG_WRITE(ah, AR_SWBA_PERIOD, bperiod);
965         OS_REG_WRITE(ah, AR_NDP_PERIOD, bperiod);
966
967         /*
968          * Reset TSF if required.
969          */
970         if (bt->bt_intval & HAL_BEACON_RESET_TSF)
971                 ar9300_reset_tsf(ah);
972
973         /* enable timers */
974         /* NB: flags == 0 handled specially for backwards compatibility */
975         OS_REG_SET_BIT(ah, AR_TIMER_MODE,
976             bt->bt_flags != 0 ? bt->bt_flags :
977             AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN);
978 }
979
980
981 /*
982  * RF attach stubs
983  */
984
985 static HAL_BOOL
986 rf9330_attach(struct ath_hal *ah, HAL_STATUS *status)
987 {
988
989         (*status) = HAL_EINVAL;
990         return (AH_FALSE);
991 }
992
993 static HAL_BOOL
994 rf9330_probe(struct ath_hal *ah)
995 {
996         return (AH_FALSE);
997 }
998
999 AH_RF(RF9330, rf9330_probe, rf9330_attach);
1000