📄 ar5212.c
字号:
_XTX_TRIES(3);#undef _XTX_TRIES return (AH_TRUE);}HAL_STATUS /*O.K.*/ar5k_ar5212_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc){ struct ar5k_ar5212_tx_status *tx_status; struct ar5k_ar5212_tx_desc *tx_desc; AR5K_TRACE; tx_desc = (struct ar5k_ar5212_tx_desc*)&desc->ds_ctl0; tx_status = (struct ar5k_ar5212_tx_status*)&desc->ds_hw[2]; /* No frame has been send or error */ if ((tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_DONE) == 0) return (HAL_EINPROGRESS); /* * Get descriptor status */ desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, AR5K_AR5212_DESC_TX_STATUS0_SEND_TIMESTAMP); desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_AR5212_DESC_TX_STATUS0_RTS_FAIL_COUNT); desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_AR5212_DESC_TX_STATUS0_DATA_FAIL_COUNT); desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, AR5K_AR5212_DESC_TX_STATUS1_SEQ_NUM); desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, AR5K_AR5212_DESC_TX_STATUS1_ACK_SIG_STRENGTH); desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 & AR5K_AR5212_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; desc->ds_us.tx.ts_status = 0; switch (AR5K_REG_MS(tx_status->tx_status_1, AR5K_AR5212_DESC_TX_STATUS1_FINAL_TS_INDEX)) { case 0: desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 & AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE0; break; case 1: desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE1); desc->ds_us.tx.ts_longretry += AR5K_REG_MS(tx_desc->tx_control_2, AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES1); break; case 2: desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE2); desc->ds_us.tx.ts_longretry += AR5K_REG_MS(tx_desc->tx_control_2, AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES2); break; case 3: desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, AR5K_AR5212_DESC_TX_CTL3_XMIT_RATE3); desc->ds_us.tx.ts_longretry += AR5K_REG_MS(tx_desc->tx_control_2, AR5K_AR5212_DESC_TX_CTL2_XMIT_TRIES3); break; } if ((tx_status->tx_status_0 & AR5K_AR5212_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) { if (tx_status->tx_status_0 & AR5K_AR5212_DESC_TX_STATUS0_EXCESSIVE_RETRIES) desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY; if (tx_status->tx_status_0 & AR5K_AR5212_DESC_TX_STATUS0_FIFO_UNDERRUN) desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO; if (tx_status->tx_status_0 & AR5K_AR5212_DESC_TX_STATUS0_FILTERED) desc->ds_us.tx.ts_status |= HAL_TXERR_FILT; } return (HAL_OK);}HAL_BOOL /*O.K. - needs revision (what about VEOL cap ?)*/ar5k_ar5212_has_veol(struct ath_hal *hal){ return (AH_TRUE);}void /*Unimplemented*/ar5k_ar5212_get_tx_inter_queue(struct ath_hal *hal, u_int32_t *i){ AR5K_TRACE; /* XXX */ return;}/* * Receive functions */u_int32_t /*O.K.*/ar5k_ar5212_get_rx_buf(struct ath_hal *hal){ return (AR5K_REG_READ(AR5K_AR5212_RXDP));}void /*O.K.*/ar5k_ar5212_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr){ AR5K_TRACE; AR5K_REG_WRITE(AR5K_AR5212_RXDP, phys_addr);}void /*O.K.*/ar5k_ar5212_start_rx(struct ath_hal *hal){ AR5K_TRACE; AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXE);}HAL_BOOL /*O.K.*/ar5k_ar5212_stop_rx_dma(struct ath_hal *hal){ int i; AR5K_TRACE; AR5K_REG_WRITE(AR5K_AR5212_CR, AR5K_AR5212_CR_RXD); /* * It may take some time to disable the DMA receive unit */ for (i = 2000; i > 0 && (AR5K_REG_READ(AR5K_AR5212_CR) & AR5K_AR5212_CR_RXE) != 0; i--) AR5K_DELAY(10); return (i > 0 ? AH_TRUE : AH_FALSE);}void /*O.K.*/ar5k_ar5212_start_rx_pcu(struct ath_hal *hal){ AR5K_TRACE; AR5K_REG_DISABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);}void /*O.K.*/ar5k_ar5212_stop_pcu_recv(struct ath_hal *hal){ AR5K_TRACE; AR5K_REG_ENABLE_BITS(AR5K_AR5212_DIAG_SW, AR5K_AR5212_DIAG_SW_DIS_RX);}void /*O.K.*/ar5k_ar5212_set_mcast_filter(struct ath_hal *hal, u_int32_t filter0, u_int32_t filter1){ AR5K_TRACE; /* Set the multicat filter */ AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL0, filter0); AR5K_REG_WRITE(AR5K_AR5212_MCAST_FIL1, filter1);}HAL_BOOL /*O.K.*/ar5k_ar5212_set_mcast_filterindex(struct ath_hal *hal, u_int32_t index){ AR5K_TRACE; if (index >= 64) { return (AH_FALSE); } else if (index >= 32) { AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL1, (1 << (index - 32))); } else { AR5K_REG_ENABLE_BITS(AR5K_AR5212_MCAST_FIL0, (1 << index)); } return (AH_TRUE);}HAL_BOOL /*O.K.*/ar5k_ar5212_clear_mcast_filter_idx(struct ath_hal *hal, u_int32_t index){ AR5K_TRACE; if (index >= 64) { return (AH_FALSE); } else if (index >= 32) { AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL1, (1 << (index - 32))); } else { AR5K_REG_DISABLE_BITS(AR5K_AR5212_MCAST_FIL0, (1 << index)); } return (AH_TRUE);}u_int32_t /*O.K.*/ar5k_ar5212_get_rx_filter(struct ath_hal *hal){ u_int32_t data, filter = 0; AR5K_TRACE; filter = AR5K_REG_READ(AR5K_AR5212_RX_FILTER); data = AR5K_REG_READ(AR5K_AR5212_PHY_ERR_FIL); if (data & AR5K_AR5212_PHY_ERR_FIL_RADAR) filter |= HAL_RX_FILTER_PHYRADAR; if (data & (AR5K_AR5212_PHY_ERR_FIL_OFDM | AR5K_AR5212_PHY_ERR_FIL_CCK)) filter |= HAL_RX_FILTER_PHYERR; return (filter);}void /*O.K. - added code from roofnet*/ar5k_ar5212_set_rx_filter(struct ath_hal *hal, u_int32_t filter){ u_int32_t data = 0; AR5K_TRACE; if (filter & HAL_RX_FILTER_PHYRADAR) data |= AR5K_AR5212_PHY_ERR_FIL_RADAR; if (filter & HAL_RX_FILTER_PHYERR) data |= AR5K_AR5212_PHY_ERR_FIL_OFDM | AR5K_AR5212_PHY_ERR_FIL_CCK; /* Got that from roofnet*/ data |= HAL_RX_FILTER_PROM | HAL_RX_FILTER_CONTROL; if (data) { AR5K_REG_ENABLE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_ZLFDMA); } else { AR5K_REG_DISABLE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_ZLFDMA); } AR5K_REG_WRITE(AR5K_AR5212_RX_FILTER, filter & 0xff); AR5K_REG_WRITE(AR5K_AR5212_PHY_ERR_FIL, data);}HAL_BOOL /*O.K. - Initialize rx_desc and clear ds_hw */ar5k_ar5212_setup_rx_desc(struct ath_hal *hal, struct ath_desc *desc, u_int32_t size, u_int flags){ struct ar5k_ar5212_rx_desc *rx_desc; AR5K_TRACE; rx_desc = (struct ar5k_ar5212_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_AR5212_DESC_RX_CTL1_BUF_LEN)) != size) return (AH_FALSE); if (flags & HAL_RXDESC_INTREQ) rx_desc->rx_control_1 |= AR5K_AR5212_DESC_RX_CTL1_INTREQ; return (AH_TRUE);}HAL_STATUS /*O.K.*/ar5k_ar5212_proc_rx_desc(struct ath_hal *hal, struct ath_desc *desc, u_int32_t phys_addr, struct ath_desc *next){ struct ar5k_ar5212_rx_status *rx_status; struct ar5k_ar5212_rx_error *rx_err; AR5K_TRACE; rx_status = (struct ar5k_ar5212_rx_status*)&desc->ds_hw[0]; /* Overlay on error */ rx_err = (struct ar5k_ar5212_rx_error*)&desc->ds_hw[0]; /* No frame received / not ready */ if ((rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DONE) == 0) return (HAL_EINPROGRESS); /* * Frame receive status */ desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 & AR5K_AR5212_DESC_RX_STATUS0_DATA_LEN; desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_SIGNAL); desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0, AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_RATE); desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 & AR5K_AR5212_DESC_RX_STATUS0_RECEIVE_ANTENNA; desc->ds_us.rx.rs_more = rx_status->rx_status_0 & AR5K_AR5212_DESC_RX_STATUS0_MORE; desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_AR5212_DESC_RX_STATUS1_RECEIVE_TIMESTAMP); desc->ds_us.rx.rs_status = 0; /* * Key table status */ if (rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_KEY_INDEX_VALID) { desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, AR5K_AR5212_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_AR5212_DESC_RX_STATUS1_FRAME_RECEIVE_OK) == 0) { if (rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_CRC_ERROR) desc->ds_us.rx.rs_status |= HAL_RXERR_CRC; if (rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_PHY_ERROR) { desc->ds_us.rx.rs_status |= HAL_RXERR_PHY; desc->ds_us.rx.rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1, AR5K_AR5212_DESC_RX_ERROR1_PHY_ERROR_CODE); } if (rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_DECRYPT_CRC_ERROR) desc->ds_us.rx.rs_status |= HAL_RXERR_DECRYPT; if (rx_status->rx_status_1 & AR5K_AR5212_DESC_RX_STATUS1_MIC_ERROR) desc->ds_us.rx.rs_status |= HAL_RXERR_MIC; } return (HAL_OK);}void /*Added HAL_NODE_STATS argument*/ar5k_ar5212_set_rx_signal(struct ath_hal *hal, const HAL_NODE_STATS *stats){ AR5K_TRACE; /* Signal state monitoring is not yet supported */}/* * Misc functions */void /*O.K.*/ar5k_ar5212_dump_state(struct ath_hal *hal){#ifdef AR5K_DEBUG#define AR5K_PRINT_REGISTER(_x) \ printf("(%s: %08x) ", #_x, AR5K_REG_READ(AR5K_AR5212_##_x)); printf("MAC registers:\n"); AR5K_PRINT_REGISTER(CR); AR5K_PRINT_REGISTER(CFG); AR5K_PRINT_REGISTER(IER); AR5K_PRINT_REGISTER(TXCFG); AR5K_PRINT_REGISTER(RXCFG); AR5K_PRINT_REGISTER(MIBC); AR5K_PRINT_REGISTER(TOPS); AR5K_PRINT_REGISTER(RXNOFRM); AR5K_PRINT_REGISTER(RPGTO); AR5K_PRINT_REGISTER(RFCNT); AR5K_PRINT_REGISTER(MISC); AR5K_PRINT_REGISTER(PISR); AR5K_PRINT_REGISTER(SISR0); AR5K_PRINT_REGISTER(SISR1); AR5K_PRINT_REGISTER(SISR3); AR5K_PRINT_REGISTER(SISR4); AR5K_PRINT_REGISTER(DCM_ADDR); AR5K_PRINT_REGISTER(DCM_DATA); AR5K_PRINT_REGISTER(DCCFG); AR5K_PRINT_REGISTER(CCFG); AR5K_PRINT_REGISTER(CCFG_CUP); AR5K_PRINT_REGISTER(CPC0); AR5K_PRINT_REGISTER(CPC1); AR5K_PRINT_REGISTER(CPC2); AR5K_PRINT_REGISTER(CPCORN); AR5K_PRINT_REGISTER(QCU_TXE); AR5K_PRINT_REGISTER(QCU_TXD); AR5K_PRINT_REGISTER(DCU_GBL_IFS_SIFS); AR5K_PRINT_REGISTER(DCU_GBL_IFS_SLOT); AR5K_PRINT_REGISTER(DCU_FP); AR5K_PRINT_REGISTER(DCU_TXP); AR5K_PRINT_REGISTER(DCU_TX_FILTER); AR5K_PRINT_REGISTER(RC); AR5K_PRINT_REGISTER(SCR); AR5K_PRINT_REGISTER(INTPEND); AR5K_PRINT_REGISTER(PCICFG); AR5K_PRINT_REGISTER(GPIOCR); AR5K_PRINT_REGISTER(GPIODO); AR5K_PRINT_REGISTER(SREV); AR5K_PRINT_REGISTER(EEPROM_BASE); AR5K_PRINT_REGISTER(EEPROM_DATA); AR5K_PRINT_REGISTER(EEPROM_CMD); AR5K_PRINT_REGISTER(EEPROM_CFG); AR5K_PRINT_REGISTER(PCU_MIN); AR5K_PRINT_REGISTER(STA_ID0); AR5K_PRINT_REGISTER(STA_ID1); AR5K_PRINT_REGISTER(BSS_ID0); AR5K_PRINT_REGISTER(SLOT_TIME); AR5K_PRINT_REGISTER(TIME_OUT); AR5K_PRINT_REGISTER(RSSI_THR); AR5K_PRINT_REGISTER(BEACON); AR5K_PRINT_REGISTER(CFP_PERIOD); AR5K_PRINT_REGISTER(TIMER0); AR5K_PRINT_REGISTER(TIMER2); AR5K_PRINT_REGISTER(TIMER3); AR5K_PRINT_REGISTER(CFP_DUR); AR5K_PRINT_REGISTER(MCAST_FIL0); AR5K_PRINT_REGISTER(MCAST_FIL1); AR5K_PRINT_REGISTER(DIAG_SW); AR5K_PRINT_REGISTER(TSF_U32); AR5K_PRINT_REGISTER(ADDAC_TEST); AR5K_PRINT_REGISTER(DEFAULT_ANTENNA); AR5K_PRINT_REGISTER(LAST_TSTP); AR5K_PRINT_REGISTER(NAV); AR5K_PRINT_REGISTER(RTS_OK); AR5K_PRINT_REGISTER(ACK_FAIL); AR5K_PRINT_REGISTER(FCS_FAIL); AR5K_PRINT_REGISTER(BEACON_CNT); AR5K_PRINT_REGISTER(TSF_PARM); AR5K_PRINT_REGISTER(RATE_DUR_0); AR5K_PRINT_REGISTER(KEYTABLE_0); printf("\n"); printf("PHY registers:\n"); AR5K_PRINT_REGISTER(PHY_TURBO); AR5K_PRINT_REGISTER(PHY_AGC); AR5K_PRINT_REGISTER(PHY_TIMING_3); AR5K_PRINT_REGISTER(PHY_CHIP_ID); AR5K_PRINT_REGISTER(PHY_AGCCTL); AR5K_PRINT_REGISTER(PHY_NF); AR5K_PRINT_REGISTER(PHY_SCR); AR5K_PRINT_REGISTER(PHY_SLMT); AR5K_PRINT_REGISTER(PHY_SCAL); AR5K_PRINT_REGISTER(PHY_RX_DELAY); AR5K_PRINT_REGISTER(PHY_IQ); AR5K_PRINT_REGISTER(PHY_PAPD_PROBE); AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE1); AR5K_PRINT_REGISTER(PHY_TXPOWER_RATE2); AR5K_PRINT_REGISTER(PHY_FC); AR5K_PRINT_REGISTER(PHY_RADAR); AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_0); AR5K_PRINT_REGISTER(PHY_ANT_SWITCH_TABLE_1); printf("\n");#endif}HAL_BOOL /*Added arguments*/ar5k_ar5212_get_diag_state(struct ath_hal *hal, int request, const void *args, u_int32_t argsize, void **result, u_int32_t *resultsize){ AR5K_TRACE; /* * 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);}void /*O.K.*/ar5k_ar5212_get_lladdr(struct ath_hal *hal, u_int8_t *mac){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -