Skip to content

Commit

Permalink
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/linville/wireless

John W. Linville says:

====================
A few stragglers hoping for 3.9, somewhat delayed due to my travels...

On the mac80211 bits, Johannes says:

"Sadly, I have another pull request -- the idle handling fix broke LED
handling in some cases."

and:

"Yet one more!

This fixes a fairly important/annoying bug -- when roaming between
multiple APs of the same network, the system could get stuck thinking it
was connected to the old one while it really wasn't."

On top of that...

Arend sends a brcmfmac patch that removes advertising a feature that
isn't actually fully supported, and a brcmsmac patch that rearranges
code to request firmware at IFF_UP to play more nicely with being
built into the kernel.

Felix gives us a minor ath9k_htc fix to support the newly released
open source firmware, and an ath9k_hw initvals fix to improve device
stability.

Rafał Miłecki provides a fix for an ssb regression that caused a
serious performance problem with b43.

Zefir Kurtisi offers an ath9k fix to change some kmalloc flags to
allow the DFS detector to be called in softirq context.

Please let me know if there are problems.  If these don't make 3.9,
I'll just pull them into wireless-next -- just let me know if you
want to do it that way!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 19, 2013
2 parents 12fb3dd + 5a22483 commit 6a4cd3f
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 157 deletions.
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = {
{0x00008258, 0x00000000},
{0x0000825c, 0x40000000},
{0x00008260, 0x00080922},
{0x00008264, 0x9bc00010},
{0x00008264, 0x9d400010},
{0x00008268, 0xffffffff},
{0x0000826c, 0x0000ffff},
{0x00008270, 0x00000000},
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,14 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq)
u32 sz, i;
struct channel_detector *cd;

cd = kmalloc(sizeof(*cd), GFP_KERNEL);
cd = kmalloc(sizeof(*cd), GFP_ATOMIC);
if (cd == NULL)
goto fail;

INIT_LIST_HEAD(&cd->head);
cd->freq = freq;
sz = sizeof(cd->detectors) * dpd->num_radar_types;
cd->detectors = kzalloc(sz, GFP_KERNEL);
cd->detectors = kzalloc(sz, GFP_ATOMIC);
if (cd->detectors == NULL)
goto fail;

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath9k/dfs_pri_detector.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts)
{
struct pulse_elem *p = pool_get_pulse_elem();
if (p == NULL) {
p = kmalloc(sizeof(*p), GFP_KERNEL);
p = kmalloc(sizeof(*p), GFP_ATOMIC);
if (p == NULL) {
DFS_POOL_STAT_INC(pulse_alloc_error);
return false;
Expand Down Expand Up @@ -299,7 +299,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde,
ps.deadline_ts = ps.first_ts + ps.dur;
new_ps = pool_get_pseq_elem();
if (new_ps == NULL) {
new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL);
new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC);
if (new_ps == NULL) {
DFS_POOL_STAT_INC(pseq_alloc_error);
return false;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/htc_drv_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
* required version.
*/
if (priv->fw_version_major != MAJOR_VERSION_REQ ||
priv->fw_version_minor != MINOR_VERSION_REQ) {
priv->fw_version_minor < MINOR_VERSION_REQ) {
dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
return -EINVAL;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/b43/phy_n.c
Original file line number Diff line number Diff line change
Expand Up @@ -5165,7 +5165,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
/* FIXME */
ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
avoid);
break;
#endif
}
Expand Down
7 changes: 1 addition & 6 deletions drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -4126,10 +4126,6 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP)
},
{
.max = 1,
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
},
{
.max = 1,
.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
Expand Down Expand Up @@ -4187,8 +4183,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_DEVICE);
BIT(NL80211_IFTYPE_P2P_GO);
wiphy->iface_combinations = brcmf_iface_combos;
wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
Expand Down
264 changes: 132 additions & 132 deletions drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,130 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
}
}

/**
* This function frees the WL per-device resources.
*
* This function frees resources owned by the WL device pointed to
* by the wl parameter.
*
* precondition: can both be called locked and unlocked
*
*/
static void brcms_free(struct brcms_info *wl)
{
struct brcms_timer *t, *next;

/* free ucode data */
if (wl->fw.fw_cnt)
brcms_ucode_data_free(&wl->ucode);
if (wl->irq)
free_irq(wl->irq, wl);

/* kill dpc */
tasklet_kill(&wl->tasklet);

if (wl->pub) {
brcms_debugfs_detach(wl->pub);
brcms_c_module_unregister(wl->pub, "linux", wl);
}

/* free common resources */
if (wl->wlc) {
brcms_c_detach(wl->wlc);
wl->wlc = NULL;
wl->pub = NULL;
}

/* virtual interface deletion is deferred so we cannot spinwait */

/* wait for all pending callbacks to complete */
while (atomic_read(&wl->callbacks) > 0)
schedule();

/* free timers */
for (t = wl->timers; t; t = next) {
next = t->next;
#ifdef DEBUG
kfree(t->name);
#endif
kfree(t);
}
}

/*
* called from both kernel as from this kernel module (error flow on attach)
* precondition: perimeter lock is not acquired.
*/
static void brcms_remove(struct bcma_device *pdev)
{
struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
struct brcms_info *wl = hw->priv;

if (wl->wlc) {
wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
ieee80211_unregister_hw(hw);
}

brcms_free(wl);

bcma_set_drvdata(pdev, NULL);
ieee80211_free_hw(hw);
}

/*
* Precondition: Since this function is called in brcms_pci_probe() context,
* no locking is required.
*/
static void brcms_release_fw(struct brcms_info *wl)
{
int i;
for (i = 0; i < MAX_FW_IMAGES; i++) {
release_firmware(wl->fw.fw_bin[i]);
release_firmware(wl->fw.fw_hdr[i]);
}
}

/*
* Precondition: Since this function is called in brcms_pci_probe() context,
* no locking is required.
*/
static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
{
int status;
struct device *device = &pdev->dev;
char fw_name[100];
int i;

memset(&wl->fw, 0, sizeof(struct brcms_firmware));
for (i = 0; i < MAX_FW_IMAGES; i++) {
if (brcms_firmwares[i] == NULL)
break;
sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
UCODE_LOADER_API_VER);
status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
if (status) {
wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
KBUILD_MODNAME, fw_name);
return status;
}
sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
UCODE_LOADER_API_VER);
status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
if (status) {
wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
KBUILD_MODNAME, fw_name);
return status;
}
wl->fw.hdr_num_entries[i] =
wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
}
wl->fw.fw_cnt = i;
status = brcms_ucode_data_init(wl, &wl->ucode);
brcms_release_fw(wl);
return status;
}

static void brcms_ops_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
Expand Down Expand Up @@ -306,6 +430,14 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
if (!blocked)
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);

if (!wl->ucode.bcm43xx_bomminor) {
err = brcms_request_fw(wl, wl->wlc->hw->d11core);
if (err) {
brcms_remove(wl->wlc->hw->d11core);
return -ENOENT;
}
}

spin_lock_bh(&wl->lock);
/* avoid acknowledging frames before a non-monitor device is added */
wl->mute_tx = true;
Expand Down Expand Up @@ -793,128 +925,6 @@ void brcms_dpc(unsigned long data)
wake_up(&wl->tx_flush_wq);
}

/*
* Precondition: Since this function is called in brcms_pci_probe() context,
* no locking is required.
*/
static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
{
int status;
struct device *device = &pdev->dev;
char fw_name[100];
int i;

memset(&wl->fw, 0, sizeof(struct brcms_firmware));
for (i = 0; i < MAX_FW_IMAGES; i++) {
if (brcms_firmwares[i] == NULL)
break;
sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
UCODE_LOADER_API_VER);
status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
if (status) {
wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
KBUILD_MODNAME, fw_name);
return status;
}
sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
UCODE_LOADER_API_VER);
status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
if (status) {
wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
KBUILD_MODNAME, fw_name);
return status;
}
wl->fw.hdr_num_entries[i] =
wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
}
wl->fw.fw_cnt = i;
return brcms_ucode_data_init(wl, &wl->ucode);
}

/*
* Precondition: Since this function is called in brcms_pci_probe() context,
* no locking is required.
*/
static void brcms_release_fw(struct brcms_info *wl)
{
int i;
for (i = 0; i < MAX_FW_IMAGES; i++) {
release_firmware(wl->fw.fw_bin[i]);
release_firmware(wl->fw.fw_hdr[i]);
}
}

/**
* This function frees the WL per-device resources.
*
* This function frees resources owned by the WL device pointed to
* by the wl parameter.
*
* precondition: can both be called locked and unlocked
*
*/
static void brcms_free(struct brcms_info *wl)
{
struct brcms_timer *t, *next;

/* free ucode data */
if (wl->fw.fw_cnt)
brcms_ucode_data_free(&wl->ucode);
if (wl->irq)
free_irq(wl->irq, wl);

/* kill dpc */
tasklet_kill(&wl->tasklet);

if (wl->pub) {
brcms_debugfs_detach(wl->pub);
brcms_c_module_unregister(wl->pub, "linux", wl);
}

/* free common resources */
if (wl->wlc) {
brcms_c_detach(wl->wlc);
wl->wlc = NULL;
wl->pub = NULL;
}

/* virtual interface deletion is deferred so we cannot spinwait */

/* wait for all pending callbacks to complete */
while (atomic_read(&wl->callbacks) > 0)
schedule();

/* free timers */
for (t = wl->timers; t; t = next) {
next = t->next;
#ifdef DEBUG
kfree(t->name);
#endif
kfree(t);
}
}

/*
* called from both kernel as from this kernel module (error flow on attach)
* precondition: perimeter lock is not acquired.
*/
static void brcms_remove(struct bcma_device *pdev)
{
struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
struct brcms_info *wl = hw->priv;

if (wl->wlc) {
wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
ieee80211_unregister_hw(hw);
}

brcms_free(wl);

bcma_set_drvdata(pdev, NULL);
ieee80211_free_hw(hw);
}

static irqreturn_t brcms_isr(int irq, void *dev_id)
{
struct brcms_info *wl;
Expand Down Expand Up @@ -1047,18 +1057,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
spin_lock_init(&wl->lock);
spin_lock_init(&wl->isr_lock);

/* prepare ucode */
if (brcms_request_fw(wl, pdev) < 0) {
wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
"%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
brcms_release_fw(wl);
brcms_remove(pdev);
return NULL;
}

/* common load-time initialization */
wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
brcms_release_fw(wl);
if (!wl->wlc) {
wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
KBUILD_MODNAME, err);
Expand Down
Loading

0 comments on commit 6a4cd3f

Please sign in to comment.