From patchwork Wed Apr 27 11:26:51 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sujith Manoharan X-Patchwork-Id: 736051 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3RBxxae004507 for ; Wed, 27 Apr 2011 12:36:22 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758655Ab1D0LYS (ORCPT ); Wed, 27 Apr 2011 07:24:18 -0400 Received: from mail-pv0-f174.google.com ([74.125.83.174]:55101 "EHLO mail-pv0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756125Ab1D0LYR (ORCPT ); Wed, 27 Apr 2011 07:24:17 -0400 Received: by pvg12 with SMTP id 12so1111368pvg.19 for ; Wed, 27 Apr 2011 04:24:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:mime-version:content-type :content-transfer-encoding:message-id:date:to:cc:subject; bh=vDMROeBnrfWHPt03HKxBRc5rJgn78eM64a5eZ64zskY=; b=OAB++gdny46EzMJ/lx3RS4vtlhJKpRmisP2AgwWQ7LmLTn03WDz2xYnnafIpRNiKDi th6QFtdY9yS3Zr1XVs5p4S/VNZIPt06H/4ukH7lLx7dFfP6hOMROfrG5g8vCKSp3SvZQ YUbX5t+FARkSyz+6N4LgOOKb4wMO20+mfDBGU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:mime-version:content-type:content-transfer-encoding:message-id :date:to:cc:subject; b=lGB+oSpl2ugPMVpRiBkdm9ebvj3n3rV04A1+cjKTsgH1w7xrPfSNXS9XJ4OZlKSGAi 6zxrWoQslFz8es2ekw4WFQtAhBrC4qee1nveb/wBHXRzHJAUTHnP5hlUx3AoTIzVaetu rT09pXDyXL2R8pqnFsgP58e2kA7WPqvFt5mFw= Received: by 10.68.40.71 with SMTP id v7mr2049950pbk.518.1303903456905; Wed, 27 Apr 2011 04:24:16 -0700 (PDT) Received: from atheros-test ([182.72.177.186]) by mx.google.com with ESMTPS id d9sm508750pba.16.2011.04.27.04.24.14 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 27 Apr 2011 04:24:16 -0700 (PDT) From: Sujith MIME-Version: 1.0 Message-ID: <19895.64891.154225.629077@gargle.gargle.HOWL> Date: Wed, 27 Apr 2011 16:56:51 +0530 To: "John W. Linville" CC: Johannes Berg , linux-wireless Subject: [PATCH v3] mac80211: Add new API for rate selection Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 27 Apr 2011 12:36:22 +0000 (UTC) From: Sujith Manoharan 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 --- v2 : rc_rateidx_mask has to be updated for drivers using IEEE80211_HW_HAS_RATE_CONTROL since building IEs for a probe request makes use of it. v3 : Replace ENOTSUPP with EOPNOTSUPP. include/net/mac80211.h | 6 ++++++ net/mac80211/cfg.c | 15 ++++++--------- net/mac80211/driver-ops.h | 18 ++++++++++++++++++ net/mac80211/driver-trace.h | 27 +++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d23dd6c..4c97fc8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -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); }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a9ddaf6..12d52ce 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -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; diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 00a0685..2ddb56e 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -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 */ diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index c8c934d..191e834 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -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. */