]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
Merge ACPICA 20150717.
[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 void
101 ar9300_attach_freebsd_ops(struct ath_hal *ah)
102 {
103
104         /* Global functions */
105         ah->ah_detach           = ar9300_detach;
106         ah->ah_getRateTable             = ar9300_get_rate_table;
107
108         /* Reset functions */
109         ah->ah_reset            = ar9300_reset_freebsd;
110         ah->ah_phyDisable               = ar9300_phy_disable;
111         ah->ah_disable          = ar9300_disable;
112         ah->ah_configPCIE               = ar9300_config_pcie_freebsd;
113 //      ah->ah_disablePCIE              = ar9300_disable_pcie_phy;
114         ah->ah_setPCUConfig             = ar9300_set_pcu_config;
115         // perCalibration
116         ah->ah_perCalibrationN  = ar9300_per_calibration_freebsd;
117         ah->ah_resetCalValid    = ar9300_reset_cal_valid_freebsd;
118         ah->ah_setTxPowerLimit  = ar9300_freebsd_set_tx_power_limit;
119         ah->ah_getChanNoise             = ath_hal_getChanNoise;
120
121         /* Transmit functions */
122         ah->ah_setupTxQueue             = ar9300_setup_tx_queue;
123         ah->ah_setTxQueueProps  = ar9300_set_tx_queue_props;
124         ah->ah_getTxQueueProps  = ar9300_get_tx_queue_props;
125         ah->ah_releaseTxQueue   = ar9300_release_tx_queue;
126         ah->ah_resetTxQueue             = ar9300_reset_tx_queue;
127         ah->ah_getTxDP          = ar9300_get_tx_dp;
128         ah->ah_setTxDP          = ar9300_set_tx_dp;
129         ah->ah_numTxPending             = ar9300_num_tx_pending;
130         ah->ah_startTxDma               = ar9300_start_tx_dma;
131         ah->ah_stopTxDma                = ar9300_stop_tx_dma_freebsd;
132         ah->ah_setupTxDesc              = ar9300_freebsd_setup_tx_desc;
133         ah->ah_setupXTxDesc             = ar9300_freebsd_setup_x_tx_desc;
134         ah->ah_fillTxDesc               = ar9300_freebsd_fill_tx_desc;
135         ah->ah_procTxDesc               = ar9300_freebsd_proc_tx_desc;
136         ah->ah_getTxIntrQueue   = ar9300_get_tx_intr_queue;
137         // reqTxIntrDesc
138         ah->ah_getTxCompletionRates     = ar9300_freebsd_get_tx_completion_rates;
139         ah->ah_setTxDescLink    = ar9300_set_desc_link;
140         ah->ah_getTxDescLink    = ar9300_freebsd_get_desc_link;
141         ah->ah_getTxDescLinkPtr = ar9300_get_desc_link_ptr;
142         ah->ah_setupTxStatusRing        = ar9300_setup_tx_status_ring;
143         ah->ah_getTxRawTxDesc    = ar9300_get_raw_tx_desc;
144         ah->ah_updateTxTrigLevel        = ar9300_update_tx_trig_level;
145
146         /* RX functions */
147         ah->ah_getRxDP          = ar9300_get_rx_dp;
148         ah->ah_setRxDP          = ar9300_set_rx_dp;
149         ah->ah_enableReceive    = ar9300_enable_receive;
150         ah->ah_stopDmaReceive   = ar9300_stop_dma_receive_freebsd;
151         ah->ah_startPcuReceive  = ar9300_start_pcu_receive_freebsd;
152         ah->ah_stopPcuReceive   = ar9300_stop_pcu_receive;
153         ah->ah_setMulticastFilter       = ar9300_set_multicast_filter;
154         ah->ah_setMulticastFilterIndex = ar9300SetMulticastFilterIndex;
155         ah->ah_clrMulticastFilterIndex = ar9300ClrMulticastFilterIndex;
156         ah->ah_getRxFilter              = ar9300_get_rx_filter;
157         ah->ah_setRxFilter              = ar9300_set_rx_filter;
158         /* setupRxDesc */
159         ah->ah_procRxDesc               = ar9300_proc_rx_desc_freebsd;
160         ah->ah_rxMonitor                = ar9300_ani_rxmonitor_freebsd;
161         ah->ah_aniPoll          = ar9300_ani_poll_freebsd;
162         ah->ah_procMibEvent             = ar9300_process_mib_intr;
163
164         /* Misc functions */
165         ah->ah_getCapability    = ar9300_get_capability;
166         ah->ah_setCapability    = ar9300_set_capability;
167         ah->ah_getDiagState             = ar9300_get_diag_state;
168         ah->ah_getMacAddress    = ar9300_get_mac_address;
169         ah->ah_setMacAddress    = ar9300_set_mac_address;
170         ah->ah_getBssIdMask             = ar9300_get_bss_id_mask;
171         ah->ah_setBssIdMask             = ar9300_set_bss_id_mask;
172         ah->ah_setRegulatoryDomain      = ar9300_set_regulatory_domain;
173         ah->ah_setLedState              = ar9300_set_led_state;
174         ah->ah_writeAssocid             = ar9300_write_associd;
175         ah->ah_gpioCfgInput             = ar9300_gpio_cfg_input;
176         ah->ah_gpioCfgOutput    = ar9300_gpio_cfg_output;
177         ah->ah_gpioGet          = ar9300_gpio_get;
178         ah->ah_gpioSet          = ar9300_gpio_set;
179         ah->ah_gpioSetIntr              = ar9300_gpio_set_intr;
180         /* polarity */
181         /* mask */
182         ah->ah_getTsf32         = ar9300_get_tsf32;
183         ah->ah_getTsf64         = ar9300_get_tsf64;
184         ah->ah_resetTsf         = ar9300_reset_tsf;
185         ah->ah_detectCardPresent        = ar9300_detect_card_present;
186         // ah->ah_updateMibCounters     = ar9300_update_mib_counters;
187         ah->ah_getRfGain                = ar9300_get_rfgain;
188         ah->ah_getDefAntenna    = ar9300_get_def_antenna;
189         ah->ah_setDefAntenna    = ar9300_set_def_antenna;
190         ah->ah_getAntennaSwitch = ar9300_freebsd_get_antenna_switch;
191         ah->ah_setAntennaSwitch = ar9300_freebsd_set_antenna_switch;
192         // ah->ah_setSifsTime           = ar9300_set_sifs_time;
193         // ah->ah_getSifsTime           = ar9300_get_sifs_time;
194         ah->ah_setSlotTime              = ar9300_set_slot_time;
195         ah->ah_getSlotTime              = ar9300GetSlotTime;
196         ah->ah_getAckTimeout    = ar9300_get_ack_timeout;
197         ah->ah_setAckTimeout    = ar9300_set_ack_timeout;
198         // XXX ack/ctsrate
199         // XXX CTS timeout
200         ah->ah_getCTSTimeout = ar9300_freebsd_get_cts_timeout;
201         // XXX decompmask
202         // coverageclass
203         ah->ah_setQuiet         = ar9300_set_quiet;
204         ah->ah_getMibCycleCounts        = ar9300_freebsd_get_mib_cycle_counts;
205
206         /* DFS functions */
207         ah->ah_enableDfs                = ar9300_enable_dfs;
208         ah->ah_getDfsThresh             = ar9300_get_dfs_thresh;
209         ah->ah_getDfsDefaultThresh      = ar9300_freebsd_get_dfs_default_thresh;
210         // procradarevent
211         ah->ah_isFastClockEnabled       = ar9300_is_fast_clock_enabled;
212         ah->ah_get11nExtBusy    = ar9300_get_11n_ext_busy;
213
214         /* Key cache functions */
215         ah->ah_getKeyCacheSize  = ar9300_get_key_cache_size;
216         ah->ah_resetKeyCacheEntry       = ar9300_reset_key_cache_entry;
217         ah->ah_isKeyCacheEntryValid     = ar9300_is_key_cache_entry_valid;
218         ah->ah_setKeyCacheEntry = ar9300_set_key_cache_entry;
219         ah->ah_setKeyCacheEntryMac      = ar9300_set_key_cache_entry_mac;
220
221         /* Power management functions */
222         ah->ah_setPowerMode             = ar9300_set_power_mode;
223         ah->ah_getPowerMode             = ar9300_get_power_mode;
224
225         /* Beacon functions */
226         /* ah_setBeaconTimers */
227         ah->ah_beaconInit               = ar9300_freebsd_beacon_init;
228         ah->ah_setBeaconTimers          = ar9300_beacon_set_beacon_timers;
229         ah->ah_setStationBeaconTimers = ar9300_set_sta_beacon_timers;
230         /* ah_resetStationBeaconTimers */
231         ah->ah_getNextTBTT = ar9300_get_next_tbtt;
232
233         /* Interrupt functions */
234         ah->ah_isInterruptPending       = ar9300_is_interrupt_pending;
235         ah->ah_getPendingInterrupts     = ar9300_get_pending_interrupts_freebsd;
236         ah->ah_getInterrupts =  ar9300_get_interrupts;
237         ah->ah_setInterrupts =  ar9300_set_interrupts_freebsd;
238
239         /* Regulatory/internal functions */
240         //    AH_PRIVATE(ah)->ah_getNfAdjust = ar9300_get_nf_adjust;
241         AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
242         //    AH_PRIVATE(ah)->ah_getChipPowerLimits = ar9300_get_chip_power_limits;
243         AH_PRIVATE(ah)->ah_getWirelessModes = ar9300_get_wireless_modes;
244         AH_PRIVATE(ah)->ah_getChannelEdges = ar9300_get_channel_edges;
245
246         AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
247         /* XXX ah_eeprom */
248         /* XXX ah_eeversion */
249         /* XXX ah_eepromDetach */
250         /* XXX ah_eepromGet */
251         AH_PRIVATE(ah)->ah_eepromGet = ar9300_eeprom_get_freebsd;
252         /* XXX ah_eepromSet */
253         /* XXX ah_getSpurChan */
254         /* XXX ah_eepromDiag */
255
256         /* 802.11n functions */
257         ah->ah_chainTxDesc = ar9300_freebsd_chain_tx_desc;
258         ah->ah_setupFirstTxDesc= ar9300_freebsd_setup_first_tx_desc;
259         ah->ah_setupLastTxDesc = ar9300_freebsd_setup_last_tx_desc;
260         ah->ah_set11nRateScenario = ar9300_freebsd_set_11n_rate_scenario;
261         ah->ah_set11nTxDesc = ar9300_freebsd_setup_11n_desc;
262         ah->ah_set11nAggrFirst = ar9300_set_11n_aggr_first;
263         ah->ah_set11nAggrMiddle = ar9300_set_11n_aggr_middle;
264         ah->ah_set11nAggrLast = ar9300_set_11n_aggr_last;
265         ah->ah_clr11nAggr = ar9300_clr_11n_aggr;
266         ah->ah_set11nBurstDuration = ar9300_set_11n_burst_duration;
267         /* ah_get11nExtBusy */
268         ah->ah_set11nMac2040 = ar9300_set_11n_mac2040;
269         ah->ah_setChainMasks = ar9300SetChainMasks;
270         /* ah_get11nRxClear */
271         /* ah_set11nRxClear */
272
273         /* bluetooth coexistence functions */
274         ah->ah_btCoexSetInfo            = ar9300_set_bt_coex_info;
275         ah->ah_btCoexSetConfig          = ar9300_bt_coex_config;
276         ah->ah_btCoexSetQcuThresh       = ar9300_bt_coex_set_qcu_thresh;
277         ah->ah_btCoexSetWeights         = ar9300_bt_coex_set_weights;
278         ah->ah_btCoexSetBmissThresh     = ar9300_bt_coex_setup_bmiss_thresh;
279         ah->ah_btCoexSetParameter       = ar9300_bt_coex_set_parameter;
280         ah->ah_btCoexDisable            = ar9300_bt_coex_disable;
281         ah->ah_btCoexEnable             = ar9300_bt_coex_enable;
282
283         /* MCI bluetooth functions */
284         if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
285                 ah->ah_btCoexSetWeights = ar9300_mci_bt_coex_set_weights;
286                 ah->ah_btCoexDisable = ar9300_mci_bt_coex_disable;
287                 ah->ah_btCoexEnable = ar9300_mci_bt_coex_enable;
288         }
289         ah->ah_btMciSetup               = ar9300_mci_setup;
290         ah->ah_btMciSendMessage         = ar9300_mci_send_message;
291         ah->ah_btMciGetInterrupt        = ar9300_mci_get_interrupt;
292         ah->ah_btMciGetState            = ar9300_mci_state;
293         ah->ah_btMciDetach              = ar9300_mci_detach;
294
295         /* LNA diversity functions */
296         ah->ah_divLnaConfGet = ar9300_ant_div_comb_get_config;
297         ah->ah_divLnaConfSet = ar9300_ant_div_comb_set_config;
298 }
299
300 HAL_BOOL
301 ar9300_reset_freebsd(struct ath_hal *ah, HAL_OPMODE opmode,
302     struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
303     HAL_STATUS *status)
304 {
305         HAL_BOOL r;
306         HAL_HT_MACMODE macmode;
307         struct ath_hal_private  *ap  = AH_PRIVATE(ah);
308
309         macmode =
310             IEEE80211_IS_CHAN_HT40(chan) ?
311                 HAL_HT_MACMODE_2040 : HAL_HT_MACMODE_20;
312
313         r = ar9300_reset(ah, opmode, chan, macmode,
314             ap->ah_caps.halTxChainMask,
315             ap->ah_caps.halRxChainMask,
316             HAL_HT_EXTPROTSPACING_20, /* always 20Mhz channel spacing */
317             bChannelChange,
318             status,
319             AH_FALSE);       /* XXX should really extend ath_hal_reset() */
320
321         return (r);
322 }
323
324 void
325 ar9300_config_pcie_freebsd(struct ath_hal *ah, HAL_BOOL restore,
326     HAL_BOOL powerOff)
327 {
328
329         ar9300_config_pci_power_save(ah, restore ? 1 : 0, powerOff ? 1 : 0);
330 }
331
332 /*
333  * This is a copy from ar9300_eeprom_get(), purely because the FreeBSD
334  * API is very silly and inconsistent.
335  *
336  * The AR93xx HAL doesn't call the eepromGetFlag() function, so this
337  * only occurs for FreeBSD code.
338  *
339  * When I fix this particular API, I'll undo this.
340  */
341 HAL_STATUS
342 ar9300_eeprom_get_freebsd(struct ath_hal *ah, int param, void *val)
343 {
344
345         switch (param) {
346         case AR_EEP_FSTCLK_5G:
347                 return HAL_OK;
348         default:
349                 ath_hal_printf(ah, "%s: called, param=%d\n",
350                     __func__, param);
351                 return HAL_EIO;
352         }
353 }
354
355 HAL_BOOL
356 ar9300_stop_tx_dma_freebsd(struct ath_hal *ah, u_int q)
357 {
358
359         return ar9300_stop_tx_dma(ah, q, 1000);
360 }
361
362 void
363 ar9300_ani_poll_freebsd(struct ath_hal *ah,
364     const struct ieee80211_channel *chan)
365 {
366
367         HAL_NODE_STATS stats;
368         HAL_ANISTATS anistats;
369         HAL_SURVEY_SAMPLE survey;
370
371         OS_MEMZERO(&stats, sizeof(stats));
372         OS_MEMZERO(&anistats, sizeof(anistats));
373         OS_MEMZERO(&survey, sizeof(survey));
374
375         ar9300_ani_ar_poll(ah, &stats, chan, &anistats);
376
377         /*
378          * If ANI stats are valid, use them to update the
379          * channel survey.
380          */
381         if (anistats.valid) {
382                 survey.cycle_count = anistats.cyclecnt_diff;
383                 survey.chan_busy = anistats.rxclr_cnt;
384                 survey.ext_chan_busy = anistats.extrxclr_cnt;
385                 survey.tx_busy = anistats.txframecnt_diff;
386                 survey.rx_busy = anistats.rxframecnt_diff;
387                 ath_hal_survey_add_sample(ah, &survey);
388         }
389 }
390
391 /*
392  * Setup the configuration parameters in the style the AR9300 HAL
393  * wants.
394  */
395 void
396 ar9300_config_defaults_freebsd(struct ath_hal *ah, HAL_OPS_CONFIG *ah_config)
397 {
398
399         /* Until FreeBSD's HAL does this by default - just copy */
400         OS_MEMCPY(&ah->ah_config, ah_config, sizeof(HAL_OPS_CONFIG));
401         ah->ah_config.ath_hal_enable_ani = AH_TRUE;
402 }
403
404 HAL_BOOL
405 ar9300_stop_dma_receive_freebsd(struct ath_hal *ah)
406 {
407
408         return ar9300_stop_dma_receive(ah, 1000);
409 }
410
411 HAL_BOOL
412 ar9300_get_pending_interrupts_freebsd(struct ath_hal *ah, HAL_INT *masked)
413 {
414
415         /* Non-MSI, so no MSI vector; and 'nortc' = 0 */
416         return ar9300_get_pending_interrupts(ah, masked, HAL_INT_LINE, 0, 0);
417 }
418
419 HAL_INT
420 ar9300_set_interrupts_freebsd(struct ath_hal *ah, HAL_INT ints)
421 {
422
423         /* nortc = 0 */
424         return ar9300_set_interrupts(ah, ints, 0);
425 }
426
427 HAL_BOOL
428 ar9300_per_calibration_freebsd(struct ath_hal *ah,
429     struct ieee80211_channel *chan, u_int rxchainmask, HAL_BOOL long_cal,
430     HAL_BOOL *isCalDone)
431 {
432         /* XXX fake scheduled calibrations for now */
433         u_int32_t sched_cals = 0xfffffff;
434
435         return ar9300_calibration(ah, chan,
436             AH_PRIVATE(ah)->ah_caps.halRxChainMask,
437             long_cal,
438             isCalDone,
439             0,                  /* is_scan */
440             &sched_cals);
441 }
442
443 HAL_BOOL
444 ar9300_reset_cal_valid_freebsd(struct ath_hal *ah,
445     const struct ieee80211_channel *chan)
446 {
447
448         HAL_BOOL is_cal_done = AH_TRUE;
449         
450         ar9300_reset_cal_valid(ah, chan, &is_cal_done, 0xffffffff);
451         return (is_cal_done);
452 }
453
454
455 void
456 ar9300_start_pcu_receive_freebsd(struct ath_hal *ah)
457 {
458
459         /* is_scanning flag == NULL */
460         ar9300_start_pcu_receive(ah, AH_FALSE);
461 }
462
463 /*
464  * FreeBSD will just pass in the descriptor value as 'pa'.
465  * The Atheros HAL treats 'pa' as the physical address of the RX
466  * descriptor and 'bufaddr' as the physical address of the RX buffer.
467  * I'm not sure why they didn't collapse them - the AR9300 RX descriptor
468  * routine doesn't check 'pa'.
469  */
470 HAL_STATUS
471 ar9300_proc_rx_desc_freebsd(struct ath_hal *ah, struct ath_desc *ds,
472     uint32_t pa, struct ath_desc *ds_next, uint64_t tsf,
473     struct ath_rx_status *rxs)
474 {
475
476         return (ar9300_proc_rx_desc_fast(ah, ds, 0, ds_next, rxs,
477             (void *) ds));
478 }
479
480 void
481 ar9300_ani_rxmonitor_freebsd(struct ath_hal *ah, const HAL_NODE_STATS *stats,
482     const struct ieee80211_channel *chan)
483 {
484
485 }
486
487 void
488 ar9300_freebsd_get_desc_link(struct ath_hal *ah, void *ds, uint32_t *link)
489 {
490         struct ar9300_txc *ads = AR9300TXC(ds);
491
492         (*link) = ads->ds_link;
493 }
494
495 /*
496  * TX descriptor field setting wrappers - eek.
497  */
498
499
500 HAL_BOOL
501 ar9300_freebsd_setup_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
502     u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower,
503     u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags,
504     u_int rtsctsRate, u_int rtsCtsDuration, u_int compicvLen,
505     u_int compivLen, u_int comp)
506 {
507         struct ath_hal_9300 *ahp = AH9300(ah);
508
509         HAL_KEY_TYPE keyType = 0;       /* XXX No padding */
510
511         if (keyIx != HAL_TXKEYIX_INVALID)
512                 keyType = ahp->ah_keytype[keyIx];
513
514         /* XXX bounds check keyix */
515         ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
516             keyType, flags);
517
518         return AH_TRUE;
519 }
520
521 HAL_BOOL
522 ar9300_freebsd_setup_x_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
523     u_int txRate1, u_int txTries1,
524     u_int txRate2, u_int txTries2,
525     u_int txRate3, u_int txTries3)
526 {
527
528 #if 0
529         ath_hal_printf(ah, "%s: called, 0x%x/%d, 0x%x/%d, 0x%x/%d\n",
530             __func__,
531             txRate1, txTries1,
532             txRate2, txTries2,
533             txRate3, txTries3);
534 #endif
535
536         /* XXX should only be called during probe */
537         return (AH_TRUE);
538 }
539
540 HAL_BOOL
541 ar9300_freebsd_fill_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
542     HAL_DMA_ADDR *bufListPtr, uint32_t *segLenPtr, u_int descId, u_int qid,
543     HAL_BOOL firstSeg, HAL_BOOL lastSeg,
544     const struct ath_desc *ds0)
545 {
546         HAL_KEY_TYPE keyType = 0;
547         const struct ar9300_txc *ads = AR9300TXC_CONST(ds0);
548
549         /*
550          * FreeBSD's HAL doesn't pass the keytype to fill_tx_desc();
551          * it's copied as part of the descriptor chaining.
552          *
553          * So, extract it from ds0.
554          */
555         keyType = MS(ads->ds_ctl17, AR_encr_type);
556
557         return ar9300_fill_tx_desc(ah, ds, bufListPtr, segLenPtr, descId,
558             qid, keyType, firstSeg, lastSeg, ds0);
559 }
560
561 HAL_BOOL
562 ar9300_freebsd_get_tx_completion_rates(struct ath_hal *ah,
563     const struct ath_desc *ds0, int *rates, int *tries)
564 {
565
566         ath_hal_printf(ah, "%s: called\n", __func__);
567         return AH_FALSE;        /* XXX for now */
568 }
569
570
571 /*
572  * 802.11n TX descriptor wrappers
573  */
574 void
575 ar9300_freebsd_set_11n_rate_scenario(struct ath_hal *ah, struct ath_desc *ds,
576     u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[],
577     u_int nseries, u_int flags)
578 {
579
580         /* lastds=NULL, rtscts_duration is 0, smart antenna is 0 */
581         ar9300_set_11n_rate_scenario(ah, (void *) ds, (void *)ds, durUpdateEn,
582             rtsctsRate, 0, series, nseries, flags, 0);
583 }
584
585 /* chaintxdesc */
586 HAL_BOOL
587 ar9300_freebsd_chain_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
588     HAL_DMA_ADDR *bufLenList, uint32_t *segLenList,
589     u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int keyIx,
590     HAL_CIPHER cipher, uint8_t numDelims,
591     HAL_BOOL firstSeg, HAL_BOOL lastSeg, HAL_BOOL lastAggr)
592 {
593
594         ath_hal_printf(ah, "%s: called\n", __func__);
595         return AH_FALSE;
596 }
597
598 /* setupfirsttxdesc */
599 HAL_BOOL
600 ar9300_freebsd_setup_first_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
601     u_int aggrLen, u_int flags, u_int txPower, u_int txRate0,
602     u_int txTries0, u_int antMode, u_int rtsctsRate, u_int rtsctsDuration)
603 {
604
605         ath_hal_printf(ah, "%s: called\n", __func__);
606         return AH_FALSE;
607 }
608
609 /* setuplasttxdesc */
610 /*
611  * This gets called but for now let's not log anything;
612  * it's only used to update the rate control information.
613  */
614 HAL_BOOL
615 ar9300_freebsd_setup_last_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
616     const struct ath_desc *ds0)
617 {
618
619 //      ath_hal_printf(ah, "%s: called\n", __func__);
620         return AH_FALSE;
621 }
622
623 void
624 ar9300_freebsd_setup_11n_desc(struct ath_hal *ah, void *ds, u_int pktLen,
625     HAL_PKT_TYPE type, u_int txPower, u_int keyIx, u_int flags)
626 {
627         ath_hal_printf(ah, "%s: called\n", __func__);
628 #if 0
629         struct ath_hal_9300 *ahp = AH9300(ah);
630
631         HAL_KEY_TYPE keyType = 0;       /* XXX No padding */
632
633         if (keyIx != HAL_TXKEYIX_INVALID)
634                 keyType = ahp->ah_keytype[keyIx];
635
636         /* XXX bounds check keyix */
637         ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx,
638             keyType, flags);
639 #endif
640 }
641
642 HAL_STATUS
643 ar9300_freebsd_proc_tx_desc(struct ath_hal *ah, struct ath_desc *ds,
644     struct ath_tx_status *ts)
645 {
646
647         return ar9300_proc_tx_desc(ah, ts);
648 }
649
650 void
651 ar9300_freebsd_beacon_init(struct ath_hal *ah, uint32_t next_beacon,
652     uint32_t beacon_period)
653 {
654
655         ar9300_beacon_init(ah, next_beacon, beacon_period, 0,
656             AH_PRIVATE(ah)->ah_opmode);
657 }
658
659 HAL_BOOL
660 ar9300_freebsd_get_mib_cycle_counts(struct ath_hal *ah,
661     HAL_SURVEY_SAMPLE *hs)
662
663 {
664
665         return (AH_FALSE);
666 }
667
668 HAL_BOOL
669 ar9300_freebsd_get_dfs_default_thresh(struct ath_hal *ah,
670     HAL_PHYERR_PARAM *pe)
671 {
672
673         /* XXX not yet */
674
675         return (AH_FALSE);
676 }
677
678 /*
679  * Clear multicast filter by index - from FreeBSD ar5212_recv.c
680  */
681 static HAL_BOOL
682 ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
683 {
684         uint32_t val;
685
686         if (ix >= 64)
687                 return (AH_FALSE);
688         if (ix >= 32) {
689                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
690                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32))));
691         } else {
692                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
693                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<<ix)));
694         }
695         return AH_TRUE;
696 }
697
698 /*
699  * Set multicast filter by index - from FreeBSD ar5212_recv.c
700  */
701 static HAL_BOOL
702 ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
703 {
704         uint32_t val;
705
706         if (ix >= 64)
707                 return (AH_FALSE);
708         if (ix >= 32) {
709                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
710                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32))));
711         } else {
712                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
713                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<<ix)));
714         }
715         return (AH_TRUE);
716 }
717
718 #define TU_TO_USEC(_tu) ((_tu) << 10)
719 #define ONE_EIGHTH_TU_TO_USEC(_tu8) ((_tu8) << 7)
720
721 /*
722  * Initializes all of the hardware registers used to
723  * send beacons.  Note that for station operation the
724  * driver calls ar9300_set_sta_beacon_timers instead.
725  */
726 static void
727 ar9300_beacon_set_beacon_timers(struct ath_hal *ah,
728     const HAL_BEACON_TIMERS *bt)
729 {
730         uint32_t bperiod;
731
732 #if 0
733     HALASSERT(opmode == HAL_M_IBSS || opmode == HAL_M_HOSTAP);
734     if (opmode == HAL_M_IBSS) {
735         OS_REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
736     }
737 #endif
738
739         /* XXX TODO: should migrate the HAL code to always use ONE_EIGHTH_TU */
740         OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bt->bt_nexttbtt));
741         OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextdba));
742         OS_REG_WRITE(ah, AR_NEXT_SWBA, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextswba));
743         OS_REG_WRITE(ah, AR_NEXT_NDP_TIMER, TU_TO_USEC(bt->bt_nextatim));
744
745         bperiod = TU_TO_USEC(bt->bt_intval & HAL_BEACON_PERIOD);
746         /* XXX TODO! */
747 //        ahp->ah_beaconInterval = bt->bt_intval & HAL_BEACON_PERIOD;
748         OS_REG_WRITE(ah, AR_BEACON_PERIOD, bperiod);
749         OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bperiod);
750         OS_REG_WRITE(ah, AR_SWBA_PERIOD, bperiod);
751         OS_REG_WRITE(ah, AR_NDP_PERIOD, bperiod);
752
753         /*
754          * Reset TSF if required.
755          */
756         if (bt->bt_intval & HAL_BEACON_RESET_TSF)
757                 ar9300_reset_tsf(ah);
758
759         /* enable timers */
760         /* NB: flags == 0 handled specially for backwards compatibility */
761         OS_REG_SET_BIT(ah, AR_TIMER_MODE,
762             bt->bt_flags != 0 ? bt->bt_flags :
763             AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN);
764 }
765
766
767 /*
768  * RF attach stubs
769  */
770
771 static HAL_BOOL
772 rf9330_attach(struct ath_hal *ah, HAL_STATUS *status)
773 {
774
775         (*status) = HAL_EINVAL;
776         return (AH_FALSE);
777 }
778
779 static HAL_BOOL
780 rf9330_probe(struct ath_hal *ah)
781 {
782         return (AH_FALSE);
783 }
784
785 AH_RF(RF9330, rf9330_probe, rf9330_attach);
786