mac80211: put rx handlers into separate functions
authorChristian Lamparter <chunkeey@googlemail.com>
Wed, 4 Aug 2010 23:36:04 +0000 (01:36 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 16 Aug 2010 19:26:39 +0000 (15:26 -0400)
This patch takes the reorder logic from the RX path and
moves it into separate routines to make the expired frame
release accessible.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/rx.c

index 225e8ee682e3dd8daf127f69b0cb3f6091b9abbd..8301b4a980a2019d4fe0615115c31fa778a65ae5 100644 (file)
@@ -583,6 +583,57 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
  */
 #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
 
+static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
+                                         struct tid_ampdu_rx *tid_agg_rx,
+                                         struct sk_buff_head *frames)
+{
+       int index;
+
+       /* release the buffer until next missing frame */
+       index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
+                                               tid_agg_rx->buf_size;
+       if (!tid_agg_rx->reorder_buf[index] &&
+           tid_agg_rx->stored_mpdu_num > 1) {
+               /*
+                * No buffers ready to be released, but check whether any
+                * frames in the reorder buffer have timed out.
+                */
+               int j;
+               int skipped = 1;
+               for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
+                    j = (j + 1) % tid_agg_rx->buf_size) {
+                       if (!tid_agg_rx->reorder_buf[j]) {
+                               skipped++;
+                               continue;
+                       }
+                       if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
+                                       HT_RX_REORDER_BUF_TIMEOUT))
+                               break;
+
+#ifdef CONFIG_MAC80211_HT_DEBUG
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "%s: release an RX reorder "
+                                      "frame due to timeout on earlier "
+                                      "frames\n",
+                                      wiphy_name(hw->wiphy));
+#endif
+                       ieee80211_release_reorder_frame(hw, tid_agg_rx,
+                                                       j, frames);
+
+                       /*
+                        * Increment the head seq# also for the skipped slots.
+                        */
+                       tid_agg_rx->head_seq_num =
+                               (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
+                       skipped = 0;
+               }
+       } else while (tid_agg_rx->reorder_buf[index]) {
+               ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
+               index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
+                                                       tid_agg_rx->buf_size;
+       }
+}
+
 /*
  * As this function belongs to the RX path it must be under
  * rcu_read_lock protection. It returns false if the frame
@@ -643,49 +694,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
        tid_agg_rx->reorder_buf[index] = skb;
        tid_agg_rx->reorder_time[index] = jiffies;
        tid_agg_rx->stored_mpdu_num++;
-       /* release the buffer until next missing frame */
-       index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
-                                               tid_agg_rx->buf_size;
-       if (!tid_agg_rx->reorder_buf[index] &&
-           tid_agg_rx->stored_mpdu_num > 1) {
-               /*
-                * No buffers ready to be released, but check whether any
-                * frames in the reorder buffer have timed out.
-                */
-               int j;
-               int skipped = 1;
-               for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
-                    j = (j + 1) % tid_agg_rx->buf_size) {
-                       if (!tid_agg_rx->reorder_buf[j]) {
-                               skipped++;
-                               continue;
-                       }
-                       if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
-                                       HT_RX_REORDER_BUF_TIMEOUT))
-                               break;
-
-#ifdef CONFIG_MAC80211_HT_DEBUG
-                       if (net_ratelimit())
-                               printk(KERN_DEBUG "%s: release an RX reorder "
-                                      "frame due to timeout on earlier "
-                                      "frames\n",
-                                      wiphy_name(hw->wiphy));
-#endif
-                       ieee80211_release_reorder_frame(hw, tid_agg_rx,
-                                                       j, frames);
-
-                       /*
-                        * Increment the head seq# also for the skipped slots.
-                        */
-                       tid_agg_rx->head_seq_num =
-                               (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
-                       skipped = 0;
-               }
-       } else while (tid_agg_rx->reorder_buf[index]) {
-               ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
-               index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
-                                                       tid_agg_rx->buf_size;
-       }
+       ieee80211_sta_reorder_release(hw, tid_agg_rx, frames);
 
        return true;
 }
@@ -2267,19 +2276,46 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
        dev_kfree_skb(skb);
 }
 
-
-static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
-                                        struct ieee80211_rx_data *rx,
-                                        struct sk_buff *skb,
-                                        struct ieee80211_rate *rate)
+static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
+                                        ieee80211_rx_result res)
 {
-       struct sk_buff_head reorder_release;
-       ieee80211_rx_result res = RX_DROP_MONITOR;
+       switch (res) {
+       case RX_DROP_MONITOR:
+               I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+               if (rx->sta)
+                       rx->sta->rx_dropped++;
+               /* fall through */
+       case RX_CONTINUE: {
+               struct ieee80211_rate *rate = NULL;
+               struct ieee80211_supported_band *sband;
+               struct ieee80211_rx_status *status;
+
+               status = IEEE80211_SKB_RXCB((rx->skb));
+
+               sband = rx->local->hw.wiphy->bands[status->band];
+               if (!(status->flag & RX_FLAG_HT))
+                       rate = &sband->bitrates[status->rate_idx];
 
-       __skb_queue_head_init(&reorder_release);
+               ieee80211_rx_cooked_monitor(rx, rate);
+               break;
+               }
+       case RX_DROP_UNUSABLE:
+               I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
+               if (rx->sta)
+                       rx->sta->rx_dropped++;
+               dev_kfree_skb(rx->skb);
+               break;
+       case RX_QUEUED:
+               I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
+               break;
+       }
+}
 
-       rx->skb = skb;
-       rx->sdata = sdata;
+static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
+                                 struct sk_buff_head *frames)
+{
+       ieee80211_rx_result res = RX_DROP_MONITOR;
+       struct sk_buff *skb;
 
 #define CALL_RXH(rxh)                  \
        do {                            \
@@ -2288,17 +2324,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
                        goto rxh_next;  \
        } while (0);
 
-       /*
-        * NB: the rxh_next label works even if we jump
-        *     to it from here because then the list will
-        *     be empty, which is a trivial check
-        */
-       CALL_RXH(ieee80211_rx_h_passive_scan)
-       CALL_RXH(ieee80211_rx_h_check)
-
-       ieee80211_rx_reorder_ampdu(rx, &reorder_release);
-
-       while ((skb = __skb_dequeue(&reorder_release))) {
+       while ((skb = __skb_dequeue(frames))) {
                /*
                 * all the other fields are valid across frames
                 * that belong to an aMPDU since they are on the
@@ -2316,42 +2342,58 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
                CALL_RXH(ieee80211_rx_h_remove_qos_control)
                CALL_RXH(ieee80211_rx_h_amsdu)
 #ifdef CONFIG_MAC80211_MESH
-               if (ieee80211_vif_is_mesh(&sdata->vif))
+               if (ieee80211_vif_is_mesh(&rx->sdata->vif))
                        CALL_RXH(ieee80211_rx_h_mesh_fwding);
 #endif
                CALL_RXH(ieee80211_rx_h_data)
 
                /* special treatment -- needs the queue */
-               res = ieee80211_rx_h_ctrl(rx, &reorder_release);
+               res = ieee80211_rx_h_ctrl(rx, frames);
                if (res != RX_CONTINUE)
                        goto rxh_next;
 
                CALL_RXH(ieee80211_rx_h_action)
                CALL_RXH(ieee80211_rx_h_mgmt)
 
+ rxh_next:
+               ieee80211_rx_handlers_result(rx, res);
+
 #undef CALL_RXH
+       }
+}
+
+static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
+                                        struct ieee80211_rx_data *rx,
+                                        struct sk_buff *skb,
+                                        struct ieee80211_rate *rate)
+{
+       struct sk_buff_head reorder_release;
+       ieee80211_rx_result res = RX_DROP_MONITOR;
+
+       __skb_queue_head_init(&reorder_release);
+
+       rx->skb = skb;
+       rx->sdata = sdata;
+
+#define CALL_RXH(rxh)                  \
+       do {                            \
+               res = rxh(rx);          \
+               if (res != RX_CONTINUE) \
+                       goto rxh_next;  \
+       } while (0);
+
+       CALL_RXH(ieee80211_rx_h_passive_scan)
+       CALL_RXH(ieee80211_rx_h_check)
+
+       ieee80211_rx_reorder_ampdu(rx, &reorder_release);
+
+       ieee80211_rx_handlers(rx, &reorder_release);
+       return;
 
  rxh_next:
-               switch (res) {
-               case RX_DROP_MONITOR:
-                       I802_DEBUG_INC(sdata->local->rx_handlers_drop);
-                       if (rx->sta)
-                               rx->sta->rx_dropped++;
-                       /* fall through */
-               case RX_CONTINUE:
-                       ieee80211_rx_cooked_monitor(rx, rate);
-                       break;
-               case RX_DROP_UNUSABLE:
-                       I802_DEBUG_INC(sdata->local->rx_handlers_drop);
-                       if (rx->sta)
-                               rx->sta->rx_dropped++;
-                       dev_kfree_skb(rx->skb);
-                       break;
-               case RX_QUEUED:
-                       I802_DEBUG_INC(sdata->local->rx_handlers_queued);
-                       break;
-               }
-       }
+       ieee80211_rx_handlers_result(rx, res);
+
+#undef CALL_RXH
 }
 
 /* main receive path */