From 79cd76022044f8177bb00e3fd590ec8d6b5f8c35 Mon Sep 17 00:00:00 2001 From: Manoj Iyer Date: Mon, 9 Apr 2012 09:22:28 -0500 Subject: Bluetooth: btusb: Add vendor specific ID (0489 e042) for BCM20702A0 T: Bus=02 Lev=02 Prnt=02 Port=04 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e042 Rev=01.12 S: Manufacturer=Broadcom Corp S: Product=BCM20702A0 S: SerialNumber=E4D53DCA61B5 C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) Reported-by: Dennis Chua Signed-off-by: Manoj Iyer Signed-off-by: Johan Hedberg diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3311b81..9af450a 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -101,6 +101,7 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ + { USB_DEVICE(0x0489, 0xe042) }, { USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x0a5c, 0x21e6) }, { USB_DEVICE(0x0a5c, 0x21e8) }, -- cgit v0.10.2 From 87522a433ba6886b5ccbb497e0a7cb8097def64e Mon Sep 17 00:00:00 2001 From: AceLan Kao Date: Fri, 13 Apr 2012 17:39:57 +0800 Subject: Bluetooth: Add support for Atheros [13d3:3362] Add another vendor specific ID for Atheros AR3012 device. This chip is wrapped by IMC Networks. output of usb-devices: T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3362 Rev=00.02 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb Signed-off-by: AceLan Kao Signed-off-by: Johan Hedberg diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index ae9edca..639a161 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -75,6 +75,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x04CA, 0x3005) }, + { USB_DEVICE(0x13d3, 0x3362) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -94,6 +95,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { } /* Terminating entry */ }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 9af450a..a497544 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -134,6 +134,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, -- cgit v0.10.2 From 745c0ce35f904aeff8e1ea325c259a14a00ff1b7 Mon Sep 17 00:00:00 2001 From: Vishal Agarwal Date: Fri, 13 Apr 2012 17:43:22 +0530 Subject: Bluetooth: hci_persistent_key should return bool This patch changes the return type of function hci_persistent_key from int to bool because it makes more sense to return information whether a key is persistent or not as a bool. Signed-off-by: Vishal Agarwal Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6822d25..f8577c1 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -980,7 +980,7 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); int mgmt_connectable(struct hci_dev *hdev, u8 connectable); int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, - u8 persistent); + bool persistent); int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u32 flags, u8 *name, u8 name_len, u8 *dev_class); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 2054c13..c2251e4 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1216,40 +1216,40 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) return NULL; } -static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, +static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, u8 key_type, u8 old_key_type) { /* Legacy key */ if (key_type < 0x03) - return 1; + return true; /* Debug keys are insecure so don't store them persistently */ if (key_type == HCI_LK_DEBUG_COMBINATION) - return 0; + return false; /* Changed combination key and there's no previous one */ if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) - return 0; + return false; /* Security mode 3 case */ if (!conn) - return 1; + return true; /* Neither local nor remote side had no-bonding as requirement */ if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) - return 1; + return true; /* Local side had dedicated bonding as requirement */ if (conn->auth_type == 0x02 || conn->auth_type == 0x03) - return 1; + return true; /* Remote side had dedicated bonding as requirement */ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) - return 1; + return true; /* If none of the above criteria match, then don't store the key * persistently */ - return 0; + return false; } struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) @@ -1286,7 +1286,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) { struct link_key *key, *old_key; - u8 old_key_type, persistent; + u8 old_key_type; + bool persistent; old_key = hci_find_link_key(hdev, bdaddr); if (old_key) { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4ef275c..4bb03b1 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2884,7 +2884,7 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) return 0; } -int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, u8 persistent) +int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent) { struct mgmt_ev_new_link_key ev; -- cgit v0.10.2 From 6ec5bcadc21e13ceba8c144e4731eccac01d04f7 Mon Sep 17 00:00:00 2001 From: Vishal Agarwal Date: Mon, 16 Apr 2012 14:44:44 +0530 Subject: Bluetooth: Temporary keys should be retained during connection If a key is non persistent then it should not be used in future connections but it should be kept for current connection. And it should be removed when connecion is removed. Signed-off-by: Vishal Agarwal Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index f8577c1..db1c5df 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -314,6 +314,7 @@ struct hci_conn { __u8 remote_cap; __u8 remote_auth; + bool flush_key; unsigned int sent; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c2251e4..a7607e4 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1330,10 +1330,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, mgmt_new_link_key(hdev, key, persistent); - if (!persistent) { - list_del(&key->list); - kfree(key); - } + if (conn) + conn->flush_key = !persistent; return 0; } diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index badb785..6a72eae 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1902,6 +1902,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff } if (ev->status == 0) { + if (conn->type == ACL_LINK && conn->flush_key) + hci_remove_link_key(hdev, &conn->dst); hci_proto_disconn_cfm(conn, ev->reason); hci_conn_del(conn); } -- cgit v0.10.2 From ac71311e65e2c4c2dbac76db698fecbee755b016 Mon Sep 17 00:00:00 2001 From: AceLan Kao Date: Thu, 19 Apr 2012 14:53:45 +0800 Subject: Bluetooth: Add support for AR3012 [0cf3:e004] Add another vendor specific ID for Atheros AR3012 output of usb-devices: T: Bus=02 Lev=02 Prnt=02 Port=04 Cnt=01 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0cf3 ProdID=e004 Rev=00.02 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb BugLink: https://bugs.launchpad.net/bugs/922715 Signed-off-by: AceLan Kao Signed-off-by: Marcel Holtmann diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 639a161..57fd867 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -76,6 +76,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x13d3, 0x3362) }, + { USB_DEVICE(0x0CF3, 0xE004) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -96,6 +97,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { } /* Terminating entry */ }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a497544..93cc828 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -135,6 +135,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, -- cgit v0.10.2 From 16cde9931bcd8d8ca968ef1cded02684ea040374 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 13 Apr 2012 12:32:42 +0200 Subject: Bluetooth: Fix missing break in hci_cmd_complete_evt Command complete event for HCI_OP_USER_PASSKEY_NEG_REPLY would result in calling handler function also for HCI_OP_LE_SET_SCAN_PARAM. This could result in undefined behaviour. Signed-off-by: Szymon Janc Signed-off-by: Gustavo Padovan diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6a72eae..7f87a70 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2314,6 +2314,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk case HCI_OP_USER_PASSKEY_NEG_REPLY: hci_cc_user_passkey_neg_reply(hdev, skb); + break; case HCI_OP_LE_SET_SCAN_PARAM: hci_cc_le_set_scan_param(hdev, skb); -- cgit v0.10.2 From 985140369be1e886754d8ac0375dd64e4f727311 Mon Sep 17 00:00:00 2001 From: Steven Harms Date: Fri, 13 Apr 2012 14:45:55 -0400 Subject: Add Foxconn / Hon Hai IDs for btusb module This change adds 0x0489:0xe033 to the btusb module. This bluetooth usb device is integrated in the Acer TimelineX AS4830TG-6808 notebook. Output from /sys/kernel/debug/usb/devices: T: Bus=01 Lev=02 Prnt=02 Port=05 Cnt=02 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e033 Rev= 2.29 S: Manufacturer=Broadcom Corp S: Product=Acer Module S: SerialNumber=60D819F74101 C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 32 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 32 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 64 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 64 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 64 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 64 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=84(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) Signed-off-by: Steven Harms Signed-off-by: Gustavo Padovan diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 93cc828..9217121 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -108,6 +108,9 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0a5c, 0x21f3) }, { USB_DEVICE(0x413c, 0x8197) }, + /* Foxconn - Hon Hai */ + { USB_DEVICE(0x0489, 0xe033) }, + { } /* Terminating entry */ }; -- cgit v0.10.2 From 1cc2699057bafc512137272e1e848640bad14a41 Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Mon, 23 Apr 2012 14:24:52 -0700 Subject: brcm80211: fmac: fix SDIO function 0 register r/w issue SDIO stack doesn't have a structure for function 0. The structure pointer stored in card->sdio_func[0] is actually for function 1. With current implementation the register read/write is applied to function 1. This pathch fixes the issue. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Arend van Spriel Reviewed-by: Florian Fainelli Reviewed-by: Johannes Berg Signed-off-by: Franky Lin Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 4688904..758c115 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -108,9 +108,15 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, sdio_release_host(sdfunc); } } else if (regaddr == SDIO_CCCR_ABORT) { + sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), + GFP_KERNEL); + if (!sdfunc) + return -ENOMEM; + sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); + kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; @@ -486,7 +492,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, kfree(bus_if); return -ENOMEM; } - sdiodev->func[0] = func->card->sdio_func[0]; + sdiodev->func[0] = func; sdiodev->func[1] = func; sdiodev->bus_if = bus_if; bus_if->bus_priv.sdio = sdiodev; -- cgit v0.10.2 From b948a85c1f26d48395de8c6c7e392f008f1be666 Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Mon, 23 Apr 2012 14:24:53 -0700 Subject: brcm80211: fmac: fix missing completion events issue dpc takes care of all data packets transmissions for sdio function 2. It is possible that it misses some completion events when the traffic is heavy or it's running on a slow cpu. A linked list is introduced to make sure dpc is invoked whenever needed. Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Arend van Spriel Signed-off-by: Franky Lin Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 2bf5dda..eb3829b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -574,6 +574,8 @@ struct brcmf_sdio { struct task_struct *dpc_tsk; struct completion dpc_wait; + struct list_head dpc_tsklst; + spinlock_t dpc_tl_lock; struct semaphore sdsem; @@ -2594,29 +2596,58 @@ clkwait: return resched; } +static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) +{ + struct list_head *new_hd; + unsigned long flags; + + if (in_interrupt()) + new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC); + else + new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL); + if (new_hd == NULL) + return; + + spin_lock_irqsave(&bus->dpc_tl_lock, flags); + list_add_tail(new_hd, &bus->dpc_tsklst); + spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); +} + static int brcmf_sdbrcm_dpc_thread(void *data) { struct brcmf_sdio *bus = (struct brcmf_sdio *) data; + struct list_head *cur_hd, *tmp_hd; + unsigned long flags; allow_signal(SIGTERM); /* Run until signal received */ while (1) { if (kthread_should_stop()) break; - if (!wait_for_completion_interruptible(&bus->dpc_wait)) { - /* Call bus dpc unless it indicated down - (then clean stop) */ - if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) { - if (brcmf_sdbrcm_dpc(bus)) - complete(&bus->dpc_wait); - } else { + + if (list_empty(&bus->dpc_tsklst)) + if (wait_for_completion_interruptible(&bus->dpc_wait)) + break; + + spin_lock_irqsave(&bus->dpc_tl_lock, flags); + list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) { + spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); + + if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { /* after stopping the bus, exit thread */ brcmf_sdbrcm_bus_stop(bus->sdiodev->dev); bus->dpc_tsk = NULL; break; } - } else - break; + + if (brcmf_sdbrcm_dpc(bus)) + brcmf_sdbrcm_adddpctsk(bus); + + spin_lock_irqsave(&bus->dpc_tl_lock, flags); + list_del(cur_hd); + kfree(cur_hd); + } + spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); } return 0; } @@ -2669,8 +2700,10 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) /* Schedule DPC if needed to send queued packet(s) */ if (!bus->dpc_sched) { bus->dpc_sched = true; - if (bus->dpc_tsk) + if (bus->dpc_tsk) { + brcmf_sdbrcm_adddpctsk(bus); complete(&bus->dpc_wait); + } } return ret; @@ -3514,8 +3547,10 @@ void brcmf_sdbrcm_isr(void *arg) brcmf_dbg(ERROR, "isr w/o interrupt configured!\n"); bus->dpc_sched = true; - if (bus->dpc_tsk) + if (bus->dpc_tsk) { + brcmf_sdbrcm_adddpctsk(bus); complete(&bus->dpc_wait); + } } static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) @@ -3559,8 +3594,10 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->ipend = true; bus->dpc_sched = true; - if (bus->dpc_tsk) + if (bus->dpc_tsk) { + brcmf_sdbrcm_adddpctsk(bus); complete(&bus->dpc_wait); + } } } @@ -3897,6 +3934,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) } /* Initialize DPC thread */ init_completion(&bus->dpc_wait); + INIT_LIST_HEAD(&bus->dpc_tsklst); + spin_lock_init(&bus->dpc_tl_lock); bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread, bus, "brcmf_dpc"); if (IS_ERR(bus->dpc_tsk)) { -- cgit v0.10.2 From 3708dc248946daba8802c8f31a68dca81ffc445f Mon Sep 17 00:00:00 2001 From: Jonathan Bither Date: Tue, 24 Apr 2012 05:20:15 -0400 Subject: ath5k: add missing iounmap to AHB probe removal When our driver device is removed on the AHB bus, our IO memory is never unmapped. Signed-off-by: Jonathan Bither Reviewed-by: Pavel Roskin Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 8c50d9d..aec33cc 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -220,6 +220,7 @@ static int ath_ahb_remove(struct platform_device *pdev) } ath5k_deinit_ah(ah); + iounmap(ah->iobase); platform_set_drvdata(pdev, NULL); ieee80211_free_hw(hw); -- cgit v0.10.2 From 1ed2ec37b44e86eaa8e0a03b908a39c80f65ee45 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 25 Apr 2012 08:10:08 -0700 Subject: iwlwifi: use 6000G2B for 6030 device series "iwlwifi: use correct released ucode version" change the ucode api ok from 6000G2 to 6000G2B, but it shall belong to 6030 device series, not the 6005 device series. Fix it Cc: stable@vger.kernel.org #3.3+ Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index b1b6951..f0c9150 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -336,7 +336,7 @@ static const struct iwl_bt_params iwl6000_bt_params = { #define IWL_DEVICE_6005 \ .fw_name_pre = IWL6005_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ + .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ @@ -390,7 +390,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { #define IWL_DEVICE_6030 \ .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ + .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ -- cgit v0.10.2 From dbdedbdf4fbff3d4962a0786f37aa86dfdc48a7e Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Wed, 25 Apr 2012 17:28:00 -0500 Subject: b43: only reload config after successful initialization Commit 2a19032 (b43: reload phy and bss settings after core restarts) introduced an unconditional call to b43_op_config() at the end of b43_op_start(). When firmware fails to load this can wedge the system. There's no need to reload the configuration after a failed initialization anyway, so only make the call if initialization was successful. BugLink: http://bugs.launchpad.net/bugs/950295 Cc: Felix Fietkau Cc: Signed-off-by: Seth Forshee Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c79e663..e4d6dc2 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4827,8 +4827,14 @@ static int b43_op_start(struct ieee80211_hw *hw) out_mutex_unlock: mutex_unlock(&wl->mutex); - /* reload configuration */ - b43_op_config(hw, ~0); + /* + * Configuration may have been overwritten during initialization. + * Reload the configuration, but only if initialization was + * successful. Reloading the configuration after a failed init + * may hang the system. + */ + if (!err) + b43_op_config(hw, ~0); return err; } -- cgit v0.10.2 From 328c32f0f85467af5a6c4c3289e168d9ad2555af Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 26 Apr 2012 23:07:43 +0300 Subject: wl1251: fix crash on remove due to premature kfree Currently SDIO glue frees it's own structure before calling wl1251_free_hw(), which in turn calls ieee80211_unregister_hw(). The later call may result in a need to communicate with the chip to stop it (as it happens now if the interface is still up before rmmod), which means calls are made back to the glue, resulting in freed memory access. Fix this by freeing glue data last. Cc: stable@vger.kernel.org # v2.6.37+ Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index f786942..1b851f6 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) if (wl->irq) free_irq(wl->irq, wl); - kfree(wl_sdio); wl1251_free_hw(wl); + kfree(wl_sdio); sdio_claim_host(func); sdio_release_irq(func); -- cgit v0.10.2 From 4c1bcdb5a3354b250b82a67549f57ac27a3bb85f Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 26 Apr 2012 23:07:44 +0300 Subject: wl1251: fix crash on remove due to leftover work item This driver currently leaves elp_work behind when stopping, which occasionally results in data corruption because work function ends up accessing freed memory, typical symptoms of this are various worker_thread crashes. Fix it by cancelling elp_work. Cc: stable@vger.kernel.org # v2.6.37+ Signed-off-by: Grazvydas Ignotas Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 41302c7..d1afb8e 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -479,6 +479,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_work_sync(&wl->filter_work); + cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); -- cgit v0.10.2 From 66f2c99af3d6f2d0aa1120884cf1c60613ef61c0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 29 Apr 2012 15:44:16 +0200 Subject: mac80211: fix AP mode EAP tx for VLAN stations EAP frames for stations in an AP VLAN are sent on the main AP interface to avoid race conditions wrt. moving stations. For that to work properly, sta_info_get_bss must be used instead of sta_info_get when sending EAP packets. Previously this was only done for cooked monitor injected packets, so this patch adds a check for tx->skb->protocol to the same place. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: John W. Linville diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 782a601..e76facc 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1158,7 +1158,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, tx->sta = rcu_dereference(sdata->u.vlan.sta); if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) return TX_DROP; - } else if (info->flags & IEEE80211_TX_CTL_INJECTED) { + } else if (info->flags & IEEE80211_TX_CTL_INJECTED || + tx->sdata->control_port_protocol == tx->skb->protocol) { tx->sta = sta_info_get_bss(sdata, hdr->addr1); } if (!tx->sta) -- cgit v0.10.2