diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2008-10-29 00:43:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-10 15:14:55 -0500 |
commit | b5aa9bf9460f9e97f2c10940b029d75c6557ad7c (patch) | |
tree | 60bc06b72761339e048139fdb076de14f2f4273e /drivers | |
parent | 17683c65c8a5f3f29f5408334992986b996d8205 (diff) |
ath9k: Node cleanup
Start removing the internal node list in ath9k, in preparation
for using mac80211's STA list.
Remove lists, locks, routines, flags, functions managing nodes in ath9k.
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath9k/core.c | 116 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 46 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 94 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/recv.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/xmit.c | 107 |
6 files changed, 94 insertions, 326 deletions
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 0089e023c609..49fc264cfe5a 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c | |||
@@ -47,6 +47,41 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) | |||
47 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ | 47 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ |
48 | } | 48 | } |
49 | 49 | ||
50 | static u8 parse_mpdudensity(u8 mpdudensity) | ||
51 | { | ||
52 | /* | ||
53 | * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": | ||
54 | * 0 for no restriction | ||
55 | * 1 for 1/4 us | ||
56 | * 2 for 1/2 us | ||
57 | * 3 for 1 us | ||
58 | * 4 for 2 us | ||
59 | * 5 for 4 us | ||
60 | * 6 for 8 us | ||
61 | * 7 for 16 us | ||
62 | */ | ||
63 | switch (mpdudensity) { | ||
64 | case 0: | ||
65 | return 0; | ||
66 | case 1: | ||
67 | case 2: | ||
68 | case 3: | ||
69 | /* Our lower layer calculations limit our precision to | ||
70 | 1 microsecond */ | ||
71 | return 1; | ||
72 | case 4: | ||
73 | return 2; | ||
74 | case 5: | ||
75 | return 4; | ||
76 | case 6: | ||
77 | return 8; | ||
78 | case 7: | ||
79 | return 16; | ||
80 | default: | ||
81 | return 0; | ||
82 | } | ||
83 | } | ||
84 | |||
50 | /* | 85 | /* |
51 | * Set current operating mode | 86 | * Set current operating mode |
52 | * | 87 | * |
@@ -1321,7 +1356,7 @@ void ath_deinit(struct ath_softc *sc) | |||
1321 | /* Node Management */ | 1356 | /* Node Management */ |
1322 | /*******************/ | 1357 | /*******************/ |
1323 | 1358 | ||
1324 | struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id) | 1359 | void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, int if_id) |
1325 | { | 1360 | { |
1326 | struct ath_vap *avp; | 1361 | struct ath_vap *avp; |
1327 | struct ath_node *an; | 1362 | struct ath_node *an; |
@@ -1329,90 +1364,30 @@ struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id) | |||
1329 | avp = sc->sc_vaps[if_id]; | 1364 | avp = sc->sc_vaps[if_id]; |
1330 | ASSERT(avp != NULL); | 1365 | ASSERT(avp != NULL); |
1331 | 1366 | ||
1332 | /* mac80211 sta_notify callback is from an IRQ context, so no sleep */ | 1367 | an = (struct ath_node *)sta->drv_priv; |
1333 | an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC); | ||
1334 | if (an == NULL) | ||
1335 | return NULL; | ||
1336 | memset(an, 0, sizeof(*an)); | ||
1337 | |||
1338 | an->an_sc = sc; | ||
1339 | memcpy(an->an_addr, addr, ETH_ALEN); | ||
1340 | atomic_set(&an->an_refcnt, 1); | ||
1341 | 1368 | ||
1342 | /* set up per-node tx/rx state */ | 1369 | /* set up per-node tx/rx state */ |
1343 | ath_tx_node_init(sc, an); | 1370 | ath_tx_node_init(sc, an); |
1344 | ath_rx_node_init(sc, an); | 1371 | ath_rx_node_init(sc, an); |
1345 | 1372 | ||
1373 | an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + | ||
1374 | sta->ht_cap.ampdu_factor); | ||
1375 | an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); | ||
1376 | |||
1346 | ath_chainmask_sel_init(sc, an); | 1377 | ath_chainmask_sel_init(sc, an); |
1347 | ath_chainmask_sel_timerstart(&an->an_chainmask_sel); | 1378 | ath_chainmask_sel_timerstart(&an->an_chainmask_sel); |
1348 | list_add(&an->list, &sc->node_list); | ||
1349 | |||
1350 | return an; | ||
1351 | } | 1379 | } |
1352 | 1380 | ||
1353 | void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag) | 1381 | void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) |
1354 | { | 1382 | { |
1355 | unsigned long flags; | 1383 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
1356 | 1384 | ||
1357 | ath_chainmask_sel_timerstop(&an->an_chainmask_sel); | 1385 | ath_chainmask_sel_timerstop(&an->an_chainmask_sel); |
1358 | an->an_flags |= ATH_NODE_CLEAN; | 1386 | |
1359 | ath_tx_node_cleanup(sc, an, bh_flag); | 1387 | ath_tx_node_cleanup(sc, an); |
1360 | ath_rx_node_cleanup(sc, an); | ||
1361 | 1388 | ||
1362 | ath_tx_node_free(sc, an); | 1389 | ath_tx_node_free(sc, an); |
1363 | ath_rx_node_free(sc, an); | 1390 | ath_rx_node_free(sc, an); |
1364 | |||
1365 | spin_lock_irqsave(&sc->node_lock, flags); | ||
1366 | |||
1367 | list_del(&an->list); | ||
1368 | |||
1369 | spin_unlock_irqrestore(&sc->node_lock, flags); | ||
1370 | |||
1371 | kfree(an); | ||
1372 | } | ||
1373 | |||
1374 | /* Finds a node and increases the refcnt if found */ | ||
1375 | |||
1376 | struct ath_node *ath_node_get(struct ath_softc *sc, u8 *addr) | ||
1377 | { | ||
1378 | struct ath_node *an = NULL, *an_found = NULL; | ||
1379 | |||
1380 | if (list_empty(&sc->node_list)) /* FIXME */ | ||
1381 | goto out; | ||
1382 | list_for_each_entry(an, &sc->node_list, list) { | ||
1383 | if (!compare_ether_addr(an->an_addr, addr)) { | ||
1384 | atomic_inc(&an->an_refcnt); | ||
1385 | an_found = an; | ||
1386 | break; | ||
1387 | } | ||
1388 | } | ||
1389 | out: | ||
1390 | return an_found; | ||
1391 | } | ||
1392 | |||
1393 | /* Decrements the refcnt and if it drops to zero, detach the node */ | ||
1394 | |||
1395 | void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag) | ||
1396 | { | ||
1397 | if (atomic_dec_and_test(&an->an_refcnt)) | ||
1398 | ath_node_detach(sc, an, bh_flag); | ||
1399 | } | ||
1400 | |||
1401 | /* Finds a node, doesn't increment refcnt. Caller must hold sc->node_lock */ | ||
1402 | struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr) | ||
1403 | { | ||
1404 | struct ath_node *an = NULL, *an_found = NULL; | ||
1405 | |||
1406 | if (list_empty(&sc->node_list)) | ||
1407 | return NULL; | ||
1408 | |||
1409 | list_for_each_entry(an, &sc->node_list, list) | ||
1410 | if (!compare_ether_addr(an->an_addr, addr)) { | ||
1411 | an_found = an; | ||
1412 | break; | ||
1413 | } | ||
1414 | |||
1415 | return an_found; | ||
1416 | } | 1391 | } |
1417 | 1392 | ||
1418 | /* | 1393 | /* |
@@ -1437,7 +1412,6 @@ void ath_newassoc(struct ath_softc *sc, | |||
1437 | ath_rx_aggr_teardown(sc, an, tidno); | 1412 | ath_rx_aggr_teardown(sc, an, tidno); |
1438 | } | 1413 | } |
1439 | } | 1414 | } |
1440 | an->an_flags = 0; | ||
1441 | } | 1415 | } |
1442 | 1416 | ||
1443 | /**************/ | 1417 | /**************/ |
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index fbff9aa4c28f..d7228ec66c2f 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -373,7 +373,6 @@ void ath_flushrecv(struct ath_softc *sc); | |||
373 | u32 ath_calcrxfilter(struct ath_softc *sc); | 373 | u32 ath_calcrxfilter(struct ath_softc *sc); |
374 | void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an); | 374 | void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an); |
375 | void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an); | 375 | void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an); |
376 | void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an); | ||
377 | void ath_handle_rx_intr(struct ath_softc *sc); | 376 | void ath_handle_rx_intr(struct ath_softc *sc); |
378 | int ath_rx_init(struct ath_softc *sc, int nbufs); | 377 | int ath_rx_init(struct ath_softc *sc, int nbufs); |
379 | void ath_rx_cleanup(struct ath_softc *sc); | 378 | void ath_rx_cleanup(struct ath_softc *sc); |
@@ -546,8 +545,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx); | |||
546 | void ath_tx_draintxq(struct ath_softc *sc, | 545 | void ath_tx_draintxq(struct ath_softc *sc, |
547 | struct ath_txq *txq, bool retry_tx); | 546 | struct ath_txq *txq, bool retry_tx); |
548 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | 547 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); |
549 | void ath_tx_node_cleanup(struct ath_softc *sc, | 548 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); |
550 | struct ath_node *an, bool bh_flag); | ||
551 | void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an); | 549 | void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an); |
552 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); | 550 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); |
553 | int ath_tx_init(struct ath_softc *sc, int nbufs); | 551 | int ath_tx_init(struct ath_softc *sc, int nbufs); |
@@ -568,11 +566,6 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); | |||
568 | /* Node / Aggregation */ | 566 | /* Node / Aggregation */ |
569 | /**********************/ | 567 | /**********************/ |
570 | 568 | ||
571 | /* indicates the node is clened up */ | ||
572 | #define ATH_NODE_CLEAN 0x1 | ||
573 | /* indicates the node is 80211 power save */ | ||
574 | #define ATH_NODE_PWRSAVE 0x2 | ||
575 | |||
576 | #define ADDBA_EXCHANGE_ATTEMPTS 10 | 569 | #define ADDBA_EXCHANGE_ATTEMPTS 10 |
577 | #define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ | 570 | #define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ |
578 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ | 571 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ |
@@ -584,6 +577,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); | |||
584 | #define IEEE80211_SEQ_SEQ_SHIFT 4 | 577 | #define IEEE80211_SEQ_SEQ_SHIFT 4 |
585 | #define IEEE80211_SEQ_MAX 4096 | 578 | #define IEEE80211_SEQ_MAX 4096 |
586 | #define IEEE80211_MIN_AMPDU_BUF 0x8 | 579 | #define IEEE80211_MIN_AMPDU_BUF 0x8 |
580 | #define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 | ||
587 | 581 | ||
588 | /* return whether a bit at index _n in bitmap _bm is set | 582 | /* return whether a bit at index _n in bitmap _bm is set |
589 | * _sz is the size of the bitmap */ | 583 | * _sz is the size of the bitmap */ |
@@ -638,15 +632,10 @@ struct ath_node_aggr { | |||
638 | 632 | ||
639 | /* driver-specific node state */ | 633 | /* driver-specific node state */ |
640 | struct ath_node { | 634 | struct ath_node { |
641 | struct list_head list; | ||
642 | struct ath_softc *an_sc; | 635 | struct ath_softc *an_sc; |
643 | atomic_t an_refcnt; | ||
644 | struct ath_chainmask_sel an_chainmask_sel; | 636 | struct ath_chainmask_sel an_chainmask_sel; |
645 | struct ath_node_aggr an_aggr; | 637 | struct ath_node_aggr an_aggr; |
646 | u8 an_smmode; /* SM Power save mode */ | 638 | u8 an_smmode; /* SM Power save mode */ |
647 | u8 an_flags; | ||
648 | u8 an_addr[ETH_ALEN]; | ||
649 | |||
650 | u16 maxampdu; | 639 | u16 maxampdu; |
651 | u8 mpdudensity; | 640 | u8 mpdudensity; |
652 | }; | 641 | }; |
@@ -659,28 +648,17 @@ void ath_tx_aggr_teardown(struct ath_softc *sc, | |||
659 | struct ath_node *an, u8 tidno); | 648 | struct ath_node *an, u8 tidno); |
660 | void ath_rx_aggr_teardown(struct ath_softc *sc, | 649 | void ath_rx_aggr_teardown(struct ath_softc *sc, |
661 | struct ath_node *an, u8 tidno); | 650 | struct ath_node *an, u8 tidno); |
662 | int ath_rx_aggr_start(struct ath_softc *sc, | 651 | int ath_rx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
663 | const u8 *addr, | 652 | u16 tid, u16 *ssn); |
664 | u16 tid, | 653 | int ath_rx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
665 | u16 *ssn); | 654 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
666 | int ath_rx_aggr_stop(struct ath_softc *sc, | 655 | u16 tid, u16 *ssn); |
667 | const u8 *addr, | 656 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
668 | u16 tid); | ||
669 | int ath_tx_aggr_start(struct ath_softc *sc, | ||
670 | const u8 *addr, | ||
671 | u16 tid, | ||
672 | u16 *ssn); | ||
673 | int ath_tx_aggr_stop(struct ath_softc *sc, | ||
674 | const u8 *addr, | ||
675 | u16 tid); | ||
676 | void ath_newassoc(struct ath_softc *sc, | 657 | void ath_newassoc(struct ath_softc *sc, |
677 | struct ath_node *node, int isnew, int isuapsd); | 658 | struct ath_node *node, int isnew, int isuapsd); |
678 | struct ath_node *ath_node_attach(struct ath_softc *sc, | 659 | void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, |
679 | u8 addr[ETH_ALEN], int if_id); | 660 | int if_id); |
680 | void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag); | 661 | void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta); |
681 | struct ath_node *ath_node_get(struct ath_softc *sc, u8 addr[ETH_ALEN]); | ||
682 | void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag); | ||
683 | struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr); | ||
684 | 662 | ||
685 | /*******************/ | 663 | /*******************/ |
686 | /* Beacon Handling */ | 664 | /* Beacon Handling */ |
@@ -975,7 +953,6 @@ struct ath_softc { | |||
975 | u8 sc_rxotherant; /* rx's on non-default antenna */ | 953 | u8 sc_rxotherant; /* rx's on non-default antenna */ |
976 | 954 | ||
977 | struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ | 955 | struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ |
978 | struct list_head node_list; | ||
979 | struct ath_ht_info sc_ht_info; | 956 | struct ath_ht_info sc_ht_info; |
980 | enum ath9k_ht_extprotspacing sc_ht_extprotspacing; | 957 | enum ath9k_ht_extprotspacing sc_ht_extprotspacing; |
981 | 958 | ||
@@ -1036,7 +1013,6 @@ struct ath_softc { | |||
1036 | spinlock_t sc_rxbuflock; | 1013 | spinlock_t sc_rxbuflock; |
1037 | spinlock_t sc_txbuflock; | 1014 | spinlock_t sc_txbuflock; |
1038 | spinlock_t sc_resetlock; | 1015 | spinlock_t sc_resetlock; |
1039 | spinlock_t node_lock; | ||
1040 | 1016 | ||
1041 | /* LEDs */ | 1017 | /* LEDs */ |
1042 | struct ath_led radio_led; | 1018 | struct ath_led radio_led; |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index b25c8f9670d1..b1b1e7f3b0b8 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -21,8 +21,6 @@ | |||
21 | 21 | ||
22 | #define ATH_PCI_VERSION "0.1" | 22 | #define ATH_PCI_VERSION "0.1" |
23 | 23 | ||
24 | #define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 | ||
25 | |||
26 | static char *dev_info = "ath9k"; | 24 | static char *dev_info = "ath9k"; |
27 | 25 | ||
28 | MODULE_AUTHOR("Atheros Communications"); | 26 | MODULE_AUTHOR("Atheros Communications"); |
@@ -297,41 +295,6 @@ static void ath9k_rx_prepare(struct ath_softc *sc, | |||
297 | rx_status->flag |= RX_FLAG_TSFT; | 295 | rx_status->flag |= RX_FLAG_TSFT; |
298 | } | 296 | } |
299 | 297 | ||
300 | static u8 parse_mpdudensity(u8 mpdudensity) | ||
301 | { | ||
302 | /* | ||
303 | * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": | ||
304 | * 0 for no restriction | ||
305 | * 1 for 1/4 us | ||
306 | * 2 for 1/2 us | ||
307 | * 3 for 1 us | ||
308 | * 4 for 2 us | ||
309 | * 5 for 4 us | ||
310 | * 6 for 8 us | ||
311 | * 7 for 16 us | ||
312 | */ | ||
313 | switch (mpdudensity) { | ||
314 | case 0: | ||
315 | return 0; | ||
316 | case 1: | ||
317 | case 2: | ||
318 | case 3: | ||
319 | /* Our lower layer calculations limit our precision to | ||
320 | 1 microsecond */ | ||
321 | return 1; | ||
322 | case 4: | ||
323 | return 2; | ||
324 | case 5: | ||
325 | return 4; | ||
326 | case 6: | ||
327 | return 8; | ||
328 | case 7: | ||
329 | return 16; | ||
330 | default: | ||
331 | return 0; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | static void ath9k_ht_conf(struct ath_softc *sc, | 298 | static void ath9k_ht_conf(struct ath_softc *sc, |
336 | struct ieee80211_bss_conf *bss_conf) | 299 | struct ieee80211_bss_conf *bss_conf) |
337 | { | 300 | { |
@@ -479,8 +442,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
479 | tx_info->status.rates[0].count = tx_status->retries + 1; | 442 | tx_info->status.rates[0].count = tx_status->retries + 1; |
480 | 443 | ||
481 | ieee80211_tx_status(hw, skb); | 444 | ieee80211_tx_status(hw, skb); |
482 | if (an) | ||
483 | ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE); | ||
484 | } | 445 | } |
485 | 446 | ||
486 | int _ath_rx_indicate(struct ath_softc *sc, | 447 | int _ath_rx_indicate(struct ath_softc *sc, |
@@ -518,10 +479,6 @@ int _ath_rx_indicate(struct ath_softc *sc, | |||
518 | rx_status.flag |= RX_FLAG_DECRYPTED; | 479 | rx_status.flag |= RX_FLAG_DECRYPTED; |
519 | } | 480 | } |
520 | 481 | ||
521 | spin_lock_bh(&sc->node_lock); | ||
522 | an = ath_node_find(sc, hdr->addr2); | ||
523 | spin_unlock_bh(&sc->node_lock); | ||
524 | |||
525 | if (an) { | 482 | if (an) { |
526 | ath_rx_input(sc, an, | 483 | ath_rx_input(sc, an, |
527 | skb, status, &st); | 484 | skb, status, &st); |
@@ -913,11 +870,6 @@ static int ath_attach(u16 devid, | |||
913 | if (error != 0) | 870 | if (error != 0) |
914 | return error; | 871 | return error; |
915 | 872 | ||
916 | /* Init nodes */ | ||
917 | |||
918 | INIT_LIST_HEAD(&sc->node_list); | ||
919 | spin_lock_init(&sc->node_lock); | ||
920 | |||
921 | /* get mac address from hardware and set in mac80211 */ | 873 | /* get mac address from hardware and set in mac80211 */ |
922 | 874 | ||
923 | SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr); | 875 | SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr); |
@@ -1404,50 +1356,22 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
1404 | __func__, sc->rx_filter); | 1356 | __func__, sc->rx_filter); |
1405 | } | 1357 | } |
1406 | 1358 | ||
1359 | /* Only a single interface is currently supported, | ||
1360 | so pass 0 as the interface id to ath_node_attach */ | ||
1361 | |||
1407 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | 1362 | static void ath9k_sta_notify(struct ieee80211_hw *hw, |
1408 | struct ieee80211_vif *vif, | 1363 | struct ieee80211_vif *vif, |
1409 | enum sta_notify_cmd cmd, | 1364 | enum sta_notify_cmd cmd, |
1410 | struct ieee80211_sta *sta) | 1365 | struct ieee80211_sta *sta) |
1411 | { | 1366 | { |
1412 | struct ath_softc *sc = hw->priv; | 1367 | struct ath_softc *sc = hw->priv; |
1413 | struct ath_node *an; | ||
1414 | unsigned long flags; | ||
1415 | |||
1416 | spin_lock_irqsave(&sc->node_lock, flags); | ||
1417 | an = ath_node_find(sc, sta->addr); | ||
1418 | spin_unlock_irqrestore(&sc->node_lock, flags); | ||
1419 | 1368 | ||
1420 | switch (cmd) { | 1369 | switch (cmd) { |
1421 | case STA_NOTIFY_ADD: | 1370 | case STA_NOTIFY_ADD: |
1422 | spin_lock_irqsave(&sc->node_lock, flags); | 1371 | ath_node_attach(sc, sta, 0); |
1423 | if (!an) { | ||
1424 | ath_node_attach(sc, sta->addr, 0); | ||
1425 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %pM\n", | ||
1426 | __func__, sta->addr); | ||
1427 | } else { | ||
1428 | ath_node_get(sc, sta->addr); | ||
1429 | } | ||
1430 | |||
1431 | /* XXX: Is this right? Can the capabilities change? */ | ||
1432 | an = ath_node_find(sc, sta->addr); | ||
1433 | an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + | ||
1434 | sta->ht_cap.ampdu_factor); | ||
1435 | an->mpdudensity = | ||
1436 | parse_mpdudensity(sta->ht_cap.ampdu_density); | ||
1437 | |||
1438 | spin_unlock_irqrestore(&sc->node_lock, flags); | ||
1439 | break; | 1372 | break; |
1440 | case STA_NOTIFY_REMOVE: | 1373 | case STA_NOTIFY_REMOVE: |
1441 | if (!an) | 1374 | ath_node_detach(sc, sta); |
1442 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1443 | "%s: Removal of a non-existent node\n", | ||
1444 | __func__); | ||
1445 | else { | ||
1446 | ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT); | ||
1447 | DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %pM\n", | ||
1448 | __func__, | ||
1449 | sta->addr); | ||
1450 | } | ||
1451 | break; | 1375 | break; |
1452 | default: | 1376 | default: |
1453 | break; | 1377 | break; |
@@ -1595,21 +1519,21 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1595 | 1519 | ||
1596 | switch (action) { | 1520 | switch (action) { |
1597 | case IEEE80211_AMPDU_RX_START: | 1521 | case IEEE80211_AMPDU_RX_START: |
1598 | ret = ath_rx_aggr_start(sc, sta->addr, tid, ssn); | 1522 | ret = ath_rx_aggr_start(sc, sta, tid, ssn); |
1599 | if (ret < 0) | 1523 | if (ret < 0) |
1600 | DPRINTF(sc, ATH_DBG_FATAL, | 1524 | DPRINTF(sc, ATH_DBG_FATAL, |
1601 | "%s: Unable to start RX aggregation\n", | 1525 | "%s: Unable to start RX aggregation\n", |
1602 | __func__); | 1526 | __func__); |
1603 | break; | 1527 | break; |
1604 | case IEEE80211_AMPDU_RX_STOP: | 1528 | case IEEE80211_AMPDU_RX_STOP: |
1605 | ret = ath_rx_aggr_stop(sc, sta->addr, tid); | 1529 | ret = ath_rx_aggr_stop(sc, sta, tid); |
1606 | if (ret < 0) | 1530 | if (ret < 0) |
1607 | DPRINTF(sc, ATH_DBG_FATAL, | 1531 | DPRINTF(sc, ATH_DBG_FATAL, |
1608 | "%s: Unable to stop RX aggregation\n", | 1532 | "%s: Unable to stop RX aggregation\n", |
1609 | __func__); | 1533 | __func__); |
1610 | break; | 1534 | break; |
1611 | case IEEE80211_AMPDU_TX_START: | 1535 | case IEEE80211_AMPDU_TX_START: |
1612 | ret = ath_tx_aggr_start(sc, sta->addr, tid, ssn); | 1536 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); |
1613 | if (ret < 0) | 1537 | if (ret < 0) |
1614 | DPRINTF(sc, ATH_DBG_FATAL, | 1538 | DPRINTF(sc, ATH_DBG_FATAL, |
1615 | "%s: Unable to start TX aggregation\n", | 1539 | "%s: Unable to start TX aggregation\n", |
@@ -1618,7 +1542,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1618 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 1542 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); |
1619 | break; | 1543 | break; |
1620 | case IEEE80211_AMPDU_TX_STOP: | 1544 | case IEEE80211_AMPDU_TX_STOP: |
1621 | ret = ath_tx_aggr_stop(sc, sta->addr, tid); | 1545 | ret = ath_tx_aggr_stop(sc, sta, tid); |
1622 | if (ret < 0) | 1546 | if (ret < 0) |
1623 | DPRINTF(sc, ATH_DBG_FATAL, | 1547 | DPRINTF(sc, ATH_DBG_FATAL, |
1624 | "%s: Unable to stop TX aggregation\n", | 1548 | "%s: Unable to stop TX aggregation\n", |
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index ecffd6f45fd0..1305873b2a09 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -1867,9 +1867,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1867 | /* XXX: UGLY HACK!! */ | 1867 | /* XXX: UGLY HACK!! */ |
1868 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | 1868 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; |
1869 | 1869 | ||
1870 | spin_lock_bh(&sc->node_lock); | 1870 | an = (struct ath_node *)sta->drv_priv; |
1871 | an = ath_node_find(sc, hdr->addr1); | ||
1872 | spin_unlock_bh(&sc->node_lock); | ||
1873 | 1871 | ||
1874 | if (tx_info_priv == NULL) | 1872 | if (tx_info_priv == NULL) |
1875 | return; | 1873 | return; |
@@ -1984,16 +1982,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
1984 | qc = ieee80211_get_qos_ctl(hdr); | 1982 | qc = ieee80211_get_qos_ctl(hdr); |
1985 | tid = qc[0] & 0xf; | 1983 | tid = qc[0] & 0xf; |
1986 | 1984 | ||
1987 | spin_lock_bh(&sc->node_lock); | 1985 | an = (struct ath_node *)sta->drv_priv; |
1988 | an = ath_node_find(sc, hdr->addr1); | ||
1989 | spin_unlock_bh(&sc->node_lock); | ||
1990 | |||
1991 | if (!an) { | ||
1992 | DPRINTF(sc, ATH_DBG_AGGR, | ||
1993 | "%s: Node not found to " | ||
1994 | "init/chk TX aggr\n", __func__); | ||
1995 | return; | ||
1996 | } | ||
1997 | 1986 | ||
1998 | chk = ath_tx_aggr_check(sc, an, tid); | 1987 | chk = ath_tx_aggr_check(sc, an, tid); |
1999 | if (chk == AGGR_REQUIRED) { | 1988 | if (chk == AGGR_REQUIRED) { |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 828322840a86..6b4006ed4e01 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -1095,7 +1095,7 @@ rx_next: | |||
1095 | /* Process ADDBA request in per-TID data structure */ | 1095 | /* Process ADDBA request in per-TID data structure */ |
1096 | 1096 | ||
1097 | int ath_rx_aggr_start(struct ath_softc *sc, | 1097 | int ath_rx_aggr_start(struct ath_softc *sc, |
1098 | const u8 *addr, | 1098 | struct ieee80211_sta *sta, |
1099 | u16 tid, | 1099 | u16 tid, |
1100 | u16 *ssn) | 1100 | u16 *ssn) |
1101 | { | 1101 | { |
@@ -1105,17 +1105,7 @@ int ath_rx_aggr_start(struct ath_softc *sc, | |||
1105 | struct ieee80211_supported_band *sband; | 1105 | struct ieee80211_supported_band *sband; |
1106 | u16 buffersize = 0; | 1106 | u16 buffersize = 0; |
1107 | 1107 | ||
1108 | spin_lock_bh(&sc->node_lock); | 1108 | an = (struct ath_node *)sta->drv_priv; |
1109 | an = ath_node_find(sc, (u8 *) addr); | ||
1110 | spin_unlock_bh(&sc->node_lock); | ||
1111 | |||
1112 | if (!an) { | ||
1113 | DPRINTF(sc, ATH_DBG_AGGR, | ||
1114 | "%s: Node not found to initialize RX aggregation\n", | ||
1115 | __func__); | ||
1116 | return -1; | ||
1117 | } | ||
1118 | |||
1119 | sband = hw->wiphy->bands[hw->conf.channel->band]; | 1109 | sband = hw->wiphy->bands[hw->conf.channel->band]; |
1120 | buffersize = IEEE80211_MIN_AMPDU_BUF << | 1110 | buffersize = IEEE80211_MIN_AMPDU_BUF << |
1121 | sband->ht_cap.ampdu_factor; /* FIXME */ | 1111 | sband->ht_cap.ampdu_factor; /* FIXME */ |
@@ -1172,21 +1162,9 @@ int ath_rx_aggr_start(struct ath_softc *sc, | |||
1172 | 1162 | ||
1173 | /* Process DELBA */ | 1163 | /* Process DELBA */ |
1174 | 1164 | ||
1175 | int ath_rx_aggr_stop(struct ath_softc *sc, | 1165 | int ath_rx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
1176 | const u8 *addr, | ||
1177 | u16 tid) | ||
1178 | { | 1166 | { |
1179 | struct ath_node *an; | 1167 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
1180 | |||
1181 | spin_lock_bh(&sc->node_lock); | ||
1182 | an = ath_node_find(sc, (u8 *) addr); | ||
1183 | spin_unlock_bh(&sc->node_lock); | ||
1184 | |||
1185 | if (!an) { | ||
1186 | DPRINTF(sc, ATH_DBG_AGGR, | ||
1187 | "%s: RX aggr stop for non-existent node\n", __func__); | ||
1188 | return -1; | ||
1189 | } | ||
1190 | 1168 | ||
1191 | ath_rx_aggr_teardown(sc, an, tid); | 1169 | ath_rx_aggr_teardown(sc, an, tid); |
1192 | return 0; | 1170 | return 0; |
@@ -1194,8 +1172,7 @@ int ath_rx_aggr_stop(struct ath_softc *sc, | |||
1194 | 1172 | ||
1195 | /* Rx aggregation tear down */ | 1173 | /* Rx aggregation tear down */ |
1196 | 1174 | ||
1197 | void ath_rx_aggr_teardown(struct ath_softc *sc, | 1175 | void ath_rx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) |
1198 | struct ath_node *an, u8 tid) | ||
1199 | { | 1176 | { |
1200 | struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid]; | 1177 | struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid]; |
1201 | 1178 | ||
@@ -1253,7 +1230,7 @@ void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
1253 | } | 1230 | } |
1254 | } | 1231 | } |
1255 | 1232 | ||
1256 | void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | 1233 | void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an) |
1257 | { | 1234 | { |
1258 | if (sc->sc_flags & SC_OP_RXAGGR) { | 1235 | if (sc->sc_flags & SC_OP_RXAGGR) { |
1259 | struct ath_arx_tid *rxtid; | 1236 | struct ath_arx_tid *rxtid; |
@@ -1281,10 +1258,3 @@ void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
1281 | } | 1258 | } |
1282 | 1259 | ||
1283 | } | 1260 | } |
1284 | |||
1285 | /* Cleanup per-node receive state */ | ||
1286 | |||
1287 | void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an) | ||
1288 | { | ||
1289 | ath_rx_node_cleanup(sc, an); | ||
1290 | } | ||
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 7cfab5a542f0..64557133b227 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
@@ -214,15 +214,6 @@ static int ath_tx_prepare(struct ath_softc *sc, | |||
214 | rt = sc->sc_currates; | 214 | rt = sc->sc_currates; |
215 | BUG_ON(!rt); | 215 | BUG_ON(!rt); |
216 | 216 | ||
217 | /* Fill misc fields */ | ||
218 | |||
219 | spin_lock_bh(&sc->node_lock); | ||
220 | txctl->an = ath_node_get(sc, hdr->addr1); | ||
221 | /* create a temp node, if the node is not there already */ | ||
222 | if (!txctl->an) | ||
223 | txctl->an = ath_node_attach(sc, hdr->addr1, 0); | ||
224 | spin_unlock_bh(&sc->node_lock); | ||
225 | |||
226 | if (ieee80211_is_data_qos(fc)) { | 217 | if (ieee80211_is_data_qos(fc)) { |
227 | qc = ieee80211_get_qos_ctl(hdr); | 218 | qc = ieee80211_get_qos_ctl(hdr); |
228 | txctl->tidno = qc[0] & 0xf; | 219 | txctl->tidno = qc[0] & 0xf; |
@@ -496,11 +487,9 @@ unlock: | |||
496 | 487 | ||
497 | /* Compute the number of bad frames */ | 488 | /* Compute the number of bad frames */ |
498 | 489 | ||
499 | static int ath_tx_num_badfrms(struct ath_softc *sc, | 490 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, |
500 | struct ath_buf *bf, int txok) | 491 | int txok) |
501 | { | 492 | { |
502 | struct ath_node *an = bf->bf_node; | ||
503 | int isnodegone = (an->an_flags & ATH_NODE_CLEAN); | ||
504 | struct ath_buf *bf_last = bf->bf_lastbf; | 493 | struct ath_buf *bf_last = bf->bf_lastbf; |
505 | struct ath_desc *ds = bf_last->bf_desc; | 494 | struct ath_desc *ds = bf_last->bf_desc; |
506 | u16 seq_st = 0; | 495 | u16 seq_st = 0; |
@@ -509,7 +498,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, | |||
509 | int nbad = 0; | 498 | int nbad = 0; |
510 | int isaggr = 0; | 499 | int isaggr = 0; |
511 | 500 | ||
512 | if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) | 501 | if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) |
513 | return 0; | 502 | return 0; |
514 | 503 | ||
515 | isaggr = bf_isaggr(bf); | 504 | isaggr = bf_isaggr(bf); |
@@ -908,7 +897,6 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
908 | u16 seq_st = 0; | 897 | u16 seq_st = 0; |
909 | u32 ba[WME_BA_BMP_SIZE >> 5]; | 898 | u32 ba[WME_BA_BMP_SIZE >> 5]; |
910 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0; | 899 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0; |
911 | int isnodegone = (an->an_flags & ATH_NODE_CLEAN); | ||
912 | 900 | ||
913 | isaggr = bf_isaggr(bf); | 901 | isaggr = bf_isaggr(bf); |
914 | if (isaggr) { | 902 | if (isaggr) { |
@@ -954,7 +942,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
954 | /* transmit completion */ | 942 | /* transmit completion */ |
955 | } else { | 943 | } else { |
956 | 944 | ||
957 | if (!tid->cleanup_inprogress && !isnodegone && | 945 | if (!tid->cleanup_inprogress && |
958 | ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { | 946 | ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { |
959 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { | 947 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { |
960 | ath_tx_set_retry(sc, bf); | 948 | ath_tx_set_retry(sc, bf); |
@@ -1083,15 +1071,6 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
1083 | bf = bf_next; | 1071 | bf = bf_next; |
1084 | } | 1072 | } |
1085 | 1073 | ||
1086 | /* | ||
1087 | * node is already gone. no more assocication | ||
1088 | * with the node. the node might have been freed | ||
1089 | * any node acces can result in panic.note tid | ||
1090 | * is part of the node. | ||
1091 | */ | ||
1092 | if (isnodegone) | ||
1093 | return; | ||
1094 | |||
1095 | if (tid->cleanup_inprogress) { | 1074 | if (tid->cleanup_inprogress) { |
1096 | /* check to see if we're done with cleaning the h/w queue */ | 1075 | /* check to see if we're done with cleaning the h/w queue */ |
1097 | spin_lock_bh(&txq->axq_lock); | 1076 | spin_lock_bh(&txq->axq_lock); |
@@ -1795,8 +1774,8 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, | |||
1795 | 1774 | ||
1796 | static void ath_tid_drain(struct ath_softc *sc, | 1775 | static void ath_tid_drain(struct ath_softc *sc, |
1797 | struct ath_txq *txq, | 1776 | struct ath_txq *txq, |
1798 | struct ath_atx_tid *tid, | 1777 | struct ath_atx_tid *tid) |
1799 | bool bh_flag) | 1778 | |
1800 | { | 1779 | { |
1801 | struct ath_buf *bf; | 1780 | struct ath_buf *bf; |
1802 | struct list_head bf_head; | 1781 | struct list_head bf_head; |
@@ -1817,18 +1796,12 @@ static void ath_tid_drain(struct ath_softc *sc, | |||
1817 | * do not indicate packets while holding txq spinlock. | 1796 | * do not indicate packets while holding txq spinlock. |
1818 | * unlock is intentional here | 1797 | * unlock is intentional here |
1819 | */ | 1798 | */ |
1820 | if (likely(bh_flag)) | 1799 | spin_unlock(&txq->axq_lock); |
1821 | spin_unlock_bh(&txq->axq_lock); | ||
1822 | else | ||
1823 | spin_unlock(&txq->axq_lock); | ||
1824 | 1800 | ||
1825 | /* complete this sub-frame */ | 1801 | /* complete this sub-frame */ |
1826 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); | 1802 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); |
1827 | 1803 | ||
1828 | if (likely(bh_flag)) | 1804 | spin_lock(&txq->axq_lock); |
1829 | spin_lock_bh(&txq->axq_lock); | ||
1830 | else | ||
1831 | spin_lock(&txq->axq_lock); | ||
1832 | } | 1805 | } |
1833 | 1806 | ||
1834 | /* | 1807 | /* |
@@ -1847,8 +1820,7 @@ static void ath_tid_drain(struct ath_softc *sc, | |||
1847 | */ | 1820 | */ |
1848 | 1821 | ||
1849 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | 1822 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, |
1850 | struct ath_txq *txq, | 1823 | struct ath_txq *txq) |
1851 | bool bh_flag) | ||
1852 | { | 1824 | { |
1853 | struct ath_atx_ac *ac, *ac_tmp; | 1825 | struct ath_atx_ac *ac, *ac_tmp; |
1854 | struct ath_atx_tid *tid, *tid_tmp; | 1826 | struct ath_atx_tid *tid, *tid_tmp; |
@@ -1859,7 +1831,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | |||
1859 | list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { | 1831 | list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { |
1860 | list_del(&tid->list); | 1832 | list_del(&tid->list); |
1861 | tid->sched = false; | 1833 | tid->sched = false; |
1862 | ath_tid_drain(sc, txq, tid, bh_flag); | 1834 | ath_tid_drain(sc, txq, tid); |
1863 | } | 1835 | } |
1864 | } | 1836 | } |
1865 | } | 1837 | } |
@@ -2294,8 +2266,6 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb) | |||
2294 | * or asynchrounsly once DMA is complete. | 2266 | * or asynchrounsly once DMA is complete. |
2295 | */ | 2267 | */ |
2296 | xmit_map_sg(sc, skb, &txctl); | 2268 | xmit_map_sg(sc, skb, &txctl); |
2297 | else | ||
2298 | ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE); | ||
2299 | 2269 | ||
2300 | /* failed packets will be dropped by the caller */ | 2270 | /* failed packets will be dropped by the caller */ |
2301 | return error; | 2271 | return error; |
@@ -2374,8 +2344,7 @@ void ath_tx_draintxq(struct ath_softc *sc, | |||
2374 | if (sc->sc_flags & SC_OP_TXAGGR) { | 2344 | if (sc->sc_flags & SC_OP_TXAGGR) { |
2375 | if (!retry_tx) { | 2345 | if (!retry_tx) { |
2376 | spin_lock_bh(&txq->axq_lock); | 2346 | spin_lock_bh(&txq->axq_lock); |
2377 | ath_txq_drain_pending_buffers(sc, txq, | 2347 | ath_txq_drain_pending_buffers(sc, txq); |
2378 | ATH9K_BH_STATUS_CHANGE); | ||
2379 | spin_unlock_bh(&txq->axq_lock); | 2348 | spin_unlock_bh(&txq->axq_lock); |
2380 | } | 2349 | } |
2381 | } | 2350 | } |
@@ -2441,24 +2410,13 @@ enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc, | |||
2441 | 2410 | ||
2442 | /* Start TX aggregation */ | 2411 | /* Start TX aggregation */ |
2443 | 2412 | ||
2444 | int ath_tx_aggr_start(struct ath_softc *sc, | 2413 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
2445 | const u8 *addr, | 2414 | u16 tid, u16 *ssn) |
2446 | u16 tid, | ||
2447 | u16 *ssn) | ||
2448 | { | 2415 | { |
2449 | struct ath_atx_tid *txtid; | 2416 | struct ath_atx_tid *txtid; |
2450 | struct ath_node *an; | 2417 | struct ath_node *an; |
2451 | 2418 | ||
2452 | spin_lock_bh(&sc->node_lock); | 2419 | an = (struct ath_node *)sta->drv_priv; |
2453 | an = ath_node_find(sc, (u8 *) addr); | ||
2454 | spin_unlock_bh(&sc->node_lock); | ||
2455 | |||
2456 | if (!an) { | ||
2457 | DPRINTF(sc, ATH_DBG_AGGR, | ||
2458 | "%s: Node not found to initialize " | ||
2459 | "TX aggregation\n", __func__); | ||
2460 | return -1; | ||
2461 | } | ||
2462 | 2420 | ||
2463 | if (sc->sc_flags & SC_OP_TXAGGR) { | 2421 | if (sc->sc_flags & SC_OP_TXAGGR) { |
2464 | txtid = ATH_AN_2_TID(an, tid); | 2422 | txtid = ATH_AN_2_TID(an, tid); |
@@ -2471,21 +2429,9 @@ int ath_tx_aggr_start(struct ath_softc *sc, | |||
2471 | 2429 | ||
2472 | /* Stop tx aggregation */ | 2430 | /* Stop tx aggregation */ |
2473 | 2431 | ||
2474 | int ath_tx_aggr_stop(struct ath_softc *sc, | 2432 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
2475 | const u8 *addr, | ||
2476 | u16 tid) | ||
2477 | { | 2433 | { |
2478 | struct ath_node *an; | 2434 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
2479 | |||
2480 | spin_lock_bh(&sc->node_lock); | ||
2481 | an = ath_node_find(sc, (u8 *) addr); | ||
2482 | spin_unlock_bh(&sc->node_lock); | ||
2483 | |||
2484 | if (!an) { | ||
2485 | DPRINTF(sc, ATH_DBG_AGGR, | ||
2486 | "%s: TX aggr stop for non-existent node\n", __func__); | ||
2487 | return -1; | ||
2488 | } | ||
2489 | 2435 | ||
2490 | ath_tx_aggr_teardown(sc, an, tid); | 2436 | ath_tx_aggr_teardown(sc, an, tid); |
2491 | return 0; | 2437 | return 0; |
@@ -2498,8 +2444,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc, | |||
2498 | * - Discard all retry frames from the s/w queue. | 2444 | * - Discard all retry frames from the s/w queue. |
2499 | */ | 2445 | */ |
2500 | 2446 | ||
2501 | void ath_tx_aggr_teardown(struct ath_softc *sc, | 2447 | void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) |
2502 | struct ath_node *an, u8 tid) | ||
2503 | { | 2448 | { |
2504 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); | 2449 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); |
2505 | struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum]; | 2450 | struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum]; |
@@ -2625,8 +2570,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2625 | struct ath_atx_ac *ac; | 2570 | struct ath_atx_ac *ac; |
2626 | int tidno, acno; | 2571 | int tidno, acno; |
2627 | 2572 | ||
2628 | an->maxampdu = ATH_AMPDU_LIMIT_DEFAULT; | ||
2629 | |||
2630 | /* | 2573 | /* |
2631 | * Init per tid tx state | 2574 | * Init per tid tx state |
2632 | */ | 2575 | */ |
@@ -2684,8 +2627,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2684 | 2627 | ||
2685 | /* Cleanupthe pending buffers for the node. */ | 2628 | /* Cleanupthe pending buffers for the node. */ |
2686 | 2629 | ||
2687 | void ath_tx_node_cleanup(struct ath_softc *sc, | 2630 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) |
2688 | struct ath_node *an, bool bh_flag) | ||
2689 | { | 2631 | { |
2690 | int i; | 2632 | int i; |
2691 | struct ath_atx_ac *ac, *ac_tmp; | 2633 | struct ath_atx_ac *ac, *ac_tmp; |
@@ -2695,10 +2637,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, | |||
2695 | if (ATH_TXQ_SETUP(sc, i)) { | 2637 | if (ATH_TXQ_SETUP(sc, i)) { |
2696 | txq = &sc->sc_txq[i]; | 2638 | txq = &sc->sc_txq[i]; |
2697 | 2639 | ||
2698 | if (likely(bh_flag)) | 2640 | spin_lock(&txq->axq_lock); |
2699 | spin_lock_bh(&txq->axq_lock); | ||
2700 | else | ||
2701 | spin_lock(&txq->axq_lock); | ||
2702 | 2641 | ||
2703 | list_for_each_entry_safe(ac, | 2642 | list_for_each_entry_safe(ac, |
2704 | ac_tmp, &txq->axq_acq, list) { | 2643 | ac_tmp, &txq->axq_acq, list) { |
@@ -2713,17 +2652,14 @@ void ath_tx_node_cleanup(struct ath_softc *sc, | |||
2713 | tid_tmp, &ac->tid_q, list) { | 2652 | tid_tmp, &ac->tid_q, list) { |
2714 | list_del(&tid->list); | 2653 | list_del(&tid->list); |
2715 | tid->sched = false; | 2654 | tid->sched = false; |
2716 | ath_tid_drain(sc, txq, tid, bh_flag); | 2655 | ath_tid_drain(sc, txq, tid); |
2717 | tid->addba_exchangecomplete = 0; | 2656 | tid->addba_exchangecomplete = 0; |
2718 | tid->addba_exchangeattempts = 0; | 2657 | tid->addba_exchangeattempts = 0; |
2719 | tid->cleanup_inprogress = false; | 2658 | tid->cleanup_inprogress = false; |
2720 | } | 2659 | } |
2721 | } | 2660 | } |
2722 | 2661 | ||
2723 | if (likely(bh_flag)) | 2662 | spin_unlock(&txq->axq_lock); |
2724 | spin_unlock_bh(&txq->axq_lock); | ||
2725 | else | ||
2726 | spin_unlock(&txq->axq_lock); | ||
2727 | } | 2663 | } |
2728 | } | 2664 | } |
2729 | } | 2665 | } |
@@ -2794,7 +2730,6 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) | |||
2794 | */ | 2730 | */ |
2795 | xmit_map_sg(sc, skb, &txctl); | 2731 | xmit_map_sg(sc, skb, &txctl); |
2796 | } else { | 2732 | } else { |
2797 | ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE); | ||
2798 | DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ failed\n", __func__); | 2733 | DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ failed\n", __func__); |
2799 | dev_kfree_skb_any(skb); | 2734 | dev_kfree_skb_any(skb); |
2800 | } | 2735 | } |