static void ath_fill_led_pin(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; /* Set default led pin if invalid */ if (ah->led_pin < 0) { if (AR_SREV_9287(ah)) ah->led_pin = ATH_LED_PIN_9287; else if (AR_SREV_9485(ah)) ah->led_pin = ATH_LED_PIN_9485; else if (AR_SREV_9300(ah)) ah->led_pin = ATH_LED_PIN_9300; else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) ah->led_pin = ATH_LED_PIN_9462; else ah->led_pin = ATH_LED_PIN_DEF; } /* Configure gpio for output */ ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led", AR_GPIO_OUTPUT_MUX_AS_OUTPUT); /* LED off, active low */ ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1); }
void ath_init_leds(struct ath_softc *sc) { char *trigger; int ret; if (AR_SREV_9287(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9287; else if (AR_SREV_9300(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9300; else sc->sc_ah->led_pin = ATH_LED_PIN_DEF; /* Configure gpio 1 for output */ ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); /* LED off, active low */ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); if (led_blink) INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); trigger = ieee80211_get_radio_led_name(sc->hw); snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); ret = ath_register_led(sc, &sc->radio_led, trigger); sc->radio_led.led_type = ATH_LED_RADIO; if (ret) goto fail; trigger = ieee80211_get_assoc_led_name(sc->hw); snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); ret = ath_register_led(sc, &sc->assoc_led, trigger); sc->assoc_led.led_type = ATH_LED_ASSOC; if (ret) goto fail; trigger = ieee80211_get_tx_led_name(sc->hw); snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); ret = ath_register_led(sc, &sc->tx_led, trigger); sc->tx_led.led_type = ATH_LED_TX; if (ret) goto fail; trigger = ieee80211_get_rx_led_name(sc->hw); snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); ret = ath_register_led(sc, &sc->rx_led, trigger); sc->rx_led.led_type = ATH_LED_RX; if (ret) goto fail; return; fail: if (led_blink) cancel_delayed_work_sync(&sc->ath_led_blink_work); ath_deinit_leds(sc); }
void ath9k_init_leds(struct ath9k_htc_priv *priv) { int ret; if (AR_SREV_9287(priv->ah)) priv->ah->led_pin = ATH_LED_PIN_9287; else if (AR_SREV_9271(priv->ah)) priv->ah->led_pin = ATH_LED_PIN_9271; else if (AR_DEVID_7010(priv->ah)) priv->ah->led_pin = ATH_LED_PIN_7010; else priv->ah->led_pin = ATH_LED_PIN_DEF; /* Configure gpio 1 for output */ ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); /* LED off, active low */ ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); snprintf(priv->led_name, sizeof(priv->led_name), "ath9k_htc-%s", wiphy_name(priv->hw->wiphy)); priv->led_cdev.name = priv->led_name; priv->led_cdev.brightness_set = ath9k_led_brightness; ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev); if (ret < 0) return; INIT_WORK(&priv->led_work, ath9k_led_work); priv->led_registered = true; return; }
void ath_init_leds(struct ath_softc *sc) { int ret; if (AR_SREV_9100(sc->sc_ah)) return; if (sc->sc_ah->led_pin < 0) { if (AR_SREV_9287(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9287; else if (AR_SREV_9485(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9485; else if (AR_SREV_9300(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9300; else if (AR_SREV_9462(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9462; else sc->sc_ah->led_pin = ATH_LED_PIN_DEF; } /* Configure gpio 1 for output */ ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); /* LED off, active low */ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); if (!led_blink) sc->led_cdev.default_trigger = ieee80211_get_radio_led_name(sc->hw); snprintf(sc->led_name, sizeof(sc->led_name), "ath9k-%s", wiphy_name(sc->hw->wiphy)); sc->led_cdev.name = sc->led_name; sc->led_cdev.brightness_set = ath_led_brightness; ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); if (ret < 0) return; sc->led_registered = true; }
int ath9k_hw_eeprom_init(struct ath_hw *ah) { int status; if (AR_SREV_9300_20_OR_LATER(ah)) ah->eep_ops = &eep_ar9300_ops; else if (AR_SREV_9287(ah)) { ah->eep_ops = &eep_ar9287_ops; } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { ah->eep_ops = &eep_4k_ops; } else { ah->eep_ops = &eep_def_ops; } if (!ah->eep_ops->fill_eeprom(ah)) return -EIO; status = ah->eep_ops->check_eeprom(ah); return status; }
int ath9k_hw_eeprom_init(struct ath_hw *ah) { int status; if (AR_SREV_9287(ah)) { ah->eep_map = EEP_MAP_AR9287; ah->eep_ops = &eep_AR9287_ops; } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { ah->eep_map = EEP_MAP_4KBITS; ah->eep_ops = &eep_4k_ops; } else { ah->eep_map = EEP_MAP_DEFAULT; ah->eep_ops = &eep_def_ops; } if (!ah->eep_ops->fill_eeprom(ah)) return -EIO; status = ah->eep_ops->check_eeprom(ah); return status; }
void ath_fill_led_pin(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; if (AR_SREV_9100(ah) || (ah->led_pin >= 0)) return; if (AR_SREV_9287(ah)) ah->led_pin = ATH_LED_PIN_9287; else if (AR_SREV_9485(sc->sc_ah)) ah->led_pin = ATH_LED_PIN_9485; else if (AR_SREV_9300(sc->sc_ah)) ah->led_pin = ATH_LED_PIN_9300; else if (AR_SREV_9462(sc->sc_ah) || AR_SREV_9565(sc->sc_ah)) ah->led_pin = ATH_LED_PIN_9462; else ah->led_pin = ATH_LED_PIN_DEF; /* Configure gpio 1 for output */ ath9k_hw_cfg_output(ah, ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); /* LED off, active low */ ath9k_hw_set_gpio(ah, ah->led_pin, 1); }
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) { int i, j; s16 noise_floor; if (AR_SREV_9280(ah)) noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; else if (AR_SREV_9287(ah)) noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; else noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE; for (i = 0; i < NUM_NF_READINGS; i++) { ah->nfCalHist[i].currIndex = 0; ah->nfCalHist[i].privNF = noise_floor; ah->nfCalHist[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH; for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { ah->nfCalHist[i].nfCalBuffer[j] = noise_floor; } } }
void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, struct ath9k_channel *chan, void *pRawDataSet, u8 *bChans, u16 availPiers, u16 tPdGainOverlap, u16 *pPdGainBoundaries, u8 *pPDADCValues, u16 numXpdGains) { int i, j, k; int16_t ss; u16 idxL = 0, idxR = 0, numPiers; static u8 vpdTableL[AR5416_NUM_PD_GAINS] [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; static u8 vpdTableR[AR5416_NUM_PD_GAINS] [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; static u8 vpdTableI[AR5416_NUM_PD_GAINS] [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; u8 minPwrT4[AR5416_NUM_PD_GAINS]; u8 maxPwrT4[AR5416_NUM_PD_GAINS]; int16_t vpdStep; int16_t tmpVal; u16 sizeCurrVpdTable, maxIndex, tgtIndex; bool match; int16_t minDelta = 0; struct chan_centers centers; int pdgain_boundary_default; struct cal_data_per_freq *data_def = pRawDataSet; struct cal_data_per_freq_4k *data_4k = pRawDataSet; struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet; bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah); int intercepts; if (AR_SREV_9287(ah)) intercepts = AR9287_PD_GAIN_ICEPTS; else intercepts = AR5416_PD_GAIN_ICEPTS; memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { if (bChans[numPiers] == AR5416_BCHAN_UNUSED) break; } match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), bChans, numPiers, &idxL, &idxR); if (match) { if (AR_SREV_9287(ah)) { /* FIXME: array overrun? */ for (i = 0; i < numXpdGains; i++) { minPwrT4[i] = data_9287[idxL].pwrPdg[i][0]; maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_9287[idxL].pwrPdg[i], data_9287[idxL].vpdPdg[i], intercepts, vpdTableI[i]); } } else if (eeprom_4k) { for (i = 0; i < numXpdGains; i++) { minPwrT4[i] = data_4k[idxL].pwrPdg[i][0]; maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_4k[idxL].pwrPdg[i], data_4k[idxL].vpdPdg[i], intercepts, vpdTableI[i]); } } else { for (i = 0; i < numXpdGains; i++) { minPwrT4[i] = data_def[idxL].pwrPdg[i][0]; maxPwrT4[i] = data_def[idxL].pwrPdg[i][4]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_def[idxL].pwrPdg[i], data_def[idxL].vpdPdg[i], intercepts, vpdTableI[i]); } } } else { for (i = 0; i < numXpdGains; i++) { if (AR_SREV_9287(ah)) { pVpdL = data_9287[idxL].vpdPdg[i]; pPwrL = data_9287[idxL].pwrPdg[i]; pVpdR = data_9287[idxR].vpdPdg[i]; pPwrR = data_9287[idxR].pwrPdg[i]; } else if (eeprom_4k) { pVpdL = data_4k[idxL].vpdPdg[i]; pPwrL = data_4k[idxL].pwrPdg[i]; pVpdR = data_4k[idxR].vpdPdg[i]; pPwrR = data_4k[idxR].pwrPdg[i]; } else { pVpdL = data_def[idxL].vpdPdg[i]; pPwrL = data_def[idxL].pwrPdg[i]; pVpdR = data_def[idxR].vpdPdg[i]; pPwrR = data_def[idxR].pwrPdg[i]; } minPwrT4[i] = max(pPwrL[0], pPwrR[0]); maxPwrT4[i] = min(pPwrL[intercepts - 1], pPwrR[intercepts - 1]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, intercepts, vpdTableL[i]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, intercepts, vpdTableR[i]); for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { vpdTableI[i][j] = (u8)(ath9k_hw_interpolate((u16) FREQ2FBIN(centers. synth_center, IS_CHAN_2GHZ (chan)), bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j])); } } } k = 0; for (i = 0; i < numXpdGains; i++) { if (i == (numXpdGains - 1)) pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2); else pPdGainBoundaries[i] = (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); pPdGainBoundaries[i] = min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); minDelta = 0; if (i == 0) { if (AR_SREV_9280_20_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; } else { ss = (int16_t)((pPdGainBoundaries[i - 1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta); } vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); ss++; } sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2)); maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { pPDADCValues[k++] = vpdTableI[i][ss++]; } vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]); vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); if (tgtIndex >= maxIndex) { while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); pPDADCValues[k++] = (u8)((tmpVal > 255) ? 255 : tmpVal); ss++; } } } if (eeprom_4k) pdgain_boundary_default = 58; else pdgain_boundary_default = pPdGainBoundaries[i - 1]; while (i < AR5416_PD_GAINS_IN_MASK) { pPdGainBoundaries[i] = pdgain_boundary_default; i++; } while (k < AR5416_NUM_PDADC_VALUES) { pPDADCValues[k] = pPDADCValues[k - 1]; k++; } }
static void ath9k_hw_do_getnf(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]) { int16_t nf; if (AR_SREV_9280_10_OR_LATER(ah)) nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); else nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ctl] [chain 0] is %d\n", nf); nfarray[0] = nf; if (!AR_SREV_9285(ah)) { if (AR_SREV_9280_10_OR_LATER(ah)) nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); else nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ctl] [chain 1] is %d\n", nf); nfarray[1] = nf; if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ctl] [chain 2] is %d\n", nf); nfarray[2] = nf; } } if (AR_SREV_9280_10_OR_LATER(ah)) nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); else nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ext] [chain 0] is %d\n", nf); nfarray[3] = nf; if (!AR_SREV_9285(ah)) { if (AR_SREV_9280_10_OR_LATER(ah)) nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); else nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ext] [chain 1] is %d\n", nf); nfarray[4] = nf; if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ext] [chain 2] is %d\n", nf); nfarray[5] = nf; } } }
void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath9k_nfcal_hist *h; int i, j; int32_t val; const u32 ar5416_cca_regs[6] = { AR_PHY_CCA, AR_PHY_CH1_CCA, AR_PHY_CH2_CCA, AR_PHY_EXT_CCA, AR_PHY_CH1_EXT_CCA, AR_PHY_CH2_EXT_CCA }; u8 chainmask, rx_chain_status; rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK); if (AR_SREV_9285(ah)) chainmask = 0x9; else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4)) chainmask = 0x1B; else chainmask = 0x09; } else { if (rx_chain_status & 0x4) chainmask = 0x3F; else if (rx_chain_status & 0x2) chainmask = 0x1B; else chainmask = 0x09; } h = ah->nfCalHist; for (i = 0; i < NUM_NF_READINGS; i++) { if (chainmask & (1 << i)) { val = REG_READ(ah, ar5416_cca_regs[i]); val &= 0xFFFFFE00; val |= (((u32) (h[i].privNF) << 1) & 0x1ff); REG_WRITE(ah, ar5416_cca_regs[i], val); } } REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF); REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); for (j = 0; j < 1000; j++) { if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) break; udelay(10); } for (i = 0; i < NUM_NF_READINGS; i++) { if (chainmask & (1 << i)) { val = REG_READ(ah, ar5416_cca_regs[i]); val &= 0xFFFFFE00; val |= (((u32) (-50) << 1) & 0x1ff); REG_WRITE(ah, ar5416_cca_regs[i], val); } } }