Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09039f42 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho
Browse files

wl12xx: AP-mode - count free FW TX blocks per link



Count the number of FW TX blocks allocated per link. We add blocks to a
link counter when allocated for a TX descriptor. We remove blocks
according to counters in fw_status indicating the number of freed blocks
in FW. These counters are polled after each IRQ.

Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 409622ec
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -574,6 +574,17 @@ static void wl1271_fw_status(struct wl1271 *wl,
	if (total)
		clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);

	if (wl->bss_type == BSS_TYPE_AP_BSS) {
		for (i = 0; i < AP_MAX_LINKS; i++) {
			u8 cnt = status->tx_lnk_free_blks[i] -
				wl->links[i].prev_freed_blks;

			wl->links[i].prev_freed_blks =
				status->tx_lnk_free_blks[i];
			wl->links[i].allocated_blks -= cnt;
		}
	}

	/* update the host-chipset time offset */
	getnstimeofday(&ts);
	wl->time_offset = (timespec_to_ns(&ts) >> 10) -
+0 −2
Original line number Diff line number Diff line
@@ -172,5 +172,3 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,

	return ret;
}

+29 −24
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb)
}

static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
				u32 buf_offset)
				u32 buf_offset, u8 hlid)
{
	struct wl1271_tx_hw_descr *desc;
	u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
@@ -137,6 +137,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,

		wl->tx_blocks_available -= total_blocks;

		if (wl->bss_type == BSS_TYPE_AP_BSS)
			wl->links[hlid].allocated_blks += total_blocks;

		ret = 0;

		wl1271_debug(DEBUG_TX,
@@ -150,7 +153,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
}

static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
			      u32 extra, struct ieee80211_tx_info *control)
			      u32 extra, struct ieee80211_tx_info *control,
			      u8 hlid)
{
	struct timespec ts;
	struct wl1271_tx_hw_descr *desc;
@@ -186,7 +190,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
	desc->tid = ac;

	if (wl->bss_type != BSS_TYPE_AP_BSS) {
		desc->aid = TX_HW_DEFAULT_AID;
		desc->aid = hlid;

		/* if the packets are destined for AP (have a STA entry)
		   send them with AP rate policies, otherwise use default
@@ -196,25 +200,17 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
		else
			rate_idx = ACX_TX_BASIC_RATE;
	} else {
		if (control->control.sta) {
			struct wl1271_station *wl_sta;

			wl_sta = (struct wl1271_station *)
					control->control.sta->drv_priv;
			desc->hlid = wl_sta->hlid;
			rate_idx = ac;
		} else {
			struct ieee80211_hdr *hdr;

			hdr = (struct ieee80211_hdr *)
						(skb->data + sizeof(*desc));
			if (ieee80211_is_mgmt(hdr->frame_control)) {
				desc->hlid = WL1271_AP_GLOBAL_HLID;
		desc->hlid = hlid;
		switch (hlid) {
		case WL1271_AP_GLOBAL_HLID:
			rate_idx = ACX_TX_AP_MODE_MGMT_RATE;
			} else {
				desc->hlid = WL1271_AP_BROADCAST_HLID;
			break;
		case WL1271_AP_BROADCAST_HLID:
			rate_idx = ACX_TX_AP_MODE_BCST_RATE;
			}
			break;
		default:
			rate_idx = ac;
			break;
		}
	}

@@ -245,6 +241,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
	u32 extra = 0;
	int ret = 0;
	u32 total_len;
	u8 hlid;

	if (!skb)
		return -EINVAL;
@@ -271,14 +268,19 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
		}
	}

	ret = wl1271_tx_allocate(wl, skb, extra, buf_offset);
	if (wl->bss_type == BSS_TYPE_AP_BSS)
		hlid = wl1271_tx_get_hlid(skb);
	else
		hlid = TX_HW_DEFAULT_AID;

	ret = wl1271_tx_allocate(wl, skb, extra, buf_offset, hlid);
	if (ret < 0)
		return ret;

	if (wl->bss_type == BSS_TYPE_AP_BSS)
		wl1271_tx_ap_update_inconnection_sta(wl, skb);

	wl1271_tx_fill_hdr(wl, skb, extra, info);
	wl1271_tx_fill_hdr(wl, skb, extra, info, hlid);

	/*
	 * The length of each packet is stored in terms of words. Thus, we must
@@ -635,8 +637,11 @@ void wl1271_tx_reset(struct wl1271 *wl)

	/* TX failure */
	if (wl->bss_type == BSS_TYPE_AP_BSS) {
		for (i = 0; i < AP_MAX_LINKS; i++)
		for (i = 0; i < AP_MAX_LINKS; i++) {
			wl1271_tx_reset_link_queues(wl, i);
			wl->links[i].allocated_blks = 0;
			wl->links[i].prev_freed_blks = 0;
		}

		wl->last_tx_hlid = 0;
	} else {
+4 −0
Original line number Diff line number Diff line
@@ -322,6 +322,10 @@ enum wl12xx_flags {
struct wl1271_link {
	/* AP-mode - TX queue per AC in link */
	struct sk_buff_head tx_queue[NUM_TX_QUEUES];

	/* accounting for allocated / available TX blocks in FW */
	u8 allocated_blks;
	u8 prev_freed_blks;
};

struct wl1271 {