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:

====================
Alexey Khoroshilov provides a potential memory leak in rndis_wlan.

Bob Copeland gives us an ath5k fix for a lockdep problem.

Dan Carpenter fixes a signedness mismatch in at76c50x.

Felix Fietkau corrects a regression caused by an earlier commit that can
lead to an IRQ storm.

Lorenzo Bianconi offers a fix for a bad variable initialization in ath9k
that can cause it to improperly mark decrypted frames.

Rajkumar Manoharan fixes ath9k to prevent the btcoex time from running
when the hardware is asleep.

The remainder are Bluetooth fixes, about which Gustavo says:

	"Here goes some fixes for 3.6-rc1, there are a few fix to
	thte inquiry code by Ram Malovany, support for 2 new devices,
	and few others fixes for NULL dereference, possible deadlock
	and a memory leak."
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 15, 2012
2 parents 4acd494 + 1e55217 commit 7bab3ae
Show file tree
Hide file tree
Showing 16 changed files with 68 additions and 36 deletions.
2 changes: 2 additions & 0 deletions drivers/bluetooth/ath3k.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3362) },
{ USB_DEVICE(0x0CF3, 0xE004) },
{ USB_DEVICE(0x0930, 0x0219) },
{ USB_DEVICE(0x0489, 0xe057) },

/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
Expand All @@ -104,6 +105,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },

/* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
Expand Down
2 changes: 2 additions & 0 deletions drivers/bluetooth/btusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ static struct usb_device_id btusb_table[] = {
{ USB_DEVICE(0x0a5c, 0x21e6) },
{ USB_DEVICE(0x0a5c, 0x21e8) },
{ USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x0a5c, 0x21f4) },
{ USB_DEVICE(0x413c, 0x8197) },

/* Foxconn - Hon Hai */
Expand Down Expand Up @@ -133,6 +134,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },

/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/at76c50x-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ static int at76_dfu_get_status(struct usb_device *udev,
return ret;
}

static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
static int at76_dfu_get_state(struct usb_device *udev, u8 *state)
{
int ret;

Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2056,9 +2056,7 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf)
void
ath5k_beacon_config(struct ath5k_hw *ah)
{
unsigned long flags;

spin_lock_irqsave(&ah->block, flags);
spin_lock_bh(&ah->block);
ah->bmisscount = 0;
ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);

Expand All @@ -2085,7 +2083,7 @@ ath5k_beacon_config(struct ath5k_hw *ah)

ath5k_hw_set_imr(ah, ah->imask);
mmiowb();
spin_unlock_irqrestore(&ah->block, flags);
spin_unlock_bh(&ah->block);
}

static void ath5k_tasklet_beacon(unsigned long data)
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/ath/ath5k/mac80211-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ath5k_vif *avf = (void *)vif->drv_priv;
struct ath5k_hw *ah = hw->priv;
struct ath_common *common = ath5k_hw_common(ah);
unsigned long flags;

mutex_lock(&ah->lock);

Expand Down Expand Up @@ -300,9 +299,9 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}

if (changes & BSS_CHANGED_BEACON) {
spin_lock_irqsave(&ah->block, flags);
spin_lock_bh(&ah->block);
ath5k_beacon_update(hw, vif);
spin_unlock_irqrestore(&ah->block, flags);
spin_unlock_bh(&ah->block);
}

if (changes & BSS_CHANGED_BEACON_ENABLED)
Expand Down
18 changes: 12 additions & 6 deletions drivers/net/wireless/ath/ath9k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,15 +773,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_intrpend);

void ath9k_hw_disable_interrupts(struct ath_hw *ah)
void ath9k_hw_kill_interrupts(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);

if (!(ah->imask & ATH9K_INT_GLOBAL))
atomic_set(&ah->intr_ref_cnt, -1);
else
atomic_dec(&ah->intr_ref_cnt);

ath_dbg(common, INTERRUPT, "disable IER\n");
REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
(void) REG_READ(ah, AR_IER);
Expand All @@ -793,6 +788,17 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
(void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
}
}
EXPORT_SYMBOL(ath9k_hw_kill_interrupts);

void ath9k_hw_disable_interrupts(struct ath_hw *ah)
{
if (!(ah->imask & ATH9K_INT_GLOBAL))
atomic_set(&ah->intr_ref_cnt, -1);
else
atomic_dec(&ah->intr_ref_cnt);

ath9k_hw_kill_interrupts(ah);
}
EXPORT_SYMBOL(ath9k_hw_disable_interrupts);

void ath9k_hw_enable_interrupts(struct ath_hw *ah)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath9k/mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah);
void ath9k_hw_set_interrupts(struct ath_hw *ah);
void ath9k_hw_enable_interrupts(struct ath_hw *ah);
void ath9k_hw_disable_interrupts(struct ath_hw *ah);
void ath9k_hw_kill_interrupts(struct ath_hw *ah);

void ar9002_hw_attach_mac_ops(struct ath_hw *ah);

Expand Down
4 changes: 3 additions & 1 deletion drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,10 @@ irqreturn_t ath_isr(int irq, void *dev)
if (!ath9k_hw_intrpend(ah))
return IRQ_NONE;

if(test_bit(SC_OP_HW_RESET, &sc->sc_flags))
if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) {
ath9k_hw_kill_interrupts(ah);
return IRQ_HANDLED;
}

/*
* Figure out the reason(s) for the interrupt. Note
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath9k/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ static int ath_pci_suspend(struct device *device)
* Otherwise the chip never moved to full sleep,
* when no interface is up.
*/
ath9k_stop_btcoex(sc);
ath9k_hw_disable(sc->sc_ah);
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
struct ieee80211_hw *hw = sc->hw;
struct ieee80211_hdr *hdr;
int retval;
bool decrypt_error = false;
struct ath_rx_status rs;
enum ath9k_rx_qtype qtype;
bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
Expand All @@ -1066,6 +1065,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
tsf_lower = tsf & 0xffffffff;

do {
bool decrypt_error = false;
/* If handling rx interrupt and flush is in progress => exit */
if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
break;
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/wireless/rndis_wlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,7 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
struct cfg80211_pmksa *pmksa,
int max_pmkids)
{
struct ndis_80211_pmkid *new_pmkids;
int i, err, newlen;
unsigned int count;

Expand Down Expand Up @@ -1833,11 +1834,12 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
/* add new pmkid */
newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]);

pmkids = krealloc(pmkids, newlen, GFP_KERNEL);
if (!pmkids) {
new_pmkids = krealloc(pmkids, newlen, GFP_KERNEL);
if (!new_pmkids) {
err = -ENOMEM;
goto error;
}
pmkids = new_pmkids;

pmkids->length = cpu_to_le32(newlen);
pmkids->bssid_info_count = cpu_to_le32(count + 1);
Expand Down
28 changes: 22 additions & 6 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,9 @@ static bool hci_resolve_next_name(struct hci_dev *hdev)
return false;

e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
if (!e)
return false;

if (hci_resolve_name(hdev, e) == 0) {
e->name_state = NAME_PENDING;
return true;
Expand Down Expand Up @@ -1393,12 +1396,20 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
return;

e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
if (e) {
/* If the device was not found in a list of found devices names of which
* are pending. there is no need to continue resolving a next name as it
* will be done upon receiving another Remote Name Request Complete
* Event */
if (!e)
return;

list_del(&e->list);
if (name) {
e->name_state = NAME_KNOWN;
list_del(&e->list);
if (name)
mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
e->data.rssi, name, name_len);
mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
e->data.rssi, name, name_len);
} else {
e->name_state = NAME_NOT_KNOWN;
}

if (hci_resolve_next_name(hdev))
Expand Down Expand Up @@ -1762,7 +1773,12 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (conn->type == ACL_LINK) {
conn->state = BT_CONFIG;
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;

if (!conn->out && !hci_conn_ssp_enabled(conn) &&
!hci_find_link_key(hdev, &ev->bdaddr))
conn->disc_timeout = HCI_PAIRING_TIMEOUT;
else
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
} else
conn->state = BT_CONNECTED;

Expand Down
1 change: 1 addition & 0 deletions net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
sk = chan->sk;

hci_conn_hold(conn->hcon);
conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;

bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
Expand Down
2 changes: 1 addition & 1 deletion net/bluetooth/l2cap_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p

chan = l2cap_chan_create();
if (!chan) {
l2cap_sock_kill(sk);
sk_free(sk);
return NULL;
}

Expand Down
19 changes: 9 additions & 10 deletions net/bluetooth/sco.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
sco_sock_clear_timer(sk);
sco_chan_del(sk, err);
bh_unlock_sock(sk);

sco_conn_lock(conn);
conn->sk = NULL;
sco_pi(sk)->conn = NULL;
sco_conn_unlock(conn);

if (conn->hcon)
hci_conn_put(conn->hcon);

sco_sock_kill(sk);
}

Expand Down Expand Up @@ -821,16 +830,6 @@ static void sco_chan_del(struct sock *sk, int err)

BT_DBG("sk %p, conn %p, err %d", sk, conn, err);

if (conn) {
sco_conn_lock(conn);
conn->sk = NULL;
sco_pi(sk)->conn = NULL;
sco_conn_unlock(conn);

if (conn->hcon)
hci_conn_put(conn->hcon);
}

sk->sk_state = BT_CLOSED;
sk->sk_err = err;
sk->sk_state_change(sk);
Expand Down
5 changes: 4 additions & 1 deletion net/bluetooth/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)

if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
smp = smp_chan_create(conn);
else
smp = conn->smp_chan;

smp = conn->smp_chan;
if (!smp)
return SMP_UNSPECIFIED;

smp->preq[0] = SMP_CMD_PAIRING_REQ;
memcpy(&smp->preq[1], req, sizeof(*req));
Expand Down

0 comments on commit 7bab3ae

Please sign in to comment.