aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/acx.c28
-rw-r--r--drivers/net/wireless/wl12xx/acx.h9
-rw-r--r--drivers/net/wireless/wl12xx/init.c2
-rw-r--r--drivers/net/wireless/wl12xx/main.c151
-rw-r--r--drivers/net/wireless/wl12xx/ps.c78
-rw-r--r--drivers/net/wireless/wl12xx/ps.h2
-rw-r--r--drivers/net/wireless/wl12xx/rx.c6
-rw-r--r--drivers/net/wireless/wl12xx/rx.h4
-rw-r--r--drivers/net/wireless/wl12xx/tx.c237
-rw-r--r--drivers/net/wireless/wl12xx/tx.h5
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h37
11 files changed, 479 insertions, 80 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 33840d95d17d..3badc6bb7866 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1328,10 +1328,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1328 /* get data from A-MPDU parameters field */ 1328 /* get data from A-MPDU parameters field */
1329 acx->ampdu_max_length = ht_cap->ampdu_factor; 1329 acx->ampdu_max_length = ht_cap->ampdu_factor;
1330 acx->ampdu_min_spacing = ht_cap->ampdu_density; 1330 acx->ampdu_min_spacing = ht_cap->ampdu_density;
1331
1332 memcpy(acx->mac_address, mac_address, ETH_ALEN);
1333 } 1331 }
1334 1332
1333 memcpy(acx->mac_address, mac_address, ETH_ALEN);
1335 acx->ht_capabilites = cpu_to_le32(ht_capabilites); 1334 acx->ht_capabilites = cpu_to_le32(ht_capabilites);
1336 1335
1337 ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); 1336 ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
@@ -1542,3 +1541,28 @@ out:
1542 kfree(config_ps); 1541 kfree(config_ps);
1543 return ret; 1542 return ret;
1544} 1543}
1544
1545int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
1546{
1547 struct wl1271_acx_inconnection_sta *acx = NULL;
1548 int ret;
1549
1550 wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr);
1551
1552 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1553 if (!acx)
1554 return -ENOMEM;
1555
1556 memcpy(acx->addr, addr, ETH_ALEN);
1557
1558 ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST,
1559 acx, sizeof(*acx));
1560 if (ret < 0) {
1561 wl1271_warning("acx set inconnaction sta failed: %d", ret);
1562 goto out;
1563 }
1564
1565out:
1566 kfree(acx);
1567 return ret;
1568}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 4e301de916bb..dd19b01d807b 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1155,6 +1155,13 @@ struct wl1271_acx_config_ps {
1155 __le32 null_data_rate; 1155 __le32 null_data_rate;
1156} __packed; 1156} __packed;
1157 1157
1158struct wl1271_acx_inconnection_sta {
1159 struct acx_header header;
1160
1161 u8 addr[ETH_ALEN];
1162 u8 padding1[2];
1163} __packed;
1164
1158enum { 1165enum {
1159 ACX_WAKE_UP_CONDITIONS = 0x0002, 1166 ACX_WAKE_UP_CONDITIONS = 0x0002,
1160 ACX_MEM_CFG = 0x0003, 1167 ACX_MEM_CFG = 0x0003,
@@ -1215,6 +1222,7 @@ enum {
1215 ACX_GEN_FW_CMD = 0x0070, 1222 ACX_GEN_FW_CMD = 0x0070,
1216 ACX_HOST_IF_CFG_BITMAP = 0x0071, 1223 ACX_HOST_IF_CFG_BITMAP = 0x0071,
1217 ACX_MAX_TX_FAILURE = 0x0072, 1224 ACX_MAX_TX_FAILURE = 0x0072,
1225 ACX_UPDATE_INCONNECTION_STA_LIST = 0x0073,
1218 DOT11_RX_MSDU_LIFE_TIME = 0x1004, 1226 DOT11_RX_MSDU_LIFE_TIME = 0x1004,
1219 DOT11_CUR_TX_PWR = 0x100D, 1227 DOT11_CUR_TX_PWR = 0x100D,
1220 DOT11_RX_DOT11_MODE = 0x1012, 1228 DOT11_RX_DOT11_MODE = 0x1012,
@@ -1290,5 +1298,6 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
1290int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); 1298int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
1291int wl1271_acx_max_tx_retry(struct wl1271 *wl); 1299int wl1271_acx_max_tx_retry(struct wl1271 *wl);
1292int wl1271_acx_config_ps(struct wl1271 *wl); 1300int wl1271_acx_config_ps(struct wl1271 *wl);
1301int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
1293 1302
1294#endif /* __WL1271_ACX_H__ */ 1303#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index 62dc9839dd31..6072fe457135 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -483,7 +483,7 @@ static void wl1271_check_ba_support(struct wl1271 *wl)
483static int wl1271_set_ba_policies(struct wl1271 *wl) 483static int wl1271_set_ba_policies(struct wl1271 *wl)
484{ 484{
485 u8 tid_index; 485 u8 tid_index;
486 u8 ret = 0; 486 int ret = 0;
487 487
488 /* Reset the BA RX indicators */ 488 /* Reset the BA RX indicators */
489 wl->ba_rx_bitmap = 0; 489 wl->ba_rx_bitmap = 0;
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 61dea73f5fdc..947491a1d9cc 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -482,6 +482,10 @@ static int wl1271_plt_init(struct wl1271 *wl)
482 if (ret < 0) 482 if (ret < 0)
483 goto out_free_memmap; 483 goto out_free_memmap;
484 484
485 ret = wl1271_acx_sta_mem_cfg(wl);
486 if (ret < 0)
487 goto out_free_memmap;
488
485 /* Default fragmentation threshold */ 489 /* Default fragmentation threshold */
486 ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold); 490 ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
487 if (ret < 0) 491 if (ret < 0)
@@ -533,6 +537,57 @@ static int wl1271_plt_init(struct wl1271 *wl)
533 return ret; 537 return ret;
534} 538}
535 539
540static void wl1271_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_blks)
541{
542 bool fw_ps;
543
544 /* only regulate station links */
545 if (hlid < WL1271_AP_STA_HLID_START)
546 return;
547
548 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
549
550 /*
551 * Wake up from high level PS if the STA is asleep with too little
552 * blocks in FW or if the STA is awake.
553 */
554 if (!fw_ps || tx_blks < WL1271_PS_STA_MAX_BLOCKS)
555 wl1271_ps_link_end(wl, hlid);
556
557 /* Start high-level PS if the STA is asleep with enough blocks in FW */
558 else if (fw_ps && tx_blks >= WL1271_PS_STA_MAX_BLOCKS)
559 wl1271_ps_link_start(wl, hlid, true);
560}
561
562static void wl1271_irq_update_links_status(struct wl1271 *wl,
563 struct wl1271_fw_ap_status *status)
564{
565 u32 cur_fw_ps_map;
566 u8 hlid;
567
568 cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap);
569 if (wl->ap_fw_ps_map != cur_fw_ps_map) {
570 wl1271_debug(DEBUG_PSM,
571 "link ps prev 0x%x cur 0x%x changed 0x%x",
572 wl->ap_fw_ps_map, cur_fw_ps_map,
573 wl->ap_fw_ps_map ^ cur_fw_ps_map);
574
575 wl->ap_fw_ps_map = cur_fw_ps_map;
576 }
577
578 for (hlid = WL1271_AP_STA_HLID_START; hlid < AP_MAX_LINKS; hlid++) {
579 u8 cnt = status->tx_lnk_free_blks[hlid] -
580 wl->links[hlid].prev_freed_blks;
581
582 wl->links[hlid].prev_freed_blks =
583 status->tx_lnk_free_blks[hlid];
584 wl->links[hlid].allocated_blks -= cnt;
585
586 wl1271_irq_ps_regulate_link(wl, hlid,
587 wl->links[hlid].allocated_blks);
588 }
589}
590
536static void wl1271_fw_status(struct wl1271 *wl, 591static void wl1271_fw_status(struct wl1271 *wl,
537 struct wl1271_fw_full_status *full_status) 592 struct wl1271_fw_full_status *full_status)
538{ 593{
@@ -570,6 +625,10 @@ static void wl1271_fw_status(struct wl1271 *wl,
570 if (total) 625 if (total)
571 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); 626 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
572 627
628 /* for AP update num of allocated TX blocks per link and ps status */
629 if (wl->bss_type == BSS_TYPE_AP_BSS)
630 wl1271_irq_update_links_status(wl, &full_status->ap);
631
573 /* update the host-chipset time offset */ 632 /* update the host-chipset time offset */
574 getnstimeofday(&ts); 633 getnstimeofday(&ts);
575 wl->time_offset = (timespec_to_ns(&ts) >> 10) - 634 wl->time_offset = (timespec_to_ns(&ts) >> 10) -
@@ -975,19 +1034,37 @@ int wl1271_plt_stop(struct wl1271 *wl)
975 return ret; 1034 return ret;
976} 1035}
977 1036
978static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 1037static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
979{ 1038{
980 struct wl1271 *wl = hw->priv; 1039 struct wl1271 *wl = hw->priv;
981 unsigned long flags; 1040 unsigned long flags;
982 int q; 1041 int q;
1042 u8 hlid = 0;
983 1043
984 spin_lock_irqsave(&wl->wl_lock, flags); 1044 spin_lock_irqsave(&wl->wl_lock, flags);
985 wl->tx_queue_count++; 1045 wl->tx_queue_count++;
1046
1047 /*
1048 * The workqueue is slow to process the tx_queue and we need stop
1049 * the queue here, otherwise the queue will get too long.
1050 */
1051 if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
1052 wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
1053 ieee80211_stop_queues(wl->hw);
1054 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
1055 }
1056
986 spin_unlock_irqrestore(&wl->wl_lock, flags); 1057 spin_unlock_irqrestore(&wl->wl_lock, flags);
987 1058
988 /* queue the packet */ 1059 /* queue the packet */
989 q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 1060 q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
990 skb_queue_tail(&wl->tx_queue[q], skb); 1061 if (wl->bss_type == BSS_TYPE_AP_BSS) {
1062 hlid = wl1271_tx_get_hlid(skb);
1063 wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q);
1064 skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);
1065 } else {
1066 skb_queue_tail(&wl->tx_queue[q], skb);
1067 }
991 1068
992 /* 1069 /*
993 * The chip specific setup must run before the first TX packet - 1070 * The chip specific setup must run before the first TX packet -
@@ -996,21 +1073,6 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
996 1073
997 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) 1074 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
998 ieee80211_queue_work(wl->hw, &wl->tx_work); 1075 ieee80211_queue_work(wl->hw, &wl->tx_work);
999
1000 /*
1001 * The workqueue is slow to process the tx_queue and we need stop
1002 * the queue here, otherwise the queue will get too long.
1003 */
1004 if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
1005 wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
1006
1007 spin_lock_irqsave(&wl->wl_lock, flags);
1008 ieee80211_stop_queues(wl->hw);
1009 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
1010 spin_unlock_irqrestore(&wl->wl_lock, flags);
1011 }
1012
1013 return NETDEV_TX_OK;
1014} 1076}
1015 1077
1016static struct notifier_block wl1271_dev_notifier = { 1078static struct notifier_block wl1271_dev_notifier = {
@@ -1221,6 +1283,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
1221 wl->filters = 0; 1283 wl->filters = 0;
1222 wl1271_free_ap_keys(wl); 1284 wl1271_free_ap_keys(wl);
1223 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); 1285 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
1286 wl->ap_fw_ps_map = 0;
1287 wl->ap_ps_map = 0;
1224 1288
1225 for (i = 0; i < NUM_TX_QUEUES; i++) 1289 for (i = 0; i < NUM_TX_QUEUES; i++)
1226 wl->tx_blocks_freed[i] = 0; 1290 wl->tx_blocks_freed[i] = 0;
@@ -2218,6 +2282,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2218 u32 sta_rate_set = 0; 2282 u32 sta_rate_set = 0;
2219 int ret; 2283 int ret;
2220 struct ieee80211_sta *sta; 2284 struct ieee80211_sta *sta;
2285 bool sta_exists = false;
2286 struct ieee80211_sta_ht_cap sta_ht_cap;
2221 2287
2222 if (is_ibss) { 2288 if (is_ibss) {
2223 ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, 2289 ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf,
@@ -2289,16 +2355,20 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2289 if (sta->ht_cap.ht_supported) 2355 if (sta->ht_cap.ht_supported)
2290 sta_rate_set |= 2356 sta_rate_set |=
2291 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); 2357 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
2358 sta_ht_cap = sta->ht_cap;
2359 sta_exists = true;
2360 }
2361 rcu_read_unlock();
2292 2362
2363 if (sta_exists) {
2293 /* handle new association with HT and HT information change */ 2364 /* handle new association with HT and HT information change */
2294 if ((changed & BSS_CHANGED_HT) && 2365 if ((changed & BSS_CHANGED_HT) &&
2295 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { 2366 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
2296 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, 2367 ret = wl1271_acx_set_ht_capabilities(wl, &sta_ht_cap,
2297 true); 2368 true);
2298 if (ret < 0) { 2369 if (ret < 0) {
2299 wl1271_warning("Set ht cap true failed %d", 2370 wl1271_warning("Set ht cap true failed %d",
2300 ret); 2371 ret);
2301 rcu_read_unlock();
2302 goto out; 2372 goto out;
2303 } 2373 }
2304 ret = wl1271_acx_set_ht_information(wl, 2374 ret = wl1271_acx_set_ht_information(wl,
@@ -2306,23 +2376,20 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2306 if (ret < 0) { 2376 if (ret < 0) {
2307 wl1271_warning("Set ht information failed %d", 2377 wl1271_warning("Set ht information failed %d",
2308 ret); 2378 ret);
2309 rcu_read_unlock();
2310 goto out; 2379 goto out;
2311 } 2380 }
2312 } 2381 }
2313 /* handle new association without HT and disassociation */ 2382 /* handle new association without HT and disassociation */
2314 else if (changed & BSS_CHANGED_ASSOC) { 2383 else if (changed & BSS_CHANGED_ASSOC) {
2315 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, 2384 ret = wl1271_acx_set_ht_capabilities(wl, &sta_ht_cap,
2316 false); 2385 false);
2317 if (ret < 0) { 2386 if (ret < 0) {
2318 wl1271_warning("Set ht cap false failed %d", 2387 wl1271_warning("Set ht cap false failed %d",
2319 ret); 2388 ret);
2320 rcu_read_unlock();
2321 goto out; 2389 goto out;
2322 } 2390 }
2323 } 2391 }
2324 } 2392 }
2325 rcu_read_unlock();
2326 2393
2327 if ((changed & BSS_CHANGED_ASSOC)) { 2394 if ((changed & BSS_CHANGED_ASSOC)) {
2328 if (bss_conf->assoc) { 2395 if (bss_conf->assoc) {
@@ -2612,7 +2679,7 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
2612 return 0; 2679 return 0;
2613} 2680}
2614 2681
2615static int wl1271_allocate_hlid(struct wl1271 *wl, 2682static int wl1271_allocate_sta(struct wl1271 *wl,
2616 struct ieee80211_sta *sta, 2683 struct ieee80211_sta *sta,
2617 u8 *hlid) 2684 u8 *hlid)
2618{ 2685{
@@ -2626,18 +2693,25 @@ static int wl1271_allocate_hlid(struct wl1271 *wl,
2626 } 2693 }
2627 2694
2628 wl_sta = (struct wl1271_station *)sta->drv_priv; 2695 wl_sta = (struct wl1271_station *)sta->drv_priv;
2629
2630 __set_bit(id, wl->ap_hlid_map); 2696 __set_bit(id, wl->ap_hlid_map);
2631 wl_sta->hlid = WL1271_AP_STA_HLID_START + id; 2697 wl_sta->hlid = WL1271_AP_STA_HLID_START + id;
2632 *hlid = wl_sta->hlid; 2698 *hlid = wl_sta->hlid;
2699 memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
2633 return 0; 2700 return 0;
2634} 2701}
2635 2702
2636static void wl1271_free_hlid(struct wl1271 *wl, u8 hlid) 2703static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
2637{ 2704{
2638 int id = hlid - WL1271_AP_STA_HLID_START; 2705 int id = hlid - WL1271_AP_STA_HLID_START;
2639 2706
2707 if (WARN_ON(!test_bit(id, wl->ap_hlid_map)))
2708 return;
2709
2640 __clear_bit(id, wl->ap_hlid_map); 2710 __clear_bit(id, wl->ap_hlid_map);
2711 memset(wl->links[hlid].addr, 0, ETH_ALEN);
2712 wl1271_tx_reset_link_queues(wl, hlid);
2713 __clear_bit(hlid, &wl->ap_ps_map);
2714 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
2641} 2715}
2642 2716
2643static int wl1271_op_sta_add(struct ieee80211_hw *hw, 2717static int wl1271_op_sta_add(struct ieee80211_hw *hw,
@@ -2658,13 +2732,13 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw,
2658 2732
2659 wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); 2733 wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid);
2660 2734
2661 ret = wl1271_allocate_hlid(wl, sta, &hlid); 2735 ret = wl1271_allocate_sta(wl, sta, &hlid);
2662 if (ret < 0) 2736 if (ret < 0)
2663 goto out; 2737 goto out;
2664 2738
2665 ret = wl1271_ps_elp_wakeup(wl, false); 2739 ret = wl1271_ps_elp_wakeup(wl, false);
2666 if (ret < 0) 2740 if (ret < 0)
2667 goto out; 2741 goto out_free_sta;
2668 2742
2669 ret = wl1271_cmd_add_sta(wl, sta, hlid); 2743 ret = wl1271_cmd_add_sta(wl, sta, hlid);
2670 if (ret < 0) 2744 if (ret < 0)
@@ -2673,6 +2747,10 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw,
2673out_sleep: 2747out_sleep:
2674 wl1271_ps_elp_sleep(wl); 2748 wl1271_ps_elp_sleep(wl);
2675 2749
2750out_free_sta:
2751 if (ret < 0)
2752 wl1271_free_sta(wl, hlid);
2753
2676out: 2754out:
2677 mutex_unlock(&wl->mutex); 2755 mutex_unlock(&wl->mutex);
2678 return ret; 2756 return ret;
@@ -2709,7 +2787,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
2709 if (ret < 0) 2787 if (ret < 0)
2710 goto out_sleep; 2788 goto out_sleep;
2711 2789
2712 wl1271_free_hlid(wl, wl_sta->hlid); 2790 wl1271_free_sta(wl, wl_sta->hlid);
2713 2791
2714out_sleep: 2792out_sleep:
2715 wl1271_ps_elp_sleep(wl); 2793 wl1271_ps_elp_sleep(wl);
@@ -3212,7 +3290,9 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
3212 IEEE80211_HW_SUPPORTS_UAPSD | 3290 IEEE80211_HW_SUPPORTS_UAPSD |
3213 IEEE80211_HW_HAS_RATE_CONTROL | 3291 IEEE80211_HW_HAS_RATE_CONTROL |
3214 IEEE80211_HW_CONNECTION_MONITOR | 3292 IEEE80211_HW_CONNECTION_MONITOR |
3215 IEEE80211_HW_SUPPORTS_CQM_RSSI; 3293 IEEE80211_HW_SUPPORTS_CQM_RSSI |
3294 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
3295 IEEE80211_HW_AP_LINK_PS;
3216 3296
3217 wl->hw->wiphy->cipher_suites = cipher_suites; 3297 wl->hw->wiphy->cipher_suites = cipher_suites;
3218 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 3298 wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
@@ -3264,7 +3344,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3264 struct ieee80211_hw *hw; 3344 struct ieee80211_hw *hw;
3265 struct platform_device *plat_dev = NULL; 3345 struct platform_device *plat_dev = NULL;
3266 struct wl1271 *wl; 3346 struct wl1271 *wl;
3267 int i, ret; 3347 int i, j, ret;
3268 unsigned int order; 3348 unsigned int order;
3269 3349
3270 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 3350 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
@@ -3292,6 +3372,10 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3292 for (i = 0; i < NUM_TX_QUEUES; i++) 3372 for (i = 0; i < NUM_TX_QUEUES; i++)
3293 skb_queue_head_init(&wl->tx_queue[i]); 3373 skb_queue_head_init(&wl->tx_queue[i]);
3294 3374
3375 for (i = 0; i < NUM_TX_QUEUES; i++)
3376 for (j = 0; j < AP_MAX_LINKS; j++)
3377 skb_queue_head_init(&wl->links[j].tx_queue[i]);
3378
3295 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 3379 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
3296 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); 3380 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
3297 INIT_WORK(&wl->irq_work, wl1271_irq_work); 3381 INIT_WORK(&wl->irq_work, wl1271_irq_work);
@@ -3317,6 +3401,9 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3317 wl->bss_type = MAX_BSS_TYPE; 3401 wl->bss_type = MAX_BSS_TYPE;
3318 wl->set_bss_type = MAX_BSS_TYPE; 3402 wl->set_bss_type = MAX_BSS_TYPE;
3319 wl->fw_bss_type = MAX_BSS_TYPE; 3403 wl->fw_bss_type = MAX_BSS_TYPE;
3404 wl->last_tx_hlid = 0;
3405 wl->ap_ps_map = 0;
3406 wl->ap_fw_ps_map = 0;
3320 3407
3321 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); 3408 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
3322 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 3409 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
@@ -3412,5 +3499,5 @@ module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR);
3412MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); 3499MODULE_PARM_DESC(debug_level, "wl12xx debugging level");
3413 3500
3414MODULE_LICENSE("GPL"); 3501MODULE_LICENSE("GPL");
3415MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); 3502MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
3416MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 3503MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 2d3086ae6338..5c347b1bd17f 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -24,6 +24,7 @@
24#include "reg.h" 24#include "reg.h"
25#include "ps.h" 25#include "ps.h"
26#include "io.h" 26#include "io.h"
27#include "tx.h"
27 28
28#define WL1271_WAKEUP_TIMEOUT 500 29#define WL1271_WAKEUP_TIMEOUT 500
29 30
@@ -173,4 +174,81 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
173 return ret; 174 return ret;
174} 175}
175 176
177static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
178{
179 int i, filtered = 0;
180 struct sk_buff *skb;
181 struct ieee80211_tx_info *info;
182 unsigned long flags;
183
184 /* filter all frames currently the low level queus for this hlid */
185 for (i = 0; i < NUM_TX_QUEUES; i++) {
186 while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) {
187 info = IEEE80211_SKB_CB(skb);
188 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
189 info->status.rates[0].idx = -1;
190 ieee80211_tx_status(wl->hw, skb);
191 filtered++;
192 }
193 }
194
195 spin_lock_irqsave(&wl->wl_lock, flags);
196 wl->tx_queue_count -= filtered;
197 spin_unlock_irqrestore(&wl->wl_lock, flags);
198
199 wl1271_handle_tx_low_watermark(wl);
200}
201
202void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues)
203{
204 struct ieee80211_sta *sta;
205
206 if (test_bit(hlid, &wl->ap_ps_map))
207 return;
208
209 wl1271_debug(DEBUG_PSM, "start mac80211 PSM on hlid %d blks %d "
210 "clean_queues %d", hlid, wl->links[hlid].allocated_blks,
211 clean_queues);
212
213 rcu_read_lock();
214 sta = ieee80211_find_sta(wl->vif, wl->links[hlid].addr);
215 if (!sta) {
216 wl1271_error("could not find sta %pM for starting ps",
217 wl->links[hlid].addr);
218 rcu_read_unlock();
219 return;
220 }
176 221
222 ieee80211_sta_ps_transition_ni(sta, true);
223 rcu_read_unlock();
224
225 /* do we want to filter all frames from this link's queues? */
226 if (clean_queues)
227 wl1271_ps_filter_frames(wl, hlid);
228
229 __set_bit(hlid, &wl->ap_ps_map);
230}
231
232void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid)
233{
234 struct ieee80211_sta *sta;
235
236 if (!test_bit(hlid, &wl->ap_ps_map))
237 return;
238
239 wl1271_debug(DEBUG_PSM, "end mac80211 PSM on hlid %d", hlid);
240
241 __clear_bit(hlid, &wl->ap_ps_map);
242
243 rcu_read_lock();
244 sta = ieee80211_find_sta(wl->vif, wl->links[hlid].addr);
245 if (!sta) {
246 wl1271_error("could not find sta %pM for ending ps",
247 wl->links[hlid].addr);
248 goto end;
249 }
250
251 ieee80211_sta_ps_transition_ni(sta, false);
252end:
253 rcu_read_unlock();
254}
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
index 8415060f08e5..fc1f4c193593 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -32,5 +32,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
32void wl1271_ps_elp_sleep(struct wl1271 *wl); 32void wl1271_ps_elp_sleep(struct wl1271 *wl);
33int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); 33int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
34void wl1271_elp_work(struct work_struct *work); 34void wl1271_elp_work(struct work_struct *work);
35void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues);
36void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid);
35 37
36#endif /* __WL1271_PS_H__ */ 38#endif /* __WL1271_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 00d250d8da18..3d13d7a83ea1 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -92,7 +92,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
92{ 92{
93 struct wl1271_rx_descriptor *desc; 93 struct wl1271_rx_descriptor *desc;
94 struct sk_buff *skb; 94 struct sk_buff *skb;
95 u16 *fc; 95 struct ieee80211_hdr *hdr;
96 u8 *buf; 96 u8 *buf;
97 u8 beacon = 0; 97 u8 beacon = 0;
98 98
@@ -118,8 +118,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
118 /* now we pull the descriptor out of the buffer */ 118 /* now we pull the descriptor out of the buffer */
119 skb_pull(skb, sizeof(*desc)); 119 skb_pull(skb, sizeof(*desc));
120 120
121 fc = (u16 *)skb->data; 121 hdr = (struct ieee80211_hdr *)skb->data;
122 if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) 122 if (ieee80211_is_beacon(hdr->frame_control))
123 beacon = 1; 123 beacon = 1;
124 124
125 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); 125 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
index 4cef8fa3dee1..75fabf836491 100644
--- a/drivers/net/wireless/wl12xx/rx.h
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -30,10 +30,6 @@
30#define WL1271_RX_MAX_RSSI -30 30#define WL1271_RX_MAX_RSSI -30
31#define WL1271_RX_MIN_RSSI -95 31#define WL1271_RX_MIN_RSSI -95
32 32
33#define WL1271_RX_ALIGN_TO 4
34#define WL1271_RX_ALIGN(len) (((len) + WL1271_RX_ALIGN_TO - 1) & \
35 ~(WL1271_RX_ALIGN_TO - 1))
36
37#define SHORT_PREAMBLE_BIT BIT(0) 33#define SHORT_PREAMBLE_BIT BIT(0)
38#define OFDM_RATE_BIT BIT(6) 34#define OFDM_RATE_BIT BIT(6)
39#define PBCC_RATE_BIT BIT(7) 35#define PBCC_RATE_BIT BIT(7)
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 67a00946e3dd..ac60d577319f 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -70,8 +70,65 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id)
70 } 70 }
71} 71}
72 72
73static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
74 struct sk_buff *skb)
75{
76 struct ieee80211_hdr *hdr;
77
78 /*
79 * add the station to the known list before transmitting the
80 * authentication response. this way it won't get de-authed by FW
81 * when transmitting too soon.
82 */
83 hdr = (struct ieee80211_hdr *)(skb->data +
84 sizeof(struct wl1271_tx_hw_descr));
85 if (ieee80211_is_auth(hdr->frame_control))
86 wl1271_acx_set_inconnection_sta(wl, hdr->addr1);
87}
88
89static void wl1271_tx_regulate_link(struct wl1271 *wl, u8 hlid)
90{
91 bool fw_ps;
92 u8 tx_blks;
93
94 /* only regulate station links */
95 if (hlid < WL1271_AP_STA_HLID_START)
96 return;
97
98 fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
99 tx_blks = wl->links[hlid].allocated_blks;
100
101 /*
102 * if in FW PS and there is enough data in FW we can put the link
103 * into high-level PS and clean out its TX queues.
104 */
105 if (fw_ps && tx_blks >= WL1271_PS_STA_MAX_BLOCKS)
106 wl1271_ps_link_start(wl, hlid, true);
107}
108
109u8 wl1271_tx_get_hlid(struct sk_buff *skb)
110{
111 struct ieee80211_tx_info *control = IEEE80211_SKB_CB(skb);
112
113 if (control->control.sta) {
114 struct wl1271_station *wl_sta;
115
116 wl_sta = (struct wl1271_station *)
117 control->control.sta->drv_priv;
118 return wl_sta->hlid;
119 } else {
120 struct ieee80211_hdr *hdr;
121
122 hdr = (struct ieee80211_hdr *)skb->data;
123 if (ieee80211_is_mgmt(hdr->frame_control))
124 return WL1271_AP_GLOBAL_HLID;
125 else
126 return WL1271_AP_BROADCAST_HLID;
127 }
128}
129
73static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, 130static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
74 u32 buf_offset) 131 u32 buf_offset, u8 hlid)
75{ 132{
76 struct wl1271_tx_hw_descr *desc; 133 struct wl1271_tx_hw_descr *desc;
77 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; 134 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
@@ -100,6 +157,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
100 157
101 wl->tx_blocks_available -= total_blocks; 158 wl->tx_blocks_available -= total_blocks;
102 159
160 if (wl->bss_type == BSS_TYPE_AP_BSS)
161 wl->links[hlid].allocated_blks += total_blocks;
162
103 ret = 0; 163 ret = 0;
104 164
105 wl1271_debug(DEBUG_TX, 165 wl1271_debug(DEBUG_TX,
@@ -113,7 +173,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
113} 173}
114 174
115static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, 175static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
116 u32 extra, struct ieee80211_tx_info *control) 176 u32 extra, struct ieee80211_tx_info *control,
177 u8 hlid)
117{ 178{
118 struct timespec ts; 179 struct timespec ts;
119 struct wl1271_tx_hw_descr *desc; 180 struct wl1271_tx_hw_descr *desc;
@@ -149,7 +210,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
149 desc->tid = ac; 210 desc->tid = ac;
150 211
151 if (wl->bss_type != BSS_TYPE_AP_BSS) { 212 if (wl->bss_type != BSS_TYPE_AP_BSS) {
152 desc->aid = TX_HW_DEFAULT_AID; 213 desc->aid = hlid;
153 214
154 /* if the packets are destined for AP (have a STA entry) 215 /* if the packets are destined for AP (have a STA entry)
155 send them with AP rate policies, otherwise use default 216 send them with AP rate policies, otherwise use default
@@ -159,25 +220,17 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
159 else 220 else
160 rate_idx = ACX_TX_BASIC_RATE; 221 rate_idx = ACX_TX_BASIC_RATE;
161 } else { 222 } else {
162 if (control->control.sta) { 223 desc->hlid = hlid;
163 struct wl1271_station *wl_sta; 224 switch (hlid) {
164 225 case WL1271_AP_GLOBAL_HLID:
165 wl_sta = (struct wl1271_station *) 226 rate_idx = ACX_TX_AP_MODE_MGMT_RATE;
166 control->control.sta->drv_priv; 227 break;
167 desc->hlid = wl_sta->hlid; 228 case WL1271_AP_BROADCAST_HLID:
229 rate_idx = ACX_TX_AP_MODE_BCST_RATE;
230 break;
231 default:
168 rate_idx = ac; 232 rate_idx = ac;
169 } else { 233 break;
170 struct ieee80211_hdr *hdr;
171
172 hdr = (struct ieee80211_hdr *)
173 (skb->data + sizeof(*desc));
174 if (ieee80211_is_mgmt(hdr->frame_control)) {
175 desc->hlid = WL1271_AP_GLOBAL_HLID;
176 rate_idx = ACX_TX_AP_MODE_MGMT_RATE;
177 } else {
178 desc->hlid = WL1271_AP_BROADCAST_HLID;
179 rate_idx = ACX_TX_AP_MODE_BCST_RATE;
180 }
181 } 234 }
182 } 235 }
183 236
@@ -185,7 +238,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
185 desc->reserved = 0; 238 desc->reserved = 0;
186 239
187 /* align the length (and store in terms of words) */ 240 /* align the length (and store in terms of words) */
188 pad = WL1271_TX_ALIGN(skb->len); 241 pad = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
189 desc->length = cpu_to_le16(pad >> 2); 242 desc->length = cpu_to_le16(pad >> 2);
190 243
191 /* calculate number of padding bytes */ 244 /* calculate number of padding bytes */
@@ -208,6 +261,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
208 u32 extra = 0; 261 u32 extra = 0;
209 int ret = 0; 262 int ret = 0;
210 u32 total_len; 263 u32 total_len;
264 u8 hlid;
211 265
212 if (!skb) 266 if (!skb)
213 return -EINVAL; 267 return -EINVAL;
@@ -234,18 +288,28 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
234 } 288 }
235 } 289 }
236 290
237 ret = wl1271_tx_allocate(wl, skb, extra, buf_offset); 291 if (wl->bss_type == BSS_TYPE_AP_BSS)
292 hlid = wl1271_tx_get_hlid(skb);
293 else
294 hlid = TX_HW_DEFAULT_AID;
295
296 ret = wl1271_tx_allocate(wl, skb, extra, buf_offset, hlid);
238 if (ret < 0) 297 if (ret < 0)
239 return ret; 298 return ret;
240 299
241 wl1271_tx_fill_hdr(wl, skb, extra, info); 300 if (wl->bss_type == BSS_TYPE_AP_BSS) {
301 wl1271_tx_ap_update_inconnection_sta(wl, skb);
302 wl1271_tx_regulate_link(wl, hlid);
303 }
304
305 wl1271_tx_fill_hdr(wl, skb, extra, info, hlid);
242 306
243 /* 307 /*
244 * The length of each packet is stored in terms of words. Thus, we must 308 * The length of each packet is stored in terms of words. Thus, we must
245 * pad the skb data to make sure its length is aligned. 309 * pad the skb data to make sure its length is aligned.
246 * The number of padding bytes is computed and set in wl1271_tx_fill_hdr 310 * The number of padding bytes is computed and set in wl1271_tx_fill_hdr
247 */ 311 */
248 total_len = WL1271_TX_ALIGN(skb->len); 312 total_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
249 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); 313 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
250 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); 314 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
251 315
@@ -279,7 +343,7 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
279 return enabled_rates; 343 return enabled_rates;
280} 344}
281 345
282static void handle_tx_low_watermark(struct wl1271 *wl) 346void wl1271_handle_tx_low_watermark(struct wl1271 *wl)
283{ 347{
284 unsigned long flags; 348 unsigned long flags;
285 349
@@ -293,7 +357,7 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
293 } 357 }
294} 358}
295 359
296static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) 360static struct sk_buff *wl1271_sta_skb_dequeue(struct wl1271 *wl)
297{ 361{
298 struct sk_buff *skb = NULL; 362 struct sk_buff *skb = NULL;
299 unsigned long flags; 363 unsigned long flags;
@@ -319,12 +383,69 @@ out:
319 return skb; 383 return skb;
320} 384}
321 385
386static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl)
387{
388 struct sk_buff *skb = NULL;
389 unsigned long flags;
390 int i, h, start_hlid;
391
392 /* start from the link after the last one */
393 start_hlid = (wl->last_tx_hlid + 1) % AP_MAX_LINKS;
394
395 /* dequeue according to AC, round robin on each link */
396 for (i = 0; i < AP_MAX_LINKS; i++) {
397 h = (start_hlid + i) % AP_MAX_LINKS;
398
399 skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VO]);
400 if (skb)
401 goto out;
402 skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VI]);
403 if (skb)
404 goto out;
405 skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BE]);
406 if (skb)
407 goto out;
408 skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BK]);
409 if (skb)
410 goto out;
411 }
412
413out:
414 if (skb) {
415 wl->last_tx_hlid = h;
416 spin_lock_irqsave(&wl->wl_lock, flags);
417 wl->tx_queue_count--;
418 spin_unlock_irqrestore(&wl->wl_lock, flags);
419 } else {
420 wl->last_tx_hlid = 0;
421 }
422
423 return skb;
424}
425
426static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
427{
428 if (wl->bss_type == BSS_TYPE_AP_BSS)
429 return wl1271_ap_skb_dequeue(wl);
430
431 return wl1271_sta_skb_dequeue(wl);
432}
433
322static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) 434static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
323{ 435{
324 unsigned long flags; 436 unsigned long flags;
325 int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 437 int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
326 438
327 skb_queue_head(&wl->tx_queue[q], skb); 439 if (wl->bss_type == BSS_TYPE_AP_BSS) {
440 u8 hlid = wl1271_tx_get_hlid(skb);
441 skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
442
443 /* make sure we dequeue the same packet next time */
444 wl->last_tx_hlid = (hlid + AP_MAX_LINKS - 1) % AP_MAX_LINKS;
445 } else {
446 skb_queue_head(&wl->tx_queue[q], skb);
447 }
448
328 spin_lock_irqsave(&wl->wl_lock, flags); 449 spin_lock_irqsave(&wl->wl_lock, flags);
329 wl->tx_queue_count++; 450 wl->tx_queue_count++;
330 spin_unlock_irqrestore(&wl->wl_lock, flags); 451 spin_unlock_irqrestore(&wl->wl_lock, flags);
@@ -387,7 +508,7 @@ out_ack:
387 if (sent_packets) { 508 if (sent_packets) {
388 /* interrupt the firmware with the new packets */ 509 /* interrupt the firmware with the new packets */
389 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); 510 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
390 handle_tx_low_watermark(wl); 511 wl1271_handle_tx_low_watermark(wl);
391 } 512 }
392 513
393out: 514out:
@@ -504,32 +625,76 @@ void wl1271_tx_complete(struct wl1271 *wl)
504 } 625 }
505} 626}
506 627
628void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
629{
630 struct sk_buff *skb;
631 int i, total = 0;
632 unsigned long flags;
633 struct ieee80211_tx_info *info;
634
635 for (i = 0; i < NUM_TX_QUEUES; i++) {
636 while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) {
637 wl1271_debug(DEBUG_TX, "link freeing skb 0x%p", skb);
638 info = IEEE80211_SKB_CB(skb);
639 info->status.rates[0].idx = -1;
640 info->status.rates[0].count = 0;
641 ieee80211_tx_status(wl->hw, skb);
642 total++;
643 }
644 }
645
646 spin_lock_irqsave(&wl->wl_lock, flags);
647 wl->tx_queue_count -= total;
648 spin_unlock_irqrestore(&wl->wl_lock, flags);
649
650 wl1271_handle_tx_low_watermark(wl);
651}
652
507/* caller must hold wl->mutex */ 653/* caller must hold wl->mutex */
508void wl1271_tx_reset(struct wl1271 *wl) 654void wl1271_tx_reset(struct wl1271 *wl)
509{ 655{
510 int i; 656 int i;
511 struct sk_buff *skb; 657 struct sk_buff *skb;
658 struct ieee80211_tx_info *info;
512 659
513 /* TX failure */ 660 /* TX failure */
514 for (i = 0; i < NUM_TX_QUEUES; i++) { 661 if (wl->bss_type == BSS_TYPE_AP_BSS) {
515 while ((skb = skb_dequeue(&wl->tx_queue[i]))) { 662 for (i = 0; i < AP_MAX_LINKS; i++) {
516 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); 663 wl1271_tx_reset_link_queues(wl, i);
517 ieee80211_tx_status(wl->hw, skb); 664 wl->links[i].allocated_blks = 0;
665 wl->links[i].prev_freed_blks = 0;
666 }
667
668 wl->last_tx_hlid = 0;
669 } else {
670 for (i = 0; i < NUM_TX_QUEUES; i++) {
671 while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
672 wl1271_debug(DEBUG_TX, "freeing skb 0x%p",
673 skb);
674 info = IEEE80211_SKB_CB(skb);
675 info->status.rates[0].idx = -1;
676 info->status.rates[0].count = 0;
677 ieee80211_tx_status(wl->hw, skb);
678 }
518 } 679 }
519 } 680 }
681
520 wl->tx_queue_count = 0; 682 wl->tx_queue_count = 0;
521 683
522 /* 684 /*
523 * Make sure the driver is at a consistent state, in case this 685 * Make sure the driver is at a consistent state, in case this
524 * function is called from a context other than interface removal. 686 * function is called from a context other than interface removal.
525 */ 687 */
526 handle_tx_low_watermark(wl); 688 wl1271_handle_tx_low_watermark(wl);
527 689
528 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 690 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
529 if (wl->tx_frames[i] != NULL) { 691 if (wl->tx_frames[i] != NULL) {
530 skb = wl->tx_frames[i]; 692 skb = wl->tx_frames[i];
531 wl1271_free_tx_id(wl, i); 693 wl1271_free_tx_id(wl, i);
532 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); 694 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
695 info = IEEE80211_SKB_CB(skb);
696 info->status.rates[0].idx = -1;
697 info->status.rates[0].count = 0;
533 ieee80211_tx_status(wl->hw, skb); 698 ieee80211_tx_status(wl->hw, skb);
534 } 699 }
535} 700}
@@ -544,8 +709,8 @@ void wl1271_tx_flush(struct wl1271 *wl)
544 709
545 while (!time_after(jiffies, timeout)) { 710 while (!time_after(jiffies, timeout)) {
546 mutex_lock(&wl->mutex); 711 mutex_lock(&wl->mutex);
547 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", 712 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d",
548 wl->tx_frames_cnt); 713 wl->tx_frames_cnt, wl->tx_queue_count);
549 if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) { 714 if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) {
550 mutex_unlock(&wl->mutex); 715 mutex_unlock(&wl->mutex);
551 return; 716 return;
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
index 05722a560d91..02f07fa66e82 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -53,8 +53,6 @@
53#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf 53#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf
54 54
55#define WL1271_TX_ALIGN_TO 4 55#define WL1271_TX_ALIGN_TO 4
56#define WL1271_TX_ALIGN(len) (((len) + WL1271_TX_ALIGN_TO - 1) & \
57 ~(WL1271_TX_ALIGN_TO - 1))
58#define WL1271_TKIP_IV_SPACE 4 56#define WL1271_TKIP_IV_SPACE 4
59 57
60struct wl1271_tx_hw_descr { 58struct wl1271_tx_hw_descr {
@@ -152,5 +150,8 @@ void wl1271_tx_flush(struct wl1271 *wl);
152u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 150u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
153u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); 151u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
154u32 wl1271_tx_min_rate_get(struct wl1271 *wl); 152u32 wl1271_tx_min_rate_get(struct wl1271 *wl);
153u8 wl1271_tx_get_hlid(struct sk_buff *skb);
154void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
155void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
155 156
156#endif 157#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 1d6c94304b1a..338acc9f60b3 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -153,6 +153,17 @@ extern u32 wl12xx_debug_level;
153#define WL1271_AP_BROADCAST_HLID 1 153#define WL1271_AP_BROADCAST_HLID 1
154#define WL1271_AP_STA_HLID_START 2 154#define WL1271_AP_STA_HLID_START 2
155 155
156/*
157 * When in AP-mode, we allow (at least) this number of mem-blocks
158 * to be transmitted to FW for a STA in PS-mode. Only when packets are
159 * present in the FW buffers it will wake the sleeping STA. We want to put
160 * enough packets for the driver to transmit all of its buffered data before
161 * the STA goes to sleep again. But we don't want to take too much mem-blocks
162 * as it might hurt the throughput of active STAs.
163 * The number of blocks (18) is enough for 2 large packets.
164 */
165#define WL1271_PS_STA_MAX_BLOCKS (2 * 9)
166
156#define WL1271_AP_BSS_INDEX 0 167#define WL1271_AP_BSS_INDEX 0
157#define WL1271_AP_DEF_INACTIV_SEC 300 168#define WL1271_AP_DEF_INACTIV_SEC 300
158#define WL1271_AP_DEF_BEACON_EXP 20 169#define WL1271_AP_DEF_BEACON_EXP 20
@@ -319,6 +330,17 @@ enum wl12xx_flags {
319 WL1271_FLAG_AP_STARTED 330 WL1271_FLAG_AP_STARTED
320}; 331};
321 332
333struct wl1271_link {
334 /* AP-mode - TX queue per AC in link */
335 struct sk_buff_head tx_queue[NUM_TX_QUEUES];
336
337 /* accounting for allocated / available TX blocks in FW */
338 u8 allocated_blks;
339 u8 prev_freed_blks;
340
341 u8 addr[ETH_ALEN];
342};
343
322struct wl1271 { 344struct wl1271 {
323 struct platform_device *plat_dev; 345 struct platform_device *plat_dev;
324 struct ieee80211_hw *hw; 346 struct ieee80211_hw *hw;
@@ -498,6 +520,21 @@ struct wl1271 {
498 /* RX BA constraint value */ 520 /* RX BA constraint value */
499 bool ba_support; 521 bool ba_support;
500 u8 ba_rx_bitmap; 522 u8 ba_rx_bitmap;
523
524 /*
525 * AP-mode - links indexed by HLID. The global and broadcast links
526 * are always active.
527 */
528 struct wl1271_link links[AP_MAX_LINKS];
529
530 /* the hlid of the link where the last transmitted skb came from */
531 int last_tx_hlid;
532
533 /* AP-mode - a bitmap of links currently in PS mode according to FW */
534 u32 ap_fw_ps_map;
535
536 /* AP-mode - a bitmap of links currently in PS mode in mac80211 */
537 unsigned long ap_ps_map;
501}; 538};
502 539
503struct wl1271_station { 540struct wl1271_station {