diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-12-09 14:07:12 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-09 14:07:12 -0500 |
commit | e7ab5f1c323e137120561daeec75e91a1bd9ec8b (patch) | |
tree | 758be4a11287005187b055ee8f8112a24d7d8ce5 | |
parent | 1af32f0fcf33ddca52c8fd2b5bc84c129dcb1bdd (diff) | |
parent | 329456d1ffb416c220813725b7363cda9975c9aa (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
-rw-r--r-- | drivers/bluetooth/Kconfig | 6 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 15 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 2 | ||||
-rw-r--r-- | drivers/ssb/driver_pcicore.c | 8 | ||||
-rw-r--r-- | net/bluetooth/bnep/core.c | 8 | ||||
-rw-r--r-- | net/bluetooth/cmtp/core.c | 5 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 2 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 86 |
13 files changed, 76 insertions, 67 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 11b41fd40c27..5ccf142ef0b8 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -188,7 +188,7 @@ config BT_MRVL | |||
188 | The core driver to support Marvell Bluetooth devices. | 188 | The core driver to support Marvell Bluetooth devices. |
189 | 189 | ||
190 | This driver is required if you want to support | 190 | This driver is required if you want to support |
191 | Marvell Bluetooth devices, such as 8688/8787. | 191 | Marvell Bluetooth devices, such as 8688/8787/8797. |
192 | 192 | ||
193 | Say Y here to compile Marvell Bluetooth driver | 193 | Say Y here to compile Marvell Bluetooth driver |
194 | into the kernel or say M to compile it as module. | 194 | into the kernel or say M to compile it as module. |
@@ -201,8 +201,8 @@ config BT_MRVL_SDIO | |||
201 | The driver for Marvell Bluetooth chipsets with SDIO interface. | 201 | The driver for Marvell Bluetooth chipsets with SDIO interface. |
202 | 202 | ||
203 | This driver is required if you want to use Marvell Bluetooth | 203 | This driver is required if you want to use Marvell Bluetooth |
204 | devices with SDIO interface. Currently SD8688/SD8787 chipsets are | 204 | devices with SDIO interface. Currently SD8688/SD8787/SD8797 |
205 | supported. | 205 | chipsets are supported. |
206 | 206 | ||
207 | Say Y here to compile support for Marvell BT-over-SDIO driver | 207 | Say Y here to compile support for Marvell BT-over-SDIO driver |
208 | into the kernel or say M to compile it as module. | 208 | into the kernel or say M to compile it as module. |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 9ef48167e2cf..27b74b0d547b 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -65,7 +65,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = { | |||
65 | .io_port_1 = 0x01, | 65 | .io_port_1 = 0x01, |
66 | .io_port_2 = 0x02, | 66 | .io_port_2 = 0x02, |
67 | }; | 67 | }; |
68 | static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = { | 68 | static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { |
69 | .cfg = 0x00, | 69 | .cfg = 0x00, |
70 | .host_int_mask = 0x02, | 70 | .host_int_mask = 0x02, |
71 | .host_intstatus = 0x03, | 71 | .host_intstatus = 0x03, |
@@ -92,7 +92,14 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { | |||
92 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { | 92 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { |
93 | .helper = NULL, | 93 | .helper = NULL, |
94 | .firmware = "mrvl/sd8787_uapsta.bin", | 94 | .firmware = "mrvl/sd8787_uapsta.bin", |
95 | .reg = &btmrvl_reg_8787, | 95 | .reg = &btmrvl_reg_87xx, |
96 | .sd_blksz_fw_dl = 256, | ||
97 | }; | ||
98 | |||
99 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { | ||
100 | .helper = NULL, | ||
101 | .firmware = "mrvl/sd8797_uapsta.bin", | ||
102 | .reg = &btmrvl_reg_87xx, | ||
96 | .sd_blksz_fw_dl = 256, | 103 | .sd_blksz_fw_dl = 256, |
97 | }; | 104 | }; |
98 | 105 | ||
@@ -103,6 +110,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { | |||
103 | /* Marvell SD8787 Bluetooth device */ | 110 | /* Marvell SD8787 Bluetooth device */ |
104 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), | 111 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), |
105 | .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, | 112 | .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, |
113 | /* Marvell SD8797 Bluetooth device */ | ||
114 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), | ||
115 | .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, | ||
106 | 116 | ||
107 | { } /* Terminating entry */ | 117 | { } /* Terminating entry */ |
108 | }; | 118 | }; |
@@ -1076,3 +1086,4 @@ MODULE_LICENSE("GPL v2"); | |||
1076 | MODULE_FIRMWARE("sd8688_helper.bin"); | 1086 | MODULE_FIRMWARE("sd8688_helper.bin"); |
1077 | MODULE_FIRMWARE("sd8688.bin"); | 1087 | MODULE_FIRMWARE("sd8688.bin"); |
1078 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); | 1088 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); |
1089 | MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index fe4ebc375b3d..eabc437ce500 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -777,9 +777,8 @@ skip_waking: | |||
777 | usb_mark_last_busy(data->udev); | 777 | usb_mark_last_busy(data->udev); |
778 | } | 778 | } |
779 | 779 | ||
780 | usb_free_urb(urb); | ||
781 | |||
782 | done: | 780 | done: |
781 | usb_free_urb(urb); | ||
783 | return err; | 782 | return err; |
784 | } | 783 | } |
785 | 784 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 93fbe6f40898..d2348a5a7809 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -286,7 +286,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
286 | ath_start_ani(common); | 286 | ath_start_ani(common); |
287 | } | 287 | } |
288 | 288 | ||
289 | if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) { | 289 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { |
290 | struct ath_hw_antcomb_conf div_ant_conf; | 290 | struct ath_hw_antcomb_conf div_ant_conf; |
291 | u8 lna_conf; | 291 | u8 lna_conf; |
292 | 292 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 592a10ac5929..3b585aadabfc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
@@ -569,7 +569,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
569 | } | 569 | } |
570 | case ERFSLEEP:{ | 570 | case ERFSLEEP:{ |
571 | if (ppsc->rfpwr_state == ERFOFF) | 571 | if (ppsc->rfpwr_state == ERFOFF) |
572 | break; | 572 | return false; |
573 | for (queue_id = 0, i = 0; | 573 | for (queue_id = 0, i = 0; |
574 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 574 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
575 | ring = &pcipriv->dev.tx_ring[queue_id]; | 575 | ring = &pcipriv->dev.tx_ring[queue_id]; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 72852900df84..e49cf2244c75 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | |||
@@ -548,7 +548,7 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
548 | break; | 548 | break; |
549 | case ERFSLEEP: | 549 | case ERFSLEEP: |
550 | if (ppsc->rfpwr_state == ERFOFF) | 550 | if (ppsc->rfpwr_state == ERFOFF) |
551 | break; | 551 | return false; |
552 | for (queue_id = 0, i = 0; | 552 | for (queue_id = 0, i = 0; |
553 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 553 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
554 | ring = &pcipriv->dev.tx_ring[queue_id]; | 554 | ring = &pcipriv->dev.tx_ring[queue_id]; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 3ac7af1c5509..0883349e1c83 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c | |||
@@ -3374,7 +3374,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
3374 | break; | 3374 | break; |
3375 | case ERFSLEEP: | 3375 | case ERFSLEEP: |
3376 | if (ppsc->rfpwr_state == ERFOFF) | 3376 | if (ppsc->rfpwr_state == ERFOFF) |
3377 | break; | 3377 | return false; |
3378 | 3378 | ||
3379 | for (queue_id = 0, i = 0; | 3379 | for (queue_id = 0, i = 0; |
3380 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 3380 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index f27171af979c..f10ac1ad9087 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c | |||
@@ -602,7 +602,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
602 | } | 602 | } |
603 | case ERFSLEEP: | 603 | case ERFSLEEP: |
604 | if (ppsc->rfpwr_state == ERFOFF) | 604 | if (ppsc->rfpwr_state == ERFOFF) |
605 | break; | 605 | return false; |
606 | 606 | ||
607 | for (queue_id = 0, i = 0; | 607 | for (queue_id = 0, i = 0; |
608 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 608 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 84c934c0a545..520e8286db28 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
@@ -517,10 +517,14 @@ static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) | |||
517 | 517 | ||
518 | static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) | 518 | static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) |
519 | { | 519 | { |
520 | ssb_pcicore_fix_sprom_core_index(pc); | 520 | struct ssb_device *pdev = pc->dev; |
521 | struct ssb_bus *bus = pdev->bus; | ||
522 | |||
523 | if (bus->bustype == SSB_BUSTYPE_PCI) | ||
524 | ssb_pcicore_fix_sprom_core_index(pc); | ||
521 | 525 | ||
522 | /* Disable PCI interrupts. */ | 526 | /* Disable PCI interrupts. */ |
523 | ssb_write32(pc->dev, SSB_INTVEC, 0); | 527 | ssb_write32(pdev, SSB_INTVEC, 0); |
524 | 528 | ||
525 | /* Additional PCIe always once-executed workarounds */ | 529 | /* Additional PCIe always once-executed workarounds */ |
526 | if (pc->dev->id.coreid == SSB_DEV_PCIE) { | 530 | if (pc->dev->id.coreid == SSB_DEV_PCIE) { |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 91bcd3a961ec..1eea8208b2cc 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -79,17 +79,12 @@ static struct bnep_session *__bnep_get_session(u8 *dst) | |||
79 | 79 | ||
80 | static void __bnep_link_session(struct bnep_session *s) | 80 | static void __bnep_link_session(struct bnep_session *s) |
81 | { | 81 | { |
82 | /* It's safe to call __module_get() here because sessions are added | ||
83 | by the socket layer which has to hold the reference to this module. | ||
84 | */ | ||
85 | __module_get(THIS_MODULE); | ||
86 | list_add(&s->list, &bnep_session_list); | 82 | list_add(&s->list, &bnep_session_list); |
87 | } | 83 | } |
88 | 84 | ||
89 | static void __bnep_unlink_session(struct bnep_session *s) | 85 | static void __bnep_unlink_session(struct bnep_session *s) |
90 | { | 86 | { |
91 | list_del(&s->list); | 87 | list_del(&s->list); |
92 | module_put(THIS_MODULE); | ||
93 | } | 88 | } |
94 | 89 | ||
95 | static int bnep_send(struct bnep_session *s, void *data, size_t len) | 90 | static int bnep_send(struct bnep_session *s, void *data, size_t len) |
@@ -530,6 +525,7 @@ static int bnep_session(void *arg) | |||
530 | 525 | ||
531 | up_write(&bnep_session_sem); | 526 | up_write(&bnep_session_sem); |
532 | free_netdev(dev); | 527 | free_netdev(dev); |
528 | module_put_and_exit(0); | ||
533 | return 0; | 529 | return 0; |
534 | } | 530 | } |
535 | 531 | ||
@@ -616,9 +612,11 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | |||
616 | 612 | ||
617 | __bnep_link_session(s); | 613 | __bnep_link_session(s); |
618 | 614 | ||
615 | __module_get(THIS_MODULE); | ||
619 | s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name); | 616 | s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name); |
620 | if (IS_ERR(s->task)) { | 617 | if (IS_ERR(s->task)) { |
621 | /* Session thread start failed, gotta cleanup. */ | 618 | /* Session thread start failed, gotta cleanup. */ |
619 | module_put(THIS_MODULE); | ||
622 | unregister_netdev(dev); | 620 | unregister_netdev(dev); |
623 | __bnep_unlink_session(s); | 621 | __bnep_unlink_session(s); |
624 | err = PTR_ERR(s->task); | 622 | err = PTR_ERR(s->task); |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 7d00ddf9e9dc..5a6e634f7fca 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -67,14 +67,12 @@ static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr) | |||
67 | 67 | ||
68 | static void __cmtp_link_session(struct cmtp_session *session) | 68 | static void __cmtp_link_session(struct cmtp_session *session) |
69 | { | 69 | { |
70 | __module_get(THIS_MODULE); | ||
71 | list_add(&session->list, &cmtp_session_list); | 70 | list_add(&session->list, &cmtp_session_list); |
72 | } | 71 | } |
73 | 72 | ||
74 | static void __cmtp_unlink_session(struct cmtp_session *session) | 73 | static void __cmtp_unlink_session(struct cmtp_session *session) |
75 | { | 74 | { |
76 | list_del(&session->list); | 75 | list_del(&session->list); |
77 | module_put(THIS_MODULE); | ||
78 | } | 76 | } |
79 | 77 | ||
80 | static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci) | 78 | static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci) |
@@ -327,6 +325,7 @@ static int cmtp_session(void *arg) | |||
327 | up_write(&cmtp_session_sem); | 325 | up_write(&cmtp_session_sem); |
328 | 326 | ||
329 | kfree(session); | 327 | kfree(session); |
328 | module_put_and_exit(0); | ||
330 | return 0; | 329 | return 0; |
331 | } | 330 | } |
332 | 331 | ||
@@ -376,9 +375,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
376 | 375 | ||
377 | __cmtp_link_session(session); | 376 | __cmtp_link_session(session); |
378 | 377 | ||
378 | __module_get(THIS_MODULE); | ||
379 | session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d", | 379 | session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d", |
380 | session->num); | 380 | session->num); |
381 | if (IS_ERR(session->task)) { | 381 | if (IS_ERR(session->task)) { |
382 | module_put(THIS_MODULE); | ||
382 | err = PTR_ERR(session->task); | 383 | err = PTR_ERR(session->task); |
383 | goto unlink; | 384 | goto unlink; |
384 | } | 385 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d7d96b6b1f0d..643a41b76e2e 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -545,7 +545,7 @@ static void hci_setup(struct hci_dev *hdev) | |||
545 | { | 545 | { |
546 | hci_setup_event_mask(hdev); | 546 | hci_setup_event_mask(hdev); |
547 | 547 | ||
548 | if (hdev->lmp_ver > 1) | 548 | if (hdev->hci_ver > 1) |
549 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); | 549 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); |
550 | 550 | ||
551 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { | 551 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b064e4df12c6..2e4b961648d4 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -303,6 +303,38 @@ ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid) | |||
303 | __release(agg_queue); | 303 | __release(agg_queue); |
304 | } | 304 | } |
305 | 305 | ||
306 | /* | ||
307 | * splice packets from the STA's pending to the local pending, | ||
308 | * requires a call to ieee80211_agg_splice_finish later | ||
309 | */ | ||
310 | static void __acquires(agg_queue) | ||
311 | ieee80211_agg_splice_packets(struct ieee80211_local *local, | ||
312 | struct tid_ampdu_tx *tid_tx, u16 tid) | ||
313 | { | ||
314 | int queue = ieee80211_ac_from_tid(tid); | ||
315 | unsigned long flags; | ||
316 | |||
317 | ieee80211_stop_queue_agg(local, tid); | ||
318 | |||
319 | if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" | ||
320 | " from the pending queue\n", tid)) | ||
321 | return; | ||
322 | |||
323 | if (!skb_queue_empty(&tid_tx->pending)) { | ||
324 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
325 | /* copy over remaining packets */ | ||
326 | skb_queue_splice_tail_init(&tid_tx->pending, | ||
327 | &local->pending[queue]); | ||
328 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | static void __releases(agg_queue) | ||
333 | ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid) | ||
334 | { | ||
335 | ieee80211_wake_queue_agg(local, tid); | ||
336 | } | ||
337 | |||
306 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | 338 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) |
307 | { | 339 | { |
308 | struct tid_ampdu_tx *tid_tx; | 340 | struct tid_ampdu_tx *tid_tx; |
@@ -314,19 +346,17 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
314 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 346 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
315 | 347 | ||
316 | /* | 348 | /* |
317 | * While we're asking the driver about the aggregation, | 349 | * Start queuing up packets for this aggregation session. |
318 | * stop the AC queue so that we don't have to worry | 350 | * We're going to release them once the driver is OK with |
319 | * about frames that came in while we were doing that, | 351 | * that. |
320 | * which would require us to put them to the AC pending | ||
321 | * afterwards which just makes the code more complex. | ||
322 | */ | 352 | */ |
323 | ieee80211_stop_queue_agg(local, tid); | ||
324 | |||
325 | clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); | 353 | clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); |
326 | 354 | ||
327 | /* | 355 | /* |
328 | * make sure no packets are being processed to get | 356 | * Make sure no packets are being processed. This ensures that |
329 | * valid starting sequence number | 357 | * we have a valid starting sequence number and that in-flight |
358 | * packets have been flushed out and no packets for this TID | ||
359 | * will go into the driver during the ampdu_action call. | ||
330 | */ | 360 | */ |
331 | synchronize_net(); | 361 | synchronize_net(); |
332 | 362 | ||
@@ -340,17 +370,15 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
340 | " tid %d\n", tid); | 370 | " tid %d\n", tid); |
341 | #endif | 371 | #endif |
342 | spin_lock_bh(&sta->lock); | 372 | spin_lock_bh(&sta->lock); |
373 | ieee80211_agg_splice_packets(local, tid_tx, tid); | ||
343 | ieee80211_assign_tid_tx(sta, tid, NULL); | 374 | ieee80211_assign_tid_tx(sta, tid, NULL); |
375 | ieee80211_agg_splice_finish(local, tid); | ||
344 | spin_unlock_bh(&sta->lock); | 376 | spin_unlock_bh(&sta->lock); |
345 | 377 | ||
346 | ieee80211_wake_queue_agg(local, tid); | ||
347 | kfree_rcu(tid_tx, rcu_head); | 378 | kfree_rcu(tid_tx, rcu_head); |
348 | return; | 379 | return; |
349 | } | 380 | } |
350 | 381 | ||
351 | /* we can take packets again now */ | ||
352 | ieee80211_wake_queue_agg(local, tid); | ||
353 | |||
354 | /* activate the timer for the recipient's addBA response */ | 382 | /* activate the timer for the recipient's addBA response */ |
355 | mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); | 383 | mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); |
356 | #ifdef CONFIG_MAC80211_HT_DEBUG | 384 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -466,38 +494,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
466 | } | 494 | } |
467 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 495 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); |
468 | 496 | ||
469 | /* | ||
470 | * splice packets from the STA's pending to the local pending, | ||
471 | * requires a call to ieee80211_agg_splice_finish later | ||
472 | */ | ||
473 | static void __acquires(agg_queue) | ||
474 | ieee80211_agg_splice_packets(struct ieee80211_local *local, | ||
475 | struct tid_ampdu_tx *tid_tx, u16 tid) | ||
476 | { | ||
477 | int queue = ieee80211_ac_from_tid(tid); | ||
478 | unsigned long flags; | ||
479 | |||
480 | ieee80211_stop_queue_agg(local, tid); | ||
481 | |||
482 | if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" | ||
483 | " from the pending queue\n", tid)) | ||
484 | return; | ||
485 | |||
486 | if (!skb_queue_empty(&tid_tx->pending)) { | ||
487 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
488 | /* copy over remaining packets */ | ||
489 | skb_queue_splice_tail_init(&tid_tx->pending, | ||
490 | &local->pending[queue]); | ||
491 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | static void __releases(agg_queue) | ||
496 | ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid) | ||
497 | { | ||
498 | ieee80211_wake_queue_agg(local, tid); | ||
499 | } | ||
500 | |||
501 | static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | 497 | static void ieee80211_agg_tx_operational(struct ieee80211_local *local, |
502 | struct sta_info *sta, u16 tid) | 498 | struct sta_info *sta, u16 tid) |
503 | { | 499 | { |