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

John W. Linville says:

====================
Please pull these fixes intended for 3.6.  There are more commits
here than I would like -- I got a bit behind while I was stalking
Steven Rostedt in San Diego last week...  I'll slow it down after this!

There are a couple of pulls here.  One is from Johannes:

"Please pull (according to the below information) to get a few fixes.

 * a fix to properly disconnect in the driver when authentication or
   association fails
 * a fix to prevent invalid information about mesh paths being reported
   to userspace
 * a memory leak fix in an nl80211 error path"

The other comes via Gustavo:

"A few updates for the 3.6 kernel. There are two btusb patches to add
more supported devices through the new USB_VENDOR_AND_INTEFACE_INFO()
macro and another one that add a new device id for a Sony Vaio laptop,
one fix for a user-after-free and, finally, two patches from Vinicius
to fix a issue in SMP pairing."

Along with those...

Arend van Spriel provides a fix for a use-after-free bug in brcmfmac.

Daniel Drake avoids a hang by not trying to touch the libertas hardware
duing suspend if it is already powered-down.

Felix Fietkau provides a batch of ath9k fixes that adress some
potential problems with power settings, as well as a fix to avoid a
potential interrupt storm.

Gertjan van Wingerde provides a register-width fix for rt2x00, and
a rt2x00 fix to prevent incorrectly detecting the rfkill status.
He also provides a device ID patch.

Hante Meuleman gives us three brcmfmac fixes, one that properly
initializes a command structure, one that fixes a race condition that
could lose usb requests, and one that removes some log spam.

Marc Kleine-Budde offers an rt2x00 fix for a voltage setting on some
specific devices.

Mohammed Shafi Shajakhan sent an ath9k fix to avoid a crash related to
using timers that aren't allocated when 2 wire bluetooth coexistence
hardware is in use.

Sergei Poselenov changes rt2800usb to do some validity checking for
received packets, avoiding crashes on an ARM Soc.

Stone Piao gives us an mwifiex fix for an incorrectly set skb length
value for a command buffer.

All of these are localized to their specific drivers, and relatively
small.  The power-related patches from Felix are bigger than I would
like, but I merged them in consideration of their isolation to ath9k
and the sensitive nature of power settings in wireless devices.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
John W. Linville 2012-09-07 13:33:27 -04:00 committed by David S. Miller
commit 777bf135b7
34 changed files with 297 additions and 76 deletions

View File

@ -86,6 +86,7 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE03C) },
{ USB_DEVICE(0x0489, 0xE036) },
{ } /* Terminating entry */
};
@ -109,6 +110,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
{ } /* Terminating entry */
};

View File

@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
/* Apple-specific (Broadcom) devices */
{ USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) },
/* Broadcom SoftSailing reporting vendor specific */
{ USB_DEVICE(0x0a5c, 0x21e1) },
@ -94,16 +97,14 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0489, 0xe042) },
{ USB_DEVICE(0x0a5c, 0x21e3) },
{ USB_DEVICE(0x0a5c, 0x21e6) },
{ USB_DEVICE(0x0a5c, 0x21e8) },
{ USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x0a5c, 0x21f4) },
{ USB_DEVICE(0x413c, 0x8197) },
/* Foxconn - Hon Hai */
{ USB_DEVICE(0x0489, 0xe033) },
/*Broadcom devices with vendor specific id */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
{ } /* Terminating entry */
};
@ -141,6 +142,7 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
/* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },

View File

@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
};
int training_power;
int i, val;
u32 am2pm_mask = ah->paprd_ratemask;
if (IS_CHAN_2GHZ(ah->curchan))
training_power = ar9003_get_training_power_2g(ah);
@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
}
ah->paprd_training_power = training_power;
if (AR_SREV_9330(ah))
am2pm_mask = 0;
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
ah->paprd_ratemask);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
ah->paprd_ratemask);
am2pm_mask);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
ah->paprd_ratemask_ht40);
@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
}
EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah,
struct ath9k_hw_cal_data *caldata,
int chain)
{
u32 *pa_in = caldata->pa_table[chain];
int capdiv_offset, quick_drop_offset;
int capdiv2g, quick_drop;
int count = 0;
int i;
if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah))
return false;
capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
AR_PHY_65NM_CH0_TXRF3_CAPDIV2G);
quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
if (quick_drop)
quick_drop -= 0x40;
for (i = 0; i < NUM_BIN + 1; i++) {
if (pa_in[i] == 1400)
count++;
}
if (AR_SREV_9485(ah)) {
if (pa_in[23] < 800) {
capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150);
capdiv2g += capdiv_offset;
if (capdiv2g > 7) {
capdiv2g = 7;
if (pa_in[23] < 600) {
quick_drop++;
if (quick_drop > 0)
quick_drop = 0;
}
}
} else if (pa_in[23] == 1400) {
quick_drop_offset = min_t(int, count / 3, 2);
quick_drop += quick_drop_offset;
capdiv2g += quick_drop_offset / 2;
if (capdiv2g > 7)
capdiv2g = 7;
if (quick_drop > 0) {
quick_drop = 0;
capdiv2g -= quick_drop_offset;
if (capdiv2g < 0)
capdiv2g = 0;
}
} else {
return false;
}
} else if (AR_SREV_9330(ah)) {
if (pa_in[23] < 1000) {
capdiv_offset = (1000 - pa_in[23]) / 100;
capdiv2g += capdiv_offset;
if (capdiv_offset > 3) {
capdiv_offset = 1;
quick_drop--;
}
capdiv2g += capdiv_offset;
if (capdiv2g > 6)
capdiv2g = 6;
if (quick_drop < -4)
quick_drop = -4;
} else if (pa_in[23] == 1400) {
if (count > 3) {
quick_drop++;
capdiv2g -= count / 4;
if (quick_drop > -2)
quick_drop = -2;
} else {
capdiv2g--;
}
if (capdiv2g < 0)
capdiv2g = 0;
} else {
return false;
}
}
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
quick_drop);
return true;
}
int ar9003_paprd_create_curve(struct ath_hw *ah,
struct ath9k_hw_cal_data *caldata, int chain)
{
@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,
if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain))
status = -2;
if (ar9003_paprd_retrain_pa_in(ah, caldata, chain))
status = -EINPROGRESS;
REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);

View File

@ -625,6 +625,10 @@
#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
#define AR_PHY_65NM_CH0_TXRF3 0x16048
#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e
#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1
#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1)

View File

@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
{
struct ath_btcoex *btcoex = &sc->btcoex;
ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
if (btcoex->hw_timer_enabled)
ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
}
u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)

View File

@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
ah->config.spurchans[i][1] = AR_NO_SPUR;
}
/* PAPRD needs some more work to be enabled */
ah->config.paprd_disable = 1;
ah->config.rx_intr_mitigation = true;
ah->config.pcieSerDesWrite = true;
@ -978,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
else
imr_reg |= AR_IMR_TXOK;
if (opmode == NL80211_IFTYPE_AP)
imr_reg |= AR_IMR_MIB;
ENABLE_REGWRITE_BUFFER(ah);
REG_WRITE(ah, AR_IMR, imr_reg);
@ -1778,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
/* Operating channel changed, reset channel calibration data */
memset(caldata, 0, sizeof(*caldata));
ath9k_init_nfcal_hist_buffer(ah, chan);
} else if (caldata) {
caldata->paprd_packet_sent = false;
}
ah->noise = ath9k_hw_getchan_noise(ah, chan);
@ -2502,7 +2498,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->tx_desc_len = sizeof(struct ar9003_txc);
pCap->txs_len = sizeof(struct ar9003_txs);
if (!ah->config.paprd_disable &&
ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
ah->eep_ops->get_eeprom(ah, EEP_PAPRD) &&
!AR_SREV_9462(ah))
pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
} else {
pCap->tx_desc_len = sizeof(struct ath_desc);

View File

@ -405,6 +405,7 @@ struct ath9k_hw_cal_data {
int8_t iCoff;
int8_t qCoff;
bool rtt_done;
bool paprd_packet_sent;
bool paprd_done;
bool nfcal_pending;
bool nfcal_interference;

View File

@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work)
int chain_ok = 0;
int chain;
int len = 1800;
int ret;
if (!caldata)
if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done)
return;
ath9k_ps_wakeup(sc);
@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work)
continue;
chain_ok = 0;
ath_dbg(common, CALIBRATE,
"Sending PAPRD frame for thermal measurement on chain %d\n",
chain);
if (!ath_paprd_send_frame(sc, skb, chain))
goto fail_paprd;
ar9003_paprd_setup_gain_table(ah, chain);
ath_dbg(common, CALIBRATE,
@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work)
break;
}
if (ar9003_paprd_create_curve(ah, caldata, chain)) {
ret = ar9003_paprd_create_curve(ah, caldata, chain);
if (ret == -EINPROGRESS) {
ath_dbg(common, CALIBRATE,
"PAPRD curve on chain %d needs to be re-trained\n",
chain);
break;
} else if (ret) {
ath_dbg(common, CALIBRATE,
"PAPRD create curve failed on chain %d\n",
chain);

View File

@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
if (sc->sc_ah->caldata)
sc->sc_ah->caldata->paprd_packet_sent = true;
if (!(tx_flags & ATH_TX_ERROR))
/* Frame was ACKed */
tx_info->flags |= IEEE80211_TX_STAT_ACK;

View File

@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb)
else
devinfo->bus_pub.bus->dstats.tx_errors++;
dev_kfree_skb(req->skb);
brcmu_pkt_buf_free_skb(req->skb);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
devinfo->bus_pub.bus->dstats.rx_packets++;
} else {
devinfo->bus_pub.bus->dstats.rx_errors++;
dev_kfree_skb(skb);
brcmu_pkt_buf_free_skb(skb);
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
return;
}
@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb)
if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
brcmf_dbg(ERROR, "rx protocol error\n");
brcmu_pkt_buf_free_skb(skb);
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
devinfo->bus_pub.bus->dstats.rx_errors++;
} else {
brcmf_rx_packet(devinfo->dev, ifidx, skb);
brcmf_usb_rx_refill(devinfo, req);
}
} else {
dev_kfree_skb(skb);
brcmu_pkt_buf_free_skb(skb);
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
}
return;
@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,
skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
req);
req->urb->transfer_flags |= URB_ZERO_PACKET;
req->devinfo = devinfo;
brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
ret = usb_submit_urb(req->urb, GFP_ATOMIC);
if (ret == 0) {
brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
} else {
dev_kfree_skb(req->skb);
if (ret) {
brcmf_usb_del_fromq(devinfo, req);
brcmu_pkt_buf_free_skb(req->skb);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
}
@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
if (!req) {
brcmu_pkt_buf_free_skb(skb);
brcmf_dbg(ERROR, "no req to send\n");
return -ENOMEM;
}
if (!req->urb) {
brcmf_dbg(ERROR, "no urb for req %p\n", req);
return -ENOBUFS;
}
req->skb = skb;
req->devinfo = devinfo;
usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
skb->data, skb->len, brcmf_usb_tx_complete, req);
req->urb->transfer_flags |= URB_ZERO_PACKET;
brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
ret = usb_submit_urb(req->urb, GFP_ATOMIC);
if (!ret) {
brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
} else {
if (ret) {
brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n");
brcmf_usb_del_fromq(devinfo, req);
brcmu_pkt_buf_free_skb(req->skb);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
}

View File

@ -1876,16 +1876,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
}
if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
scb_val.val = cpu_to_le32(0);
memset(&scb_val, 0, sizeof(scb_val));
err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
sizeof(struct brcmf_scb_val_le));
if (err)
if (err) {
WL_ERR("Could not get rssi (%d)\n", err);
rssi = le32_to_cpu(scb_val.val);
sinfo->filled |= STATION_INFO_SIGNAL;
sinfo->signal = rssi;
WL_CONN("RSSI %d dBm\n", rssi);
} else {
rssi = le32_to_cpu(scb_val.val);
sinfo->filled |= STATION_INFO_SIGNAL;
sinfo->signal = rssi;
WL_CONN("RSSI %d dBm\n", rssi);
}
}
done:

View File

@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev)
mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
/* If we're powered off anyway, just let the mmc layer remove the
* card. */
if (!lbs_iface_active(card->priv))
return -ENOSYS;
dev_info(dev, "%s: suspend: PM flags = 0x%x\n",
sdio_func_id(func), flags);

View File

@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
cmd_code = le16_to_cpu(host_cmd->command);
cmd_size = le16_to_cpu(host_cmd->size);
skb_trim(cmd_node->cmd_skb, cmd_size);
/* Adjust skb length */
if (cmd_node->cmd_skb->len > cmd_size)
/*
* cmd_size is less than sizeof(struct host_cmd_ds_command).
* Trim off the unused portion.
*/
skb_trim(cmd_node->cmd_skb, cmd_size);
else if (cmd_node->cmd_skb->len < cmd_size)
/*
* cmd_size is larger than sizeof(struct host_cmd_ds_command)
* because we have appended custom IE TLV. Increase skb length
* accordingly.
*/
skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);
do_gettimeofday(&tstamp);
dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"

View File

@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
u32 reg;
/*
* Allocate eeprom data.
@ -1623,6 +1624,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
if (retval)
return retval;
/*
* Enable rfkill polling by setting GPIO direction of the
* rfkill switch GPIO pin correctly.
*/
rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
rt2x00_set_field32(&reg, GPIOCSR_BIT8, 1);
rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
/*
* Initialize hw specifications.
*/

View File

@ -670,6 +670,7 @@
#define GPIOCSR_BIT5 FIELD32(0x00000020)
#define GPIOCSR_BIT6 FIELD32(0x00000040)
#define GPIOCSR_BIT7 FIELD32(0x00000080)
#define GPIOCSR_BIT8 FIELD32(0x00000100)
/*
* BBPPCSR: BBP Pin control register.

View File

@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
u32 reg;
/*
* Allocate eeprom data.
@ -1941,6 +1942,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
if (retval)
return retval;
/*
* Enable rfkill polling by setting GPIO direction of the
* rfkill switch GPIO pin correctly.
*/
rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
rt2x00_set_field32(&reg, GPIOCSR_DIR0, 1);
rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
/*
* Initialize hw specifications.
*/

View File

@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
u16 reg;
rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
return rt2x00_get_field16(reg, MAC_CSR19_BIT7);
}
#ifdef CONFIG_RT2X00_LIB_LEDS
@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
u16 reg;
/*
* Allocate eeprom data.
@ -1780,6 +1781,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
if (retval)
return retval;
/*
* Enable rfkill polling by setting GPIO direction of the
* rfkill switch GPIO pin correctly.
*/
rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
rt2x00_set_field16(&reg, MAC_CSR19_BIT8, 0);
rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg);
/*
* Initialize hw specifications.
*/

View File

@ -189,14 +189,15 @@
* MAC_CSR19: GPIO control register.
*/
#define MAC_CSR19 0x0426
#define MAC_CSR19_BIT0 FIELD32(0x0001)
#define MAC_CSR19_BIT1 FIELD32(0x0002)
#define MAC_CSR19_BIT2 FIELD32(0x0004)
#define MAC_CSR19_BIT3 FIELD32(0x0008)
#define MAC_CSR19_BIT4 FIELD32(0x0010)
#define MAC_CSR19_BIT5 FIELD32(0x0020)
#define MAC_CSR19_BIT6 FIELD32(0x0040)
#define MAC_CSR19_BIT7 FIELD32(0x0080)
#define MAC_CSR19_BIT0 FIELD16(0x0001)
#define MAC_CSR19_BIT1 FIELD16(0x0002)
#define MAC_CSR19_BIT2 FIELD16(0x0004)
#define MAC_CSR19_BIT3 FIELD16(0x0008)
#define MAC_CSR19_BIT4 FIELD16(0x0010)
#define MAC_CSR19_BIT5 FIELD16(0x0020)
#define MAC_CSR19_BIT6 FIELD16(0x0040)
#define MAC_CSR19_BIT7 FIELD16(0x0080)
#define MAC_CSR19_BIT8 FIELD16(0x0100)
/*
* MAC_CSR20: LED control register.

View File

@ -4089,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
msleep(1);
rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
}

View File

@ -983,6 +983,7 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
u32 reg;
/*
* Allocate eeprom data.
@ -995,6 +996,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
if (retval)
return retval;
/*
* Enable rfkill polling by setting GPIO direction of the
* rfkill switch GPIO pin correctly.
*/
rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT2, 1);
rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
/*
* Initialize hw specifications.
*/

View File

@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
skb_pull(entry->skb, RXINFO_DESC_SIZE);
/*
* FIXME: we need to check for rx_pkt_len validity
* Check for rx_pkt_len validity. Return if invalid, leaving
* rxdesc->size zeroed out by the upper level.
*/
if (unlikely(rx_pkt_len == 0 ||
rx_pkt_len > entry->queue->data_size)) {
ERROR(entry->queue->rt2x00dev,
"Bad frame size %d, forcing to 0\n", rx_pkt_len);
return;
}
rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
/*
@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
u32 reg;
/*
* Allocate eeprom data.
@ -748,6 +757,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
if (retval)
return retval;
/*
* Enable rfkill polling by setting GPIO direction of the
* rfkill switch GPIO pin correctly.
*/
rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT2, 1);
rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
/*
* Initialize hw specifications.
*/
@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x1690, 0x0744) },
{ USB_DEVICE(0x1690, 0x0761) },
{ USB_DEVICE(0x1690, 0x0764) },
/* ASUS */
{ USB_DEVICE(0x0b05, 0x179d) },
/* Cisco */
{ USB_DEVICE(0x167b, 0x4001) },
/* EnGenius */
@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0b05, 0x1760) },
{ USB_DEVICE(0x0b05, 0x1761) },
{ USB_DEVICE(0x0b05, 0x1790) },
{ USB_DEVICE(0x0b05, 0x179d) },
/* AzureWave */
{ USB_DEVICE(0x13d3, 0x3262) },
{ USB_DEVICE(0x13d3, 0x3284) },

View File

@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
*/
if (unlikely(rxdesc.size == 0 ||
rxdesc.size > entry->queue->data_size)) {
WARNING(rt2x00dev, "Wrong frame size %d max %d.\n",
ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",
rxdesc.size, entry->queue->data_size);
dev_kfree_skb(entry->skb);
goto renew_skb;

View File

@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
u32 reg;
/*
* Disable power saving.
@ -2849,6 +2850,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
if (retval)
return retval;
/*
* Enable rfkill polling by setting GPIO direction of the
* rfkill switch GPIO pin correctly.
*/
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
rt2x00_set_field32(&reg, MAC_CSR13_BIT13, 1);
rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
/*
* Initialize hw specifications.
*/

View File

@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry {
#define MAC_CSR13_BIT10 FIELD32(0x00000400)
#define MAC_CSR13_BIT11 FIELD32(0x00000800)
#define MAC_CSR13_BIT12 FIELD32(0x00001000)
#define MAC_CSR13_BIT13 FIELD32(0x00002000)
/*
* MAC_CSR14: LED control register.

View File

@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
u32 reg;
/*
* Allocate eeprom data.
@ -2189,6 +2190,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
if (retval)
return retval;
/*
* Enable rfkill polling by setting GPIO direction of the
* rfkill switch GPIO pin correctly.
*/
rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
rt2x00_set_field32(&reg, MAC_CSR13_BIT15, 0);
rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg);
/*
* Initialize hw specifications.
*/

View File

@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry {
#define MAC_CSR13_BIT10 FIELD32(0x00000400)
#define MAC_CSR13_BIT11 FIELD32(0x00000800)
#define MAC_CSR13_BIT12 FIELD32(0x00001000)
#define MAC_CSR13_BIT13 FIELD32(0x00002000)
#define MAC_CSR13_BIT14 FIELD32(0x00004000)
#define MAC_CSR13_BIT15 FIELD32(0x00008000)
/*
* MAC_CSR14: LED control register.

View File

@ -136,7 +136,7 @@ struct smp_chan {
};
/* SMP Commands */
int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);

View File

@ -29,6 +29,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/smp.h>
static void hci_le_connect(struct hci_conn *conn)
{
@ -619,6 +620,9 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("hcon %p", conn);
if (conn->type == LE_LINK)
return smp_conn_security(conn, sec_level);
/* For sdp we don't need the link key. */
if (sec_level == BT_SECURITY_SDP)
return 1;

View File

@ -1199,14 +1199,15 @@ clean:
static void l2cap_conn_ready(struct l2cap_conn *conn)
{
struct l2cap_chan *chan;
struct hci_conn *hcon = conn->hcon;
BT_DBG("conn %p", conn);
if (!conn->hcon->out && conn->hcon->type == LE_LINK)
if (!hcon->out && hcon->type == LE_LINK)
l2cap_le_conn_ready(conn);
if (conn->hcon->out && conn->hcon->type == LE_LINK)
smp_conn_security(conn, conn->hcon->pending_sec_level);
if (hcon->out && hcon->type == LE_LINK)
smp_conn_security(hcon, hcon->pending_sec_level);
mutex_lock(&conn->chan_lock);
@ -1219,8 +1220,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
continue;
}
if (conn->hcon->type == LE_LINK) {
if (smp_conn_security(conn, chan->sec_level))
if (hcon->type == LE_LINK) {
if (smp_conn_security(hcon, chan->sec_level))
l2cap_chan_ready(chan);
} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {

View File

@ -616,7 +616,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
break;
}
if (smp_conn_security(conn, sec.level))
if (smp_conn_security(conn->hcon, sec.level))
break;
sk->sk_state = BT_CONFIG;
chan->state = BT_CONFIG;

View File

@ -267,10 +267,10 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,
hcon->dst_type, reason);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
cancel_delayed_work_sync(&conn->security_timer);
cancel_delayed_work_sync(&conn->security_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
smp_chan_destroy(conn);
}
}
#define JUST_WORKS 0x00
@ -760,9 +760,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
return 0;
}
int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
{
struct hci_conn *hcon = conn->hcon;
struct l2cap_conn *conn = hcon->l2cap_data;
struct smp_chan *smp = conn->smp_chan;
__u8 authreq;

View File

@ -1378,6 +1378,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
else
memset(next_hop, 0, ETH_ALEN);
memset(pinfo, 0, sizeof(*pinfo));
pinfo->generation = mesh_paths_generation;
pinfo->filled = MPATH_INFO_FRAME_QLEN |
@ -1396,7 +1398,6 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
pinfo->discovery_timeout =
jiffies_to_msecs(mpath->discovery_timeout);
pinfo->discovery_retries = mpath->discovery_retries;
pinfo->flags = 0;
if (mpath->flags & MESH_PATH_ACTIVE)
pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
if (mpath->flags & MESH_PATH_RESOLVING)
@ -1405,10 +1406,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
if (mpath->flags & MESH_PATH_FIXED)
pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
if (mpath->flags & MESH_PATH_RESOLVING)
pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
pinfo->flags = mpath->flags;
if (mpath->flags & MESH_PATH_RESOLVED)
pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED;
}
static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,

View File

@ -3248,6 +3248,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
goto out_unlock;
err_clear:
memset(ifmgd->bssid, 0, ETH_ALEN);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
ifmgd->auth_data = NULL;
err_free:
kfree(auth_data);
@ -3439,6 +3441,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
err = 0;
goto out;
err_clear:
memset(ifmgd->bssid, 0, ETH_ALEN);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
ifmgd->assoc_data = NULL;
err_free:
kfree(assoc_data);

View File

@ -5633,8 +5633,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
sizeof(connect.ht_capa_mask));
if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
kfree(connkeys);
return -EINVAL;
}
memcpy(&connect.ht_capa,
nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
sizeof(connect.ht_capa));