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