Search Linux Wireless

[PATCH v2 01/40] wl12xx: Revert "wl12xx: schedule TX packets according to FW occupancy"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Arik Nemtsov <arik@xxxxxxxxxx>

This does not make sense in fw >= 6/7.3.0.0.75 (wl127x/wl128x) -
we don't use Tx blocks to measure FW occupancy anymore.

This reverts commit 9e374a37b6fa2310b71d3c5657cd0c1e693120c6.

Signed-off-by: Arik Nemtsov <arik@xxxxxxxxxx>
Signed-off-by: Eliad Peller <eliad@xxxxxxxxxx>
---
 drivers/net/wireless/wl12xx/debugfs.c |    5 +--
 drivers/net/wireless/wl12xx/main.c    |   30 ++++-----------
 drivers/net/wireless/wl12xx/tx.c      |   68 +++++++++++----------------------
 drivers/net/wireless/wl12xx/wl12xx.h  |    2 +-
 4 files changed, 33 insertions(+), 72 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 37934b5..3b5f240 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -336,16 +336,13 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
 #define DRIVER_STATE_PRINT_INT(x)  DRIVER_STATE_PRINT(x, "%d")
 #define DRIVER_STATE_PRINT_STR(x)  DRIVER_STATE_PRINT(x, "%s")
 #define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
 #define DRIVER_STATE_PRINT_HEX(x)  DRIVER_STATE_PRINT(x, "0x%x")
 
 	DRIVER_STATE_PRINT_INT(tx_blocks_available);
-	DRIVER_STATE_PRINT_INT(tx_allocated_blocks[0]);
-	DRIVER_STATE_PRINT_INT(tx_allocated_blocks[1]);
-	DRIVER_STATE_PRINT_INT(tx_allocated_blocks[2]);
-	DRIVER_STATE_PRINT_INT(tx_allocated_blocks[3]);
+	DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
 	DRIVER_STATE_PRINT_INT(tx_frames_cnt);
 	DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]);
 	DRIVER_STATE_PRINT_INT(tx_queue_count[0]);
 	DRIVER_STATE_PRINT_INT(tx_queue_count[1]);
 	DRIVER_STATE_PRINT_INT(tx_queue_count[2]);
 	DRIVER_STATE_PRINT_INT(tx_queue_count[3]);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 98258fe..f91875e 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -821,30 +821,19 @@ static void wl1271_irq_update_links_status(struct wl1271 *wl,
 
 		wl1271_irq_ps_regulate_link(wl, hlid,
 					    wl->links[hlid].allocated_blks);
 	}
 }
 
-static u32 wl1271_tx_allocated_blocks(struct wl1271 *wl)
-{
-	int i;
-	u32 total_alloc_blocks = 0;
-
-	for (i = 0; i < NUM_TX_QUEUES; i++)
-		total_alloc_blocks += wl->tx_allocated_blocks[i];
-
-	return total_alloc_blocks;
-}
-
 static void wl1271_fw_status(struct wl1271 *wl,
 			     struct wl1271_fw_full_status *full_status)
 {
 	struct wl1271_fw_common_status *status = &full_status->common;
 	struct timespec ts;
 	u32 old_tx_blk_count = wl->tx_blocks_available;
-	u32 freed_blocks = 0, ac_freed_blocks;
+	u32 freed_blocks = 0;
 	int i;
 
 	if (wl->bss_type == BSS_TYPE_AP_BSS) {
 		wl1271_raw_read(wl, FW_STATUS_ADDR, status,
 				sizeof(struct wl1271_fw_ap_status), false);
 	} else {
@@ -858,29 +847,27 @@ static void wl1271_fw_status(struct wl1271 *wl,
 		     status->fw_rx_counter,
 		     status->drv_rx_counter,
 		     status->tx_results_counter);
 
 	/* update number of available TX blocks */
 	for (i = 0; i < NUM_TX_QUEUES; i++) {
-		ac_freed_blocks = le32_to_cpu(status->tx_released_blks[i]) -
-				  wl->tx_blocks_freed[i];
-		freed_blocks += ac_freed_blocks;
-
-		wl->tx_allocated_blocks[i] -= ac_freed_blocks;
+		freed_blocks += le32_to_cpu(status->tx_released_blks[i]) -
+				wl->tx_blocks_freed[i];
 
 		wl->tx_blocks_freed[i] =
 			le32_to_cpu(status->tx_released_blks[i]);
 	}
 
+	wl->tx_allocated_blocks -= freed_blocks;
+
 	if (wl->bss_type == BSS_TYPE_AP_BSS) {
 		/* Update num of allocated TX blocks per link and ps status */
 		wl1271_irq_update_links_status(wl, &full_status->ap);
 		wl->tx_blocks_available += freed_blocks;
 	} else {
-		int avail = full_status->sta.tx_total -
-			    wl1271_tx_allocated_blocks(wl);
+		int avail = full_status->sta.tx_total - wl->tx_allocated_blocks;
 
 		/*
 		 * The FW might change the total number of TX memblocks before
 		 * we get a notification about blocks being released. Thus, the
 		 * available blocks calculation might yield a temporary result
 		 * which is lower than the actual available blocks. Keeping in
@@ -2010,12 +1997,13 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
 	wl->band = IEEE80211_BAND_2GHZ;
 
 	wl->rx_counter = 0;
 	wl->psm_entry_retry = 0;
 	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
 	wl->tx_blocks_available = 0;
+	wl->tx_allocated_blocks = 0;
 	wl->tx_results_count = 0;
 	wl->tx_packets_count = 0;
 	wl->time_offset = 0;
 	wl->session_counter = 0;
 	wl->rate_set = CONF_TX_RATE_MASK_BASIC;
 	wl->vif = NULL;
@@ -2030,16 +2018,14 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
 	 * this is performed after the cancel_work calls and the associated
 	 * mutex_lock, so that wl1271_op_add_interface does not accidentally
 	 * get executed before all these vars have been reset.
 	 */
 	wl->flags = 0;
 
-	for (i = 0; i < NUM_TX_QUEUES; i++) {
+	for (i = 0; i < NUM_TX_QUEUES; i++)
 		wl->tx_blocks_freed[i] = 0;
-		wl->tx_allocated_blocks[i] = 0;
-	}
 
 	wl1271_debugfs_reset(wl);
 
 	kfree(wl->fw_status);
 	wl->fw_status = NULL;
 	kfree(wl->tx_res_if);
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 48fde96..0696aed 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -165,13 +165,13 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
 				u32 buf_offset, u8 hlid)
 {
 	struct wl1271_tx_hw_descr *desc;
 	u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
 	u32 len;
 	u32 total_blocks;
-	int id, ret = -EBUSY, ac;
+	int id, ret = -EBUSY;
 	u32 spare_blocks;
 
 	if (unlikely(wl->quirks & WL12XX_QUIRK_USE_2_SPARE_BLOCKS))
 		spare_blocks = 2;
 	else
 		spare_blocks = 1;
@@ -203,15 +203,13 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
 			desc->wl127x_mem.total_mem_blocks = total_blocks;
 		}
 
 		desc->id = id;
 
 		wl->tx_blocks_available -= total_blocks;
-
-		ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
-		wl->tx_allocated_blocks[ac] += total_blocks;
+		wl->tx_allocated_blocks += total_blocks;
 
 		if (wl->bss_type == BSS_TYPE_AP_BSS)
 			wl->links[hlid].allocated_blks += total_blocks;
 
 		ret = 0;
 
@@ -456,47 +454,27 @@ void wl1271_handle_tx_low_watermark(struct wl1271 *wl)
 			clear_bit(i, &wl->stopped_queues_map);
 			spin_unlock_irqrestore(&wl->wl_lock, flags);
 		}
 	}
 }
 
-static struct sk_buff_head *wl1271_select_queue(struct wl1271 *wl,
-						struct sk_buff_head *queues)
-{
-	int i, q = -1;
-	u32 min_blks = 0xffffffff;
-
-	/*
-	 * Find a non-empty ac where:
-	 * 1. There are packets to transmit
-	 * 2. The FW has the least allocated blocks
-	 */
-	for (i = 0; i < NUM_TX_QUEUES; i++)
-		if (!skb_queue_empty(&queues[i]) &&
-		    (wl->tx_allocated_blocks[i] < min_blks)) {
-			q = i;
-			min_blks = wl->tx_allocated_blocks[q];
-		}
-
-	if (q == -1)
-		return NULL;
-
-	return &queues[q];
-}
-
 static struct sk_buff *wl1271_sta_skb_dequeue(struct wl1271 *wl)
 {
 	struct sk_buff *skb = NULL;
 	unsigned long flags;
-	struct sk_buff_head *queue;
 
-	queue = wl1271_select_queue(wl, wl->tx_queue);
-	if (!queue)
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VO]);
+	if (skb)
 		goto out;
-
-	skb = skb_dequeue(queue);
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VI]);
+	if (skb)
+		goto out;
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BE]);
+	if (skb)
+		goto out;
+	skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BK]);
 
 out:
 	if (skb) {
 		int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
 		spin_lock_irqsave(&wl->wl_lock, flags);
 		wl->tx_queue_count[q]--;
@@ -508,35 +486,35 @@ out:
 
 static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl)
 {
 	struct sk_buff *skb = NULL;
 	unsigned long flags;
 	int i, h, start_hlid;
-	struct sk_buff_head *queue;
 
 	/* start from the link after the last one */
 	start_hlid = (wl->last_tx_hlid + 1) % AP_MAX_LINKS;
 
 	/* dequeue according to AC, round robin on each link */
 	for (i = 0; i < AP_MAX_LINKS; i++) {
 		h = (start_hlid + i) % AP_MAX_LINKS;
 
-		/* only consider connected stations */
-		if (h >= WL1271_AP_STA_HLID_START &&
-		    !test_bit(h - WL1271_AP_STA_HLID_START, wl->ap_hlid_map))
-			continue;
-
-		queue = wl1271_select_queue(wl, wl->links[h].tx_queue);
-		if (!queue)
-			continue;
-
-		skb = skb_dequeue(queue);
+		skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VO]);
 		if (skb)
-			break;
+			goto out;
+		skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VI]);
+		if (skb)
+			goto out;
+		skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BE]);
+		if (skb)
+			goto out;
+		skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BK]);
+		if (skb)
+			goto out;
 	}
 
+out:
 	if (skb) {
 		int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
 		wl->last_tx_hlid = h;
 		spin_lock_irqsave(&wl->wl_lock, flags);
 		wl->tx_queue_count[q]--;
 		spin_unlock_irqrestore(&wl->wl_lock, flags);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 0bc2935..5b00a84 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -421,13 +421,13 @@ struct wl1271 {
 
 	struct wl1271_acx_mem_map *target_mem_map;
 
 	/* Accounting for allocated / available TX blocks on HW */
 	u32 tx_blocks_freed[NUM_TX_QUEUES];
 	u32 tx_blocks_available;
-	u32 tx_allocated_blocks[NUM_TX_QUEUES];
+	u32 tx_allocated_blocks;
 	u32 tx_results_count;
 
 	/* Transmitted TX packets counter for chipset interface */
 	u32 tx_packets_count;
 
 	/* Time-offset between host and chipset clocks */
-- 
1.7.6.401.g6a319

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux