mirror of https://gitee.com/openkylin/linux.git
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: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
parent
409622ecc2
commit
09039f42a2
|
@ -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) -
|
||||
|
|
|
@ -172,5 +172,3 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
desc->hlid = hlid;
|
||||
switch (hlid) {
|
||||
case WL1271_AP_GLOBAL_HLID:
|
||||
rate_idx = ACX_TX_AP_MODE_MGMT_RATE;
|
||||
break;
|
||||
case WL1271_AP_BROADCAST_HLID:
|
||||
rate_idx = ACX_TX_AP_MODE_BCST_RATE;
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
rate_idx = ACX_TX_AP_MODE_MGMT_RATE;
|
||||
} else {
|
||||
desc->hlid = WL1271_AP_BROADCAST_HLID;
|
||||
rate_idx = ACX_TX_AP_MODE_BCST_RATE;
|
||||
}
|
||||
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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue