rsi: Changed the logic of dequeuing packets from hal queues.
authorJahnavi Meher <jahnavi.meher@gmail.com>
Mon, 16 Jun 2014 14:15:03 +0000 (19:45 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 19 Jun 2014 19:49:22 +0000 (15:49 -0400)
The number of packets being dequeued from s/w queues was fixed -
changed it to a dynamic calculation based on txop. There are also
some fixes to the dequeuing algorithm.

Signed-off-by: Jahnavi Meher <jahnavi.meher@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rsi/rsi_91x_core.c
drivers/net/wireless/rsi/rsi_main.h

index cf61d6e3eaa7cd746a7bec20853277b5f1c69001..264e8fac83ff2cd9a70d1ae0781490e30b91e326 100644 (file)
@@ -76,6 +76,50 @@ static bool rsi_recalculate_weights(struct rsi_common *common)
        return recontend_queue;
 }
 
+/**
+ * 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;
+       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 {
+               txop -= ieee80211_generic_frame_duration(adapter->hw,
+                                                        adapter->vifs[0],
+                                                        common->band,
+                                                        skb->len, &rate);
+               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.
@@ -88,7 +132,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 +140,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 +153,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,26 +188,10 @@ 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;
 }
index 2cb73e7edb98d9e11f0d2e02902517a81b4051aa..86291310e293858e107f4d069afd683fc63b2660 100644 (file)
@@ -115,6 +115,7 @@ struct wmm_qinfo {
        s32 weight;
        s32 wme_params;
        s32 pkt_contended;
+       s32 txop;
 };
 
 struct transmit_q_stats {
@@ -192,6 +193,8 @@ struct rsi_common {
        u8 selected_qnum;
        u32 pkt_cnt;
        u8 min_weight;
+
+       bool hw_data_qs_blocked;
 };
 
 struct rsi_hw {