18fe65368SLuis R. Rodriguez /* 25b68138eSSujith Manoharan * Copyright (c) 2008-2011 Atheros Communications Inc. 38fe65368SLuis R. Rodriguez * 48fe65368SLuis R. Rodriguez * Permission to use, copy, modify, and/or distribute this software for any 58fe65368SLuis R. Rodriguez * purpose with or without fee is hereby granted, provided that the above 68fe65368SLuis R. Rodriguez * copyright notice and this permission notice appear in all copies. 78fe65368SLuis R. Rodriguez * 88fe65368SLuis R. Rodriguez * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98fe65368SLuis R. Rodriguez * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 108fe65368SLuis R. Rodriguez * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 118fe65368SLuis R. Rodriguez * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 128fe65368SLuis R. Rodriguez * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 138fe65368SLuis R. Rodriguez * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 148fe65368SLuis R. Rodriguez * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 158fe65368SLuis R. Rodriguez */ 168fe65368SLuis R. Rodriguez 178fe65368SLuis R. Rodriguez /** 188fe65368SLuis R. Rodriguez * DOC: Programming Atheros 802.11n analog front end radios 198fe65368SLuis R. Rodriguez * 208fe65368SLuis R. Rodriguez * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express 218fe65368SLuis R. Rodriguez * devices have either an external AR2133 analog front end radio for single 228fe65368SLuis R. Rodriguez * band 2.4 GHz communication or an AR5133 analog front end radio for dual 238fe65368SLuis R. Rodriguez * band 2.4 GHz / 5 GHz communication. 248fe65368SLuis R. Rodriguez * 258fe65368SLuis R. Rodriguez * All devices after the AR5416 and AR5418 family starting with the AR9280 268fe65368SLuis R. Rodriguez * have their analog front radios, MAC/BB and host PCIe/USB interface embedded 278fe65368SLuis R. Rodriguez * into a single-chip and require less programming. 288fe65368SLuis R. Rodriguez * 298fe65368SLuis R. Rodriguez * The following single-chips exist with a respective embedded radio: 308fe65368SLuis R. Rodriguez * 318fe65368SLuis R. Rodriguez * AR9280 - 11n dual-band 2x2 MIMO for PCIe 328fe65368SLuis R. Rodriguez * AR9281 - 11n single-band 1x2 MIMO for PCIe 338fe65368SLuis R. Rodriguez * AR9285 - 11n single-band 1x1 for PCIe 348fe65368SLuis R. Rodriguez * AR9287 - 11n single-band 2x2 MIMO for PCIe 358fe65368SLuis R. Rodriguez * 368fe65368SLuis R. Rodriguez * AR9220 - 11n dual-band 2x2 MIMO for PCI 378fe65368SLuis R. Rodriguez * AR9223 - 11n single-band 2x2 MIMO for PCI 388fe65368SLuis R. Rodriguez * 398fe65368SLuis R. Rodriguez * AR9287 - 11n single-band 1x1 MIMO for USB 408fe65368SLuis R. Rodriguez */ 418fe65368SLuis R. Rodriguez 428fe65368SLuis R. Rodriguez #include "hw.h" 438fe65368SLuis R. Rodriguez #include "ar9002_phy.h" 448fe65368SLuis R. Rodriguez 458fe65368SLuis R. Rodriguez /** 468fe65368SLuis R. Rodriguez * ar9002_hw_set_channel - set channel on single-chip device 478fe65368SLuis R. Rodriguez * @ah: atheros hardware structure 488fe65368SLuis R. Rodriguez * @chan: 498fe65368SLuis R. Rodriguez * 508fe65368SLuis R. Rodriguez * This is the function to change channel on single-chip devices, that is 518fe65368SLuis R. Rodriguez * all devices after ar9280. 528fe65368SLuis R. Rodriguez * 538fe65368SLuis R. Rodriguez * This function takes the channel value in MHz and sets 548fe65368SLuis R. Rodriguez * hardware channel value. Assumes writes have been enabled to analog bus. 558fe65368SLuis R. Rodriguez * 568fe65368SLuis R. Rodriguez * Actual Expression, 578fe65368SLuis R. Rodriguez * 588fe65368SLuis R. Rodriguez * For 2GHz channel, 598fe65368SLuis R. Rodriguez * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) 608fe65368SLuis R. Rodriguez * (freq_ref = 40MHz) 618fe65368SLuis R. Rodriguez * 628fe65368SLuis R. Rodriguez * For 5GHz channel, 638fe65368SLuis R. Rodriguez * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) 648fe65368SLuis R. Rodriguez * (freq_ref = 40MHz/(24>>amodeRefSel)) 658fe65368SLuis R. Rodriguez */ 668fe65368SLuis R. Rodriguez static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) 678fe65368SLuis R. Rodriguez { 688fe65368SLuis R. Rodriguez u16 bMode, fracMode, aModeRefSel = 0; 698fe65368SLuis R. Rodriguez u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; 708fe65368SLuis R. Rodriguez struct chan_centers centers; 718fe65368SLuis R. Rodriguez u32 refDivA = 24; 728fe65368SLuis R. Rodriguez 738fe65368SLuis R. Rodriguez ath9k_hw_get_channel_centers(ah, chan, ¢ers); 748fe65368SLuis R. Rodriguez freq = centers.synth_center; 758fe65368SLuis R. Rodriguez 768fe65368SLuis R. Rodriguez reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL); 778fe65368SLuis R. Rodriguez reg32 &= 0xc0000000; 788fe65368SLuis R. Rodriguez 798fe65368SLuis R. Rodriguez if (freq < 4800) { /* 2 GHz, fractional mode */ 808fe65368SLuis R. Rodriguez u32 txctl; 818fe65368SLuis R. Rodriguez int regWrites = 0; 828fe65368SLuis R. Rodriguez 838fe65368SLuis R. Rodriguez bMode = 1; 848fe65368SLuis R. Rodriguez fracMode = 1; 858fe65368SLuis R. Rodriguez aModeRefSel = 0; 867152451aSLuis R. Rodriguez channelSel = CHANSEL_2G(freq); 878fe65368SLuis R. Rodriguez 888fe65368SLuis R. Rodriguez if (AR_SREV_9287_11_OR_LATER(ah)) { 898fe65368SLuis R. Rodriguez if (freq == 2484) { 908fe65368SLuis R. Rodriguez /* Enable channel spreading for channel 14 */ 918fe65368SLuis R. Rodriguez REG_WRITE_ARRAY(&ah->iniCckfirJapan2484, 928fe65368SLuis R. Rodriguez 1, regWrites); 938fe65368SLuis R. Rodriguez } else { 948fe65368SLuis R. Rodriguez REG_WRITE_ARRAY(&ah->iniCckfirNormal, 958fe65368SLuis R. Rodriguez 1, regWrites); 968fe65368SLuis R. Rodriguez } 978fe65368SLuis R. Rodriguez } else { 988fe65368SLuis R. Rodriguez txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); 998fe65368SLuis R. Rodriguez if (freq == 2484) { 1008fe65368SLuis R. Rodriguez /* Enable channel spreading for channel 14 */ 1018fe65368SLuis R. Rodriguez REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 1028fe65368SLuis R. Rodriguez txctl | AR_PHY_CCK_TX_CTRL_JAPAN); 1038fe65368SLuis R. Rodriguez } else { 1048fe65368SLuis R. Rodriguez REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 1058fe65368SLuis R. Rodriguez txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); 1068fe65368SLuis R. Rodriguez } 1078fe65368SLuis R. Rodriguez } 1088fe65368SLuis R. Rodriguez } else { 1098fe65368SLuis R. Rodriguez bMode = 0; 1108fe65368SLuis R. Rodriguez fracMode = 0; 1118fe65368SLuis R. Rodriguez 1128fe65368SLuis R. Rodriguez switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) { 1138fe65368SLuis R. Rodriguez case 0: 1140407cf1cSFelix Fietkau if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) 1150407cf1cSFelix Fietkau aModeRefSel = 0; 1160407cf1cSFelix Fietkau else if ((freq % 20) == 0) 1178fe65368SLuis R. Rodriguez aModeRefSel = 3; 1188fe65368SLuis R. Rodriguez else if ((freq % 10) == 0) 1198fe65368SLuis R. Rodriguez aModeRefSel = 2; 1208fe65368SLuis R. Rodriguez if (aModeRefSel) 1218fe65368SLuis R. Rodriguez break; 122*221af813SGustavo A. R. Silva fallthrough; 1238fe65368SLuis R. Rodriguez case 1: 1248fe65368SLuis R. Rodriguez default: 1258fe65368SLuis R. Rodriguez aModeRefSel = 0; 1268fe65368SLuis R. Rodriguez /* 1278fe65368SLuis R. Rodriguez * Enable 2G (fractional) mode for channels 1288fe65368SLuis R. Rodriguez * which are 5MHz spaced. 1298fe65368SLuis R. Rodriguez */ 1308fe65368SLuis R. Rodriguez fracMode = 1; 1318fe65368SLuis R. Rodriguez refDivA = 1; 1327152451aSLuis R. Rodriguez channelSel = CHANSEL_5G(freq); 1338fe65368SLuis R. Rodriguez 1348fe65368SLuis R. Rodriguez /* RefDivA setting */ 13521394754SFelix Fietkau ath9k_hw_analog_shift_rmw(ah, AR_AN_SYNTH9, 13621394754SFelix Fietkau AR_AN_SYNTH9_REFDIVA, 13721394754SFelix Fietkau AR_AN_SYNTH9_REFDIVA_S, refDivA); 1388fe65368SLuis R. Rodriguez 1398fe65368SLuis R. Rodriguez } 1408fe65368SLuis R. Rodriguez 1418fe65368SLuis R. Rodriguez if (!fracMode) { 1428fe65368SLuis R. Rodriguez ndiv = (freq * (refDivA >> aModeRefSel)) / 60; 1438fe65368SLuis R. Rodriguez channelSel = ndiv & 0x1ff; 1448fe65368SLuis R. Rodriguez channelFrac = (ndiv & 0xfffffe00) * 2; 1458fe65368SLuis R. Rodriguez channelSel = (channelSel << 17) | channelFrac; 1468fe65368SLuis R. Rodriguez } 1478fe65368SLuis R. Rodriguez } 1488fe65368SLuis R. Rodriguez 1498fe65368SLuis R. Rodriguez reg32 = reg32 | 1508fe65368SLuis R. Rodriguez (bMode << 29) | 1518fe65368SLuis R. Rodriguez (fracMode << 28) | (aModeRefSel << 26) | (channelSel); 1528fe65368SLuis R. Rodriguez 1538fe65368SLuis R. Rodriguez REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); 1548fe65368SLuis R. Rodriguez 1558fe65368SLuis R. Rodriguez ah->curchan = chan; 1568fe65368SLuis R. Rodriguez 1578fe65368SLuis R. Rodriguez return 0; 1588fe65368SLuis R. Rodriguez } 1598fe65368SLuis R. Rodriguez 1608fe65368SLuis R. Rodriguez /** 1618fe65368SLuis R. Rodriguez * ar9002_hw_spur_mitigate - convert baseband spur frequency 1628fe65368SLuis R. Rodriguez * @ah: atheros hardware structure 1638fe65368SLuis R. Rodriguez * @chan: 1648fe65368SLuis R. Rodriguez * 1658fe65368SLuis R. Rodriguez * For single-chip solutions. Converts to baseband spur frequency given the 1668fe65368SLuis R. Rodriguez * input channel frequency and compute register settings below. 1678fe65368SLuis R. Rodriguez */ 1688fe65368SLuis R. Rodriguez static void ar9002_hw_spur_mitigate(struct ath_hw *ah, 1698fe65368SLuis R. Rodriguez struct ath9k_channel *chan) 1708fe65368SLuis R. Rodriguez { 1718fe65368SLuis R. Rodriguez int bb_spur = AR_NO_SPUR; 1728fe65368SLuis R. Rodriguez int freq; 173f911085fSOleksij Rempel int bin; 1748fe65368SLuis R. Rodriguez int bb_spur_off, spur_subchannel_sd; 1758fe65368SLuis R. Rodriguez int spur_freq_sd; 1768fe65368SLuis R. Rodriguez int spur_delta_phase; 1778fe65368SLuis R. Rodriguez int denominator; 1788fe65368SLuis R. Rodriguez int tmp, newVal; 1798fe65368SLuis R. Rodriguez int i; 1808fe65368SLuis R. Rodriguez struct chan_centers centers; 1818fe65368SLuis R. Rodriguez 1828fe65368SLuis R. Rodriguez int cur_bb_spur; 1838fe65368SLuis R. Rodriguez bool is2GHz = IS_CHAN_2GHZ(chan); 1848fe65368SLuis R. Rodriguez 1858fe65368SLuis R. Rodriguez ath9k_hw_get_channel_centers(ah, chan, ¢ers); 1868fe65368SLuis R. Rodriguez freq = centers.synth_center; 1878fe65368SLuis R. Rodriguez 1888fe65368SLuis R. Rodriguez for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 1898fe65368SLuis R. Rodriguez cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); 1908fe65368SLuis R. Rodriguez 19144cefeadSBrian Prodoehl if (AR_NO_SPUR == cur_bb_spur) 19244cefeadSBrian Prodoehl break; 19344cefeadSBrian Prodoehl 1948fe65368SLuis R. Rodriguez if (is2GHz) 1958fe65368SLuis R. Rodriguez cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; 1968fe65368SLuis R. Rodriguez else 1978fe65368SLuis R. Rodriguez cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; 1988fe65368SLuis R. Rodriguez 1998fe65368SLuis R. Rodriguez cur_bb_spur = cur_bb_spur - freq; 2008fe65368SLuis R. Rodriguez 2018fe65368SLuis R. Rodriguez if (IS_CHAN_HT40(chan)) { 2028fe65368SLuis R. Rodriguez if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && 2038fe65368SLuis R. Rodriguez (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { 2048fe65368SLuis R. Rodriguez bb_spur = cur_bb_spur; 2058fe65368SLuis R. Rodriguez break; 2068fe65368SLuis R. Rodriguez } 2078fe65368SLuis R. Rodriguez } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && 2088fe65368SLuis R. Rodriguez (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { 2098fe65368SLuis R. Rodriguez bb_spur = cur_bb_spur; 2108fe65368SLuis R. Rodriguez break; 2118fe65368SLuis R. Rodriguez } 2128fe65368SLuis R. Rodriguez } 2138fe65368SLuis R. Rodriguez 2148fe65368SLuis R. Rodriguez if (AR_NO_SPUR == bb_spur) { 2158fe65368SLuis R. Rodriguez REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, 2168fe65368SLuis R. Rodriguez AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 2178fe65368SLuis R. Rodriguez return; 2188fe65368SLuis R. Rodriguez } else { 2198fe65368SLuis R. Rodriguez REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, 2208fe65368SLuis R. Rodriguez AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); 2218fe65368SLuis R. Rodriguez } 2228fe65368SLuis R. Rodriguez 2238fe65368SLuis R. Rodriguez bin = bb_spur * 320; 2248fe65368SLuis R. Rodriguez 2258fe65368SLuis R. Rodriguez tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); 2268fe65368SLuis R. Rodriguez 2277d0d0df0SSujith ENABLE_REGWRITE_BUFFER(ah); 2287d0d0df0SSujith 2298fe65368SLuis R. Rodriguez newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 2308fe65368SLuis R. Rodriguez AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 2318fe65368SLuis R. Rodriguez AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 2328fe65368SLuis R. Rodriguez AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 2338fe65368SLuis R. Rodriguez REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal); 2348fe65368SLuis R. Rodriguez 2358fe65368SLuis R. Rodriguez newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | 2368fe65368SLuis R. Rodriguez AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 2378fe65368SLuis R. Rodriguez AR_PHY_SPUR_REG_MASK_RATE_SELECT | 2388fe65368SLuis R. Rodriguez AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 2398fe65368SLuis R. Rodriguez SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); 2408fe65368SLuis R. Rodriguez REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); 2418fe65368SLuis R. Rodriguez 2428fe65368SLuis R. Rodriguez if (IS_CHAN_HT40(chan)) { 2438fe65368SLuis R. Rodriguez if (bb_spur < 0) { 2448fe65368SLuis R. Rodriguez spur_subchannel_sd = 1; 2458fe65368SLuis R. Rodriguez bb_spur_off = bb_spur + 10; 2468fe65368SLuis R. Rodriguez } else { 2478fe65368SLuis R. Rodriguez spur_subchannel_sd = 0; 2488fe65368SLuis R. Rodriguez bb_spur_off = bb_spur - 10; 2498fe65368SLuis R. Rodriguez } 2508fe65368SLuis R. Rodriguez } else { 2518fe65368SLuis R. Rodriguez spur_subchannel_sd = 0; 2528fe65368SLuis R. Rodriguez bb_spur_off = bb_spur; 2538fe65368SLuis R. Rodriguez } 2548fe65368SLuis R. Rodriguez 2558fe65368SLuis R. Rodriguez if (IS_CHAN_HT40(chan)) 2568fe65368SLuis R. Rodriguez spur_delta_phase = 2578fe65368SLuis R. Rodriguez ((bb_spur * 262144) / 2588fe65368SLuis R. Rodriguez 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 2598fe65368SLuis R. Rodriguez else 2608fe65368SLuis R. Rodriguez spur_delta_phase = 2618fe65368SLuis R. Rodriguez ((bb_spur * 524288) / 2628fe65368SLuis R. Rodriguez 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; 2638fe65368SLuis R. Rodriguez 2648fe65368SLuis R. Rodriguez denominator = IS_CHAN_2GHZ(chan) ? 44 : 40; 2658fe65368SLuis R. Rodriguez spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; 2668fe65368SLuis R. Rodriguez 2678fe65368SLuis R. Rodriguez newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | 2688fe65368SLuis R. Rodriguez SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 2698fe65368SLuis R. Rodriguez SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 2708fe65368SLuis R. Rodriguez REG_WRITE(ah, AR_PHY_TIMING11, newVal); 2718fe65368SLuis R. Rodriguez 2728fe65368SLuis R. Rodriguez newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; 2738fe65368SLuis R. Rodriguez REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); 2748fe65368SLuis R. Rodriguez 275f911085fSOleksij Rempel ar5008_hw_cmn_spur_mitigate(ah, chan, bin); 2767d0d0df0SSujith 2777d0d0df0SSujith REGWRITE_BUFFER_FLUSH(ah); 2788fe65368SLuis R. Rodriguez } 2798fe65368SLuis R. Rodriguez 2808fe65368SLuis R. Rodriguez static void ar9002_olc_init(struct ath_hw *ah) 2818fe65368SLuis R. Rodriguez { 2828fe65368SLuis R. Rodriguez u32 i; 2838fe65368SLuis R. Rodriguez 2848fe65368SLuis R. Rodriguez if (!OLC_FOR_AR9280_20_LATER) 2858fe65368SLuis R. Rodriguez return; 2868fe65368SLuis R. Rodriguez 2878fe65368SLuis R. Rodriguez if (OLC_FOR_AR9287_10_LATER) { 2888fe65368SLuis R. Rodriguez REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9, 2898fe65368SLuis R. Rodriguez AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL); 2908fe65368SLuis R. Rodriguez ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0, 2918fe65368SLuis R. Rodriguez AR9287_AN_TXPC0_TXPCMODE, 2928fe65368SLuis R. Rodriguez AR9287_AN_TXPC0_TXPCMODE_S, 2938fe65368SLuis R. Rodriguez AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE); 2948fe65368SLuis R. Rodriguez udelay(100); 2958fe65368SLuis R. Rodriguez } else { 2968fe65368SLuis R. Rodriguez for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) 2978fe65368SLuis R. Rodriguez ah->originalGain[i] = 2988fe65368SLuis R. Rodriguez MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4), 2998fe65368SLuis R. Rodriguez AR_PHY_TX_GAIN); 3008fe65368SLuis R. Rodriguez ah->PDADCdelta = 0; 3018fe65368SLuis R. Rodriguez } 3028fe65368SLuis R. Rodriguez } 3038fe65368SLuis R. Rodriguez 30464773964SLuis R. Rodriguez static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah, 30564773964SLuis R. Rodriguez struct ath9k_channel *chan) 30664773964SLuis R. Rodriguez { 307804f6acbSFelix Fietkau int ref_div = 5; 308804f6acbSFelix Fietkau int pll_div = 0x2c; 30964773964SLuis R. Rodriguez u32 pll; 31064773964SLuis R. Rodriguez 311804f6acbSFelix Fietkau if (chan && IS_CHAN_5GHZ(chan) && !IS_CHAN_A_FAST_CLOCK(ah, chan)) { 312804f6acbSFelix Fietkau if (AR_SREV_9280_20(ah)) { 313804f6acbSFelix Fietkau ref_div = 10; 314804f6acbSFelix Fietkau pll_div = 0x50; 315804f6acbSFelix Fietkau } else { 316804f6acbSFelix Fietkau pll_div = 0x28; 317804f6acbSFelix Fietkau } 318804f6acbSFelix Fietkau } 319804f6acbSFelix Fietkau 320804f6acbSFelix Fietkau pll = SM(ref_div, AR_RTC_9160_PLL_REFDIV); 321804f6acbSFelix Fietkau pll |= SM(pll_div, AR_RTC_9160_PLL_DIV); 32264773964SLuis R. Rodriguez 32364773964SLuis R. Rodriguez if (chan && IS_CHAN_HALF_RATE(chan)) 32464773964SLuis R. Rodriguez pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); 32564773964SLuis R. Rodriguez else if (chan && IS_CHAN_QUARTER_RATE(chan)) 32664773964SLuis R. Rodriguez pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); 32764773964SLuis R. Rodriguez 32864773964SLuis R. Rodriguez return pll; 32964773964SLuis R. Rodriguez } 33064773964SLuis R. Rodriguez 331641d9921SFelix Fietkau static void ar9002_hw_do_getnf(struct ath_hw *ah, 332641d9921SFelix Fietkau int16_t nfarray[NUM_NF_READINGS]) 333641d9921SFelix Fietkau { 334641d9921SFelix Fietkau int16_t nf; 335641d9921SFelix Fietkau 336641d9921SFelix Fietkau nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); 3377919a57bSAndreas Herrmann nfarray[0] = sign_extend32(nf, 8); 338641d9921SFelix Fietkau 339641d9921SFelix Fietkau nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); 340866b7780SFelix Fietkau if (IS_CHAN_HT40(ah->curchan)) 3417919a57bSAndreas Herrmann nfarray[3] = sign_extend32(nf, 8); 342641d9921SFelix Fietkau 3438a5b7ab3SSujith Manoharan if (!(ah->rxchainmask & BIT(1))) 34454bd5006SFelix Fietkau return; 345641d9921SFelix Fietkau 34654bd5006SFelix Fietkau nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); 3477919a57bSAndreas Herrmann nfarray[1] = sign_extend32(nf, 8); 348641d9921SFelix Fietkau 34954bd5006SFelix Fietkau nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); 350866b7780SFelix Fietkau if (IS_CHAN_HT40(ah->curchan)) 3517919a57bSAndreas Herrmann nfarray[4] = sign_extend32(nf, 8); 352641d9921SFelix Fietkau } 353641d9921SFelix Fietkau 354f2552e28SFelix Fietkau static void ar9002_hw_set_nf_limits(struct ath_hw *ah) 355f2552e28SFelix Fietkau { 356f2552e28SFelix Fietkau if (AR_SREV_9285(ah)) { 357f2552e28SFelix Fietkau ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ; 358f2552e28SFelix Fietkau ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ; 359f2552e28SFelix Fietkau ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ; 360f2552e28SFelix Fietkau } else if (AR_SREV_9287(ah)) { 361f2552e28SFelix Fietkau ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ; 362f2552e28SFelix Fietkau ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ; 363f2552e28SFelix Fietkau ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ; 364f2552e28SFelix Fietkau } else if (AR_SREV_9271(ah)) { 365f2552e28SFelix Fietkau ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ; 366f2552e28SFelix Fietkau ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ; 367f2552e28SFelix Fietkau ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9271_2GHZ; 368f2552e28SFelix Fietkau } else { 369f2552e28SFelix Fietkau ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ; 370f2552e28SFelix Fietkau ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ; 371f2552e28SFelix Fietkau ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ; 372f2552e28SFelix Fietkau ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ; 373f2552e28SFelix Fietkau ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ; 374f2552e28SFelix Fietkau ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ; 375f2552e28SFelix Fietkau } 376f2552e28SFelix Fietkau } 377f2552e28SFelix Fietkau 37869de3721SMohammed Shafi Shajakhan static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah, 37921cc630fSVasanthakumar Thiagarajan struct ath_hw_antcomb_conf *antconf) 38021cc630fSVasanthakumar Thiagarajan { 38121cc630fSVasanthakumar Thiagarajan u32 regval; 38221cc630fSVasanthakumar Thiagarajan 38321cc630fSVasanthakumar Thiagarajan regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 38421cc630fSVasanthakumar Thiagarajan antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >> 38521cc630fSVasanthakumar Thiagarajan AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S; 38621cc630fSVasanthakumar Thiagarajan antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >> 38721cc630fSVasanthakumar Thiagarajan AR_PHY_9285_ANT_DIV_ALT_LNACONF_S; 38821cc630fSVasanthakumar Thiagarajan antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >> 38921cc630fSVasanthakumar Thiagarajan AR_PHY_9285_FAST_DIV_BIAS_S; 390f96bd2adSSujith Manoharan antconf->lna1_lna2_switch_delta = -1; 3918afbcc8bSMohammed Shafi Shajakhan antconf->lna1_lna2_delta = -3; 3928afbcc8bSMohammed Shafi Shajakhan antconf->div_group = 0; 39321cc630fSVasanthakumar Thiagarajan } 39421cc630fSVasanthakumar Thiagarajan 39569de3721SMohammed Shafi Shajakhan static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah, 39621cc630fSVasanthakumar Thiagarajan struct ath_hw_antcomb_conf *antconf) 39721cc630fSVasanthakumar Thiagarajan { 39821cc630fSVasanthakumar Thiagarajan u32 regval; 39921cc630fSVasanthakumar Thiagarajan 40021cc630fSVasanthakumar Thiagarajan regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 40121cc630fSVasanthakumar Thiagarajan regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF | 40221cc630fSVasanthakumar Thiagarajan AR_PHY_9285_ANT_DIV_ALT_LNACONF | 40321cc630fSVasanthakumar Thiagarajan AR_PHY_9285_FAST_DIV_BIAS); 40421cc630fSVasanthakumar Thiagarajan regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S) 40521cc630fSVasanthakumar Thiagarajan & AR_PHY_9285_ANT_DIV_MAIN_LNACONF); 40621cc630fSVasanthakumar Thiagarajan regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S) 40721cc630fSVasanthakumar Thiagarajan & AR_PHY_9285_ANT_DIV_ALT_LNACONF); 40821cc630fSVasanthakumar Thiagarajan regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S) 40921cc630fSVasanthakumar Thiagarajan & AR_PHY_9285_FAST_DIV_BIAS); 41021cc630fSVasanthakumar Thiagarajan 41121cc630fSVasanthakumar Thiagarajan REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); 41221cc630fSVasanthakumar Thiagarajan } 41369de3721SMohammed Shafi Shajakhan 41436e8825eSSujith Manoharan #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 41536e8825eSSujith Manoharan 416d7150908SSujith Manoharan static void ar9002_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) 417d7150908SSujith Manoharan { 418d7150908SSujith Manoharan struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; 419d7150908SSujith Manoharan u8 antdiv_ctrl1, antdiv_ctrl2; 420d7150908SSujith Manoharan u32 regval; 421d7150908SSujith Manoharan 422d7150908SSujith Manoharan if (enable) { 423d7150908SSujith Manoharan antdiv_ctrl1 = ATH_BT_COEX_ANTDIV_CONTROL1_ENABLE; 424d7150908SSujith Manoharan antdiv_ctrl2 = ATH_BT_COEX_ANTDIV_CONTROL2_ENABLE; 425d7150908SSujith Manoharan 426d7150908SSujith Manoharan /* 427d7150908SSujith Manoharan * Don't disable BT ant to allow BB to control SWCOM. 428d7150908SSujith Manoharan */ 429d7150908SSujith Manoharan btcoex->bt_coex_mode2 &= (~(AR_BT_DISABLE_BT_ANT)); 430d7150908SSujith Manoharan REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2); 431d7150908SSujith Manoharan 432d7150908SSujith Manoharan REG_WRITE(ah, AR_PHY_SWITCH_COM, ATH_BT_COEX_ANT_DIV_SWITCH_COM); 433d7150908SSujith Manoharan REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000); 434d7150908SSujith Manoharan } else { 435d7150908SSujith Manoharan /* 436d7150908SSujith Manoharan * Disable antenna diversity, use LNA1 only. 437d7150908SSujith Manoharan */ 438d7150908SSujith Manoharan antdiv_ctrl1 = ATH_BT_COEX_ANTDIV_CONTROL1_FIXED_A; 439d7150908SSujith Manoharan antdiv_ctrl2 = ATH_BT_COEX_ANTDIV_CONTROL2_FIXED_A; 440d7150908SSujith Manoharan 441d7150908SSujith Manoharan /* 442d7150908SSujith Manoharan * Disable BT Ant. to allow concurrent BT and WLAN receive. 443d7150908SSujith Manoharan */ 444d7150908SSujith Manoharan btcoex->bt_coex_mode2 |= AR_BT_DISABLE_BT_ANT; 445d7150908SSujith Manoharan REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2); 446d7150908SSujith Manoharan 447d7150908SSujith Manoharan /* 448d7150908SSujith Manoharan * Program SWCOM table to make sure RF switch always parks 449d7150908SSujith Manoharan * at BT side. 450d7150908SSujith Manoharan */ 451d7150908SSujith Manoharan REG_WRITE(ah, AR_PHY_SWITCH_COM, 0); 452d7150908SSujith Manoharan REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000); 453d7150908SSujith Manoharan } 454d7150908SSujith Manoharan 455d7150908SSujith Manoharan regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); 456d7150908SSujith Manoharan regval &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL)); 457d7150908SSujith Manoharan /* 458d7150908SSujith Manoharan * Clear ant_fast_div_bias [14:9] since for WB195, 459d7150908SSujith Manoharan * the main LNA is always LNA1. 460d7150908SSujith Manoharan */ 461d7150908SSujith Manoharan regval &= (~(AR_PHY_9285_FAST_DIV_BIAS)); 462d7150908SSujith Manoharan regval |= SM(antdiv_ctrl1, AR_PHY_9285_ANT_DIV_CTL); 463d7150908SSujith Manoharan regval |= SM(antdiv_ctrl2, AR_PHY_9285_ANT_DIV_ALT_LNACONF); 464d7150908SSujith Manoharan regval |= SM((antdiv_ctrl2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF); 465d7150908SSujith Manoharan regval |= SM((antdiv_ctrl1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB); 466d7150908SSujith Manoharan regval |= SM((antdiv_ctrl1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB); 467d7150908SSujith Manoharan REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); 468d7150908SSujith Manoharan 469d7150908SSujith Manoharan regval = REG_READ(ah, AR_PHY_CCK_DETECT); 470d7150908SSujith Manoharan regval &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 471d7150908SSujith Manoharan regval |= SM((antdiv_ctrl1 >> 3), AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); 472d7150908SSujith Manoharan REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 473d7150908SSujith Manoharan } 474d7150908SSujith Manoharan 47536e8825eSSujith Manoharan #endif 47636e8825eSSujith Manoharan 477e2d4a24eSFengguang Wu static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, 478e93d083fSSimon Wunderlich struct ath_spec_scan *param) 479e93d083fSSimon Wunderlich { 4807d6c2d1eSFelix Fietkau u32 repeat_bit; 481e93d083fSSimon Wunderlich u8 count; 482e93d083fSSimon Wunderlich 483e93d083fSSimon Wunderlich if (!param->enabled) { 484e93d083fSSimon Wunderlich REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, 485e93d083fSSimon Wunderlich AR_PHY_SPECTRAL_SCAN_ENABLE); 486e93d083fSSimon Wunderlich return; 487e93d083fSSimon Wunderlich } 488e93d083fSSimon Wunderlich REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA); 489e93d083fSSimon Wunderlich REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); 490e93d083fSSimon Wunderlich 4917d6c2d1eSFelix Fietkau if (AR_SREV_9280(ah)) 4927d6c2d1eSFelix Fietkau repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 493e93d083fSSimon Wunderlich else 4947d6c2d1eSFelix Fietkau repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; 4957d6c2d1eSFelix Fietkau 4967d6c2d1eSFelix Fietkau if (param->short_repeat) 4977d6c2d1eSFelix Fietkau REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit); 4987d6c2d1eSFelix Fietkau else 4997d6c2d1eSFelix Fietkau REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit); 500e93d083fSSimon Wunderlich 501e93d083fSSimon Wunderlich /* on AR92xx, the highest bit of count will make the the chip send 502e93d083fSSimon Wunderlich * spectral samples endlessly. Check if this really was intended, 503e93d083fSSimon Wunderlich * and fix otherwise. 504e93d083fSSimon Wunderlich */ 505e93d083fSSimon Wunderlich count = param->count; 50646140ddfSOleksij Rempel if (param->endless) { 5077d6c2d1eSFelix Fietkau if (AR_SREV_9280(ah)) 508aad12edeSSimon Wunderlich count = 0x80; 5097d6c2d1eSFelix Fietkau else 5107d6c2d1eSFelix Fietkau count = 0; 51146140ddfSOleksij Rempel } else if (count & 0x80) 512e93d083fSSimon Wunderlich count = 0x7f; 5137d6c2d1eSFelix Fietkau else if (!count) 5147d6c2d1eSFelix Fietkau count = 1; 515e93d083fSSimon Wunderlich 5167d6c2d1eSFelix Fietkau if (AR_SREV_9280(ah)) { 517e93d083fSSimon Wunderlich REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, 518e93d083fSSimon Wunderlich AR_PHY_SPECTRAL_SCAN_COUNT, count); 5197d6c2d1eSFelix Fietkau } else { 5207d6c2d1eSFelix Fietkau REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, 5217d6c2d1eSFelix Fietkau AR_PHY_SPECTRAL_SCAN_COUNT_KIWI, count); 5227d6c2d1eSFelix Fietkau REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, 5237d6c2d1eSFelix Fietkau AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT); 5247d6c2d1eSFelix Fietkau } 5257d6c2d1eSFelix Fietkau 526e93d083fSSimon Wunderlich REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, 527e93d083fSSimon Wunderlich AR_PHY_SPECTRAL_SCAN_PERIOD, param->period); 528e93d083fSSimon Wunderlich REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, 529e93d083fSSimon Wunderlich AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period); 530e93d083fSSimon Wunderlich 531e93d083fSSimon Wunderlich return; 532e93d083fSSimon Wunderlich } 533e93d083fSSimon Wunderlich 534e93d083fSSimon Wunderlich static void ar9002_hw_spectral_scan_trigger(struct ath_hw *ah) 535e93d083fSSimon Wunderlich { 536e93d083fSSimon Wunderlich REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); 537e93d083fSSimon Wunderlich /* Activate spectral scan */ 538e93d083fSSimon Wunderlich REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, 539e93d083fSSimon Wunderlich AR_PHY_SPECTRAL_SCAN_ACTIVE); 540e93d083fSSimon Wunderlich } 541e93d083fSSimon Wunderlich 542e93d083fSSimon Wunderlich static void ar9002_hw_spectral_scan_wait(struct ath_hw *ah) 543e93d083fSSimon Wunderlich { 544e93d083fSSimon Wunderlich struct ath_common *common = ath9k_hw_common(ah); 545e93d083fSSimon Wunderlich 546e93d083fSSimon Wunderlich /* Poll for spectral scan complete */ 547e93d083fSSimon Wunderlich if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN, 548e93d083fSSimon Wunderlich AR_PHY_SPECTRAL_SCAN_ACTIVE, 549e93d083fSSimon Wunderlich 0, AH_WAIT_TIMEOUT)) { 550e93d083fSSimon Wunderlich ath_err(common, "spectral scan wait failed\n"); 551e93d083fSSimon Wunderlich return; 552e93d083fSSimon Wunderlich } 553e93d083fSSimon Wunderlich } 554e93d083fSSimon Wunderlich 55589f927afSLuis R. Rodriguez static void ar9002_hw_tx99_start(struct ath_hw *ah, u32 qnum) 55689f927afSLuis R. Rodriguez { 55789f927afSLuis R. Rodriguez REG_SET_BIT(ah, 0x9864, 0x7f000); 55889f927afSLuis R. Rodriguez REG_SET_BIT(ah, 0x9924, 0x7f00fe); 55989f927afSLuis R. Rodriguez REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); 56089f927afSLuis R. Rodriguez REG_WRITE(ah, AR_CR, AR_CR_RXD); 56189f927afSLuis R. Rodriguez REG_WRITE(ah, AR_DLCL_IFS(qnum), 0); 56289f927afSLuis R. Rodriguez REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 20); 56389f927afSLuis R. Rodriguez REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 20); 56489f927afSLuis R. Rodriguez REG_WRITE(ah, AR_D_FPCTL, 0x10|qnum); 56589f927afSLuis R. Rodriguez REG_WRITE(ah, AR_TIME_OUT, 0x00000400); 56689f927afSLuis R. Rodriguez REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff); 56789f927afSLuis R. Rodriguez REG_SET_BIT(ah, AR_QMISC(qnum), AR_Q_MISC_DCU_EARLY_TERM_REQ); 56889f927afSLuis R. Rodriguez } 56989f927afSLuis R. Rodriguez 57089f927afSLuis R. Rodriguez static void ar9002_hw_tx99_stop(struct ath_hw *ah) 57189f927afSLuis R. Rodriguez { 57289f927afSLuis R. Rodriguez REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); 57389f927afSLuis R. Rodriguez } 57489f927afSLuis R. Rodriguez 57569de3721SMohammed Shafi Shajakhan void ar9002_hw_attach_phy_ops(struct ath_hw *ah) 57669de3721SMohammed Shafi Shajakhan { 57769de3721SMohammed Shafi Shajakhan struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 57869de3721SMohammed Shafi Shajakhan struct ath_hw_ops *ops = ath9k_hw_ops(ah); 57969de3721SMohammed Shafi Shajakhan 58069de3721SMohammed Shafi Shajakhan priv_ops->set_rf_regs = NULL; 58169de3721SMohammed Shafi Shajakhan priv_ops->rf_set_freq = ar9002_hw_set_channel; 58269de3721SMohammed Shafi Shajakhan priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate; 58369de3721SMohammed Shafi Shajakhan priv_ops->olc_init = ar9002_olc_init; 58469de3721SMohammed Shafi Shajakhan priv_ops->compute_pll_control = ar9002_hw_compute_pll_control; 58569de3721SMohammed Shafi Shajakhan priv_ops->do_getnf = ar9002_hw_do_getnf; 58669de3721SMohammed Shafi Shajakhan 58769de3721SMohammed Shafi Shajakhan ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; 58869de3721SMohammed Shafi Shajakhan ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; 589e93d083fSSimon Wunderlich ops->spectral_scan_config = ar9002_hw_spectral_scan_config; 590e93d083fSSimon Wunderlich ops->spectral_scan_trigger = ar9002_hw_spectral_scan_trigger; 591e93d083fSSimon Wunderlich ops->spectral_scan_wait = ar9002_hw_spectral_scan_wait; 59269de3721SMohammed Shafi Shajakhan 59336e8825eSSujith Manoharan #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 59436e8825eSSujith Manoharan ops->set_bt_ant_diversity = ar9002_hw_set_bt_ant_diversity; 59536e8825eSSujith Manoharan #endif 59689f927afSLuis R. Rodriguez ops->tx99_start = ar9002_hw_tx99_start; 59789f927afSLuis R. Rodriguez ops->tx99_stop = ar9002_hw_tx99_stop; 59836e8825eSSujith Manoharan 59969de3721SMohammed Shafi Shajakhan ar9002_hw_set_nf_limits(ah); 60069de3721SMohammed Shafi Shajakhan } 601