@@ -23,7 +23,8 @@
#include <net/cfg80211.h>
#include "ar9003_eeprom.h"
-#define AH_USE_EEPROM 0x1
+#define AH_USE_EEPROM 0x00000001
+#define AH_UNPLUGGED 0x00000002
#ifdef __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5
@@ -125,7 +125,8 @@ void ath_deinit_leds(struct ath_softc *sc)
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, sc->sc_ah->led_pin, 1);
+ if (!(sc->sc_ah->ah_flags & AH_UNPLUGGED))
+ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
}
void ath_init_leds(struct ath_softc *sc)
@@ -542,6 +542,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
if (!sc->dev->platform_data)
ah->ah_flags |= AH_USE_EEPROM;
+ sc->sc_ah->ah_flags &= ~AH_UNPLUGGED;
common = ath9k_hw_common(ah);
common->ops = &ath9k_common_ops;
common->bus_ops = bus_ops;
@@ -818,8 +819,8 @@ void ath9k_deinit_device(struct ath_softc *sc)
struct ieee80211_hw *hw = sc->hw;
int i = 0;
- ath9k_ps_wakeup(sc);
-
+ if (!(sc->sc_ah->ah_flags & AH_UNPLUGGED))
+ ath9k_ps_wakeup(sc);
wiphy_rfkill_stop_polling(sc->hw->wiphy);
ath_deinit_leds(sc);
@@ -1220,6 +1220,12 @@ static int ath9k_tx(struct ieee80211_hw *hw,
struct ath_tx_control txctl;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ if (sc->sc_ah->ah_flags & AH_UNPLUGGED) {
+ ath_dbg(common, ATH_DBG_ANY,
+ "Device not present, can not xmit\n");
+ goto exit;
+ }
+
if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
ath_dbg(common, ATH_DBG_XMIT,
"ath9k: %s: TX in unexpected wiphy state %d\n",
@@ -1318,6 +1324,12 @@ static void ath9k_stop(struct ieee80211_hw *hw)
return;
}
+ if (ah->ah_flags & AH_UNPLUGGED) {
+ ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
+ mutex_unlock(&sc->mutex);
+ return;
+ }
+
if (ath9k_wiphy_started(sc)) {
mutex_unlock(&sc->mutex);
return; /* another wiphy still in use */
@@ -1585,6 +1597,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&sc->mutex);
+ if (ah->ah_flags & AH_UNPLUGGED) {
+ mutex_unlock(&sc->mutex);
+ return 0;
+ }
+
/*
* Leave this as the first check because we need to turn on the
* radio if it was disabled before prior to processing the rest
@@ -1765,6 +1782,9 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
changed_flags &= SUPPORTED_FILTERS;
*total_flags &= SUPPORTED_FILTERS;
+ if (sc->sc_ah->ah_flags & AH_UNPLUGGED)
+ return;
+
sc->rx.rxfilter = *total_flags;
ath9k_ps_wakeup(sc);
rfilt = ath_calcrxfilter(sc);
@@ -264,6 +264,7 @@ static void ath_pci_remove(struct pci_dev *pdev)
struct ath_softc *sc = aphy->sc;
void __iomem *mem = sc->mem;
+ sc->sc_ah->ah_flags |= AH_UNPLUGGED;
ath9k_deinit_device(sc);
free_irq(sc->irq, sc);
ieee80211_free_hw(sc->hw);