📄 ar5210.c
字号:
voidar5k_ar5210_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0, u_int32_t filter1){ /* Set the multicat filter */ AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL0, filter0); AR5K_REG_WRITE(AR5K_AR5210_MCAST_FIL1, filter1);}HAL_BOOLar5k_ar5210_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index){ if (index >= 64) { return (AH_FALSE); } else if (index >= 32) { AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL1, (1 << (index - 32))); } else { AR5K_REG_ENABLE_BITS(AR5K_AR5210_MCAST_FIL0, (1 << index)); } return (AH_TRUE);}HAL_BOOLar5k_ar5210_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index){ if (index >= 64) { return (AH_FALSE); } else if (index >= 32) { AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL1, (1 << (index - 32))); } else { AR5K_REG_DISABLE_BITS(AR5K_AR5210_MCAST_FIL0, (1 << index)); } return (AH_TRUE);}u_int32_tar5k_ar5210_get_rx_filter(struct ath_hal *hal){ return (AR5K_REG_READ(AR5K_AR5210_RX_FILTER));}voidar5k_ar5210_set_rx_filter(struct ath_hal *hal, u_int32_t filter){ /* * The AR5210 uses promiscous mode to detect radar activity */ if (filter & HAL_RX_FILTER_PHYRADAR) { filter &= ~HAL_RX_FILTER_PHYRADAR; filter |= AR5K_AR5210_RX_FILTER_PROMISC; } AR5K_REG_WRITE(AR5K_AR5210_RX_FILTER, filter);}HAL_BOOL /*O.K. - Initialize rx_desc and clear ds_hw */ar5k_ar5210_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc, u_int32_t size, u_int flags){ struct ar5k_ar5210_rx_desc *rx_desc; rx_desc = (struct ar5k_ar5210_rx_desc*)&desc->ds_ctl0; /* *Clear ds_hw * If we don't clean the descriptor, while * scanning we get too many results, * most of them virtual, after some secs * of scanning system halts. M.F. */ bzero(desc->ds_hw, sizeof(desc->ds_hw)); /*Initialize rx descriptor*/ rx_desc->rx_control_0 = 0; rx_desc->rx_control_1 = 0; /*Setup descriptor*/ if ((rx_desc->rx_control_1 = (size & AR5K_AR5210_DESC_RX_CTL1_BUF_LEN)) != size) return (AH_FALSE); if (flags & HAL_RXDESC_INTREQ) rx_desc->rx_control_1 |= AR5K_AR5210_DESC_RX_CTL1_INTREQ; return (AH_TRUE);}HAL_STATUSar5k_ar5210_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc, u_int32_t phys_addr, struct ath_desc *next){ struct ar5k_ar5210_rx_status *rx_status; rx_status = (struct ar5k_ar5210_rx_status*)&desc->ds_hw[0]; /* No frame received / not ready */ if ((rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_DONE) == 0) return (HAL_EINPROGRESS); /* * Frame receive status */ desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 & AR5K_AR5210_DESC_RX_STATUS0_DATA_LEN; desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_SIGNAL); desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0, AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_RATE); desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 & AR5K_AR5210_DESC_RX_STATUS0_RECEIVE_ANTENNA; desc->ds_us.rx.rs_more = rx_status->rx_status_0 & AR5K_AR5210_DESC_RX_STATUS0_MORE; desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_AR5210_DESC_RX_STATUS1_RECEIVE_TIMESTAMP); desc->ds_us.rx.rs_status = 0; /* * Key table status */ if (rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX_VALID) { desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, AR5K_AR5210_DESC_RX_STATUS1_KEY_INDEX); } else { desc->ds_us.rx.rs_keyix = HAL_RXKEYIX_INVALID; } /* * Receive/descriptor errors */ if ((rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) { if (rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_CRC_ERROR) desc->ds_us.rx.rs_status |= HAL_RXERR_CRC; if (rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_FIFO_OVERRUN) desc->ds_us.rx.rs_status |= HAL_RXERR_FIFO; if (rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR) { desc->ds_us.rx.rs_status |= HAL_RXERR_PHY; desc->ds_us.rx.rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, AR5K_AR5210_DESC_RX_STATUS1_PHY_ERROR); } if (rx_status->rx_status_1 & AR5K_AR5210_DESC_RX_STATUS1_DECRYPT_CRC_ERROR) desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT; } return (HAL_OK);}void /*Added HAL_NODE_STATS argument*/ar5k_ar5210_set_rx_signal(struct ath_hal *hal, const HAL_NODE_STATS *stats){ /* Signal state monitoring is not yet supported */}/* * Misc functions */voidar5k_ar5210_dump_state(struct ath_hal *hal){#ifdef AR5K_DEBUG#define AR5K_PRINT_REGISTER(_x) \ printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5210_##_x)); printf("DMA registers:\n"); AR5K_PRINT_REGISTER(TXDP0); AR5K_PRINT_REGISTER(TXDP1); AR5K_PRINT_REGISTER(CR); AR5K_PRINT_REGISTER(RXDP); AR5K_PRINT_REGISTER(CFG); AR5K_PRINT_REGISTER(ISR); AR5K_PRINT_REGISTER(IMR); AR5K_PRINT_REGISTER(IER); AR5K_PRINT_REGISTER(BCR); AR5K_PRINT_REGISTER(BSR); AR5K_PRINT_REGISTER(TXCFG); AR5K_PRINT_REGISTER(RXCFG); AR5K_PRINT_REGISTER(MIBC); AR5K_PRINT_REGISTER(TOPS); AR5K_PRINT_REGISTER(RXNOFRM); AR5K_PRINT_REGISTER(TXNOFRM); AR5K_PRINT_REGISTER(RPGTO); AR5K_PRINT_REGISTER(RFCNT); AR5K_PRINT_REGISTER(MISC); AR5K_PRINT_REGISTER(RC); AR5K_PRINT_REGISTER(SCR); AR5K_PRINT_REGISTER(INTPEND); AR5K_PRINT_REGISTER(SFR); AR5K_PRINT_REGISTER(PCICFG); AR5K_PRINT_REGISTER(GPIOCR); AR5K_PRINT_REGISTER(GPIODO); AR5K_PRINT_REGISTER(GPIODI); AR5K_PRINT_REGISTER(SREV); printf("\n"); printf("PCU registers:\n"); AR5K_PRINT_REGISTER(STA_ID0); AR5K_PRINT_REGISTER(STA_ID1); AR5K_PRINT_REGISTER(BSS_ID0); AR5K_PRINT_REGISTER(BSS_ID1); AR5K_PRINT_REGISTER(SLOT_TIME); AR5K_PRINT_REGISTER(TIME_OUT); AR5K_PRINT_REGISTER(RSSI_THR); AR5K_PRINT_REGISTER(RETRY_LMT); AR5K_PRINT_REGISTER(USEC); AR5K_PRINT_REGISTER(BEACON); AR5K_PRINT_REGISTER(CFP_PERIOD); AR5K_PRINT_REGISTER(TIMER0); AR5K_PRINT_REGISTER(TIMER1); AR5K_PRINT_REGISTER(TIMER2); AR5K_PRINT_REGISTER(TIMER3); AR5K_PRINT_REGISTER(IFS0); AR5K_PRINT_REGISTER(IFS1); AR5K_PRINT_REGISTER(CFP_DUR); AR5K_PRINT_REGISTER(RX_FILTER); AR5K_PRINT_REGISTER(MCAST_FIL0); AR5K_PRINT_REGISTER(MCAST_FIL1); AR5K_PRINT_REGISTER(TX_MASK0); AR5K_PRINT_REGISTER(TX_MASK1); AR5K_PRINT_REGISTER(CLR_TMASK); AR5K_PRINT_REGISTER(TRIG_LVL); AR5K_PRINT_REGISTER(DIAG_SW); AR5K_PRINT_REGISTER(TSF_L32); AR5K_PRINT_REGISTER(TSF_U32); AR5K_PRINT_REGISTER(LAST_TSTP); AR5K_PRINT_REGISTER(RETRY_CNT); AR5K_PRINT_REGISTER(BACKOFF); AR5K_PRINT_REGISTER(NAV); AR5K_PRINT_REGISTER(RTS_OK); AR5K_PRINT_REGISTER(RTS_FAIL); AR5K_PRINT_REGISTER(ACK_FAIL); AR5K_PRINT_REGISTER(FCS_FAIL); AR5K_PRINT_REGISTER(BEACON_CNT); AR5K_PRINT_REGISTER(KEYTABLE_0); printf("\n"); printf("PHY registers:\n"); AR5K_PRINT_REGISTER(PHY(0)); AR5K_PRINT_REGISTER(PHY_FC); AR5K_PRINT_REGISTER(PHY_AGC); AR5K_PRINT_REGISTER(PHY_CHIP_ID); AR5K_PRINT_REGISTER(PHY_ACTIVE); AR5K_PRINT_REGISTER(PHY_AGCCTL); printf("\n");#endif}HAL_BOOL /*Added arguments*/ar5k_ar5210_get_diag_state(struct ath_hal *hal, int request, const void *args, u_int32_t argsize, void **result, u_int32_t *resultsize){ /* * We'll ignore this right now. This seems to be some kind of an obscure * debugging interface for the binary-only HAL. */ return (AH_FALSE);}voidar5k_ar5210_get_lladdr(struct ath_hal *hal, u_int8_t *mac){ bcopy(hal->ah_sta_id, mac, IEEE80211_ADDR_LEN);}HAL_BOOLar5k_ar5210_set_lladdr(struct ath_hal *hal, const u_int8_t *mac){ u_int32_t low_id, high_id; /* Set new station ID */ bcopy(mac, hal->ah_sta_id, IEEE80211_ADDR_LEN); bcopy(mac, &low_id, 4); bcopy(mac + 4, &high_id, 2); high_id = 0x0000ffff & high_id; AR5K_REG_WRITE(AR5K_AR5210_STA_ID0, low_id); AR5K_REG_WRITE(AR5K_AR5210_STA_ID1, high_id); return (AH_TRUE);}HAL_BOOLar5k_ar5210_set_regdomain(struct ath_hal *hal, u_int16_t regdomain, HAL_STATUS *status){ ieee80211_regdomain_t ieee_regdomain; ieee_regdomain = ar5k_regdomain_to_ieee(regdomain); if (ar5k_eeprom_regulation_domain(hal, AH_TRUE, &ieee_regdomain) == AH_TRUE) { *status = HAL_OK; return (AH_TRUE); } *status = EIO; return (AH_FALSE);}voidar5k_ar5210_set_ledstate(struct ath_hal *hal, HAL_LED_STATE state){ u_int32_t led; led = AR5K_REG_READ(AR5K_AR5210_PCICFG); /* * Some blinking values, define at your wish */ switch (state) { case IEEE80211_S_SCAN: case IEEE80211_S_INIT: led |= AR5K_AR5210_PCICFG_LED_PEND | AR5K_AR5210_PCICFG_LED_BCTL; break; case IEEE80211_S_RUN: led |= AR5K_AR5210_PCICFG_LED_ACT; break; default: led |= AR5K_AR5210_PCICFG_LED_ACT | AR5K_AR5210_PCICFG_LED_BCTL; break; } AR5K_REG_WRITE(AR5K_AR5210_PCICFG, led);}void /*Removed argument trim_offset for combatibility -need revision*/ar5k_ar5210_set_associd(struct ath_hal *hal, const u_int8_t *bssid, u_int16_t assoc_id){ u_int32_t low_id, high_id; u_int16_t tim_offset = 0; /* * Set BSSID which triggers the "SME Join" operation */ bcopy(bssid, &low_id, 4); bcopy(bssid + 4, &high_id, 2); AR5K_REG_WRITE(AR5K_AR5210_BSS_ID0, low_id); AR5K_REG_WRITE(AR5K_AR5210_BSS_ID1, high_id | ((assoc_id & 0x3fff) << AR5K_AR5210_BSS_ID1_AID_S)); bcopy(bssid, &hal->ah_bssid, IEEE80211_ADDR_LEN); if (assoc_id == 0) { ar5k_ar5210_disable_pspoll(hal); return; } AR5K_REG_WRITE_BITS(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_TIM, tim_offset ? tim_offset + 4 : 0); ar5k_ar5210_enable_pspoll(hal, NULL, 0);}HAL_BOOLar5k_ar5210_set_gpio_output(struct ath_hal *hal, u_int32_t gpio){ if (gpio > AR5K_AR5210_NUM_GPIO) return (AH_FALSE); AR5K_REG_WRITE(AR5K_AR5210_GPIOCR, (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio)) | AR5K_AR5210_GPIOCR_OUT1(gpio)); return (AH_TRUE);}HAL_BOOLar5k_ar5210_set_gpio_input(struct ath_hal *hal, u_int32_t gpio){ if (gpio > AR5K_AR5210_NUM_GPIO) return (AH_FALSE); AR5K_REG_WRITE(AR5K_AR5210_GPIOCR, (AR5K_REG_READ(AR5K_AR5210_GPIOCR) &~ AR5K_AR5210_GPIOCR_ALL(gpio)) | AR5K_AR5210_GPIOCR_IN(gpio)); return (AH_TRUE);}u_int32_tar5k_ar5210_get_gpio(struct ath_hal *hal, u_int32_t gpio){ if (gpio > AR5K_AR5210_NUM_GPIO) return (0xffffffff); /* GPIO input magic */ return (((AR5K_REG_READ(AR5K_AR5210_GPIODI) & AR5K_AR5210_GPIOD_MASK) >> gpio) & 0x1);}HAL_BOOLar5k_ar5210_set_gpio(struct ath_hal *hal, u_int32_t gpio, u_int32_t val){ u_int32_t data; if (gpio > AR5K_AR5210_NUM_GPIO) return (0xffffffff); /* GPIO output magic */ data = AR5K_REG_READ(AR5K_AR5210_GPIODO); data &= ~(1 << gpio); data |= (val&1) << gpio; AR5K_REG_WRITE(AR5K_AR5210_GPIODO, data); return (AH_TRUE);}voidar5k_ar5210_set_gpio_intr(struct ath_hal *hal, u_int gpio, u_int32_t interrupt_level){ u_int32_t data; if (gpio > AR5K_AR5210_NUM_GPIO) return; /* * Set the GPIO interrupt */ data = (AR5K_REG_READ(AR5K_AR5210_GPIOCR) & ~(AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_SELH | AR5K_AR5210_GPIOCR_INT_ENA | AR5K_AR5210_GPIOCR_ALL(gpio))) | (AR5K_AR5210_GPIOCR_INT_SEL(gpio) | AR5K_AR5210_GPIOCR_INT_ENA); AR5K_REG_WRITE(AR5K_AR5210_GPIOCR, interrupt_level ? data : (data | AR5K_AR5210_GPIOCR_INT_SELH)); hal->ah_imr |= AR5K_AR5210_IMR_GPIO; /* Enable GPIO interrupts */ AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, AR5K_AR5210_IMR_GPIO);}u_int32_tar5k_ar5210_get_tsf32(struct ath_hal *hal){ return (AR5K_REG_READ(AR5K_AR5210_TSF_L32));}u_int64_tar5k_ar5210_get_tsf64(struct ath_hal *hal){ u_int64_t tsf = AR5K_REG_READ(AR5K_AR5210_TSF_U32); return (AR5K_REG_READ(AR5K_AR5210_TSF_L32) | (tsf << 32));}voidar5k_ar5210_reset_tsf(struct ath_hal *hal){ AR5K_REG_ENABLE_BITS(AR5K_AR5210_BEACON, AR5K_AR5210_BEACON_RESET_TSF);}u_int16_tar5k_ar5210_get_regdomain(struct ath_hal *hal){ return (ar5k_get_regdomain(hal));}HAL_BOOLar5k_ar5210_detect_card_present(struct ath_hal *hal){ u_int16_t magic; /* * Checking the EEPROM's magic value could be an indication * if the card is still present. I didn't find another suitable * way to do this. */ if (ar5k_ar5210_eeprom_read(hal, AR5K_EEPROM_MAGIC, &magic) != 0) return (AH_FALSE); return (magic == AR5K_EEPROM_MAGIC_VALUE ? AH_TRUE : AH_FALSE);}voidar5k_ar5210_update_mib_counters(struct ath_hal *hal, HAL_MIB_STATS *statistics){ statistics->ackrcv_bad += AR5K_REG_READ(AR5K_AR5210_ACK_FAIL); statistics->rts_bad += AR5K_REG_READ(AR5K_AR5210_RTS_FAIL); statistics->rts_good += AR5K_REG_READ(AR5K_AR5210_RTS_OK); statistics->fcs_bad += AR5K_REG_READ(AR5K_AR5210_FCS_FAIL); statistics->beacons += AR5K_REG_READ(AR5K_AR5210_BEACON_CNT);}void /*Unimplemented*/ar5k_ar5210_proc_mib_event(struct ath_hal *hal, const HAL_NODE_STATS *stats) { AR5K_TRACE; return;}HAL_RFGAINar5k_ar5210_get_rf_gain(struct ath_hal *hal){ return (HAL_RFGAIN_INACTIVE);}HAL_BOOLar5k_ar5210_set_slot_time(struct ath_hal *hal, u_int slot_time){ if (slot_time < HAL_SLOT_TIME_9 || slot_time > HAL_SLOT_TIME_MAX) return (AH_FALSE); AR5K_REG_WRITE(AR5K_AR5210_SLOT_TIME, ar5k_htoclock(slot_time, hal->ah_turbo)); return (AH_TRUE);}u_intar5k_ar5210_get_slot_time(struct ath_hal *hal){ return (ar5k_clocktoh(AR5K_REG_READ(AR5K_AR5210_SLOT_TIME) & 0xffff, hal->ah_turbo));}HAL_BOOLar5k_ar5210_set_ack_timeout(struct ath_hal *hal, u_int timeout){ if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_ACK), hal->ah_turbo) <= timeout) return (AH_FALSE); AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_ACK, ar5k_htoclock(timeout, hal->ah_turbo)); return (AH_TRUE);}u_intar5k_ar5210_get_ack_timeout(struct ath_hal *hal){ return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT), AR5K_AR5210_TIME_OUT_ACK), hal->ah_turbo));}HAL_BOOLar5k_ar5210_set_cts_timeout(struct ath_hal *hal, u_int timeout){ if (ar5k_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_AR5210_TIME_OUT_CTS), hal->ah_turbo) <= timeout) return (AH_FALSE); AR5K_REG_WRITE_BITS(AR5K_AR5210_TIME_OUT, AR5K_AR5210_TIME_OUT_CTS, ar5k_htoclock(timeout, hal->ah_turbo)); return (AH_TRUE);}u_intar5k_ar5210_get_cts_timeout(struct ath_hal *hal){ return (ar5k_clocktoh(AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5210_TIME_OUT), AR5K_AR5210_TIME_OUT_CTS), hal->ah_turbo));}HAL_STATUS /*New*/ar5k_ar5210_get_capability(struct ath_hal *hal, HAL_CAPABILITY_TYPE cap_type, u_int32_t capability, u_int32_t *result) { AR5K_TRACE; switch (cap_type) { case HAL_CAP_REG_DMN: if (result){ *result = ar5k_get_regdomain(hal); goto yes; } case HAL_CAP_CIPHER: switch (capability) { case HAL_CIPHER_WEP: goto yes; default: goto no; } case HAL_CAP_NUM_TXQUEUES: if (result) { *result = AR5K_AR5210_TX_NUM_QUEUES; goto yes; } case HAL_CAP_VEOL: goto yes; case HAL_CAP_PSPOLL: goto no; case HAL_CAP_COMPRESSION: goto yes; case HAL_CAP_BURST: goto yes; case HAL_CAP_TPC: goto yes; case HAL_CAP_BSSIDMASK: goto yes; case HAL_CAP_XR: goto yes; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -