The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 0ad94483f9e9c295b3add1599f0fd417


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.