Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
This commit is contained in:
@@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = {
|
|||||||
{0x00008258, 0x00000000},
|
{0x00008258, 0x00000000},
|
||||||
{0x0000825c, 0x40000000},
|
{0x0000825c, 0x40000000},
|
||||||
{0x00008260, 0x00080922},
|
{0x00008260, 0x00080922},
|
||||||
{0x00008264, 0x9bc00010},
|
{0x00008264, 0x9d400010},
|
||||||
{0x00008268, 0xffffffff},
|
{0x00008268, 0xffffffff},
|
||||||
{0x0000826c, 0x0000ffff},
|
{0x0000826c, 0x0000ffff},
|
||||||
{0x00008270, 0x00000000},
|
{0x00008270, 0x00000000},
|
||||||
|
|||||||
@@ -145,14 +145,14 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq)
|
|||||||
struct channel_detector *cd;
|
struct channel_detector *cd;
|
||||||
struct ath_common *common = ath9k_hw_common(dpd->ah);
|
struct ath_common *common = ath9k_hw_common(dpd->ah);
|
||||||
|
|
||||||
cd = kmalloc(sizeof(*cd), GFP_KERNEL);
|
cd = kmalloc(sizeof(*cd), GFP_ATOMIC);
|
||||||
if (cd == NULL)
|
if (cd == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&cd->head);
|
INIT_LIST_HEAD(&cd->head);
|
||||||
cd->freq = freq;
|
cd->freq = freq;
|
||||||
sz = sizeof(cd->detectors) * dpd->num_radar_types;
|
sz = sizeof(cd->detectors) * dpd->num_radar_types;
|
||||||
cd->detectors = kzalloc(sz, GFP_KERNEL);
|
cd->detectors = kzalloc(sz, GFP_ATOMIC);
|
||||||
if (cd->detectors == NULL)
|
if (cd->detectors == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts)
|
|||||||
{
|
{
|
||||||
struct pulse_elem *p = pool_get_pulse_elem();
|
struct pulse_elem *p = pool_get_pulse_elem();
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
p = kmalloc(sizeof(*p), GFP_KERNEL);
|
p = kmalloc(sizeof(*p), GFP_ATOMIC);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
DFS_POOL_STAT_INC(pulse_alloc_error);
|
DFS_POOL_STAT_INC(pulse_alloc_error);
|
||||||
return false;
|
return false;
|
||||||
@@ -277,7 +277,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde,
|
|||||||
ps.deadline_ts = ps.first_ts + ps.dur;
|
ps.deadline_ts = ps.first_ts + ps.dur;
|
||||||
new_ps = pool_get_pseq_elem();
|
new_ps = pool_get_pseq_elem();
|
||||||
if (new_ps == NULL) {
|
if (new_ps == NULL) {
|
||||||
new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL);
|
new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC);
|
||||||
if (new_ps == NULL) {
|
if (new_ps == NULL) {
|
||||||
DFS_POOL_STAT_INC(pseq_alloc_error);
|
DFS_POOL_STAT_INC(pseq_alloc_error);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
|
|||||||
* required version.
|
* required version.
|
||||||
*/
|
*/
|
||||||
if (priv->fw_version_major != MAJOR_VERSION_REQ ||
|
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",
|
dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
|
||||||
MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
|
MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|||||||
@@ -5109,7 +5109,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_B43_SSB
|
#ifdef CONFIG_B43_SSB
|
||||||
case B43_BUS_SSB:
|
case B43_BUS_SSB:
|
||||||
/* FIXME */
|
ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
|
||||||
|
avoid);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4086,10 +4086,6 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
|
|||||||
BIT(NL80211_IFTYPE_ADHOC) |
|
BIT(NL80211_IFTYPE_ADHOC) |
|
||||||
BIT(NL80211_IFTYPE_AP)
|
BIT(NL80211_IFTYPE_AP)
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.max = 1,
|
|
||||||
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.max = 1,
|
.max = 1,
|
||||||
.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
@@ -4152,8 +4148,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
|
|||||||
BIT(NL80211_IFTYPE_ADHOC) |
|
BIT(NL80211_IFTYPE_ADHOC) |
|
||||||
BIT(NL80211_IFTYPE_AP) |
|
BIT(NL80211_IFTYPE_AP) |
|
||||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
BIT(NL80211_IFTYPE_P2P_GO);
|
||||||
BIT(NL80211_IFTYPE_P2P_DEVICE);
|
|
||||||
wiphy->iface_combinations = brcmf_iface_combos;
|
wiphy->iface_combinations = brcmf_iface_combos;
|
||||||
wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
|
wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
|
||||||
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
|
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
|
||||||
|
|||||||
@@ -276,6 +276,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,
|
static void brcms_ops_tx(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_tx_control *control,
|
struct ieee80211_tx_control *control,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
@@ -308,6 +432,14 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
|
|||||||
if (!blocked)
|
if (!blocked)
|
||||||
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
|
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);
|
spin_lock_bh(&wl->lock);
|
||||||
/* avoid acknowledging frames before a non-monitor device is added */
|
/* avoid acknowledging frames before a non-monitor device is added */
|
||||||
wl->mute_tx = true;
|
wl->mute_tx = true;
|
||||||
@@ -856,129 +988,6 @@ void brcms_dpc(unsigned long data)
|
|||||||
wake_up(&wl->tx_flush_wq);
|
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) {
|
|
||||||
brcms_led_unregister(wl);
|
|
||||||
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)
|
static irqreturn_t brcms_isr(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct brcms_info *wl;
|
struct brcms_info *wl;
|
||||||
@@ -1120,18 +1129,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
|
|||||||
spin_lock_init(&wl->lock);
|
spin_lock_init(&wl->lock);
|
||||||
spin_lock_init(&wl->isr_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 */
|
/* common load-time initialization */
|
||||||
wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
|
wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
|
||||||
brcms_release_fw(wl);
|
|
||||||
if (!wl->wlc) {
|
if (!wl->wlc) {
|
||||||
wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
|
wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
|
||||||
KBUILD_MODNAME, err);
|
KBUILD_MODNAME, err);
|
||||||
|
|||||||
@@ -670,3 +670,32 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid)
|
||||||
|
{
|
||||||
|
u32 pmu_ctl = 0;
|
||||||
|
|
||||||
|
switch (cc->dev->bus->chip_id) {
|
||||||
|
case 0x4322:
|
||||||
|
ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070);
|
||||||
|
ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a);
|
||||||
|
ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854);
|
||||||
|
if (spuravoid == 1)
|
||||||
|
ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828);
|
||||||
|
else
|
||||||
|
ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828);
|
||||||
|
pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD;
|
||||||
|
break;
|
||||||
|
case 43222:
|
||||||
|
/* TODO: BCM43222 requires updating PLLs too */
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
ssb_printk(KERN_ERR PFX
|
||||||
|
"Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
|
||||||
|
cc->dev->bus->chip_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate);
|
||||||
|
|||||||
@@ -219,6 +219,7 @@
|
|||||||
#define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */
|
#define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */
|
||||||
#define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
|
#define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
|
||||||
#define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16
|
#define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16
|
||||||
|
#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400
|
||||||
#define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
|
#define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
|
||||||
#define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
|
#define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
|
||||||
#define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
|
#define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
|
||||||
@@ -667,5 +668,6 @@ enum ssb_pmu_ldo_volt_id {
|
|||||||
void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
|
void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
|
||||||
enum ssb_pmu_ldo_volt_id id, u32 voltage);
|
enum ssb_pmu_ldo_volt_id id, u32 voltage);
|
||||||
void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
|
void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
|
||||||
|
void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid);
|
||||||
|
|
||||||
#endif /* LINUX_SSB_CHIPCO_H_ */
|
#endif /* LINUX_SSB_CHIPCO_H_ */
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
|
|||||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
|
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ieee80211_idle_off(struct ieee80211_local *local)
|
static u32 __ieee80211_idle_off(struct ieee80211_local *local)
|
||||||
{
|
{
|
||||||
if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
|
if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -87,7 +87,7 @@ u32 ieee80211_idle_off(struct ieee80211_local *local)
|
|||||||
return IEEE80211_CONF_CHANGE_IDLE;
|
return IEEE80211_CONF_CHANGE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 ieee80211_idle_on(struct ieee80211_local *local)
|
static u32 __ieee80211_idle_on(struct ieee80211_local *local)
|
||||||
{
|
{
|
||||||
if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
|
if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -98,16 +98,18 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local)
|
|||||||
return IEEE80211_CONF_CHANGE_IDLE;
|
return IEEE80211_CONF_CHANGE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_recalc_idle(struct ieee80211_local *local)
|
static u32 __ieee80211_recalc_idle(struct ieee80211_local *local,
|
||||||
|
bool force_active)
|
||||||
{
|
{
|
||||||
bool working = false, scanning, active;
|
bool working = false, scanning, active;
|
||||||
unsigned int led_trig_start = 0, led_trig_stop = 0;
|
unsigned int led_trig_start = 0, led_trig_stop = 0;
|
||||||
struct ieee80211_roc_work *roc;
|
struct ieee80211_roc_work *roc;
|
||||||
u32 change;
|
|
||||||
|
|
||||||
lockdep_assert_held(&local->mtx);
|
lockdep_assert_held(&local->mtx);
|
||||||
|
|
||||||
active = !list_empty(&local->chanctx_list) || local->monitors;
|
active = force_active ||
|
||||||
|
!list_empty(&local->chanctx_list) ||
|
||||||
|
local->monitors;
|
||||||
|
|
||||||
if (!local->ops->remain_on_channel) {
|
if (!local->ops->remain_on_channel) {
|
||||||
list_for_each_entry(roc, &local->roc_list, list) {
|
list_for_each_entry(roc, &local->roc_list, list) {
|
||||||
@@ -132,9 +134,18 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
|
|||||||
ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
|
ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
|
||||||
|
|
||||||
if (working || scanning || active)
|
if (working || scanning || active)
|
||||||
change = ieee80211_idle_off(local);
|
return __ieee80211_idle_off(local);
|
||||||
else
|
return __ieee80211_idle_on(local);
|
||||||
change = ieee80211_idle_on(local);
|
}
|
||||||
|
|
||||||
|
u32 ieee80211_idle_off(struct ieee80211_local *local)
|
||||||
|
{
|
||||||
|
return __ieee80211_recalc_idle(local, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ieee80211_recalc_idle(struct ieee80211_local *local)
|
||||||
|
{
|
||||||
|
u32 change = __ieee80211_recalc_idle(local, false);
|
||||||
if (change)
|
if (change)
|
||||||
ieee80211_hw_config(local, change);
|
ieee80211_hw_config(local, change);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4022,8 +4022,16 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
|||||||
/* prep auth_data so we don't go into idle on disassoc */
|
/* prep auth_data so we don't go into idle on disassoc */
|
||||||
ifmgd->auth_data = auth_data;
|
ifmgd->auth_data = auth_data;
|
||||||
|
|
||||||
if (ifmgd->associated)
|
if (ifmgd->associated) {
|
||||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||||
|
|
||||||
|
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
||||||
|
WLAN_REASON_UNSPECIFIED,
|
||||||
|
false, frame_buf);
|
||||||
|
|
||||||
|
__cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||||
|
sizeof(frame_buf));
|
||||||
|
}
|
||||||
|
|
||||||
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
|
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
|
||||||
|
|
||||||
@@ -4083,8 +4091,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||||||
|
|
||||||
mutex_lock(&ifmgd->mtx);
|
mutex_lock(&ifmgd->mtx);
|
||||||
|
|
||||||
if (ifmgd->associated)
|
if (ifmgd->associated) {
|
||||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||||
|
|
||||||
|
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
||||||
|
WLAN_REASON_UNSPECIFIED,
|
||||||
|
false, frame_buf);
|
||||||
|
|
||||||
|
__cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||||
|
sizeof(frame_buf));
|
||||||
|
}
|
||||||
|
|
||||||
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
|
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
|
|||||||
Reference in New Issue
Block a user