From: "Pedersen, Thomas" <c_tpeder@qca.qualcomm.com>
To: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Cc: <kvalo@qca.qualcomm.com>, <linux-wireless@vger.kernel.org>,
<ath6kl-devel@qualcomm.com>
Subject: Re: [PATCH 2/2] ath6kl: Configure htcap in fw based on the channel type in AP mode
Date: Fri, 6 Apr 2012 10:41:57 -0700 [thread overview]
Message-ID: <20120406174157.GA10355@pista> (raw)
In-Reply-To: <1333721235-16025-2-git-send-email-vthiagar@qca.qualcomm.com>
On Fri, Apr 06, 2012 at 07:37:15PM +0530, Vasanthakumar Thiagarajan wrote:
> This patch disables HT in start_ap if the type of the channel on
> which the AP mode is going to be operating is non-HT. HT is enabled
> with default ht cap setting if the operating channel is going to be
> 11n.
>
> Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
> ---
> drivers/net/wireless/ath/ath6kl/cfg80211.c | 77 ++++++++++++++++++++--------
> drivers/net/wireless/ath/ath6kl/common.h | 1 +
> drivers/net/wireless/ath/ath6kl/core.h | 9 +++
> drivers/net/wireless/ath/ath6kl/wmi.c | 37 +++++++++++++
> drivers/net/wireless/ath/ath6kl/wmi.h | 13 +++++
> 5 files changed, 116 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
> index 47dbb14..bd3e85b 100644
> --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
> +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
> @@ -2421,31 +2421,25 @@ void ath6kl_check_wow_status(struct ath6kl *ar)
> }
> #endif
>
> -static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
> - struct ieee80211_channel *chan,
> - enum nl80211_channel_type channel_type)
> +static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
> + bool ht_enable)
> {
> - struct ath6kl_vif *vif;
> -
> - /*
> - * 'dev' could be NULL if a channel change is required for the hardware
> - * device itself, instead of a particular VIF.
> - *
> - * FIXME: To be handled properly when monitor mode is supported.
> - */
> - if (!dev)
> - return -EBUSY;
> -
> - vif = netdev_priv(dev);
> + struct ath6kl_htcap *htcap = &vif->htcap;
>
> - if (!ath6kl_cfg80211_ready(vif))
> - return -EIO;
> + if (htcap->ht_enable == ht_enable)
> + return 0;
>
> - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
> - __func__, chan->center_freq, chan->hw_value);
> - vif->next_chan = chan->center_freq;
> + if (ht_enable) {
> + /* Set default ht capabilities */
> + htcap->ht_enable = true;
> + htcap->cap_info = (band == IEEE80211_BAND_2GHZ) ?
> + ath6kl_g_htcap : ath6kl_a_htcap;
> + htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
> + } else /* Disable ht */
> + memset(htcap, 0, sizeof(*htcap));
>
> - return 0;
> + return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
> + band, htcap);
> }
>
> static bool ath6kl_is_p2p_ie(const u8 *pos)
> @@ -2568,6 +2562,35 @@ static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
> return 0;
> }
>
> +static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
> + struct ieee80211_channel *chan,
> + enum nl80211_channel_type channel_type)
> +{
> + struct ath6kl_vif *vif;
> +
> + /*
> + * 'dev' could be NULL if a channel change is required for the hardware
> + * device itself, instead of a particular VIF.
> + *
> + * FIXME: To be handled properly when monitor mode is supported.
> + */
> + if (!dev)
> + return -EBUSY;
> +
> + vif = netdev_priv(dev);
> +
> + if (!ath6kl_cfg80211_ready(vif))
> + return -EIO;
> +
> + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
> + __func__, chan->center_freq, chan->hw_value);
> + vif->next_chan = chan->center_freq;
> + vif->next_ch_type = channel_type;
> + vif->next_ch_band = chan->band;
Why this indirection? Can't we just call ath6kl_set_htcap() here and
thereby handle the STA case as well?
> + return 0;
> +}
> +
> static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
> struct cfg80211_ap_settings *info)
> {
> @@ -2734,6 +2757,10 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
> return res;
> }
>
> + if (ath6kl_set_htcap(vif, vif->next_ch_band,
> + vif->next_ch_type != NL80211_CHAN_NO_HT))
> + return -EIO;
> +
> res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
> if (res < 0)
> return res;
> @@ -2768,6 +2795,13 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
> ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
> clear_bit(CONNECTED, &vif->flags);
>
> + /* Restore ht setting in firmware */
> + if (ath6kl_set_htcap(vif, IEEE80211_BAND_2GHZ, true))
> + return -EIO;
> +
> + if (ath6kl_set_htcap(vif, IEEE80211_BAND_5GHZ, true))
> + return -EIO;
> +
> return 0;
> }
>
> @@ -3313,6 +3347,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
> vif->next_mode = nw_type;
> vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
> vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
> + vif->htcap.ht_enable = true;
>
> memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
> if (fw_vif_idx != 0)
> diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
> index 71f5450..98a8861 100644
> --- a/drivers/net/wireless/ath/ath6kl/common.h
> +++ b/drivers/net/wireless/ath/ath6kl/common.h
> @@ -78,6 +78,7 @@ enum crypto_type {
>
> struct htc_endpoint_credit_dist;
> struct ath6kl;
> +struct ath6kl_htcap;
> enum htc_credit_dist_reason;
> struct ath6kl_htc_credit_info;
>
> diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
> index 72e6a94..d27d0cf 100644
> --- a/drivers/net/wireless/ath/ath6kl/core.h
> +++ b/drivers/net/wireless/ath/ath6kl/core.h
> @@ -477,6 +477,12 @@ struct ath6kl_mc_filter {
> char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
> };
>
> +struct ath6kl_htcap {
> + bool ht_enable;
> + unsigned short cap_info;
> + u8 ampdu_factor;
> +};
> +
> /*
> * Driver's maximum limit, note that some firmwares support only one vif
> * and the runtime (current) limit must be checked from ar->vif_max.
> @@ -525,6 +531,7 @@ struct ath6kl_vif {
> struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
> struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
> struct aggr_info *aggr_cntxt;
> + struct ath6kl_htcap htcap;
>
> struct timer_list disconnect_timer;
> struct timer_list sched_scan_timer;
> @@ -537,6 +544,8 @@ struct ath6kl_vif {
> u32 send_action_id;
> bool probe_req_report;
> u16 next_chan;
> + enum nl80211_channel_type next_ch_type;
> + enum ieee80211_band next_ch_band;
> u16 assoc_bss_beacon_int;
> u16 listen_intvl_t;
> u16 bmiss_time_t;
> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
> index 7cd1d96..7c8a997 100644
> --- a/drivers/net/wireless/ath/ath6kl/wmi.c
> +++ b/drivers/net/wireless/ath/ath6kl/wmi.c
> @@ -2882,6 +2882,43 @@ int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
> return ret;
> }
>
> +int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
> + enum ieee80211_band band,
> + struct ath6kl_htcap *htcap)
> +{
> + struct sk_buff *skb;
> + struct wmi_set_htcap_cmd *cmd;
> +
> + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
> + if (!skb)
> + return -ENOMEM;
> +
> + cmd = (struct wmi_set_htcap_cmd *) skb->data;
> +
> + /*
> + * NOTE: Band in firmware matches enum ieee80211_band, it is unlikely
> + * this will be changed in firmware. If at all there is any change in
> + * band value, the host needs to be fixed.
> + */
> + cmd->band = band;
> + cmd->ht_enable = !!htcap->ht_enable;
> + cmd->ht20_sgi = !!(htcap->cap_info & IEEE80211_HT_CAP_SGI_20);
> + cmd->ht40_supported =
> + !!(htcap->cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
> + cmd->ht40_sgi = !!(htcap->cap_info & IEEE80211_HT_CAP_SGI_40);
> + cmd->intolerant_40mhz =
> + !!(htcap->cap_info & IEEE80211_HT_CAP_40MHZ_INTOLERANT);
> + cmd->max_ampdu_len_exp = htcap->ampdu_factor;
> +
> + ath6kl_dbg(ATH6KL_DBG_WMI,
> + "Set htcap: band:%d ht_enable:%d 40mhz:%d sgi_20mhz:%d sgi_40mhz:%d 40mhz_intolerant:%d ampdu_len_exp:%d\n",
> + cmd->band, cmd->ht_enable, cmd->ht40_supported,
> + cmd->ht20_sgi, cmd->ht40_sgi, cmd->intolerant_40mhz,
> + cmd->max_ampdu_len_exp);
> + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_HT_CAP_CMDID,
> + NO_SYNC_WMIFLAG);
> +}
> +
> int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
> {
> struct sk_buff *skb;
> diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
> index 25aa6b8..d3d2ab5 100644
> --- a/drivers/net/wireless/ath/ath6kl/wmi.h
> +++ b/drivers/net/wireless/ath/ath6kl/wmi.h
> @@ -1277,6 +1277,16 @@ struct wmi_mcast_filter_add_del_cmd {
> u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
> } __packed;
>
> +struct wmi_set_htcap_cmd {
> + u8 band;
> + u8 ht_enable;
> + u8 ht40_supported;
> + u8 ht20_sgi;
> + u8 ht40_sgi;
> + u8 intolerant_40mhz;
> + u8 max_ampdu_len_exp;
> +} __packed;
> +
> /* Command Replies */
>
> /* WMI_GET_CHANNEL_LIST_CMDID reply */
> @@ -2487,6 +2497,9 @@ int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi);
> int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg);
> int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
> u8 keep_alive_intvl);
> +int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
> + enum ieee80211_band band,
> + struct ath6kl_htcap *htcap);
> int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
>
> s32 ath6kl_wmi_get_rate(s8 rate_index);
> --
> 1.7.0.4
>
next prev parent reply other threads:[~2012-04-06 17:42 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-06 14:07 [PATCH 1/2] ath6kl: Don't advertise HT40 support in 2.4 Ghz Vasanthakumar Thiagarajan
2012-04-06 14:07 ` [PATCH 2/2] ath6kl: Configure htcap in fw based on the channel type in AP mode Vasanthakumar Thiagarajan
2012-04-06 14:54 ` Joe Perches
2012-04-06 15:10 ` Vasanthakumar Thiagarajan
2012-04-06 17:41 ` Pedersen, Thomas [this message]
2012-04-07 12:55 ` Vasanthakumar Thiagarajan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120406174157.GA10355@pista \
--to=c_tpeder@qca.qualcomm.com \
--cc=ath6kl-devel@qualcomm.com \
--cc=kvalo@qca.qualcomm.com \
--cc=linux-wireless@vger.kernel.org \
--cc=vthiagar@qca.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).