Search Linux Wireless

Re: [RFC 2/2] cfg80211: provide channel to start_ap function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Johannes,

Are these patches meant for 3.5?

If so, we will have to modify our AP solution mwifiex AP-STA to set
channel in start_ap itself.

Regards,
Avinash.

On Fri, May 11, 2012 at 2:00 AM, Johannes Berg
<johannes@xxxxxxxxxxxxxxxx> wrote:
> From: Johannes Berg <johannes.berg@xxxxxxxxx>
>
> Instead of setting the channel first and then
> starting the AP, let cfg80211 store the channel
> and provide it as one of the AP settings.
>
> This means that now you have to set the channel
> before you can start an AP interface, but since
> hostapd/wpa_supplicant always do that we're OK
> with this small userspace API change.
>
> Alternatively, it's now possible to give the
> channel as an attribute to the start-ap nl80211
> command as well.
>
> Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx>
> ---
>  drivers/net/wireless/ath/ath6kl/cfg80211.c |   36 +--------------------
>  drivers/net/wireless/ath/ath6kl/core.h     |    3 -
>  include/linux/nl80211.h                    |    2 +
>  include/net/cfg80211.h                     |   12 ++++++-
>  net/mac80211/cfg.c                         |    5 +++
>  net/wireless/nl80211.c                     |   48 ++++++++++++++++++++++++++++-
>  6 files changed, 68 insertions(+), 38 deletions(-)
>
> --- a/include/net/cfg80211.h    2012-05-10 21:42:19.000000000 +0200
> +++ b/include/net/cfg80211.h    2012-05-10 21:51:37.000000000 +0200
> @@ -404,6 +404,8 @@ struct cfg80211_beacon_data {
>  *
>  * Used to configure an AP interface.
>  *
> + * @channel: the channel to start the AP on
> + * @channel_type: the channel type to use
>  * @beacon: beacon data
>  * @beacon_interval: beacon interval
>  * @dtim_period: DTIM period
> @@ -417,6 +419,9 @@ struct cfg80211_beacon_data {
>  * @inactivity_timeout: time in seconds to determine station's inactivity.
>  */
>  struct cfg80211_ap_settings {
> +       struct ieee80211_channel *channel;
> +       enum nl80211_channel_type channel_type;
> +
>        struct cfg80211_beacon_data beacon;
>
>        int beacon_interval, dtim_period;
> @@ -2263,7 +2268,10 @@ struct cfg80211_cached_keys;
>  * @netdev: (private) Used to reference back to the netdev
>  * @current_bss: (private) Used by the internal configuration code
>  * @channel: (private) Used by the internal configuration code to track
> - *     user-set AP, monitor and WDS channels for wireless extensions
> + *     the user-set AP, monitor and WDS channel
> + * @preset_chan: (private) Used by the internal configuration code to
> + *     track the channel to be used for AP later
> + * @preset_chantype: (private) the corresponding channel type
>  * @bssid: (private) Used by the internal configuration code
>  * @ssid: (private) Used by the internal configuration code
>  * @ssid_len: (private) Used by the internal configuration code
> @@ -2314,6 +2322,8 @@ struct wireless_dev {
>
>        struct cfg80211_internal_bss *current_bss; /* associated / joined */
>        struct ieee80211_channel *channel;
> +       struct ieee80211_channel *preset_chan;
> +       enum nl80211_channel_type preset_chantype;
>
>        bool ps;
>        int ps_timeout;
> --- a/net/wireless/nl80211.c    2012-05-10 21:42:19.000000000 +0200
> +++ b/net/wireless/nl80211.c    2012-05-10 22:29:18.000000000 +0200
> @@ -1132,6 +1132,9 @@ static bool nl80211_can_set_dev_channel(
>         * Monitors are special as they are normally slaved to
>         * whatever else is going on, so they behave as though
>         * you tried setting the wiphy channel itself.
> +        *
> +        * For AP/GO modes, it's only for compatibility, you can
> +        * also give the channel to the start-AP command.
>         */
>        return !wdev ||
>                wdev->iftype == NL80211_IFTYPE_AP ||
> @@ -1166,6 +1169,7 @@ static int __nl80211_set_channel(struct
>                                 struct wireless_dev *wdev,
>                                 struct genl_info *info)
>  {
> +       struct ieee80211_channel *channel;
>        enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
>        u32 freq;
>        int result;
> @@ -1187,8 +1191,27 @@ static int __nl80211_set_channel(struct
>                wdev_lock(wdev);
>                result = cfg80211_set_freq(rdev, wdev, freq, channel_type);
>                wdev_unlock(wdev);
> -       } else {
> +       } else switch (wdev->iftype) {
> +       case NL80211_IFTYPE_AP:
> +       case NL80211_IFTYPE_P2P_GO:
> +               if (wdev->beacon_interval) {
> +                       result = -EBUSY;
> +                       break;
> +               }
> +               channel = rdev_freq_to_chan(rdev, freq, channel_type);
> +               if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
> +                                                             channel,
> +                                                             channel_type)) {
> +                       result = -EINVAL;
> +                       break;
> +               }
> +               wdev->preset_chan = channel;
> +               wdev->preset_chantype = channel_type;
> +               result = 0;
> +               break;
> +       default:
>                result = cfg80211_set_freq(rdev, NULL, freq, channel_type);
> +               break;
>        }
>        mutex_unlock(&rdev->devlist_mtx);
>
> @@ -2259,6 +2282,29 @@ static int nl80211_start_ap(struct sk_bu
>                        info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
>        }
>
> +       if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
> +               enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
> +
> +               if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
> +                   !nl80211_valid_channel_type(info, &channel_type))
> +                       return -EINVAL;
> +
> +               params.channel = rdev_freq_to_chan(rdev,
> +                       nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
> +                       channel_type);
> +               if (!params.channel)
> +                       return -EINVAL;
> +               params.channel_type = channel_type;
> +       } else if (wdev->preset_chan) {
> +               params.channel = wdev->preset_chan;
> +               params.channel_type = wdev->preset_chantype;
> +       } else
> +               return -EINVAL;
> +
> +       if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
> +                                         params.channel_type))
> +               return -EINVAL;
> +
>        err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
>        if (!err)
>                wdev->beacon_interval = params.beacon_interval;
> --- a/include/linux/nl80211.h   2012-05-10 21:42:19.000000000 +0200
> +++ b/include/linux/nl80211.h   2012-05-10 21:51:37.000000000 +0200
> @@ -170,6 +170,8 @@
>  *     %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
>  *     %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
>  *     %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
> + *     The channel to use can be set on the interface or be given using the
> + *     %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_WIPHY_CHANNEL_TYPE attrs.
>  * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
>  * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
>  * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
> --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c        2012-05-10 21:42:19.000000000 +0200
> +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c        2012-05-10 21:51:37.000000000 +0200
> @@ -2521,35 +2521,6 @@ static int ath6kl_set_ies(struct ath6kl_
>        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;
> -
> -       return 0;
> -}
> -
>  static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
>                                u8 *rsn_capab)
>  {
> @@ -2721,7 +2692,7 @@ static int ath6kl_start_ap(struct wiphy
>        p.ssid_len = vif->ssid_len;
>        memcpy(p.ssid, vif->ssid, vif->ssid_len);
>        p.dot11_auth_mode = vif->dot11_auth_mode;
> -       p.ch = cpu_to_le16(vif->next_chan);
> +       p.ch = cpu_to_le16(info->channel->center_freq);
>
>        /* Enable uAPSD support by default */
>        res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
> @@ -2745,8 +2716,8 @@ static int ath6kl_start_ap(struct wiphy
>                        return res;
>        }
>
> -       if (ath6kl_set_htcap(vif, vif->next_ch_band,
> -                            vif->next_ch_type != NL80211_CHAN_NO_HT))
> +       if (ath6kl_set_htcap(vif, info->channel->band,
> +                            info->channel_type != NL80211_CHAN_NO_HT))
>                return -EIO;
>
>        /*
> @@ -3213,7 +3184,6 @@ static struct cfg80211_ops ath6kl_cfg802
>        .suspend = __ath6kl_cfg80211_suspend,
>        .resume = __ath6kl_cfg80211_resume,
>  #endif
> -       .set_channel = ath6kl_set_channel,
>        .start_ap = ath6kl_start_ap,
>        .change_beacon = ath6kl_change_beacon,
>        .stop_ap = ath6kl_stop_ap,
> --- a/drivers/net/wireless/ath/ath6kl/core.h    2012-05-10 21:42:19.000000000 +0200
> +++ b/drivers/net/wireless/ath/ath6kl/core.h    2012-05-10 21:51:37.000000000 +0200
> @@ -543,9 +543,6 @@ struct ath6kl_vif {
>        u32 last_cancel_roc_id;
>        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;
> --- a/net/mac80211/cfg.c        2012-05-10 21:51:35.000000000 +0200
> +++ b/net/mac80211/cfg.c        2012-05-10 21:51:37.000000000 +0200
> @@ -823,6 +823,11 @@ static int ieee80211_start_ap(struct wip
>        if (old)
>                return -EALREADY;
>
> +       err = ieee80211_set_channel(wiphy, dev, params->channel,
> +                                   params->channel_type);
> +       if (err)
> +               return err;
> +
>        /*
>         * Apply control port protocol, this allows us to
>         * not encrypt dynamic WEP control frames.
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux