1*d2dd70acSstsp /* $OpenBSD: athnvar.h,v 1.42 2021/04/15 18:25:43 stsp Exp $ */ 2498e8a28Sdamien 3498e8a28Sdamien /*- 4498e8a28Sdamien * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> 5498e8a28Sdamien * 6498e8a28Sdamien * Permission to use, copy, modify, and distribute this software for any 7498e8a28Sdamien * purpose with or without fee is hereby granted, provided that the above 8498e8a28Sdamien * copyright notice and this permission notice appear in all copies. 9498e8a28Sdamien * 10498e8a28Sdamien * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11498e8a28Sdamien * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12498e8a28Sdamien * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13498e8a28Sdamien * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14498e8a28Sdamien * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15498e8a28Sdamien * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16498e8a28Sdamien * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17498e8a28Sdamien */ 18498e8a28Sdamien 19c0a11cf8Sdamien #ifdef notyet 20c0a11cf8Sdamien #define ATHN_BT_COEXISTENCE 1 21c0a11cf8Sdamien #endif 22498e8a28Sdamien 23498e8a28Sdamien #ifdef ATHN_DEBUG 24498e8a28Sdamien #define DPRINTF(x) do { if (athn_debug > 0) printf x; } while (0) 25498e8a28Sdamien #define DPRINTFN(n, x) do { if (athn_debug >= (n)) printf x; } while (0) 26498e8a28Sdamien extern int athn_debug; 27498e8a28Sdamien #else 28498e8a28Sdamien #define DPRINTF(x) 29498e8a28Sdamien #define DPRINTFN(n, x) 30498e8a28Sdamien #endif 31498e8a28Sdamien 326c0255d5Sdamien #define LE_READ_4(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24) 336c0255d5Sdamien #define LE_READ_2(p) ((p)[0] | (p)[1] << 8) 346c0255d5Sdamien 35498e8a28Sdamien #define ATHN_RXBUFSZ 3872 36498e8a28Sdamien #define ATHN_TXBUFSZ 4096 37498e8a28Sdamien 38498e8a28Sdamien #define ATHN_NRXBUFS 64 39498e8a28Sdamien #define ATHN_NTXBUFS 64 /* Shared between all Tx queues. */ 40498e8a28Sdamien 41498e8a28Sdamien struct athn_rx_radiotap_header { 42498e8a28Sdamien struct ieee80211_radiotap_header wr_ihdr; 43498e8a28Sdamien uint64_t wr_tsft; 44498e8a28Sdamien uint8_t wr_flags; 45498e8a28Sdamien uint8_t wr_rate; 46498e8a28Sdamien uint16_t wr_chan_freq; 47498e8a28Sdamien uint16_t wr_chan_flags; 48498e8a28Sdamien int8_t wr_dbm_antsignal; 49498e8a28Sdamien uint8_t wr_antenna; 50498e8a28Sdamien } __packed; 51498e8a28Sdamien 52498e8a28Sdamien #define ATHN_RX_RADIOTAP_PRESENT \ 53498e8a28Sdamien (1 << IEEE80211_RADIOTAP_TSFT | \ 54498e8a28Sdamien 1 << IEEE80211_RADIOTAP_FLAGS | \ 55498e8a28Sdamien 1 << IEEE80211_RADIOTAP_RATE | \ 56498e8a28Sdamien 1 << IEEE80211_RADIOTAP_CHANNEL | \ 57498e8a28Sdamien 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL | \ 58498e8a28Sdamien 1 << IEEE80211_RADIOTAP_ANTENNA) 59498e8a28Sdamien 60498e8a28Sdamien struct athn_tx_radiotap_header { 61498e8a28Sdamien struct ieee80211_radiotap_header wt_ihdr; 62498e8a28Sdamien uint8_t wt_flags; 63498e8a28Sdamien uint8_t wt_rate; 64498e8a28Sdamien uint16_t wt_chan_freq; 65498e8a28Sdamien uint16_t wt_chan_flags; 66498e8a28Sdamien } __packed; 67498e8a28Sdamien 68498e8a28Sdamien #define ATHN_TX_RADIOTAP_PRESENT \ 69498e8a28Sdamien (1 << IEEE80211_RADIOTAP_FLAGS | \ 70498e8a28Sdamien 1 << IEEE80211_RADIOTAP_RATE | \ 71eb1adcecSmpi 1 << IEEE80211_RADIOTAP_CHANNEL) 72498e8a28Sdamien 73498e8a28Sdamien struct athn_tx_buf { 74498e8a28Sdamien SIMPLEQ_ENTRY(athn_tx_buf) bf_list; 75498e8a28Sdamien 76bd6ea91dSdamien void *bf_descs; 77498e8a28Sdamien bus_dmamap_t bf_map; 78498e8a28Sdamien bus_addr_t bf_daddr; 79498e8a28Sdamien 80498e8a28Sdamien struct mbuf *bf_m; 81498e8a28Sdamien struct ieee80211_node *bf_ni; 82*d2dd70acSstsp int bf_txmcs; 83436170c5Sdamien int bf_txflags; 84df31d9afSdamien #define ATHN_TXFLAG_PAPRD (1 << 0) 855dde5fe4Skettenis #define ATHN_TXFLAG_CAB (1 << 1) 86498e8a28Sdamien }; 87498e8a28Sdamien 88498e8a28Sdamien struct athn_txq { 89498e8a28Sdamien SIMPLEQ_HEAD(, athn_tx_buf) head; 90bd6ea91dSdamien void *lastds; 916c0255d5Sdamien struct athn_tx_buf *wait; 926c0255d5Sdamien int queued; 93498e8a28Sdamien }; 94498e8a28Sdamien 95498e8a28Sdamien struct athn_rx_buf { 96498e8a28Sdamien SIMPLEQ_ENTRY(athn_rx_buf) bf_list; 97498e8a28Sdamien 98bd6ea91dSdamien void *bf_desc; 99498e8a28Sdamien bus_dmamap_t bf_map; 100498e8a28Sdamien 101498e8a28Sdamien struct mbuf *bf_m; 102498e8a28Sdamien bus_addr_t bf_daddr; 103498e8a28Sdamien }; 104498e8a28Sdamien 105498e8a28Sdamien struct athn_rxq { 106bd6ea91dSdamien struct athn_rx_buf *bf; 107498e8a28Sdamien 108bd6ea91dSdamien void *descs; 109bd6ea91dSdamien void *lastds; 110498e8a28Sdamien bus_dmamap_t map; 111498e8a28Sdamien bus_dma_segment_t seg; 112bd6ea91dSdamien int count; 113498e8a28Sdamien 114498e8a28Sdamien SIMPLEQ_HEAD(, athn_rx_buf) head; 115498e8a28Sdamien }; 116498e8a28Sdamien 117498e8a28Sdamien /* Software rate indexes. */ 118498e8a28Sdamien #define ATHN_RIDX_CCK1 0 1198f9a2877Sdamien #define ATHN_RIDX_CCK2 1 120498e8a28Sdamien #define ATHN_RIDX_OFDM6 4 121498e8a28Sdamien #define ATHN_RIDX_MCS0 12 1227363c99eSstsp #define ATHN_RIDX_MCS8 (ATHN_RIDX_MCS0 + 8) 123498e8a28Sdamien #define ATHN_RIDX_MCS15 27 124498e8a28Sdamien #define ATHN_RIDX_MAX 27 1257363c99eSstsp #define ATHN_MCS_MAX 15 1267363c99eSstsp #define ATHN_NUM_MCS (ATHN_MCS_MAX + 1) 127498e8a28Sdamien #define ATHN_IS_HT_RIDX(ridx) ((ridx) >= ATHN_RIDX_MCS0) 1287363c99eSstsp #define ATHN_IS_MIMO_RIDX(ridx) ((ridx) >= ATHN_RIDX_MCS8) 129498e8a28Sdamien 130498e8a28Sdamien static const struct athn_rate { 1317363c99eSstsp uint16_t rate; /* Rate in 500Kbps unit. */ 132498e8a28Sdamien uint8_t hwrate; /* HW representation. */ 1338f9a2877Sdamien uint8_t rspridx; /* Control Response Frame rate index. */ 134498e8a28Sdamien enum ieee80211_phytype phy; 135498e8a28Sdamien } athn_rates[] = { 1368f9a2877Sdamien { 2, 0x1b, 0, IEEE80211_T_DS }, 1378f9a2877Sdamien { 4, 0x1a, 1, IEEE80211_T_DS }, 1388f9a2877Sdamien { 11, 0x19, 1, IEEE80211_T_DS }, 1398f9a2877Sdamien { 22, 0x18, 1, IEEE80211_T_DS }, 1408f9a2877Sdamien { 12, 0x0b, 4, IEEE80211_T_OFDM }, 1418f9a2877Sdamien { 18, 0x0f, 4, IEEE80211_T_OFDM }, 1428f9a2877Sdamien { 24, 0x0a, 6, IEEE80211_T_OFDM }, 1438f9a2877Sdamien { 36, 0x0e, 6, IEEE80211_T_OFDM }, 1448f9a2877Sdamien { 48, 0x09, 8, IEEE80211_T_OFDM }, 1458f9a2877Sdamien { 72, 0x0d, 8, IEEE80211_T_OFDM }, 1468f9a2877Sdamien { 96, 0x08, 8, IEEE80211_T_OFDM }, 1478f9a2877Sdamien { 108, 0x0c, 8, IEEE80211_T_OFDM }, 1487363c99eSstsp { 13, 0x80, 4, IEEE80211_T_OFDM }, 1497363c99eSstsp { 26, 0x81, 6, IEEE80211_T_OFDM }, 1507363c99eSstsp { 39, 0x82, 6, IEEE80211_T_OFDM }, 1517363c99eSstsp { 52, 0x83, 8, IEEE80211_T_OFDM }, 1527363c99eSstsp { 78, 0x84, 8, IEEE80211_T_OFDM }, 1537363c99eSstsp { 104, 0x85, 8, IEEE80211_T_OFDM }, 1547363c99eSstsp { 117, 0x86, 8, IEEE80211_T_OFDM }, 1557363c99eSstsp { 130, 0x87, 8, IEEE80211_T_OFDM }, 1567363c99eSstsp { 26, 0x88, 4, IEEE80211_T_OFDM }, 1577363c99eSstsp { 52, 0x89, 6, IEEE80211_T_OFDM }, 1587363c99eSstsp { 78, 0x8a, 8, IEEE80211_T_OFDM }, 1597363c99eSstsp { 104, 0x8b, 8, IEEE80211_T_OFDM }, 1607363c99eSstsp { 156, 0x8c, 8, IEEE80211_T_OFDM }, 1617363c99eSstsp { 208, 0x8d, 8, IEEE80211_T_OFDM }, 1627363c99eSstsp { 234, 0x8e, 8, IEEE80211_T_OFDM }, 1637363c99eSstsp { 260, 0x8f, 8, IEEE80211_T_OFDM } 164498e8a28Sdamien }; 165498e8a28Sdamien 166498e8a28Sdamien struct athn_series { 167498e8a28Sdamien uint16_t dur; 1686b118bcdSdamien uint8_t hwrate; 169498e8a28Sdamien }; 170498e8a28Sdamien 171498e8a28Sdamien struct athn_pier { 172498e8a28Sdamien uint8_t fbin; 173498e8a28Sdamien const uint8_t *pwr[AR_PD_GAINS_IN_MASK]; 174498e8a28Sdamien const uint8_t *vpd[AR_PD_GAINS_IN_MASK]; 175498e8a28Sdamien }; 176498e8a28Sdamien 177498e8a28Sdamien /* 178498e8a28Sdamien * Structures used to store initialization values. 179498e8a28Sdamien */ 180498e8a28Sdamien struct athn_ini { 181498e8a28Sdamien int nregs; 182498e8a28Sdamien const uint16_t *regs; 183498e8a28Sdamien const uint32_t *vals_5g20; 184498e8a28Sdamien const uint32_t *vals_5g40; 185498e8a28Sdamien const uint32_t *vals_2g40; 186498e8a28Sdamien const uint32_t *vals_2g20; 187498e8a28Sdamien int ncmregs; 188498e8a28Sdamien const uint16_t *cmregs; 189498e8a28Sdamien const uint32_t *cmvals; 19097bf8fdcSdamien int nfastregs; 19197bf8fdcSdamien const uint16_t *fastregs; 19297bf8fdcSdamien const uint32_t *fastvals_5g20; 19397bf8fdcSdamien const uint32_t *fastvals_5g40; 194498e8a28Sdamien }; 195498e8a28Sdamien 196498e8a28Sdamien struct athn_gain { 197498e8a28Sdamien int nregs; 198498e8a28Sdamien const uint16_t *regs; 199498e8a28Sdamien const uint32_t *vals_5g; 200498e8a28Sdamien const uint32_t *vals_2g; 201498e8a28Sdamien }; 202498e8a28Sdamien 203498e8a28Sdamien struct athn_addac { 204498e8a28Sdamien int nvals; 205498e8a28Sdamien const uint32_t *vals; 206498e8a28Sdamien }; 207498e8a28Sdamien 208328b15b2Skettenis struct athn_serdes { 209328b15b2Skettenis int nvals; 210c8971d2aSstsp const uint32_t *regs; 211328b15b2Skettenis const uint32_t *vals; 212328b15b2Skettenis }; 213328b15b2Skettenis 214bd6ea91dSdamien /* Rx queue software indexes. */ 215bd6ea91dSdamien #define ATHN_QID_LP 0 21617ac1014Sstsp #define ATHN_QID_HP 1 217bd6ea91dSdamien 218498e8a28Sdamien /* Tx queue software indexes. */ 219498e8a28Sdamien #define ATHN_QID_AC_BE 0 220498e8a28Sdamien #define ATHN_QID_PSPOLL 1 221498e8a28Sdamien #define ATHN_QID_AC_BK 2 222498e8a28Sdamien #define ATHN_QID_AC_VI 3 223498e8a28Sdamien #define ATHN_QID_AC_VO 4 224498e8a28Sdamien #define ATHN_QID_UAPSD 5 225498e8a28Sdamien #define ATHN_QID_CAB 6 226498e8a28Sdamien #define ATHN_QID_BEACON 7 227498e8a28Sdamien #define ATHN_QID_COUNT 8 228498e8a28Sdamien 229498e8a28Sdamien /* Map Access Category to Tx queue Id. */ 230498e8a28Sdamien static const uint8_t athn_ac2qid[EDCA_NUM_AC] = { 231498e8a28Sdamien ATHN_QID_AC_BE, /* EDCA_AC_BE */ 232498e8a28Sdamien ATHN_QID_AC_BK, /* EDCA_AC_BK */ 233498e8a28Sdamien ATHN_QID_AC_VI, /* EDCA_AC_VI */ 234498e8a28Sdamien ATHN_QID_AC_VO /* EDCA_AC_VO */ 235498e8a28Sdamien }; 236498e8a28Sdamien 237498e8a28Sdamien static const uint8_t athn_5ghz_chans[] = { 238498e8a28Sdamien /* UNII 1. */ 239498e8a28Sdamien 36, 40, 44, 48, 240498e8a28Sdamien /* UNII 2. */ 241498e8a28Sdamien 52, 56, 60, 64, 242498e8a28Sdamien /* Middle band. */ 243498e8a28Sdamien 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 244498e8a28Sdamien /* UNII 3. */ 245498e8a28Sdamien 149, 153, 157, 161, 165 246498e8a28Sdamien }; 247498e8a28Sdamien 248498e8a28Sdamien /* Number of data bits per OFDM symbol for MCS[0-15]. */ 249498e8a28Sdamien /* See tables 20-29, 20-30, 20-33, 20-34. */ 250498e8a28Sdamien static const uint16_t ar_mcs_ndbps[][2] = { 251498e8a28Sdamien /* 20MHz 40MHz */ 252498e8a28Sdamien { 26, 54 }, /* MCS0 */ 253498e8a28Sdamien { 52, 108 }, /* MCS1 */ 254498e8a28Sdamien { 78, 162 }, /* MCS2 */ 255498e8a28Sdamien { 104, 216 }, /* MCS3 */ 256498e8a28Sdamien { 156, 324 }, /* MCS4 */ 257498e8a28Sdamien { 208, 432 }, /* MCS5 */ 258498e8a28Sdamien { 234, 486 }, /* MCS6 */ 259498e8a28Sdamien { 260, 540 }, /* MCS7 */ 260498e8a28Sdamien { 26, 108 }, /* MCS8 */ 261498e8a28Sdamien { 52, 216 }, /* MCS9 */ 262498e8a28Sdamien { 78, 324 }, /* MCS10 */ 263498e8a28Sdamien { 104, 432 }, /* MCS11 */ 264498e8a28Sdamien { 156, 648 }, /* MCS12 */ 265498e8a28Sdamien { 208, 864 }, /* MCS13 */ 266498e8a28Sdamien { 234, 972 }, /* MCS14 */ 267498e8a28Sdamien { 260, 1080 } /* MCS15 */ 268498e8a28Sdamien }; 269498e8a28Sdamien 270498e8a28Sdamien #define ATHN_POWER_OFDM6 0 271498e8a28Sdamien #define ATHN_POWER_OFDM9 1 272498e8a28Sdamien #define ATHN_POWER_OFDM12 2 273498e8a28Sdamien #define ATHN_POWER_OFDM18 3 274498e8a28Sdamien #define ATHN_POWER_OFDM24 4 275498e8a28Sdamien #define ATHN_POWER_OFDM36 5 276498e8a28Sdamien #define ATHN_POWER_OFDM48 6 277498e8a28Sdamien #define ATHN_POWER_OFDM54 7 278498e8a28Sdamien #define ATHN_POWER_CCK1_LP 8 279498e8a28Sdamien #define ATHN_POWER_CCK2_LP 9 280498e8a28Sdamien #define ATHN_POWER_CCK2_SP 10 281498e8a28Sdamien #define ATHN_POWER_CCK55_LP 11 282498e8a28Sdamien #define ATHN_POWER_CCK55_SP 12 283498e8a28Sdamien #define ATHN_POWER_CCK11_LP 13 284498e8a28Sdamien #define ATHN_POWER_CCK11_SP 14 285498e8a28Sdamien #define ATHN_POWER_XR 15 286498e8a28Sdamien #define ATHN_POWER_HT20(mcs) (16 + (mcs)) 287bd6ea91dSdamien #define ATHN_POWER_HT40(mcs) (40 + (mcs)) 288bd6ea91dSdamien #define ATHN_POWER_CCK_DUP 64 289bd6ea91dSdamien #define ATHN_POWER_OFDM_DUP 65 290bd6ea91dSdamien #define ATHN_POWER_CCK_EXT 66 291bd6ea91dSdamien #define ATHN_POWER_OFDM_EXT 67 292bd6ea91dSdamien #define ATHN_POWER_COUNT 68 293498e8a28Sdamien 2947363c99eSstsp #define ATHN_NUM_LEGACY_RATES IEEE80211_RATE_MAXSIZE 2957363c99eSstsp #define ATHN_NUM_RATES (ATHN_NUM_LEGACY_RATES + ATHN_NUM_MCS) 296498e8a28Sdamien struct athn_node { 297498e8a28Sdamien struct ieee80211_node ni; 298498e8a28Sdamien struct ieee80211_amrr_node amn; 299*d2dd70acSstsp struct ieee80211_ra_node rn; 3007363c99eSstsp uint8_t ridx[ATHN_NUM_RATES]; 3017363c99eSstsp uint8_t fallback[ATHN_NUM_RATES]; 30213236e8dSdamien uint8_t sta_index; 303498e8a28Sdamien }; 304498e8a28Sdamien 305bd6ea91dSdamien /* 306bd6ea91dSdamien * Adaptive noise immunity state. 307bd6ea91dSdamien */ 308498e8a28Sdamien #define ATHN_ANI_PERIOD 100 309498e8a28Sdamien #define ATHN_ANI_RSSI_THR_HIGH 40 310498e8a28Sdamien #define ATHN_ANI_RSSI_THR_LOW 7 311498e8a28Sdamien struct athn_ani { 312498e8a28Sdamien uint8_t noise_immunity_level; 313498e8a28Sdamien uint8_t spur_immunity_level; 314498e8a28Sdamien uint8_t firstep_level; 315498e8a28Sdamien uint8_t ofdm_weak_signal; 316498e8a28Sdamien uint8_t cck_weak_signal; 317498e8a28Sdamien 318498e8a28Sdamien uint32_t listen_time; 319498e8a28Sdamien 320498e8a28Sdamien uint32_t ofdm_trig_high; 321498e8a28Sdamien uint32_t ofdm_trig_low; 322498e8a28Sdamien 323498e8a28Sdamien int32_t cck_trig_high; 324498e8a28Sdamien int32_t cck_trig_low; 325498e8a28Sdamien 326498e8a28Sdamien uint32_t ofdm_phy_err_base; 327498e8a28Sdamien uint32_t cck_phy_err_base; 328498e8a28Sdamien uint32_t ofdm_phy_err_count; 329498e8a28Sdamien uint32_t cck_phy_err_count; 330498e8a28Sdamien 331498e8a28Sdamien uint32_t cyccnt; 332498e8a28Sdamien uint32_t txfcnt; 333498e8a28Sdamien uint32_t rxfcnt; 334498e8a28Sdamien }; 335498e8a28Sdamien 336498e8a28Sdamien struct athn_iq_cal { 337498e8a28Sdamien uint32_t pwr_meas_i; 338498e8a28Sdamien uint32_t pwr_meas_q; 339498e8a28Sdamien int32_t iq_corr_meas; 340498e8a28Sdamien }; 341498e8a28Sdamien 342498e8a28Sdamien struct athn_adc_cal { 343498e8a28Sdamien uint32_t pwr_meas_odd_i; 344498e8a28Sdamien uint32_t pwr_meas_even_i; 345498e8a28Sdamien uint32_t pwr_meas_odd_q; 346498e8a28Sdamien uint32_t pwr_meas_even_q; 347498e8a28Sdamien }; 348498e8a28Sdamien 349498e8a28Sdamien struct athn_calib { 350498e8a28Sdamien int nsamples; 351498e8a28Sdamien struct athn_iq_cal iq[AR_MAX_CHAINS]; 352498e8a28Sdamien struct athn_adc_cal adc_gain[AR_MAX_CHAINS]; 353498e8a28Sdamien struct athn_adc_cal adc_dc_offset[AR_MAX_CHAINS]; 354498e8a28Sdamien }; 355498e8a28Sdamien 356498e8a28Sdamien #define ATHN_NF_CAL_HIST_MAX 5 357498e8a28Sdamien 358498e8a28Sdamien struct athn_softc; 359498e8a28Sdamien 360498e8a28Sdamien struct athn_ops { 361c0a11cf8Sdamien /* Bus callbacks. */ 362c0a11cf8Sdamien uint32_t (*read)(struct athn_softc *, uint32_t); 363c0a11cf8Sdamien void (*write)(struct athn_softc *, uint32_t, uint32_t); 364c0a11cf8Sdamien void (*write_barrier)(struct athn_softc *); 365c0a11cf8Sdamien 366498e8a28Sdamien void (*setup)(struct athn_softc *); 367498e8a28Sdamien void (*set_txpower)(struct athn_softc *, struct ieee80211_channel *, 368498e8a28Sdamien struct ieee80211_channel *); 369498e8a28Sdamien void (*spur_mitigate)(struct athn_softc *, 370498e8a28Sdamien struct ieee80211_channel *, struct ieee80211_channel *); 371bd6ea91dSdamien const struct ar_spur_chan * 372bd6ea91dSdamien (*get_spur_chans)(struct athn_softc *, int); 373498e8a28Sdamien void (*init_from_rom)(struct athn_softc *, 374498e8a28Sdamien struct ieee80211_channel *, struct ieee80211_channel *); 375498e8a28Sdamien int (*set_synth)(struct athn_softc *, struct ieee80211_channel *, 376498e8a28Sdamien struct ieee80211_channel *); 3773a686414Sdamien int (*read_rom_data)(struct athn_softc *, uint32_t, void *, int); 378e7e15635Sdamien const uint8_t * 379e7e15635Sdamien (*get_rom_template)(struct athn_softc *, uint8_t); 380498e8a28Sdamien void (*swap_rom)(struct athn_softc *); 381498e8a28Sdamien void (*olpc_init)(struct athn_softc *); 382b46f6896Sdamien void (*olpc_temp_compensation)(struct athn_softc *); 383bd6ea91dSdamien /* GPIO callbacks. */ 384bd6ea91dSdamien int (*gpio_read)(struct athn_softc *, int); 385bd6ea91dSdamien void (*gpio_write)(struct athn_softc *, int, int); 386bd6ea91dSdamien void (*gpio_config_input)(struct athn_softc *, int); 387bd6ea91dSdamien void (*gpio_config_output)(struct athn_softc *, int, int); 388bd6ea91dSdamien void (*rfsilent_init)(struct athn_softc *); 389bd6ea91dSdamien /* DMA callbacks. */ 390bd6ea91dSdamien int (*dma_alloc)(struct athn_softc *); 391bd6ea91dSdamien void (*dma_free)(struct athn_softc *); 392bd6ea91dSdamien void (*rx_enable)(struct athn_softc *); 393bd6ea91dSdamien int (*intr)(struct athn_softc *); 394bd6ea91dSdamien int (*tx)(struct athn_softc *, struct mbuf *, 395436170c5Sdamien struct ieee80211_node *, int); 396bd6ea91dSdamien /* PHY callbacks. */ 397bd6ea91dSdamien void (*set_rf_mode)(struct athn_softc *, 398bd6ea91dSdamien struct ieee80211_channel *); 399bd6ea91dSdamien int (*rf_bus_request)(struct athn_softc *); 400bd6ea91dSdamien void (*rf_bus_release)(struct athn_softc *); 401bd6ea91dSdamien void (*set_phy)(struct athn_softc *, struct ieee80211_channel *, 402bd6ea91dSdamien struct ieee80211_channel *); 403bd6ea91dSdamien void (*set_delta_slope)(struct athn_softc *, 404bd6ea91dSdamien struct ieee80211_channel *, struct ieee80211_channel *); 405bd6ea91dSdamien void (*enable_antenna_diversity)(struct athn_softc *); 406bd6ea91dSdamien void (*init_baseband)(struct athn_softc *); 407bd6ea91dSdamien void (*disable_phy)(struct athn_softc *); 408bd6ea91dSdamien void (*set_rxchains)(struct athn_softc *); 409bd6ea91dSdamien void (*noisefloor_calib)(struct athn_softc *); 4109d1f2812Sstsp void (*init_noisefloor_calib)(struct athn_softc *); 4119d1f2812Sstsp int (*get_noisefloor)(struct athn_softc *); 4129d1f2812Sstsp void (*apply_noisefloor)(struct athn_softc *); 413bd6ea91dSdamien void (*do_calib)(struct athn_softc *); 414bd6ea91dSdamien void (*next_calib)(struct athn_softc *); 415bd6ea91dSdamien void (*hw_init)(struct athn_softc *, struct ieee80211_channel *, 416bd6ea91dSdamien struct ieee80211_channel *); 417df31d9afSdamien void (*get_paprd_masks)(struct athn_softc *sc, 418df31d9afSdamien struct ieee80211_channel *, uint32_t *, uint32_t *); 419bd6ea91dSdamien /* ANI callbacks. */ 420bd6ea91dSdamien void (*set_noise_immunity_level)(struct athn_softc *, int); 421bd6ea91dSdamien void (*enable_ofdm_weak_signal)(struct athn_softc *); 422bd6ea91dSdamien void (*disable_ofdm_weak_signal)(struct athn_softc *); 423bd6ea91dSdamien void (*set_cck_weak_signal)(struct athn_softc *, int); 424bd6ea91dSdamien void (*set_firstep_level)(struct athn_softc *, int); 425bd6ea91dSdamien void (*set_spur_immunity_level)(struct athn_softc *, int); 426498e8a28Sdamien }; 427498e8a28Sdamien 428498e8a28Sdamien struct athn_softc { 429498e8a28Sdamien struct device sc_dev; 430498e8a28Sdamien struct ieee80211com sc_ic; 431498e8a28Sdamien 432498e8a28Sdamien int (*sc_enable)(struct athn_softc *); 433498e8a28Sdamien void (*sc_disable)(struct athn_softc *); 434498e8a28Sdamien void (*sc_power)(struct athn_softc *, int); 435498e8a28Sdamien void (*sc_disable_aspm)(struct athn_softc *); 43644176b8eSdamien void (*sc_enable_extsynch)( 43744176b8eSdamien struct athn_softc *); 438498e8a28Sdamien 439498e8a28Sdamien int (*sc_newstate)(struct ieee80211com *, 440498e8a28Sdamien enum ieee80211_state, int); 441498e8a28Sdamien 442498e8a28Sdamien bus_dma_tag_t sc_dmat; 443498e8a28Sdamien 444498e8a28Sdamien struct timeout scan_to; 445498e8a28Sdamien struct timeout calib_to; 446498e8a28Sdamien struct ieee80211_amrr amrr; 447498e8a28Sdamien 448498e8a28Sdamien u_int flags; 449498e8a28Sdamien #define ATHN_FLAG_PCIE (1 << 0) 450c0a11cf8Sdamien #define ATHN_FLAG_USB (1 << 1) 451c0a11cf8Sdamien #define ATHN_FLAG_OLPC (1 << 2) 452c0a11cf8Sdamien #define ATHN_FLAG_PAPRD (1 << 3) 453c0a11cf8Sdamien #define ATHN_FLAG_FAST_PLL_CLOCK (1 << 4) 454c0a11cf8Sdamien #define ATHN_FLAG_RFSILENT (1 << 5) 455c0a11cf8Sdamien #define ATHN_FLAG_RFSILENT_REVERSED (1 << 6) 456c0a11cf8Sdamien #define ATHN_FLAG_BTCOEX2WIRE (1 << 7) 457c0a11cf8Sdamien #define ATHN_FLAG_BTCOEX3WIRE (1 << 8) 458498e8a28Sdamien /* Shortcut. */ 459498e8a28Sdamien #define ATHN_FLAG_BTCOEX (ATHN_FLAG_BTCOEX2WIRE | ATHN_FLAG_BTCOEX3WIRE) 460c0a11cf8Sdamien #define ATHN_FLAG_11A (1 << 9) 461c0a11cf8Sdamien #define ATHN_FLAG_11G (1 << 10) 462c0a11cf8Sdamien #define ATHN_FLAG_11N (1 << 11) 463c0a11cf8Sdamien #define ATHN_FLAG_AN_TOP2_FIXUP (1 << 12) 464c0a11cf8Sdamien #define ATHN_FLAG_NON_ENTERPRISE (1 << 13) 46544176b8eSdamien #define ATHN_FLAG_3TREDUCE_CHAIN (1 << 14) 466498e8a28Sdamien 467498e8a28Sdamien uint8_t ngpiopins; 4689feb3d58Sdamien int led_pin; 469498e8a28Sdamien int rfsilent_pin; 4705632af28Sdamien int led_state; 4717f0116d0Sdamien uint32_t isync; 4727f0116d0Sdamien uint32_t imask; 473498e8a28Sdamien 474498e8a28Sdamien uint16_t mac_ver; 475498e8a28Sdamien uint8_t mac_rev; 476498e8a28Sdamien uint8_t rf_rev; 477498e8a28Sdamien uint16_t eep_rev; 478498e8a28Sdamien 479498e8a28Sdamien uint8_t txchainmask; 480498e8a28Sdamien uint8_t rxchainmask; 481498e8a28Sdamien uint8_t ntxchains; 482498e8a28Sdamien uint8_t nrxchains; 483498e8a28Sdamien 48426bcd0d6Sdamien uint8_t sup_calib_mask; 48526bcd0d6Sdamien uint8_t cur_calib_mask; 486498e8a28Sdamien #define ATHN_CAL_IQ (1 << 0) 487498e8a28Sdamien #define ATHN_CAL_ADC_GAIN (1 << 1) 488498e8a28Sdamien #define ATHN_CAL_ADC_DC (1 << 2) 489bd6ea91dSdamien #define ATHN_CAL_TEMP (1 << 3) 490498e8a28Sdamien 491aca706e9Sdamien struct ieee80211_channel *curchan; 492aca706e9Sdamien struct ieee80211_channel *curchanext; 493aca706e9Sdamien 494498e8a28Sdamien /* Open Loop Power Control. */ 495498e8a28Sdamien int8_t tx_gain_tbl[AR9280_TX_GAIN_TABLE_SIZE]; 496498e8a28Sdamien int8_t pdadc; 497498e8a28Sdamien int8_t tcomp; 498b46f6896Sdamien int olpc_ticks; 499cc6e2d0bSstsp int iqcal_ticks; 500498e8a28Sdamien 501df31d9afSdamien /* PA predistortion. */ 502df31d9afSdamien uint16_t gain1[AR_MAX_CHAINS]; 503df31d9afSdamien uint32_t txgain[AR9003_TX_GAIN_TABLE_SIZE]; 50449841013Sdamien int16_t pa_in[AR_MAX_CHAINS] 50549841013Sdamien [AR9003_PAPRD_MEM_TAB_SIZE]; 50649841013Sdamien int16_t angle[AR_MAX_CHAINS] 507df31d9afSdamien [AR9003_PAPRD_MEM_TAB_SIZE]; 508df31d9afSdamien int32_t trainpow; 509df31d9afSdamien uint8_t paprd_curchain; 510df31d9afSdamien 511498e8a28Sdamien uint32_t rwbuf[64]; 512498e8a28Sdamien 513498e8a28Sdamien int kc_entries; 514498e8a28Sdamien 515498e8a28Sdamien void *eep; 516bd6ea91dSdamien const void *eep_def; 517498e8a28Sdamien uint32_t eep_base; 518498e8a28Sdamien uint32_t eep_size; 519498e8a28Sdamien 520bd6ea91dSdamien struct athn_rxq rxq[2]; 521bd6ea91dSdamien struct athn_txq txq[31]; 522498e8a28Sdamien 523bd6ea91dSdamien void *descs; 524498e8a28Sdamien bus_dmamap_t map; 525498e8a28Sdamien bus_dma_segment_t seg; 526498e8a28Sdamien SIMPLEQ_HEAD(, athn_tx_buf) txbufs; 527eff5798eSdamien struct athn_tx_buf *bcnbuf; 528498e8a28Sdamien struct athn_tx_buf txpool[ATHN_NTXBUFS]; 529498e8a28Sdamien 530bd6ea91dSdamien bus_dmamap_t txsmap; 531bd6ea91dSdamien bus_dma_segment_t txsseg; 532bd6ea91dSdamien void *txsring; 533bd6ea91dSdamien int txscur; 534bd6ea91dSdamien 535277846c0Sdamien int sc_if_flags; 536498e8a28Sdamien int sc_tx_timer; 537498e8a28Sdamien 538498e8a28Sdamien const struct athn_ini *ini; 539498e8a28Sdamien const struct athn_gain *rx_gain; 540498e8a28Sdamien const struct athn_gain *tx_gain; 541498e8a28Sdamien const struct athn_addac *addac; 542328b15b2Skettenis const struct athn_serdes *serdes; 543498e8a28Sdamien uint32_t workaround; 544bd6ea91dSdamien uint32_t obs_off; 545bd6ea91dSdamien uint32_t gpio_input_en_off; 546498e8a28Sdamien 547498e8a28Sdamien struct athn_ops ops; 548498e8a28Sdamien 549498e8a28Sdamien int fixed_ridx; 550498e8a28Sdamien 551bd6ea91dSdamien int16_t cca_min_2g; 552bd6ea91dSdamien int16_t cca_max_2g; 553bd6ea91dSdamien int16_t cca_min_5g; 554bd6ea91dSdamien int16_t cca_max_5g; 555498e8a28Sdamien struct { 556498e8a28Sdamien int16_t nf[AR_MAX_CHAINS]; 557498e8a28Sdamien int16_t nf_ext[AR_MAX_CHAINS]; 558498e8a28Sdamien } nf_hist[ATHN_NF_CAL_HIST_MAX]; 559498e8a28Sdamien int nf_hist_cur; 5609d1f2812Sstsp int nf_hist_nvalid; 561498e8a28Sdamien int16_t nf_priv[AR_MAX_CHAINS]; 562498e8a28Sdamien int16_t nf_ext_priv[AR_MAX_CHAINS]; 5639d1f2812Sstsp int nf_calib_pending; 5649d1f2812Sstsp int nf_calib_ticks; 5654116fd83Sdamien int pa_calib_ticks; 566498e8a28Sdamien 567498e8a28Sdamien struct athn_calib calib; 568498e8a28Sdamien struct athn_ani ani; 569498e8a28Sdamien 570498e8a28Sdamien #if NBPFILTER > 0 571498e8a28Sdamien caddr_t sc_drvbpf; 572498e8a28Sdamien 573498e8a28Sdamien union { 574498e8a28Sdamien struct athn_rx_radiotap_header th; 575498e8a28Sdamien uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; 576498e8a28Sdamien } sc_rxtapu; 577498e8a28Sdamien #define sc_rxtap sc_rxtapu.th 578498e8a28Sdamien int sc_rxtap_len; 579498e8a28Sdamien 580498e8a28Sdamien union { 581498e8a28Sdamien struct athn_tx_radiotap_header th; 582498e8a28Sdamien uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; 583498e8a28Sdamien } sc_txtapu; 584498e8a28Sdamien #define sc_txtap sc_txtapu.th 585498e8a28Sdamien int sc_txtap_len; 586498e8a28Sdamien #endif 587498e8a28Sdamien }; 588498e8a28Sdamien 589498e8a28Sdamien extern int athn_attach(struct athn_softc *); 590498e8a28Sdamien extern void athn_detach(struct athn_softc *); 59195d74b5fSkettenis extern void athn_suspend(struct athn_softc *); 59237ecb596Sderaadt extern void athn_wakeup(struct athn_softc *); 593498e8a28Sdamien extern int athn_intr(void *); 594