mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
c3da63f357
17 changed files with 338 additions and 89 deletions
|
|
@ -538,6 +538,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
|
|||
sc->iobase = mem; /* So we can unmap it on detach */
|
||||
sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
|
||||
sc->opmode = NL80211_IFTYPE_STATION;
|
||||
sc->bintval = 1000;
|
||||
mutex_init(&sc->lock);
|
||||
spin_lock_init(&sc->rxbuflock);
|
||||
spin_lock_init(&sc->txbuflock);
|
||||
|
|
@ -686,6 +687,13 @@ ath5k_pci_resume(struct pci_dev *pdev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* 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_write_config_byte(pdev, 0x41, 0);
|
||||
|
||||
err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
|
||||
if (err) {
|
||||
ATH5K_ERR(sc, "request_irq failed\n");
|
||||
|
|
@ -2748,9 +2756,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
|
|||
goto end;
|
||||
}
|
||||
|
||||
/* Set to a reasonable value. Note that this will
|
||||
* be set to mac80211's value at ath5k_config(). */
|
||||
sc->bintval = 1000;
|
||||
ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
|
||||
|
||||
ret = 0;
|
||||
|
|
|
|||
|
|
@ -1196,8 +1196,8 @@ void ath_radio_disable(struct ath_softc *sc)
|
|||
|
||||
ath9k_hw_phy_disable(ah);
|
||||
ath9k_hw_configpcipowersave(ah, 1);
|
||||
ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
|
||||
ath9k_ps_restore(sc);
|
||||
ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
|
||||
}
|
||||
|
||||
/*******************/
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
struct ath_softc *sc;
|
||||
struct ieee80211_hw *hw;
|
||||
u8 csz;
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
struct ath_hw *ah;
|
||||
|
||||
|
|
@ -133,6 +134,14 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
|
||||
pci_set_master(pdev);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
ret = pci_request_region(pdev, 0, "ath9k");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "PCI memory region reserve error\n");
|
||||
|
|
@ -239,12 +248,21 @@ static int ath_pci_resume(struct pci_dev *pdev)
|
|||
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
struct ath_softc *sc = aphy->sc;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
return err;
|
||||
pci_restore_state(pdev);
|
||||
/*
|
||||
* 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, ATH_LED_PIN,
|
||||
|
|
|
|||
|
|
@ -539,11 +539,14 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
|
|||
if (ath_beacon_dtim_pending_cab(skb)) {
|
||||
/*
|
||||
* Remain awake waiting for buffered broadcast/multicast
|
||||
* frames.
|
||||
* frames. If the last broadcast/multicast frame is not
|
||||
* received properly, the next beacon frame will work as
|
||||
* a backup trigger for returning into NETWORK SLEEP state,
|
||||
* so we are waiting for it as well.
|
||||
*/
|
||||
DPRINTF(sc, ATH_DBG_PS, "Received DTIM beacon indicating "
|
||||
"buffered broadcast/multicast frame(s)\n");
|
||||
sc->sc_flags |= SC_OP_WAIT_FOR_CAB;
|
||||
sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -288,6 +288,7 @@ struct iwm_priv {
|
|||
u8 *eeprom;
|
||||
struct timer_list watchdog;
|
||||
struct work_struct reset_worker;
|
||||
struct mutex mutex;
|
||||
struct rfkill *rfkill;
|
||||
|
||||
char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
|
||||
|
|
@ -315,8 +316,11 @@ extern const struct iw_handler_def iwm_iw_handler_def;
|
|||
void *iwm_if_alloc(int sizeof_bus, struct device *dev,
|
||||
struct iwm_if_ops *if_ops);
|
||||
void iwm_if_free(struct iwm_priv *iwm);
|
||||
int iwm_if_add(struct iwm_priv *iwm);
|
||||
void iwm_if_remove(struct iwm_priv *iwm);
|
||||
int iwm_mode_to_nl80211_iftype(int mode);
|
||||
int iwm_priv_init(struct iwm_priv *iwm);
|
||||
void iwm_priv_deinit(struct iwm_priv *iwm);
|
||||
void iwm_reset(struct iwm_priv *iwm);
|
||||
void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
|
||||
struct iwm_umac_notif_alive *alive);
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ static void iwm_statistics_request(struct work_struct *work)
|
|||
iwm_send_umac_stats_req(iwm, 0);
|
||||
}
|
||||
|
||||
int __iwm_up(struct iwm_priv *iwm);
|
||||
int __iwm_down(struct iwm_priv *iwm);
|
||||
|
||||
static void iwm_reset_worker(struct work_struct *work)
|
||||
{
|
||||
struct iwm_priv *iwm;
|
||||
|
|
@ -120,6 +123,19 @@ static void iwm_reset_worker(struct work_struct *work)
|
|||
|
||||
iwm = container_of(work, struct iwm_priv, reset_worker);
|
||||
|
||||
/*
|
||||
* XXX: The iwm->mutex is introduced purely for this reset work,
|
||||
* because the other users for iwm_up and iwm_down are only netdev
|
||||
* ndo_open and ndo_stop which are already protected by rtnl.
|
||||
* Please remove iwm->mutex together if iwm_reset_worker() is not
|
||||
* required in the future.
|
||||
*/
|
||||
if (!mutex_trylock(&iwm->mutex)) {
|
||||
IWM_WARN(iwm, "We are in the middle of interface bringing "
|
||||
"UP/DOWN. Skip driver resetting.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (iwm->umac_profile_active) {
|
||||
profile = kmalloc(sizeof(struct iwm_umac_profile), GFP_KERNEL);
|
||||
if (profile)
|
||||
|
|
@ -128,10 +144,10 @@ static void iwm_reset_worker(struct work_struct *work)
|
|||
IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
|
||||
}
|
||||
|
||||
iwm_down(iwm);
|
||||
__iwm_down(iwm);
|
||||
|
||||
while (retry++ < 3) {
|
||||
ret = iwm_up(iwm);
|
||||
ret = __iwm_up(iwm);
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
|
|
@ -142,7 +158,7 @@ static void iwm_reset_worker(struct work_struct *work)
|
|||
IWM_WARN(iwm, "iwm_up() failed: %d\n", ret);
|
||||
|
||||
kfree(profile);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (profile) {
|
||||
|
|
@ -151,6 +167,9 @@ static void iwm_reset_worker(struct work_struct *work)
|
|||
iwm_send_mlme_profile(iwm);
|
||||
kfree(profile);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&iwm->mutex);
|
||||
}
|
||||
|
||||
static void iwm_watchdog(unsigned long data)
|
||||
|
|
@ -215,10 +234,21 @@ int iwm_priv_init(struct iwm_priv *iwm)
|
|||
init_timer(&iwm->watchdog);
|
||||
iwm->watchdog.function = iwm_watchdog;
|
||||
iwm->watchdog.data = (unsigned long)iwm;
|
||||
mutex_init(&iwm->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwm_priv_deinit(struct iwm_priv *iwm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IWM_TX_QUEUES; i++)
|
||||
destroy_workqueue(iwm->txq[i].wq);
|
||||
|
||||
destroy_workqueue(iwm->rx_wq);
|
||||
}
|
||||
|
||||
/*
|
||||
* We reset all the structures, and we reset the UMAC.
|
||||
* After calling this routine, you're expected to reload
|
||||
|
|
@ -466,7 +496,7 @@ void iwm_link_off(struct iwm_priv *iwm)
|
|||
|
||||
iwm_rx_free(iwm);
|
||||
|
||||
cancel_delayed_work(&iwm->stats_request);
|
||||
cancel_delayed_work_sync(&iwm->stats_request);
|
||||
memset(wstats, 0, sizeof(struct iw_statistics));
|
||||
wstats->qual.updated = IW_QUAL_ALL_INVALID;
|
||||
|
||||
|
|
@ -511,7 +541,7 @@ static int iwm_channels_init(struct iwm_priv *iwm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int iwm_up(struct iwm_priv *iwm)
|
||||
int __iwm_up(struct iwm_priv *iwm)
|
||||
{
|
||||
int ret;
|
||||
struct iwm_notif *notif_reboot, *notif_ack = NULL;
|
||||
|
|
@ -647,7 +677,18 @@ int iwm_up(struct iwm_priv *iwm)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
int iwm_down(struct iwm_priv *iwm)
|
||||
int iwm_up(struct iwm_priv *iwm)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&iwm->mutex);
|
||||
ret = __iwm_up(iwm);
|
||||
mutex_unlock(&iwm->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __iwm_down(struct iwm_priv *iwm)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -678,3 +719,14 @@ int iwm_down(struct iwm_priv *iwm)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwm_down(struct iwm_priv *iwm)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&iwm->mutex);
|
||||
ret = __iwm_down(iwm);
|
||||
mutex_unlock(&iwm->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,32 +114,31 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
|
|||
iwm = wdev_to_iwm(wdev);
|
||||
iwm->bus_ops = if_ops;
|
||||
iwm->wdev = wdev;
|
||||
iwm_priv_init(iwm);
|
||||
|
||||
ret = iwm_priv_init(iwm);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to init iwm_priv\n");
|
||||
goto out_wdev;
|
||||
}
|
||||
|
||||
wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
|
||||
|
||||
ndev = alloc_netdev_mq(0, "wlan%d", ether_setup,
|
||||
IWM_TX_QUEUES);
|
||||
ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
|
||||
if (!ndev) {
|
||||
dev_err(dev, "no memory for network device instance\n");
|
||||
goto out_wdev;
|
||||
goto out_priv;
|
||||
}
|
||||
|
||||
ndev->netdev_ops = &iwm_netdev_ops;
|
||||
ndev->wireless_handlers = &iwm_iw_handler_def;
|
||||
ndev->ieee80211_ptr = wdev;
|
||||
SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
|
||||
ret = register_netdev(ndev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to register netdev: %d\n", ret);
|
||||
goto out_ndev;
|
||||
}
|
||||
|
||||
wdev->netdev = ndev;
|
||||
|
||||
return iwm;
|
||||
|
||||
out_ndev:
|
||||
free_netdev(ndev);
|
||||
out_priv:
|
||||
iwm_priv_deinit(iwm);
|
||||
|
||||
out_wdev:
|
||||
iwm_wdev_free(iwm);
|
||||
|
|
@ -148,15 +147,29 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
|
|||
|
||||
void iwm_if_free(struct iwm_priv *iwm)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!iwm_to_ndev(iwm))
|
||||
return;
|
||||
|
||||
unregister_netdev(iwm_to_ndev(iwm));
|
||||
free_netdev(iwm_to_ndev(iwm));
|
||||
iwm_wdev_free(iwm);
|
||||
destroy_workqueue(iwm->rx_wq);
|
||||
for (i = 0; i < IWM_TX_QUEUES; i++)
|
||||
destroy_workqueue(iwm->txq[i].wq);
|
||||
iwm_priv_deinit(iwm);
|
||||
}
|
||||
|
||||
int iwm_if_add(struct iwm_priv *iwm)
|
||||
{
|
||||
struct net_device *ndev = iwm_to_ndev(iwm);
|
||||
int ret;
|
||||
|
||||
ret = register_netdev(ndev);
|
||||
if (ret < 0) {
|
||||
dev_err(&ndev->dev, "Failed to register netdev: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwm_if_remove(struct iwm_priv *iwm)
|
||||
{
|
||||
unregister_netdev(iwm_to_ndev(iwm));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -454,10 +454,18 @@ static int iwm_sdio_probe(struct sdio_func *func,
|
|||
|
||||
INIT_WORK(&hw->isr_worker, iwm_sdio_isr_worker);
|
||||
|
||||
ret = iwm_if_add(iwm);
|
||||
if (ret) {
|
||||
dev_err(dev, "add SDIO interface failed\n");
|
||||
goto destroy_wq;
|
||||
}
|
||||
|
||||
dev_info(dev, "IWM SDIO probe\n");
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_wq:
|
||||
destroy_workqueue(hw->isr_wq);
|
||||
debugfs_exit:
|
||||
iwm_debugfs_exit(iwm);
|
||||
if_free:
|
||||
|
|
@ -471,9 +479,10 @@ static void iwm_sdio_remove(struct sdio_func *func)
|
|||
struct iwm_priv *iwm = hw_to_iwm(hw);
|
||||
struct device *dev = &func->dev;
|
||||
|
||||
iwm_if_remove(iwm);
|
||||
destroy_workqueue(hw->isr_wq);
|
||||
iwm_debugfs_exit(iwm);
|
||||
iwm_if_free(iwm);
|
||||
destroy_workqueue(hw->isr_wq);
|
||||
|
||||
sdio_set_drvdata(func, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ static struct usb_device_id usb_ids[] = {
|
|||
{ USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x083a, 0xe503), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x083a, 0xe506), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B },
|
||||
|
|
|
|||
Loading…
Reference in a new issue