static int ath_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; u32 val; /* * Suspend/Resume resets the PCI configuration space, so we have to * re-disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ pci_read_config_dword(pdev, 0x40, &val); if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); /* Enable LED */ ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); /* * Reset key cache to sane defaults (all entries cleared) instead of * semi-random values after suspend/resume. */ ath9k_ps_wakeup(sc); ath9k_init_crypto(sc); ath9k_ps_restore(sc); sc->ps_idle = true; ath_radio_disable(sc, hw); return 0; }
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { struct ath_hw *ah = NULL; struct ath_common *common; int ret = 0, i; int csz = 0; ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); if (!ah) return -ENOMEM; ah->hw_version.devid = devid; ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; common = ath9k_hw_common(ah); common->ops = &ath9k_common_ops; common->bus_ops = bus_ops; common->ah = ah; common->hw = sc->hw; common->priv = sc; common->debug_mask = ath9k_debug; spin_lock_init(&sc->wiphy_lock); spin_lock_init(&sc->sc_resetlock); spin_lock_init(&sc->sc_serial_rw); spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, (unsigned long)sc); /* * Cache line size is used to size and align various * structures used to communicate with the hardware. */ ath_read_cachesize(common, &csz); common->cachelsz = csz << 2; /* convert to bytes */ ret = ath9k_hw_init(ah); if (ret) { ath_print(common, ATH_DBG_FATAL, "Unable to initialize hardware; " "initialization status: %d\n", ret); goto err_hw; } ret = ath9k_init_debug(ah); if (ret) { ath_print(common, ATH_DBG_FATAL, "Unable to create debugfs files\n"); goto err_debug; } ret = ath9k_init_queues(sc); if (ret) goto err_queues; ret = ath9k_init_btcoex(sc); if (ret) goto err_btcoex; ath9k_init_crypto(sc); ath9k_init_channels_rates(sc); ath9k_init_misc(sc); return 0; err_btcoex: for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_cleanupq(sc, &sc->tx.txq[i]); err_queues: ath9k_exit_debug(ah); err_debug: ath9k_hw_deinit(ah); err_hw: tasklet_kill(&sc->intr_tq); tasklet_kill(&sc->bcon_tasklet); kfree(ah); sc->sc_ah = NULL; return ret; }
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { struct ath_hw *ah = NULL; struct ath_common *common; int ret = 0, i; int csz = 0; ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); if (!ah) return -ENOMEM; ah->hw = sc->hw; ah->hw_version.devid = devid; ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; if (!sc->dev->platform_data) ah->ah_flags |= AH_USE_EEPROM; common = ath9k_hw_common(ah); common->ops = &ath9k_common_ops; common->bus_ops = bus_ops; common->ah = ah; common->hw = sc->hw; common->priv = sc; common->debug_mask = ath9k_debug; common->btcoex_enabled = ath9k_btcoex_enable == 1; spin_lock_init(&common->cc_lock); spin_lock_init(&sc->sc_serial_rw); spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); #ifdef CONFIG_ATH9K_DEBUGFS spin_lock_init(&sc->nodes_lock); INIT_LIST_HEAD(&sc->nodes); #endif tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, (unsigned long)sc); /* * Cache line size is used to size and align various * structures used to communicate with the hardware. */ ath_read_cachesize(common, &csz); common->cachelsz = csz << 2; /* convert to bytes */ /* Initializes the hardware for all supported chipsets */ ret = ath9k_hw_init(ah); if (ret) goto err_hw; ret = ath9k_init_queues(sc); if (ret) goto err_queues; ret = ath9k_init_btcoex(sc); if (ret) goto err_btcoex; ret = ath9k_init_channels_rates(sc); if (ret) goto err_btcoex; ath9k_init_crypto(sc); ath9k_init_misc(sc); return 0; err_btcoex: for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_cleanupq(sc, &sc->tx.txq[i]); err_queues: ath9k_hw_deinit(ah); err_hw: kfree(ah); sc->sc_ah = NULL; return ret; }
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { struct ath_hw *ah = NULL; struct ath_common *common; int ret = 0, i; int csz = 0; ah = zalloc(sizeof(struct ath_hw)); if (!ah) return -ENOMEM; ah->dev = sc->dev; ah->hw_version.devid = devid; ah->hw_version.subsysid = subsysid; ah->reg_ops.read = ath9k_ioread32; ah->reg_ops.write = ath9k_iowrite32; ah->reg_ops.rmw = ath9k_reg_rmw; sc->sc_ah = ah; sc->hwinfo = zalloc(sizeof(*sc->hwinfo)); if (!sc->hwinfo) { DBG("ath9k: cannot allocate 802.11 hardware info structure\n"); return -ENOMEM; } ah->ah_flags |= AH_USE_EEPROM; sc->sc_ah->led_pin = -1; common = ath9k_hw_common(ah); common->ops = &ah->reg_ops; common->bus_ops = bus_ops; common->ah = ah; common->dev = sc->dev; common->priv = sc; sc->intr_tq = ath9k_tasklet; /* * Cache line size is used to size and align various * structures used to communicate with the hardware. */ ath_read_cachesize(common, &csz); common->cachelsz = csz << 2; /* convert to bytes */ /* Initializes the hardware for all supported chipsets */ ret = ath9k_hw_init(ah); if (ret) goto err_hw; memcpy(sc->hwinfo->hwaddr, common->macaddr, ETH_ALEN); ret = ath9k_init_queues(sc); if (ret) goto err_queues; ret = ath9k_init_channels_rates(sc); if (ret) goto err_btcoex; ath9k_init_crypto(sc); ath9k_init_misc(sc); return 0; err_btcoex: for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_cleanupq(sc, &sc->tx.txq[i]); err_queues: ath9k_hw_deinit(ah); err_hw: free(sc->hwinfo); sc->hwinfo = NULL; free(ah); sc->sc_ah = NULL; return ret; }