Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352207
b: refs/heads/master
c: 0e81047
h: refs/heads/master
i:
  352205: 5b74957
  352203: 83abca7
  352199: e9e65ad
  352191: 812fe48
v: v3
  • Loading branch information
Arik Nemtsov authored and Luciano Coelho committed Dec 5, 2012
1 parent 50151a6 commit f7bfd2b
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9ebcb232158c737db21e22b7bfdc4fc6d661ea8c
refs/heads/master: 0e81047996fdde7fc9e8a1c01d532df1f53586fa
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/ti/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ static struct wlcore_conf wl12xx_conf = {
.tmpl_short_retry_limit = 10,
.tmpl_long_retry_limit = 10,
.tx_watchdog_timeout = 5000,
.slow_link_thold = 3,
.fast_link_thold = 10,
},
.conn = {
.wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/ti/wl18xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ static struct wlcore_conf wl18xx_conf = {
.tmpl_short_retry_limit = 10,
.tmpl_long_retry_limit = 10,
.tx_watchdog_timeout = 5000,
.slow_link_thold = 3,
.fast_link_thold = 30,
},
.conn = {
.wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
Expand Down
14 changes: 13 additions & 1 deletion trunk/drivers/net/wireless/ti/wlcore/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,18 @@ struct conf_tx_settings {

/* Time in ms for Tx watchdog timer to expire */
u32 tx_watchdog_timeout;

/*
* when a slow link has this much packets pending, it becomes a low
* priority link, scheduling-wise
*/
u8 slow_link_thold;

/*
* when a fast link has this much packets pending, it becomes a low
* priority link, scheduling-wise
*/
u8 fast_link_thold;
} __packed;

enum {
Expand Down Expand Up @@ -1281,7 +1293,7 @@ struct conf_recovery_settings {
* version, the two LSB are the lower driver's private conf
* version.
*/
#define WLCORE_CONF_VERSION (0x0004 << 16)
#define WLCORE_CONF_VERSION (0x0005 << 16)
#define WLCORE_CONF_MASK 0xffff0000
#define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \
sizeof(struct wlcore_conf))
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/net/wireless/ti/wlcore/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,6 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
u32 cur_fw_ps_map;
u8 hlid;

/* TODO: also use link_fast_bitmap here */

cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap);
if (wl->ap_fw_ps_map != cur_fw_ps_map) {
wl1271_debug(DEBUG_PSM,
Expand Down Expand Up @@ -479,6 +477,8 @@ static int wlcore_fw_status(struct wl1271 *wl,
wl->time_offset = (timespec_to_ns(&ts) >> 10) -
(s64)le32_to_cpu(status_2->fw_localtime);

wl->fw_fast_lnk_map = le32_to_cpu(status_2->link_fast_bitmap);

return 0;
}

Expand Down
124 changes: 90 additions & 34 deletions trunk/drivers/net/wireless/ti/wlcore/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,7 @@ void wl1271_handle_tx_low_watermark(struct wl1271 *wl)
}
}

static struct sk_buff_head *wl1271_select_queue(struct wl1271 *wl,
struct sk_buff_head *queues)
static int wlcore_select_ac(struct wl1271 *wl)
{
int i, q = -1, ac;
u32 min_pkts = 0xffffffff;
Expand All @@ -482,33 +481,24 @@ static struct sk_buff_head *wl1271_select_queue(struct wl1271 *wl,
*/
for (i = 0; i < NUM_TX_QUEUES; i++) {
ac = wl1271_tx_get_queue(i);
if (!skb_queue_empty(&queues[ac]) &&
(wl->tx_allocated_pkts[ac] < min_pkts)) {
if (wl->tx_queue_count[ac] &&
wl->tx_allocated_pkts[ac] < min_pkts) {
q = ac;
min_pkts = wl->tx_allocated_pkts[q];
}
}

if (q == -1)
return NULL;

return &queues[q];
return q;
}

static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl,
struct wl1271_link *lnk)
static struct sk_buff *wlcore_lnk_dequeue(struct wl1271 *wl,
struct wl1271_link *lnk, u8 q)
{
struct sk_buff *skb;
unsigned long flags;
struct sk_buff_head *queue;

queue = wl1271_select_queue(wl, lnk->tx_queue);
if (!queue)
return NULL;

skb = skb_dequeue(queue);
skb = skb_dequeue(&lnk->tx_queue[q]);
if (skb) {
int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
spin_lock_irqsave(&wl->wl_lock, flags);
WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
wl->tx_queue_count[q]--;
Expand All @@ -522,9 +512,41 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl,
return skb;
}

static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
u8 *hlid)
static bool wlcore_lnk_high_prio(struct wl1271 *wl, u8 hlid,
struct wl1271_link *lnk)
{
u8 thold;

if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map))
thold = wl->conf.tx.fast_link_thold;
else
thold = wl->conf.tx.slow_link_thold;

return lnk->allocated_pkts < thold;
}

static struct sk_buff *wlcore_lnk_dequeue_high_prio(struct wl1271 *wl,
u8 hlid, u8 ac,
u8 *low_prio_hlid)
{
struct wl1271_link *lnk = &wl->links[hlid];

if (!wlcore_lnk_high_prio(wl, hlid, lnk)) {
if (*low_prio_hlid == WL12XX_INVALID_LINK_ID &&
!skb_queue_empty(&lnk->tx_queue[ac]))
/* we found the first non-empty low priority queue */
*low_prio_hlid = hlid;

return NULL;
}

return wlcore_lnk_dequeue(wl, lnk, ac);
}

static struct sk_buff *wlcore_vif_dequeue_high_prio(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
u8 ac, u8 *hlid,
u8 *low_prio_hlid)
{
struct sk_buff *skb = NULL;
int i, h, start_hlid;
Expand All @@ -540,7 +562,8 @@ static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl,
if (!test_bit(h, wlvif->links_map))
continue;

skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[h]);
skb = wlcore_lnk_dequeue_high_prio(wl, h, ac,
low_prio_hlid);
if (!skb)
continue;

Expand All @@ -560,42 +583,74 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid)
unsigned long flags;
struct wl12xx_vif *wlvif = wl->last_wlvif;
struct sk_buff *skb = NULL;
int ac;
u8 low_prio_hlid = WL12XX_INVALID_LINK_ID;

ac = wlcore_select_ac(wl);
if (ac < 0)
goto out;

/* continue from last wlvif (round robin) */
if (wlvif) {
wl12xx_for_each_wlvif_continue(wl, wlvif) {
skb = wl12xx_vif_skb_dequeue(wl, wlvif, hlid);
if (skb) {
wl->last_wlvif = wlvif;
break;
}
if (!wlvif->tx_queue_count[ac])
continue;

skb = wlcore_vif_dequeue_high_prio(wl, wlvif, ac, hlid,
&low_prio_hlid);
if (!skb)
continue;

wl->last_wlvif = wlvif;
break;
}
}

/* dequeue from the system HLID before the restarting wlvif list */
if (!skb) {
skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
*hlid = wl->system_hlid;
skb = wlcore_lnk_dequeue_high_prio(wl, wl->system_hlid,
ac, &low_prio_hlid);
if (skb) {
*hlid = wl->system_hlid;
wl->last_wlvif = NULL;
}
}

/* do a new pass over the wlvif list */
/* Do a new pass over the wlvif list. But no need to continue
* after last_wlvif. The previous pass should have found it. */
if (!skb) {
wl12xx_for_each_wlvif(wl, wlvif) {
skb = wl12xx_vif_skb_dequeue(wl, wlvif, hlid);
if (!wlvif->tx_queue_count[ac])
goto next;

skb = wlcore_vif_dequeue_high_prio(wl, wlvif, ac, hlid,
&low_prio_hlid);
if (skb) {
wl->last_wlvif = wlvif;
break;
}

/*
* No need to continue after last_wlvif. The previous
* pass should have found it.
*/
next:
if (wlvif == wl->last_wlvif)
break;
}
}

/* no high priority skbs found - but maybe a low priority one? */
if (!skb && low_prio_hlid != WL12XX_INVALID_LINK_ID) {
struct wl1271_link *lnk = &wl->links[low_prio_hlid];
skb = wlcore_lnk_dequeue(wl, lnk, ac);

WARN_ON(!skb); /* we checked this before */
*hlid = low_prio_hlid;

/* ensure proper round robin in the vif/link levels */
wl->last_wlvif = lnk->wlvif;
if (lnk->wlvif)
lnk->wlvif->last_tx_hlid = low_prio_hlid;

}

if (!skb &&
test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
int q;
Expand All @@ -609,6 +664,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid)
spin_unlock_irqrestore(&wl->wl_lock, flags);
}

out:
return skb;
}

Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/wireless/ti/wlcore/wlcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ struct wl1271 {
*/
struct wl1271_link links[WL12XX_MAX_LINKS];

/* Fast/slow links bitmap according to FW */
u32 fw_fast_lnk_map;

/* AP-mode - a bitmap of links currently in PS mode according to FW */
u32 ap_fw_ps_map;

Expand Down

0 comments on commit f7bfd2b

Please sign in to comment.