diff options
Diffstat (limited to 'drivers/net/wireless/rsi/rsi_91x_core.c')
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_core.c | 85 |
1 files changed, 61 insertions, 24 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c index cf61d6e3eaa7..f3d3995d8f6b 100644 --- a/drivers/net/wireless/rsi/rsi_91x_core.c +++ b/drivers/net/wireless/rsi/rsi_91x_core.c @@ -77,6 +77,52 @@ static bool rsi_recalculate_weights(struct rsi_common *common) } /** + * rsi_get_num_pkts_dequeue() - This function determines the number of + * packets to be dequeued based on the number + * of bytes calculated using txop. + * + * @common: Pointer to the driver private structure. + * @q_num: the queue from which pkts have to be dequeued + * + * Return: pkt_num: Number of pkts to be dequeued. + */ +static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num) +{ + struct rsi_hw *adapter = common->priv; + struct sk_buff *skb; + u32 pkt_cnt = 0; + s16 txop = common->tx_qinfo[q_num].txop * 32; + __le16 r_txop; + struct ieee80211_rate rate; + + rate.bitrate = RSI_RATE_MCS0 * 5 * 10; /* Convert to Kbps */ + if (q_num == VI_Q) + txop = ((txop << 5) / 80); + + if (skb_queue_len(&common->tx_queue[q_num])) + skb = skb_peek(&common->tx_queue[q_num]); + else + return 0; + + do { + r_txop = ieee80211_generic_frame_duration(adapter->hw, + adapter->vifs[0], + common->band, + skb->len, &rate); + txop -= le16_to_cpu(r_txop); + pkt_cnt += 1; + /*checking if pkts are still there*/ + if (skb_queue_len(&common->tx_queue[q_num]) - pkt_cnt) + skb = skb->next; + else + break; + + } while (txop > 0); + + return pkt_cnt; +} + +/** * rsi_core_determine_hal_queue() - This function determines the queue from * which packet has to be dequeued. * @common: Pointer to the driver private structure. @@ -88,7 +134,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common) bool recontend_queue = false; u32 q_len = 0; u8 q_num = INVALID_QUEUE; - u8 ii = 0, min = 0; + u8 ii = 0; if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) { if (!common->mgmt_q_block) @@ -96,6 +142,9 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common) return q_num; } + if (common->hw_data_qs_blocked) + return q_num; + if (common->pkt_cnt != 0) { --common->pkt_cnt; return common->selected_qnum; @@ -106,14 +155,15 @@ get_queue_num: q_num = rsi_determine_min_weight_queue(common); - q_len = skb_queue_len(&common->tx_queue[ii]); ii = q_num; /* Selecting the queue with least back off */ for (; ii < NUM_EDCA_QUEUES; ii++) { + q_len = skb_queue_len(&common->tx_queue[ii]); if (((common->tx_qinfo[ii].pkt_contended) && - (common->tx_qinfo[ii].weight < min)) && q_len) { - min = common->tx_qinfo[ii].weight; + (common->tx_qinfo[ii].weight < common->min_weight)) && + q_len) { + common->min_weight = common->tx_qinfo[ii].weight; q_num = ii; } } @@ -140,25 +190,9 @@ get_queue_num: common->selected_qnum = q_num; q_len = skb_queue_len(&common->tx_queue[q_num]); - switch (common->selected_qnum) { - case VO_Q: - if (q_len > MAX_CONTINUOUS_VO_PKTS) - common->pkt_cnt = (MAX_CONTINUOUS_VO_PKTS - 1); - else - common->pkt_cnt = --q_len; - break; - - case VI_Q: - if (q_len > MAX_CONTINUOUS_VI_PKTS) - common->pkt_cnt = (MAX_CONTINUOUS_VI_PKTS - 1); - else - common->pkt_cnt = --q_len; - - break; - - default: - common->pkt_cnt = 0; - break; + if (q_num == VO_Q || q_num == VI_Q) { + common->pkt_cnt = rsi_get_num_pkts_dequeue(common, q_num); + common->pkt_cnt -= 1; } return q_num; @@ -252,6 +286,7 @@ void rsi_core_qos_processor(struct rsi_common *common) skb = rsi_core_dequeue_pkt(common, q_num); if (skb == NULL) { + rsi_dbg(ERR_ZONE, "skb null\n"); mutex_unlock(&common->tx_rxlock); break; } @@ -306,7 +341,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) } if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) || - (ieee80211_is_ctl(tmp_hdr->frame_control))) { + (ieee80211_is_ctl(tmp_hdr->frame_control)) || + (ieee80211_is_qos_nullfunc(tmp_hdr->frame_control))) { q_num = MGMT_SOFT_Q; skb->priority = q_num; } else { @@ -325,6 +361,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) if ((q_num != MGMT_SOFT_Q) && ((skb_queue_len(&common->tx_queue[q_num]) + 1) >= DATA_QUEUE_WATER_MARK)) { + rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__); if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num))) ieee80211_stop_queue(adapter->hw, WME_AC(q_num)); rsi_set_event(&common->tx_thread.event); |