summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2014-09-30 03:19:29 +0000
committeradrian <adrian@FreeBSD.org>2014-09-30 03:19:29 +0000
commit4a5dfeb753bfdd0be78944f64b3ef6065b78b34e (patch)
tree6d3205f98a98993af31763f2b88722b87d3dd7f6 /sys/dev
parent11fa06280a7ebfc1ffd548ffd120bf3cec1e0bc6 (diff)
downloadFreeBSD-src-4a5dfeb753bfdd0be78944f64b3ef6065b78b34e.zip
FreeBSD-src-4a5dfeb753bfdd0be78944f64b3ef6065b78b34e.tar.gz
Add initial support for the AR9485 CUS198 / CUS230 variants.
These variants have a few differences from the default AR9485 NIC, namely: * a non-default antenna switch config; * slightly different RX gain table setup; * an external XLNA hooked up to a GPIO pin; * (and not yet done) RSSI threshold differences when doing slow diversity. To make this possible: * Add the PCI device list from Linux ath9k, complete with vendor and sub-vendor IDs for various things to be enabled; * .. and until FreeBSD learns about a PCI device list like this, write a search function inspired by the USB device enumeration code; * add HAL_OPS_CONFIG to the HAL attach methods; the HAL can use this to initialise its local driver parameters upon attach; * copy these parameters over in the AR9300 HAL; * don't default to override the antenna switch - only do it for the chips that require it; * I brought over ar9300_attenuation_apply() from ath9k which is cleaner and easier to read for this particular NIC. This is a work in progress. I'm worried that there's some post-AR9380 NIC out there which doesn't work without the antenna override set as I currently haven't implemented bluetooth coexistence for the AR9380 and later HAL. But I'd rather have this code in the tree and fix it up before 11.0-RELEASE happens versus having a set of newer NICs in laptops be effectively RX deaf. Tested: * AR9380 (STA) * AR9485 CUS198 (STA) Obtained from: Qualcomm Atheros, Linux ath9k
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ath/ath_hal/ah.c7
-rw-r--r--sys/dev/ath/ath_hal/ah.h4
-rw-r--r--sys/dev/ath/ath_hal/ah_internal.h1
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5312/ar5312_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_attach.c2
-rw-r--r--sys/dev/ath/ath_hal/ar9001/ar9130_attach.c4
-rw-r--r--sys/dev/ath/ath_hal/ar9001/ar9160_attach.c1
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9280_attach.c1
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9285_attach.c1
-rw-r--r--sys/dev/ath/ath_hal/ar9002/ar9287_attach.c1
-rw-r--r--sys/dev/ath/if_ath.c89
-rw-r--r--sys/dev/ath/if_ath_lna_div.c4
-rw-r--r--sys/dev/ath/if_ath_pci.c98
-rw-r--r--sys/dev/ath/if_athvar.h22
17 files changed, 232 insertions, 11 deletions
diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c
index 750248e..2aefc89 100644
--- a/sys/dev/ath/ath_hal/ah.c
+++ b/sys/dev/ath/ath_hal/ah.c
@@ -55,7 +55,9 @@ ath_hal_probe(uint16_t vendorid, uint16_t devid)
*/
struct ath_hal*
ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
- HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *error)
+ HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah_config,
+ HAL_STATUS *error)
{
struct ath_hal_chip * const *pchip;
@@ -66,7 +68,8 @@ ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
/* XXX don't have vendorid, assume atheros one works */
if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
continue;
- ah = chip->attach(devid, sc, st, sh, eepromdata, error);
+ ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config,
+ error);
if (ah != AH_NULL) {
/* copy back private state to public area */
ah->ah_devid = AH_PRIVATE(ah)->ah_devid;
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index 4f2d3e9..239ebc8 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -1264,6 +1264,7 @@ typedef struct
int ath_hal_show_bb_panic;
int ath_hal_ant_ctrl_comm2g_switch_enable;
int ath_hal_ext_atten_margin_cfg;
+ int ath_hal_min_gainidx;
int ath_hal_war70c;
uint32_t ath_hal_mci_config;
} HAL_OPS_CONFIG;
@@ -1616,7 +1617,8 @@ extern const char *__ahdecl ath_hal_probe(uint16_t vendorid, uint16_t devid);
* be returned if the status parameter is non-zero.
*/
extern struct ath_hal * __ahdecl ath_hal_attach(uint16_t devid, HAL_SOFTC,
- HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata, HAL_STATUS* status);
+ HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah_config, HAL_STATUS* status);
extern const char *ath_hal_mac_name(struct ath_hal *);
extern const char *ath_hal_rf_name(struct ath_hal *);
diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h
index 2e35148..0892a42 100644
--- a/sys/dev/ath/ath_hal/ah_internal.h
+++ b/sys/dev/ath/ath_hal/ah_internal.h
@@ -91,6 +91,7 @@ struct ath_hal_chip {
const char *(*probe)(uint16_t vendorid, uint16_t devid);
struct ath_hal *(*attach)(uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah,
HAL_STATUS *error);
};
#ifndef AH_CHIP
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
index ee11ce9..ceafa99 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
@@ -183,7 +183,7 @@ static HAL_BOOL ar5210FillCapabilityInfo(struct ath_hal *ah);
*/
static struct ath_hal *
ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
- uint16_t *eepromdata, HAL_STATUS *status)
+ uint16_t *eepromdata, HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
struct ath_hal_5210 *ahp;
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
index 4549295..3416dc0 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
@@ -203,7 +203,7 @@ ar5211GetRadioRev(struct ath_hal *ah)
static struct ath_hal *
ar5211Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
- HAL_STATUS *status)
+ HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
struct ath_hal_5211 *ahp;
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
index e0af27c..a95f244 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
@@ -317,7 +317,7 @@ ar5212IsMacSupported(uint8_t macVersion, uint8_t macRev)
static struct ath_hal *
ar5212Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
- HAL_STATUS *status)
+ HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
#define AH_EEPROM_PROTECT(ah) \
(AH_PRIVATE(ah)->ah_ispcie)? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT)
diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c b/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c
index 4ca1a4d..5c84eb8 100644
--- a/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c
+++ b/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c
@@ -62,7 +62,7 @@ ar5312AniSetup(struct ath_hal *ah)
static struct ath_hal *
ar5312Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
- HAL_STATUS *status)
+ HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
struct ath_hal_5212 *ahp = AH_NULL;
struct ath_hal *ah;
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
index bdc6111..a20499a 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
@@ -297,7 +297,7 @@ ar5416GetRadioRev(struct ath_hal *ah)
static struct ath_hal *
ar5416Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
- HAL_STATUS *status)
+ HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
struct ath_hal_5416 *ahp5416;
struct ath_hal_5212 *ahp;
diff --git a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
index 4f478c0..c270bab 100644
--- a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
+++ b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
@@ -69,7 +69,9 @@ static HAL_BOOL ar9130FillCapabilityInfo(struct ath_hal *ah);
*/
static struct ath_hal *
ar9130Attach(uint16_t devid, HAL_SOFTC sc,
- HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *status)
+ HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah_config,
+ HAL_STATUS *status)
{
struct ath_hal_5416 *ahp5416;
struct ath_hal_5212 *ahp;
diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
index 979ba1a..5bda519 100644
--- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
+++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
@@ -114,6 +114,7 @@ ar9160InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
static struct ath_hal *
ar9160Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_5416 *ahp5416;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
index 2a67fe5..3be3e35 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
@@ -148,6 +148,7 @@ ar9280InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
static struct ath_hal *
ar9280Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_9280 *ahp9280;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
index edb6f26..eb3490a 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
@@ -133,6 +133,7 @@ ar9285_eeprom_print_diversity_settings(struct ath_hal *ah)
static struct ath_hal *
ar9285Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_9285 *ahp9285;
diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
index 010e2c3..0ea565c 100644
--- a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
+++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
@@ -111,6 +111,7 @@ ar9287AniSetup(struct ath_hal *ah)
static struct ath_hal *
ar9287Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
+ HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_9287 *ahp9287;
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 898433e..af686f0 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -435,6 +435,81 @@ _ath_power_restore_power_state(struct ath_softc *sc, const char *file, int line)
}
+/*
+ * Configure the initial HAL configuration values based on bus
+ * specific parameters.
+ *
+ * Some PCI IDs and other information may need tweaking.
+ *
+ * XXX TODO: ath9k and the Atheros HAL only program comm2g_switch_enable
+ * if BT antenna diversity isn't enabled.
+ *
+ * So, let's also figure out how to enable BT diversity for AR9485.
+ */
+static void
+ath_setup_hal_config(struct ath_softc *sc, HAL_OPS_CONFIG *ah_config)
+{
+ /* XXX TODO: only for PCI devices? */
+
+ if (sc->sc_pci_devinfo & (ATH_PCI_CUS198 | ATH_PCI_CUS230)) {
+ ah_config->ath_hal_ext_lna_ctl_gpio = 0x200; /* bit 9 */
+ ah_config->ath_hal_ext_atten_margin_cfg = AH_TRUE;
+ ah_config->ath_hal_min_gainidx = AH_TRUE;
+ ah_config->ath_hal_ant_ctrl_comm2g_switch_enable = 0x000bbb88;
+ /* XXX low_rssi_thresh */
+ /* XXX fast_div_bias */
+ device_printf(sc->sc_dev, "configuring for %s\n",
+ (sc->sc_pci_devinfo & ATH_PCI_CUS198) ?
+ "CUS198" : "CUS230");
+ }
+
+ if (sc->sc_pci_devinfo & ATH_PCI_CUS217)
+ device_printf(sc->sc_dev, "CUS217 card detected\n");
+
+ if (sc->sc_pci_devinfo & ATH_PCI_CUS252)
+ device_printf(sc->sc_dev, "CUS252 card detected\n");
+
+ if (sc->sc_pci_devinfo & ATH_PCI_AR9565_1ANT)
+ device_printf(sc->sc_dev, "WB335 1-ANT card detected\n");
+
+ if (sc->sc_pci_devinfo & ATH_PCI_AR9565_2ANT)
+ device_printf(sc->sc_dev, "WB335 2-ANT card detected\n");
+
+ if (sc->sc_pci_devinfo & ATH_PCI_KILLER)
+ device_printf(sc->sc_dev, "Killer Wireless card detected\n");
+
+#if 0
+ /*
+ * Some WB335 cards do not support antenna diversity. Since
+ * we use a hardcoded value for AR9565 instead of using the
+ * EEPROM/OTP data, remove the combining feature from
+ * the HW capabilities bitmap.
+ */
+ if (sc->sc_pci_devinfo & (ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_AR9565_2ANT)) {
+ if (!(sc->sc_pci_devinfo & ATH9K_PCI_BT_ANT_DIV))
+ pCap->hw_caps &= ~ATH9K_HW_CAP_ANT_DIV_COMB;
+ }
+
+ if (sc->sc_pci_devinfo & ATH9K_PCI_BT_ANT_DIV) {
+ pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV;
+ device_printf(sc->sc_dev, "Set BT/WLAN RX diversity capability\n");
+ }
+#endif
+
+ if (sc->sc_pci_devinfo & ATH_PCI_D3_L1_WAR) {
+ ah_config->ath_hal_pcie_waen = 0x0040473b;
+ device_printf(sc->sc_dev, "Enable WAR for ASPM D3/L1\n");
+ }
+
+#if 0
+ if (sc->sc_pci_devinfo & ATH9K_PCI_NO_PLL_PWRSAVE) {
+ ah->config.no_pll_pwrsave = true;
+ device_printf(sc->sc_dev, "Disable PLL PowerSave\n");
+ }
+#endif
+
+}
+
#define HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
#define HAL_MODE_HT40 \
(HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \
@@ -450,6 +525,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
u_int wmodes;
uint8_t macaddr[IEEE80211_ADDR_LEN];
int rx_chainmask, tx_chainmask;
+ HAL_OPS_CONFIG ah_config;
DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
@@ -468,8 +544,17 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
device_get_unit(sc->sc_dev));
CURVNET_RESTORE();
+ /*
+ * Configure the initial configuration data.
+ *
+ * This is stuff that may be needed early during attach
+ * rather than done via configuration calls later.
+ */
+ bzero(&ah_config, sizeof(ah_config));
+ ath_setup_hal_config(sc, &ah_config);
+
ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh,
- sc->sc_eepromdata, &status);
+ sc->sc_eepromdata, &ah_config, &status);
if (ah == NULL) {
if_printf(ifp, "unable to attach hardware; HAL status %u\n",
status);
@@ -7101,6 +7186,6 @@ ath_node_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m)
MODULE_VERSION(if_ath, 1);
MODULE_DEPEND(if_ath, wlan, 1, 1, 1); /* 802.11 media layer */
-#if defined(IEEE80211_ALQ) || defined(AH_DEBUG_ALQ)
+#if defined(IEEE80211_ALQ) || defined(AH_DEBUG_ALQ) || defined(ATH_DEBUG_ALQ)
MODULE_DEPEND(if_ath, alq, 1, 1, 1);
#endif
diff --git a/sys/dev/ath/if_ath_lna_div.c b/sys/dev/ath/if_ath_lna_div.c
index 961b834..f0a33a5 100644
--- a/sys/dev/ath/if_ath_lna_div.c
+++ b/sys/dev/ath/if_ath_lna_div.c
@@ -209,6 +209,10 @@ bad:
return (error);
}
+/*
+ * XXX need to low_rssi_thresh config from ath9k, to support CUS198
+ * antenna diversity correctly.
+ */
static HAL_BOOL
ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, int mindelta,
int main_rssi_avg, int alt_rssi_avg, int pkt_count)
diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c
index dbbc411..057ec2c 100644
--- a/sys/dev/ath/if_ath_pci.c
+++ b/sys/dev/ath/if_ath_pci.c
@@ -80,6 +80,98 @@ struct ath_pci_softc {
void *sc_ih; /* interrupt handler */
};
+/*
+ * XXX eventually this should be some system level definition
+ * so modules will hvae probe/attach information like USB.
+ * But for now..
+ */
+struct pci_device_id {
+ int vendor_id;
+ int device_id;
+
+ int sub_vendor_id;
+ int sub_device_id;
+
+ int driver_data;
+
+ int match_populated:1;
+ int match_vendor_id:1;
+ int match_device_id:1;
+ int match_sub_vendor_id:1;
+ int match_sub_device_id:1;
+};
+
+#define PCI_VDEVICE(v, s) \
+ .vendor_id = (v), \
+ .device_id = (s), \
+ .match_populated = 1, \
+ .match_vendor_id = 1, \
+ .match_device_id = 1
+
+#define PCI_DEVICE_SUB(v, d, dv, ds) \
+ .match_populated = 1, \
+ .vendor_id = (v), .match_vendor_id = 1, \
+ .device_id = (d), .match_device_id = 1, \
+ .sub_vendor_id = (dv), .match_sub_vendor_id = 1, \
+ .sub_device_id = (ds), .match_sub_device_id = 1
+
+#define PCI_VENDOR_ID_ATHEROS 0x168c
+#define PCI_VENDOR_ID_SAMSUNG 0x144d
+#define PCI_VENDOR_ID_AZWAVE 0x1a3b
+#define PCI_VENDOR_ID_FOXCONN 0x105b
+#define PCI_VENDOR_ID_ATTANSIC 0x1969
+#define PCI_VENDOR_ID_ASUSTEK 0x1043
+#define PCI_VENDOR_ID_DELL 0x1028
+#define PCI_VENDOR_ID_QMI 0x1a32
+#define PCI_VENDOR_ID_LENOVO 0x17aa
+#define PCI_VENDOR_ID_HP 0x103c
+
+#include "if_ath_pci_devlist.h"
+
+/*
+ * Attempt to find a match for the given device in
+ * the given device table.
+ *
+ * Returns the device structure or NULL if no matching
+ * PCI device is found.
+ */
+static const struct pci_device_id *
+ath_pci_probe_device(device_t dev, const struct pci_device_id *dev_table, int nentries)
+{
+ int i;
+ int vendor_id, device_id;
+ int sub_vendor_id, sub_device_id;
+
+ vendor_id = pci_get_vendor(dev);
+ device_id = pci_get_device(dev);
+ sub_vendor_id = pci_get_subvendor(dev);
+ sub_device_id = pci_get_subdevice(dev);
+
+ for (i = 0; i < nentries; i++) {
+ /* Don't match on non-populated (eg empty) entries */
+ if (! dev_table[i].match_populated)
+ continue;
+
+ if (dev_table[i].match_vendor_id &&
+ (dev_table[i].vendor_id != vendor_id))
+ continue;
+ if (dev_table[i].match_device_id &&
+ (dev_table[i].device_id != device_id))
+ continue;
+ if (dev_table[i].match_sub_vendor_id &&
+ (dev_table[i].sub_vendor_id != sub_vendor_id))
+ continue;
+ if (dev_table[i].match_sub_device_id &&
+ (dev_table[i].sub_device_id != sub_device_id))
+ continue;
+
+ /* Match */
+ return (&dev_table[i]);
+ }
+
+ return (NULL);
+}
+
#define BS_BAR 0x10
#define PCIR_RETRY_TIMEOUT 0x41
#define PCIR_CFG_PMCSR 0x48
@@ -150,9 +242,15 @@ ath_pci_attach(device_t dev)
const struct firmware *fw = NULL;
const char *buf;
#endif
+ const struct pci_device_id *pd;
sc->sc_dev = dev;
+ /* Do this lookup anyway; figure out what to do with it later */
+ pd = ath_pci_probe_device(dev, ath_pci_id_table, nitems(ath_pci_id_table));
+ if (pd)
+ sc->sc_pci_devinfo = pd->driver_data;
+
/*
* Enable bus mastering.
*/
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 67eaecf..e888ca2 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -82,6 +82,25 @@
#define ATH_BEACON_CWMAX_DEFAULT 0 /* default cwmax for ap beacon q */
/*
+ * The following bits can be set during the PCI (and perhaps non-PCI
+ * later) device probe path.
+ *
+ * It controls some of the driver and HAL behaviour.
+ */
+
+#define ATH_PCI_CUS198 0x0001
+#define ATH_PCI_CUS230 0x0002
+#define ATH_PCI_CUS217 0x0004
+#define ATH_PCI_CUS252 0x0008
+#define ATH_PCI_WOW 0x0010
+#define ATH_PCI_BT_ANT_DIV 0x0020
+#define ATH_PCI_D3_L1_WAR 0x0040
+#define ATH_PCI_AR9565_1ANT 0x0080
+#define ATH_PCI_AR9565_2ANT 0x0100
+#define ATH_PCI_NO_PLL_PWRSAVE 0x0200
+#define ATH_PCI_KILLER 0x0400
+
+/*
* The key cache is used for h/w cipher state and also for
* tracking station state such as the current tx antenna.
* We also setup a mapping table between key cache slot indices
@@ -884,6 +903,9 @@ struct ath_softc {
HAL_POWER_MODE sc_cur_powerstate;
int sc_powersave_refcnt;
+
+ /* ATH_PCI_* flags */
+ uint32_t sc_pci_devinfo;
};
#define ATH_LOCK_INIT(_sc) \
OpenPOWER on IntegriCloud