Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/linville/wireless-next-2.6
  • Loading branch information
David S. Miller committed Jun 20, 2009
2 parents 73e4289 + a97f442 commit c3da63f
Show file tree
Hide file tree
Showing 17 changed files with 338 additions and 89 deletions.
2 changes: 2 additions & 0 deletions Documentation/rfkill.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ following attributes:

name: Name assigned by driver to this key (interface or driver name).
type: Driver type string ("wlan", "bluetooth", etc).
persistent: Whether the soft blocked state is initialised from
non-volatile storage at startup.
state: Current state of the transmitter
0: RFKILL_STATE_SOFT_BLOCKED
transmitter is turned off by software
Expand Down
6 changes: 3 additions & 3 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ M: me@bobcopeland.com
L: linux-wireless@vger.kernel.org
L: ath5k-devel@lists.ath5k.org
S: Maintained
F: drivers/net/wireless/ath5k/
F: drivers/net/wireless/ath/ath5k/

ATHEROS ATH9K WIRELESS DRIVER
P: Luis R. Rodriguez
Expand All @@ -956,15 +956,15 @@ M: senthilkumar@atheros.com
L: linux-wireless@vger.kernel.org
L: ath9k-devel@lists.ath9k.org
S: Supported
F: drivers/net/wireless/ath9k/
F: drivers/net/wireless/ath/ath9k/

ATHEROS AR9170 WIRELESS DRIVER
P: Christian Lamparter
M: chunkeey@web.de
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/en/users/Drivers/ar9170
S: Maintained
F: drivers/net/wireless/ar9170/
F: drivers/net/wireless/ath/ar9170/

ATI_REMOTE2 DRIVER
P: Ville Syrjala
Expand Down
11 changes: 8 additions & 3 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/*******************/
Expand Down
18 changes: 18 additions & 0 deletions drivers/net/wireless/ath/ath9k/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/ath/ath9k/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wireless/iwmc3200wifi/iwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down Expand Up @@ -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);
Expand Down
64 changes: 58 additions & 6 deletions drivers/net/wireless/iwmc3200wifi/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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;

Expand All @@ -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) {
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
49 changes: 31 additions & 18 deletions drivers/net/wireless/iwmc3200wifi/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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));
}
Loading

0 comments on commit c3da63f

Please sign in to comment.