Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

This commit is contained in:
David S. Miller 2011-11-04 17:14:34 -04:00
commit 39b02648d2
25 changed files with 126 additions and 94 deletions

View File

@ -105,7 +105,7 @@ static int ath3k_load_firmware(struct usb_device *udev,
pipe = usb_sndctrlpipe(udev, 0); pipe = usb_sndctrlpipe(udev, 0);
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) { if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware"); BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM; return -ENOMEM;
@ -176,7 +176,7 @@ static int ath3k_load_fwfile(struct usb_device *udev,
count = firmware->size; count = firmware->size;
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) { if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware"); BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM; return -ENOMEM;

View File

@ -24,6 +24,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/atomic.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -65,6 +66,7 @@ struct bcm203x_data {
unsigned long state; unsigned long state;
struct work_struct work; struct work_struct work;
atomic_t shutdown;
struct urb *urb; struct urb *urb;
unsigned char *buffer; unsigned char *buffer;
@ -97,6 +99,7 @@ static void bcm203x_complete(struct urb *urb)
data->state = BCM203X_SELECT_MEMORY; data->state = BCM203X_SELECT_MEMORY;
/* use workqueue to have a small delay */
schedule_work(&data->work); schedule_work(&data->work);
break; break;
@ -155,7 +158,10 @@ static void bcm203x_work(struct work_struct *work)
struct bcm203x_data *data = struct bcm203x_data *data =
container_of(work, struct bcm203x_data, work); container_of(work, struct bcm203x_data, work);
if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) if (atomic_read(&data->shutdown))
return;
if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
BT_ERR("Can't submit URB"); BT_ERR("Can't submit URB");
} }
@ -243,6 +249,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
usb_set_intfdata(intf, data); usb_set_intfdata(intf, data);
/* use workqueue to have a small delay */
schedule_work(&data->work); schedule_work(&data->work);
return 0; return 0;
@ -254,6 +261,9 @@ static void bcm203x_disconnect(struct usb_interface *intf)
BT_DBG("intf %p", intf); BT_DBG("intf %p", intf);
atomic_inc(&data->shutdown);
cancel_work_sync(&data->work);
usb_kill_urb(data->urb); usb_kill_urb(data->urb);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);

View File

@ -568,22 +568,23 @@ static int bfusb_load_firmware(struct bfusb_data *data,
BT_INFO("BlueFRITZ! USB loading firmware"); BT_INFO("BlueFRITZ! USB loading firmware");
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);
if (!buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
}
pipe = usb_sndctrlpipe(data->udev, 0); pipe = usb_sndctrlpipe(data->udev, 0);
if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) { 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
BT_ERR("Can't change to loading configuration"); BT_ERR("Can't change to loading configuration");
kfree(buf);
return -EBUSY; return -EBUSY;
} }
data->udev->toggle[0] = data->udev->toggle[1] = 0; data->udev->toggle[0] = data->udev->toggle[1] = 0;
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
if (!buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
}
pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
while (count) { while (count) {

View File

@ -868,10 +868,6 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
/* Do PA Calibration */ /* Do PA Calibration */
ar9002_hw_pa_cal(ah, true); ar9002_hw_pa_cal(ah, true);
/* Do NF Calibration after DC offset and other calibrations */
ath9k_hw_loadnf(ah, chan);
ath9k_hw_start_nfcal(ah, true);
if (ah->caldata) if (ah->caldata)
ah->caldata->nfcal_pending = true; ah->caldata->nfcal_pending = true;

View File

@ -908,12 +908,15 @@ static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
int i; int i;
bool restore; bool restore;
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT) || !ah->caldata) if (!ah->caldata)
return false; return false;
hist = &ah->caldata->rtt_hist; hist = &ah->caldata->rtt_hist;
if (!hist->num_readings)
return false;
ar9003_hw_rtt_enable(ah); ar9003_hw_rtt_enable(ah);
ar9003_hw_rtt_set_mask(ah, 0x10); ar9003_hw_rtt_set_mask(ah, 0x00);
for (i = 0; i < AR9300_MAX_CHAINS; i++) { for (i = 0; i < AR9300_MAX_CHAINS; i++) {
if (!(ah->rxchainmask & (1 << i))) if (!(ah->rxchainmask & (1 << i)))
continue; continue;
@ -1070,6 +1073,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) { if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) {
u32 *table; u32 *table;
hist->num_readings++;
for (i = 0; i < AR9300_MAX_CHAINS; i++) { for (i = 0; i < AR9300_MAX_CHAINS; i++) {
if (!(ah->rxchainmask & (1 << i))) if (!(ah->rxchainmask & (1 << i)))
continue; continue;
@ -1081,9 +1085,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
ar9003_hw_rtt_disable(ah); ar9003_hw_rtt_disable(ah);
} }
ath9k_hw_loadnf(ah, chan);
ath9k_hw_start_nfcal(ah, true);
/* Initialize list pointers */ /* Initialize list pointers */
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
ah->supp_cals = IQ_MISMATCH_CAL; ah->supp_cals = IQ_MISMATCH_CAL;

View File

@ -572,14 +572,14 @@
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
#define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + AR_SREV_9485(ah) ? \ #define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + (AR_SREV_9485(ah) ? \
0x3c4 : 0x444) 0x3c4 : 0x444))
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \ #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + (AR_SREV_9485(ah) ? \
0x3c8 : 0x448) 0x3c8 : 0x448))
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \ #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + (AR_SREV_9485(ah) ? \
0x3c4 : 0x440) 0x3c4 : 0x440))
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \ #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + (AR_SREV_9485(ah) ? \
0x3f0 : 0x48c) 0x3f0 : 0x48c))
#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
(AR_SREV_9485(ah) ? \ (AR_SREV_9485(ah) ? \
0x3d0 : 0x450) + ((_i) << 2)) 0x3d0 : 0x450) + ((_i) << 2))
@ -651,7 +651,7 @@
#define AR_SWITCH_TABLE_ALL_S (0) #define AR_SWITCH_TABLE_ALL_S (0)
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ #define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\
(AR_SREV_9485(ah) ? 0x1628c : 0x16294)) (AR_SREV_9462(ah) ? 0x16294 : 0x1628c))
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
@ -668,12 +668,12 @@
#define AR_PHY_65NM_CH2_RXTX2 0x16904 #define AR_PHY_65NM_CH2_RXTX2 0x16904
#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \
(AR_SREV_9485(ah) ? 0x16284 : 0x16290)) (AR_SREV_9462(ah) ? 0x16290 : 0x16284))
#define AR_CH0_TOP2_XPABIASLVL 0xf000 #define AR_CH0_TOP2_XPABIASLVL 0xf000
#define AR_CH0_TOP2_XPABIASLVL_S 12 #define AR_CH0_TOP2_XPABIASLVL_S 12
#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ #define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \
(AR_SREV_9485(ah) ? 0x16290 : 0x16298)) (AR_SREV_9462(ah) ? 0x16298 : 0x16290))
#define AR_CH0_XTAL_CAPINDAC 0x7f000000 #define AR_CH0_XTAL_CAPINDAC 0x7f000000
#define AR_CH0_XTAL_CAPINDAC_S 24 #define AR_CH0_XTAL_CAPINDAC_S 24
#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 #define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
@ -908,8 +908,8 @@
#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) #define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) #define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9300(ah) ? \ #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \
0x240 : 0x280)) 0x280 : 0x240))
#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240) #define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240)
#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff #define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff
#define AR_PHY_TPC_19_B1_ALPHA_THERM_S 0 #define AR_PHY_TPC_19_B1_ALPHA_THERM_S 0
@ -931,10 +931,10 @@
#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0) #define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0)
#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4) #define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4)
#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + (i) ? \ #define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + ((i) ? \
AR_SM1_BASE : AR_SM_BASE) AR_SM1_BASE : AR_SM_BASE))
#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + (i) ? \ #define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + ((i) ? \
AR_SM1_BASE : AR_SM_BASE) AR_SM1_BASE : AR_SM_BASE))
/* /*
* Channel 2 Register Map * Channel 2 Register Map
*/ */

View File

@ -521,7 +521,7 @@ static const u32 ar9485_1_1_radio_postamble[][2] = {
{0x000160ac, 0x24611800}, {0x000160ac, 0x24611800},
{0x000160b0, 0x03284f3e}, {0x000160b0, 0x03284f3e},
{0x0001610c, 0x00170000}, {0x0001610c, 0x00170000},
{0x00016140, 0x10804008}, {0x00016140, 0x50804008},
}; };
static const u32 ar9485_1_1_mac_postamble[][5] = { static const u32 ar9485_1_1_mac_postamble[][5] = {
@ -603,7 +603,7 @@ static const u32 ar9485_1_1_radio_core[][2] = {
static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x00018c00, 0x10052e5e}, {0x00018c00, 0x18052e5e},
{0x00018c04, 0x000801d8}, {0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c}, {0x00018c08, 0x0000080c},
}; };
@ -776,7 +776,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x00018c00, 0x10013e5e}, {0x00018c00, 0x18013e5e},
{0x00018c04, 0x000801d8}, {0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c}, {0x00018c08, 0x0000080c},
}; };
@ -882,7 +882,7 @@ static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x00018c00, 0x10012e5e}, {0x00018c00, 0x18012e5e},
{0x00018c04, 0x000801d8}, {0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c}, {0x00018c08, 0x0000080c},
}; };
@ -1021,7 +1021,7 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x00018c00, 0x10053e5e}, {0x00018c00, 0x18053e5e},
{0x00018c04, 0x000801d8}, {0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c}, {0x00018c08, 0x0000080c},
}; };

View File

@ -1724,6 +1724,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (!ath9k_hw_init_cal(ah, chan)) if (!ath9k_hw_init_cal(ah, chan))
return -EIO; return -EIO;
ath9k_hw_loadnf(ah, chan);
ath9k_hw_start_nfcal(ah, true);
ENABLE_REGWRITE_BUFFER(ah); ENABLE_REGWRITE_BUFFER(ah);
ath9k_hw_restore_chainmask(ah); ath9k_hw_restore_chainmask(ah);

View File

@ -296,7 +296,8 @@ static void carl9170_tx_release(struct kref *ref)
super = (void *)skb->data; super = (void *)skb->data;
txinfo->status.ampdu_len = super->s.rix; txinfo->status.ampdu_len = super->s.rix;
txinfo->status.ampdu_ack_len = super->s.cnt; txinfo->status.ampdu_ack_len = super->s.cnt;
} else if (txinfo->flags & IEEE80211_TX_STAT_ACK) { } else if ((txinfo->flags & IEEE80211_TX_STAT_ACK) &&
!(txinfo->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) {
/* /*
* drop redundant tx_status reports: * drop redundant tx_status reports:
* *
@ -308,15 +309,17 @@ static void carl9170_tx_release(struct kref *ref)
* *
* 3. minstrel_ht is picky, it only accepts * 3. minstrel_ht is picky, it only accepts
* reports of frames with the TX_STATUS_AMPDU flag. * reports of frames with the TX_STATUS_AMPDU flag.
*
* 4. mac80211 is not particularly interested in
* feedback either [CTL_REQ_TX_STATUS not set]
*/ */
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return; return;
} else { } else {
/* /*
* Frame has failed, but we want to keep it in * Either the frame transmission has failed or
* case it was lost due to a power-state * mac80211 requested tx status.
* transition.
*/ */
} }
} }

View File

@ -827,7 +827,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
#endif #endif
return; return;
drop: drop:
b43dbg(dev->wl, "RX: Packet dropped\n");
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }

View File

@ -1755,16 +1755,6 @@ static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
{ {
if (iwl_trans_check_stuck_queue(trans(priv), txq)) { if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
int ret; int ret;
if (txq == priv->shrd->cmd_queue) {
/*
* validate command queue still working
* by sending "ECHO" command
*/
if (!iwl_cmd_echo_test(priv))
return 0;
else
IWL_DEBUG_HC(priv, "echo testing fail\n");
}
ret = iwl_force_reset(priv, IWL_FW_RESET, false); ret = iwl_force_reset(priv, IWL_FW_RESET, false);
return (ret == -EAGAIN) ? 0 : 1; return (ret == -EAGAIN) ? 0 : 1;
} }

View File

@ -445,10 +445,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
err = pci_enable_msi(pdev); err = pci_enable_msi(pdev);
if (err) { if (err)
dev_printk(KERN_ERR, &pdev->dev, "pci_enable_msi failed"); dev_printk(KERN_ERR, &pdev->dev,
goto out_iounmap; "pci_enable_msi failed(0X%x)", err);
}
/* TODO: Move this away, not needed if not MSI */ /* TODO: Move this away, not needed if not MSI */
/* enable rfkill interrupt: hw bug w/a */ /* enable rfkill interrupt: hw bug w/a */
@ -469,7 +468,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_disable_msi: out_disable_msi:
pci_disable_msi(pdev); pci_disable_msi(pdev);
out_iounmap:
pci_iounmap(pdev, pci_bus->hw_base); pci_iounmap(pdev, pci_bus->hw_base);
out_pci_release_regions: out_pci_release_regions:
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);

View File

@ -407,6 +407,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
struct iwl_queue *q = &txq->q; struct iwl_queue *q = &txq->q;
enum dma_data_direction dma_dir; enum dma_data_direction dma_dir;
unsigned long flags; unsigned long flags;
spinlock_t *lock;
if (!q->n_bd) if (!q->n_bd)
return; return;
@ -414,19 +415,22 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
/* In the command queue, all the TBs are mapped as BIDI /* In the command queue, all the TBs are mapped as BIDI
* so unmap them as such. * so unmap them as such.
*/ */
if (txq_id == trans->shrd->cmd_queue) if (txq_id == trans->shrd->cmd_queue) {
dma_dir = DMA_BIDIRECTIONAL; dma_dir = DMA_BIDIRECTIONAL;
else lock = &trans->hcmd_lock;
} else {
dma_dir = DMA_TO_DEVICE; dma_dir = DMA_TO_DEVICE;
lock = &trans->shrd->sta_lock;
}
spin_lock_irqsave(&trans->shrd->sta_lock, flags); spin_lock_irqsave(lock, flags);
while (q->write_ptr != q->read_ptr) { while (q->write_ptr != q->read_ptr) {
/* The read_ptr needs to bound by q->n_window */ /* The read_ptr needs to bound by q->n_window */
iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
dma_dir); dma_dir);
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
} }
spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); spin_unlock_irqrestore(lock, flags);
} }
/** /**

View File

@ -728,15 +728,9 @@ static void lbs_scan_worker(struct work_struct *work)
le16_to_cpu(scan_cmd->hdr.size), le16_to_cpu(scan_cmd->hdr.size),
lbs_ret_scan, 0); lbs_ret_scan, 0);
if (priv->scan_channel >= priv->scan_req->n_channels) { if (priv->scan_channel >= priv->scan_req->n_channels)
/* Mark scan done */ /* Mark scan done */
if (priv->internal_scan) lbs_scan_done(priv);
kfree(priv->scan_req);
else
cfg80211_scan_done(priv->scan_req, false);
priv->scan_req = NULL;
}
/* Restart network */ /* Restart network */
if (carrier) if (carrier)
@ -774,6 +768,21 @@ static void _internal_start_scan(struct lbs_private *priv, bool internal,
lbs_deb_leave(LBS_DEB_CFG80211); lbs_deb_leave(LBS_DEB_CFG80211);
} }
/*
* Clean up priv->scan_req. Should be used to handle the allocation details.
*/
void lbs_scan_done(struct lbs_private *priv)
{
WARN_ON(!priv->scan_req);
if (priv->internal_scan)
kfree(priv->scan_req);
else
cfg80211_scan_done(priv->scan_req, false);
priv->scan_req = NULL;
}
static int lbs_cfg_scan(struct wiphy *wiphy, static int lbs_cfg_scan(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
struct cfg80211_scan_request *request) struct cfg80211_scan_request *request)

View File

@ -16,6 +16,7 @@ int lbs_reg_notifier(struct wiphy *wiphy,
void lbs_send_disconnect_notification(struct lbs_private *priv); void lbs_send_disconnect_notification(struct lbs_private *priv);
void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
void lbs_scan_done(struct lbs_private *priv);
void lbs_scan_deinit(struct lbs_private *priv); void lbs_scan_deinit(struct lbs_private *priv);
int lbs_disconnect(struct lbs_private *priv, u16 reason); int lbs_disconnect(struct lbs_private *priv, u16 reason);

View File

@ -255,10 +255,8 @@ static int lbs_eth_stop(struct net_device *dev)
lbs_update_mcast(priv); lbs_update_mcast(priv);
cancel_delayed_work_sync(&priv->scan_work); cancel_delayed_work_sync(&priv->scan_work);
if (priv->scan_req) { if (priv->scan_req)
cfg80211_scan_done(priv->scan_req, false); lbs_scan_done(priv);
priv->scan_req = NULL;
}
netif_carrier_off(priv->dev); netif_carrier_off(priv->dev);

View File

@ -211,6 +211,7 @@ struct rfcomm_dlc {
#define RFCOMM_AUTH_ACCEPT 6 #define RFCOMM_AUTH_ACCEPT 6
#define RFCOMM_AUTH_REJECT 7 #define RFCOMM_AUTH_REJECT 7
#define RFCOMM_DEFER_SETUP 8 #define RFCOMM_DEFER_SETUP 8
#define RFCOMM_ENC_DROP 9
/* Scheduling flags and events */ /* Scheduling flags and events */
#define RFCOMM_SCHED_WAKEUP 31 #define RFCOMM_SCHED_WAKEUP 31

View File

@ -3567,8 +3567,9 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
return i; return i;
/* warn when we cannot find a rate. */ /* warn when we cannot find a rate. */
WARN_ON(1); WARN_ON_ONCE(1);
/* and return 0 (the lowest index) */
return 0; return 0;
} }

View File

@ -613,7 +613,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
if (!test_bit(HCI_RAW, &hdev->flags)) { if (!test_bit(HCI_RAW, &hdev->flags)) {
set_bit(HCI_INIT, &hdev->flags); set_bit(HCI_INIT, &hdev->flags);
__hci_request(hdev, hci_reset_req, 0, __hci_request(hdev, hci_reset_req, 0,
msecs_to_jiffies(250)); msecs_to_jiffies(HCI_INIT_TIMEOUT));
clear_bit(HCI_INIT, &hdev->flags); clear_bit(HCI_INIT, &hdev->flags);
} }

View File

@ -147,8 +147,6 @@ static int read_index_list(struct sock *sk)
hci_del_off_timer(d); hci_del_off_timer(d);
set_bit(HCI_MGMT, &d->flags);
if (test_bit(HCI_SETUP, &d->flags)) if (test_bit(HCI_SETUP, &d->flags))
continue; continue;

View File

@ -1802,6 +1802,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
continue; continue;
} }
if (test_bit(RFCOMM_ENC_DROP, &d->flags)) {
__rfcomm_dlc_close(d, ECONNREFUSED);
continue;
}
if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
rfcomm_dlc_clear_timer(d); rfcomm_dlc_clear_timer(d);
if (d->out) { if (d->out) {
@ -2077,7 +2082,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) { if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
rfcomm_dlc_clear_timer(d); rfcomm_dlc_clear_timer(d);
if (status || encrypt == 0x00) { if (status || encrypt == 0x00) {
__rfcomm_dlc_close(d, ECONNREFUSED); set_bit(RFCOMM_ENC_DROP, &d->flags);
continue; continue;
} }
} }
@ -2088,7 +2093,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
continue; continue;
} else if (d->sec_level == BT_SECURITY_HIGH) { } else if (d->sec_level == BT_SECURITY_HIGH) {
__rfcomm_dlc_close(d, ECONNREFUSED); set_bit(RFCOMM_ENC_DROP, &d->flags);
continue; continue;
} }
} }

View File

@ -832,6 +832,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
if (is_multicast_ether_addr(mac)) if (is_multicast_ether_addr(mac))
return -EINVAL; return -EINVAL;
/* Only TDLS-supporting stations can add TDLS peers */
if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
!((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
sdata->vif.type == NL80211_IFTYPE_STATION))
return -ENOTSUPP;
sta = sta_info_alloc(sdata, mac, GFP_KERNEL); sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
if (!sta) if (!sta)
return -ENOMEM; return -ENOMEM;
@ -841,12 +847,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
sta_apply_parameters(local, sta, params); sta_apply_parameters(local, sta, params);
/* Only TDLS-supporting stations can add TDLS peers */
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
!((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
sdata->vif.type == NL80211_IFTYPE_STATION))
return -ENOTSUPP;
rate_control_rate_init(sta); rate_control_rate_init(sta);
layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||

View File

@ -389,6 +389,7 @@ struct ieee80211_if_managed {
unsigned long timers_running; /* used for quiesce/restart */ unsigned long timers_running; /* used for quiesce/restart */
bool powersave; /* powersave requested for this iface */ bool powersave; /* powersave requested for this iface */
bool broken_ap; /* AP is broken -- turn off powersave */
enum ieee80211_smps_mode req_smps, /* requested smps mode */ enum ieee80211_smps_mode req_smps, /* requested smps mode */
ap_smps, /* smps mode AP thinks we're in */ ap_smps, /* smps mode AP thinks we're in */
driver_smps_mode; /* smps mode request */ driver_smps_mode; /* smps mode request */

View File

@ -637,6 +637,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
if (!mgd->powersave) if (!mgd->powersave)
return false; return false;
if (mgd->broken_ap)
return false;
if (!mgd->associated) if (!mgd->associated)
return false; return false;
@ -1489,10 +1492,21 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " printk(KERN_DEBUG
"set\n", sdata->name, aid); "%s: invalid AID value 0x%x; bits 15:14 not set\n",
sdata->name, aid);
aid &= ~(BIT(15) | BIT(14)); aid &= ~(BIT(15) | BIT(14));
ifmgd->broken_ap = false;
if (aid == 0 || aid > IEEE80211_MAX_AID) {
printk(KERN_DEBUG
"%s: invalid AID value %d (out of range), turn off PS\n",
sdata->name, aid);
aid = 0;
ifmgd->broken_ap = true;
}
pos = mgmt->u.assoc_resp.variable; pos = mgmt->u.assoc_resp.variable;
ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);

View File

@ -1084,14 +1084,13 @@ static void ieee80211_work_work(struct work_struct *work)
continue; continue;
if (wk->chan != local->tmp_channel) if (wk->chan != local->tmp_channel)
continue; continue;
if (ieee80211_work_ct_coexists(wk->chan_type, if (!ieee80211_work_ct_coexists(wk->chan_type,
local->tmp_channel_type)) local->tmp_channel_type))
continue; continue;
remain_off_channel = true; remain_off_channel = true;
} }
if (!remain_off_channel && local->tmp_channel) { if (!remain_off_channel && local->tmp_channel) {
bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
local->tmp_channel = NULL; local->tmp_channel = NULL;
/* If tmp_channel wasn't operating channel, then /* If tmp_channel wasn't operating channel, then
* we need to go back on-channel. * we need to go back on-channel.
@ -1101,7 +1100,7 @@ static void ieee80211_work_work(struct work_struct *work)
* we still need to do a hardware config. Currently, * we still need to do a hardware config. Currently,
* we cannot be here while scanning, however. * we cannot be here while scanning, however.
*/ */
if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan) if (!ieee80211_cfg_on_oper_channel(local))
ieee80211_hw_config(local, 0); ieee80211_hw_config(local, 0);
/* At the least, we need to disable offchannel_ps, /* At the least, we need to disable offchannel_ps,