if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
(sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
else
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
(sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
ieee80211_queue_delayed_work(sc->hw,
case LED_OFF:
if (led->led_type == ATH_LED_ASSOC ||
led->led_type == ATH_LED_RADIO) {
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
(led->led_type == ATH_LED_RADIO));
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
if (led->led_type == ATH_LED_RADIO)
ieee80211_queue_delayed_work(sc->hw,
&sc->ath_led_blink_work, 0);
} else if (led->led_type == ATH_LED_RADIO) {
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
sc->sc_flags |= SC_OP_LED_ON;
} else {
sc->led_on_cnt++;
ath_unregister_led(&sc->tx_led);
ath_unregister_led(&sc->rx_led);
ath_unregister_led(&sc->radio_led);
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
}
static 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
+ sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+
/* Configure gpio 1 for output */
- ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+ 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, ATH_LED_PIN, 1);
+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
ath9k_hw_set_interrupts(ah, sc->imask);
/* Enable LED */
- ath9k_hw_cfg_output(ah, ATH_LED_PIN,
+ ath9k_hw_cfg_output(ah, ah->led_pin,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
+ ath9k_hw_set_gpio(ah, ah->led_pin, 0);
ieee80211_wake_queues(sc->hw);
ath9k_ps_restore(sc);
ieee80211_stop_queues(sc->hw);
/* Disable LED */
- ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1);
- ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN);
+ ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+ ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
/* Disable interrupts */
ath9k_hw_set_interrupts(ah, 0);
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
ath9k_hw_detach(sc->sc_ah);
+ sc->sc_ah = NULL;
ath9k_exit_debug(sc);
}
return ath_reg_notifier_apply(wiphy, request, reg);
}
-static int ath_init(u16 devid, struct ath_softc *sc)
+/*
+ * Initialize and fill ath_softc, ath_sofct is the
+ * "Software Carrier" struct. Historically it has existed
+ * to allow the separation between hardware specific
+ * variables (now in ath_hw) and driver specific variables.
+ */
+static int ath_init_softc(u16 devid, struct ath_softc *sc)
{
struct ath_hw *ah = NULL;
int r = 0, i;
*/
ath_read_cachesize(sc, &csz);
/* XXX assert csz is non-zero */
- sc->cachelsz = csz << 2; /* convert to bytes */
+ sc->common.cachelsz = csz << 2; /* convert to bytes */
ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
if (!ah) {
ah->hw_version.devid = devid;
sc->sc_ah = ah;
- r = ath9k_hw_attach(ah);
+ r = ath9k_hw_init(ah);
if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to attach hardware; "
+ "Unable to initialize hardware; "
"initialization status: %d\n", r);
goto bad;
}
for (i = 0; i < sc->keymax; i++)
ath9k_hw_keyreset(ah, (u16) i);
- if (r)
- goto bad;
-
/* default to MONITOR mode */
sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
bad:
- if (ah)
- ath9k_hw_detach(ah);
+ ath9k_hw_detach(ah);
+ sc->sc_ah = NULL;
bad_no_ah:
ath9k_exit_debug(sc);
&sc->sbands[IEEE80211_BAND_5GHZ];
}
-int ath_attach(u16 devid, struct ath_softc *sc)
+/* Device driver core initialization */
+int ath_init_device(u16 devid, struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
int error = 0, i;
DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
- error = ath_init(devid, sc);
+ error = ath_init_softc(devid, sc);
if (error != 0)
return error;
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
ath9k_hw_detach(sc->sc_ah);
+ sc->sc_ah = NULL;
ath9k_exit_debug(sc);
return error;
mutex_lock(&sc->mutex);
+ cancel_delayed_work_sync(&sc->tx_complete_work);
+
if (ath9k_wiphy_started(sc)) {
mutex_unlock(&sc->mutex);
return; /* another wiphy still in use */
/* disable HAL and put h/w to sleep */
ath9k_hw_disable(sc->sc_ah);
ath9k_hw_configpcipowersave(sc->sc_ah, 1);
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
sc->sc_flags |= SC_OP_INVALID;
if ((conf->type == NL80211_IFTYPE_STATION) ||
(conf->type == NL80211_IFTYPE_ADHOC) ||
(conf->type == NL80211_IFTYPE_MESH_POINT)) {
- if (ath9k_hw_phycounters(sc->sc_ah))
- sc->imask |= ATH9K_INT_MIB;
+ sc->imask |= ATH9K_INT_MIB;
sc->imask |= ATH9K_INT_TSFOOR;
}
(FIF_PROMISC_IN_BSS | \
FIF_ALLMULTI | \
FIF_CONTROL | \
+ FIF_PSPOLL | \
FIF_OTHER_BSS | \
FIF_BCN_PRBRESP_PROMISC | \
FIF_FCSFAIL)
static void ath9k_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
- int mc_count,
- struct dev_mc_list *mclist)
+ u64 multicast)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;