mac80211: Add new API for rate selection
authorSujith Manoharan <Sujith.Manoharan@atheros.com>
Wed, 27 Apr 2011 11:26:51 +0000 (16:56 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 28 Apr 2011 18:53:19 +0000 (14:53 -0400)
This patch adds a new API for setting a TX rate mask in
drivers that have rate control in either the firmware or hardware.
This can be used for various purposes, for example, masking out the
11b rates in P2P operation.

Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/driver-trace.h

index 8aad6b37c689a8eb61834d49501c5d97a9ffd2ef..63f75a06043b914c7b1237b9bea05a19552597ea 100644 (file)
@@ -1822,6 +1822,10 @@ enum ieee80211_ampdu_mlme_action {
  *
  * @tx_frames_pending: Check if there is any pending frame in the hardware
  *     queues before entering power save.
+ *
+ * @set_bitrate_mask: Set a mask of rates to be used for rate control selection
+ *     when transmitting a frame. Currently only legacy rates are handled.
+ *     The callback can sleep.
  */
 struct ieee80211_ops {
        void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1910,6 +1914,8 @@ struct ieee80211_ops {
        void (*get_ringparam)(struct ieee80211_hw *hw,
                              u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
        bool (*tx_frames_pending)(struct ieee80211_hw *hw);
+       int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                               const struct cfg80211_bitrate_mask *mask);
 };
 
 /**
index a9ddaf63ee14f404a8998297d0e609f7afbf0b87..12d52cec9515183bf020ffb8a42c3ca4e2e59bbc 100644 (file)
@@ -1633,16 +1633,13 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       int i;
-
-       /*
-        * This _could_ be supported by providing a hook for
-        * drivers for this function, but at this point it
-        * doesn't seem worth bothering.
-        */
-       if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
-               return -EOPNOTSUPP;
+       int i, ret;
 
+       if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) {
+               ret = drv_set_bitrate_mask(local, sdata, mask);
+               if (ret)
+                       return ret;
+       }
 
        for (i = 0; i < IEEE80211_NUM_BANDS; i++)
                sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
index 00a0685f240355ea136301013a90597180117605..2ddb56e5b51f240093d05347dae78629afe36e84 100644 (file)
@@ -565,4 +565,22 @@ static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
 
        return ret;
 }
+
+static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
+                                      struct ieee80211_sub_if_data *sdata,
+                                      const struct cfg80211_bitrate_mask *mask)
+{
+       int ret = -EOPNOTSUPP;
+
+       might_sleep();
+
+       trace_drv_set_bitrate_mask(local, sdata, mask);
+       if (local->ops->set_bitrate_mask)
+               ret = local->ops->set_bitrate_mask(&local->hw,
+                                                  &sdata->vif, mask);
+       trace_drv_return_int(local, ret);
+
+       return ret;
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
index c8c934d48b7ad7c8111bd156c8b244b5c9f85038..191e834ec46b11efdc21689ad45f9cf9bc92ceef 100644 (file)
@@ -989,6 +989,33 @@ DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait,
        TP_ARGS(local)
 );
 
+TRACE_EVENT(drv_set_bitrate_mask,
+       TP_PROTO(struct ieee80211_local *local,
+                struct ieee80211_sub_if_data *sdata,
+                const struct cfg80211_bitrate_mask *mask),
+
+       TP_ARGS(local, sdata, mask),
+
+       TP_STRUCT__entry(
+               LOCAL_ENTRY
+               VIF_ENTRY
+               __field(u32, legacy_2g)
+               __field(u32, legacy_5g)
+       ),
+
+       TP_fast_assign(
+               LOCAL_ASSIGN;
+               VIF_ASSIGN;
+               __entry->legacy_2g = mask->control[IEEE80211_BAND_2GHZ].legacy;
+               __entry->legacy_5g = mask->control[IEEE80211_BAND_5GHZ].legacy;
+       ),
+
+       TP_printk(
+               LOCAL_PR_FMT  VIF_PR_FMT " 2G Mask:0x%x 5G Mask:0x%x",
+               LOCAL_PR_ARG, VIF_PR_ARG, __entry->legacy_2g, __entry->legacy_5g
+       )
+);
+
 /*
  * Tracing for API calls that drivers call.
  */