From e7aceef4ac3180bd93d4c0d3fe23775850b6c31d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Feb 2014 14:21:15 +0100 Subject: cfg80211: remove NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL There's no driver using this flag and consequently no userspace application is actually looking at it. As it seems unlikely for any driver to start using it, remove it and the (very little) code that used it. Signed-off-by: Johannes Berg --- include/uapi/linux/nl80211.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index a12e6cae5132..ba1f7625625c 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3843,11 +3843,6 @@ enum nl80211_ap_sme_features { * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested * to work properly to suppport receiving regulatory hints from * cellular base stations. - * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active - * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel - * in the interface combinations, even when it's only used for scan - * and remain-on-channel. This could be due to, for example, the - * remain-on-channel implementation requiring a channel context. * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station * mode @@ -3889,7 +3884,7 @@ enum nl80211_feature_flags { NL80211_FEATURE_HT_IBSS = 1 << 1, NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, - NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, + /* bit 4 is reserved - don't use */ NL80211_FEATURE_SAE = 1 << 5, NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, NL80211_FEATURE_SCAN_FLUSH = 1 << 7, -- cgit v1.2.3-71-gd317 From df942e7ba70cd0a7aa9e0432b8a6a328de2c5574 Mon Sep 17 00:00:00 2001 From: Sunil Dutt Undekari Date: Thu, 20 Feb 2014 16:22:09 +0530 Subject: cfg80211: Pass TDLS peer capability information in tdls_mgmt While framing the TDLS Setup Confirmation frame, the driver needs to know if the TDLS peer is VHT/HT/WMM capable and thus shall construct the VHT/HT operation / WMM parameter elements accordingly. Supplicant determines if the TDLS peer is VHT/HT/WMM capable based on the presence of the respective IEs in the received TDLS Setup Response frame. The host driver should not need to parse the received TDLS Response frame and thus, should be able to rely on the supplicant to indicate the capability of the peer through additional flags while transmitting the TDLS Setup Confirmation frame through tdls_mgmt operations. Signed-off-by: Sunil Dutt Undekari Signed-off-by: Johannes Berg --- drivers/net/wireless/mwifiex/cfg80211.c | 4 ++-- include/net/cfg80211.h | 3 ++- include/uapi/linux/nl80211.h | 21 +++++++++++++++++++++ net/mac80211/cfg.c | 4 ++-- net/wireless/nl80211.c | 7 ++++++- net/wireless/rdev-ops.h | 9 ++++++--- net/wireless/trace.h | 12 ++++++++---- 7 files changed, 47 insertions(+), 13 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 436ba437a4ba..6948a97af839 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2600,8 +2600,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy, static int mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, u8 *peer, u8 action_code, u8 dialog_token, - u16 status_code, const u8 *extra_ies, - size_t extra_ies_len) + u16 status_code, u32 peer_capability, + const u8 *extra_ies, size_t extra_ies_len) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int ret; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9f90554e88c4..c89a5b5bd103 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2465,7 +2465,8 @@ struct cfg80211_ops { int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, u8 *peer, u8 action_code, u8 dialog_token, - u16 status_code, const u8 *buf, size_t len); + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len); int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, u8 *peer, enum nl80211_tdls_operation oper); diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index ba1f7625625c..47d7087513e0 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1575,6 +1575,9 @@ enum nl80211_commands { * advertise values that cannot always be met. In such cases, an attempt * to add a new station entry with @NL80211_CMD_NEW_STATION may fail. * + * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. + * As specified in the &enum nl80211_tdls_peer_capability. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1908,6 +1911,8 @@ enum nl80211_attrs { NL80211_ATTR_MAX_AP_ASSOC_STA, + NL80211_ATTR_TDLS_PEER_CAPABILITY, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -4074,4 +4079,20 @@ struct nl80211_vendor_cmd_info { __u32 subcmd; }; +/** + * enum nl80211_tdls_peer_capability - TDLS peer flags. + * + * Used by tdls_mgmt() to determine which conditional elements need + * to be added to TDLS Setup frames. + * + * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable. + * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable. + * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable. + */ +enum nl80211_tdls_peer_capability { + NL80211_TDLS_PEER_HT = 1<<0, + NL80211_TDLS_PEER_VHT = 1<<1, + NL80211_TDLS_PEER_WMM = 1<<2, +}; + #endif /* __LINUX_NL80211_H */ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3849fd07a321..1acb29109b45 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3644,8 +3644,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, u8 *peer, u8 action_code, u8 dialog_token, - u16 status_code, const u8 *extra_ies, - size_t extra_ies_len) + u16 status_code, u32 peer_capability, + const u8 *extra_ies, size_t extra_ies_len) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 058aa0e1a462..be836098d342 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -384,6 +384,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { .len = IEEE80211_QOS_MAP_LEN_MAX }, [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, + [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, }; /* policy for the key attributes */ @@ -7269,6 +7270,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; u8 action_code, dialog_token; + u32 peer_capability = 0; u16 status_code; u8 *peer; @@ -7287,9 +7289,12 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); + if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]) + peer_capability = + nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]); return rdev_tdls_mgmt(rdev, dev, peer, action_code, - dialog_token, status_code, + dialog_token, status_code, peer_capability, nla_data(info->attrs[NL80211_ATTR_IE]), nla_len(info->attrs[NL80211_ATTR_IE])); } diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index c8e225947adb..74d97d33c938 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -769,13 +769,16 @@ static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev, static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, struct net_device *dev, u8 *peer, u8 action_code, u8 dialog_token, - u16 status_code, const u8 *buf, size_t len) + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len) { int ret; trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, - dialog_token, status_code, buf, len); + dialog_token, status_code, peer_capability, + buf, len); ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, - dialog_token, status_code, buf, len); + dialog_token, status_code, peer_capability, + buf, len); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 5eaeed59db07..aabccf13e07b 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -1468,9 +1468,10 @@ TRACE_EVENT(rdev_sched_scan_start, TRACE_EVENT(rdev_tdls_mgmt, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *peer, u8 action_code, u8 dialog_token, - u16 status_code, const u8 *buf, size_t len), + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len), TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, - buf, len), + peer_capability, buf, len), TP_STRUCT__entry( WIPHY_ENTRY NETDEV_ENTRY @@ -1478,6 +1479,7 @@ TRACE_EVENT(rdev_tdls_mgmt, __field(u8, action_code) __field(u8, dialog_token) __field(u16, status_code) + __field(u32, peer_capability) __dynamic_array(u8, buf, len) ), TP_fast_assign( @@ -1487,13 +1489,15 @@ TRACE_EVENT(rdev_tdls_mgmt, __entry->action_code = action_code; __entry->dialog_token = dialog_token; __entry->status_code = status_code; + __entry->peer_capability = peer_capability; memcpy(__get_dynamic_array(buf), buf, len); ), TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " - "dialog_token: %u, status_code: %u, buf: %#.2x ", + "dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ", WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->action_code, __entry->dialog_token, - __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0]) + __entry->status_code, __entry->peer_capability, + ((u8 *)__get_dynamic_array(buf))[0]) ); TRACE_EVENT(rdev_dump_survey, -- cgit v1.2.3-71-gd317 From d9b8396a52b4e857263eeb9e1eba474ea11c19bf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 13 Feb 2014 17:16:10 +0100 Subject: cfg80211: document sched_scan_stop synchronous behaviour Due to userspace assumptions, the sched_scan_stop operation must be synchronous, i.e. once it returns a new scheduled scan must be able to start immediately. Document this in the API. Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 7 ++++++- include/uapi/linux/nl80211.h | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index c89a5b5bd103..7c9fe4b05927 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2206,7 +2206,12 @@ struct cfg80211_qos_map { * @set_cqm_txe_config: Configure connection quality monitor TX error * thresholds. * @sched_scan_start: Tell the driver to start a scheduled scan. - * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. + * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. This + * call must stop the scheduled scan and be ready for starting a new one + * before it returns, i.e. @sched_scan_start may be called immediately + * after that again and should not fail in that case. The driver should + * not call cfg80211_sched_scan_stopped() for a requested stop (when this + * method returns 0.) * * @mgmt_frame_register: Notify driver that a management frame type was * registered. Note that this callback may not sleep, and cannot run diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 47d7087513e0..81481cff1dc1 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -303,8 +303,9 @@ * passed, all channels allowed for the current regulatory domain * are used. Extra IEs can also be passed from the userspace by * using the %NL80211_ATTR_IE attribute. - * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT - * if scheduled scan is not running. + * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if + * scheduled scan is not running. The caller may assume that as soon + * as the call returns, it is safe to start a new scheduled scan again. * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan * results available. * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has -- cgit v1.2.3-71-gd317 From b0dfd2ea12d92b49639ad84f24ddd00c7ac144b5 Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Thu, 20 Feb 2014 13:52:16 +0100 Subject: cfg80211: regulatory: introduce NL80211_RRF_AUTO_BW rule flag Introduce NL80211_RRF_AUTO_BW rule flag. If this flag set maximum available bandwidth should be calculated base on contiguous rules and wider channels will be allowed to cross multiple contiguous/overlapping frequency ranges. In case of old kernels maximum bandwidth from regulatory rule will be used, while there is no NL80211_RRF_AUTO_BW flag. This fixes the previous commit 9752482083066af7ac18a5ca376f ("cfg80211: regulatory introduce maximum bandwidth calculation") which was found to be a problem for userspace API compatibility. Signed-off-by: Janusz Dziedzic [edit commit log, use sizeof()] Signed-off-by: Johannes Berg Signed-off-by: Johannes Berg --- include/uapi/linux/nl80211.h | 9 ++--- net/wireless/genregdb.awk | 2 ++ net/wireless/nl80211.c | 7 ++-- net/wireless/reg.c | 83 +++++++++++++++++++++++++------------------- 4 files changed, 58 insertions(+), 43 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 81481cff1dc1..ff72cab3cd3a 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2443,10 +2443,7 @@ enum nl80211_reg_type { * in KHz. This is not a center a frequency but an actual regulatory * band edge. * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this - * frequency range, in KHz. If not present or 0, maximum available - * bandwidth should be calculated base on contiguous rules and wider - * channels will be allowed to cross multiple contiguous/overlapping - * frequency ranges. + * frequency range, in KHz. * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain * for a given frequency range. The value is in mBi (100 * dBi). * If you don't have one then don't send this. @@ -2517,6 +2514,9 @@ enum nl80211_sched_scan_match_attr { * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, * this includes probe requests or modes of operation that require * beaconing. + * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated + * base on contiguous rules and wider channels will be allowed to cross + * multiple contiguous/overlapping frequency ranges. */ enum nl80211_reg_rule_flags { NL80211_RRF_NO_OFDM = 1<<0, @@ -2528,6 +2528,7 @@ enum nl80211_reg_rule_flags { NL80211_RRF_PTMP_ONLY = 1<<6, NL80211_RRF_NO_IR = 1<<7, __NL80211_RRF_NO_IBSS = 1<<8, + NL80211_RRF_AUTO_BW = 1<<11, }; #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk index 9a8217d2a908..fdfd3f063a9b 100644 --- a/net/wireless/genregdb.awk +++ b/net/wireless/genregdb.awk @@ -105,6 +105,8 @@ function parse_reg_rule() flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " } else if (flagarray[arg] == "NO-IR") { flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " + } else if (flagarray[arg] == "AUTO-BW") { + flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | " } } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index be836098d342..1e5a434e4224 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4628,6 +4628,8 @@ static int parse_reg_rule(struct nlattr *tb[], return -EINVAL; if (!tb[NL80211_ATTR_FREQ_RANGE_END]) return -EINVAL; + if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) + return -EINVAL; if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) return -EINVAL; @@ -4637,9 +4639,8 @@ static int parse_reg_rule(struct nlattr *tb[], nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); freq_range->end_freq_khz = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); - if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) - freq_range->max_bandwidth_khz = - nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); + freq_range->max_bandwidth_khz = + nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); power_rule->max_eirp = nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 27c5253e7a61..6b6f33ad78f2 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) break; - if (freq_range_tmp->max_bandwidth_khz) - break; - freq_range = freq_range_tmp; } @@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) break; - if (freq_range_tmp->max_bandwidth_khz) - break; - freq_range = freq_range_tmp; } @@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, max_bandwidth1 = freq_range1->max_bandwidth_khz; max_bandwidth2 = freq_range2->max_bandwidth_khz; - /* - * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set - * output bandwidth as 0 (auto calculation). Next we will - * calculate this correctly in handle_channel function. - * In other case calculate output bandwidth here. - */ - if (max_bandwidth1 || max_bandwidth2) { - if (!max_bandwidth1) - max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); - if (!max_bandwidth2) - max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); - } + if (rule1->flags & NL80211_RRF_AUTO_BW) + max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); + if (rule2->flags & NL80211_RRF_AUTO_BW) + max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); + intersected_rule->flags = rule1->flags | rule2->flags; + + /* + * In case NL80211_RRF_AUTO_BW requested for both rules + * set AUTO_BW in intersected rule also. Next we will + * calculate BW correctly in handle_channel function. + * In other case remove AUTO_BW flag while we calculate + * maximum bandwidth correctly and auto calculation is + * not required. + */ + if ((rule1->flags & NL80211_RRF_AUTO_BW) && + (rule2->flags & NL80211_RRF_AUTO_BW)) + intersected_rule->flags |= NL80211_RRF_AUTO_BW; + else + intersected_rule->flags &= ~NL80211_RRF_AUTO_BW; + freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; if (freq_range->max_bandwidth_khz > freq_diff) freq_range->max_bandwidth_khz = freq_diff; @@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, power_rule2->max_antenna_gain); - intersected_rule->flags = rule1->flags | rule2->flags; - if (!is_valid_reg_rule(intersected_rule)) return -EINVAL; @@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator) EXPORT_SYMBOL(reg_initiator_name); #ifdef CONFIG_CFG80211_REG_DEBUG -static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, +static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, + struct ieee80211_channel *chan, const struct ieee80211_reg_rule *reg_rule) { const struct ieee80211_power_rule *power_rule; const struct ieee80211_freq_range *freq_range; - char max_antenna_gain[32]; + char max_antenna_gain[32], bw[32]; power_rule = ®_rule->power_rule; freq_range = ®_rule->freq_range; if (!power_rule->max_antenna_gain) - snprintf(max_antenna_gain, 32, "N/A"); + snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A"); else - snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); + snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d", + power_rule->max_antenna_gain); + + if (reg_rule->flags & NL80211_RRF_AUTO_BW) + snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", + freq_range->max_bandwidth_khz, + reg_get_max_bandwidth(regd, reg_rule)); + else + snprintf(bw, sizeof(bw), "%d KHz", + freq_range->max_bandwidth_khz); REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", chan->center_freq); - REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n", + REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n", freq_range->start_freq_khz, freq_range->end_freq_khz, - freq_range->max_bandwidth_khz, max_antenna_gain, + bw, max_antenna_gain, power_rule->max_eirp); } #else -static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, +static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, + struct ieee80211_channel *chan, const struct ieee80211_reg_rule *reg_rule) { return; @@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy, return; } - chan_reg_rule_print_dbg(chan, reg_rule); + regd = reg_get_regdomain(wiphy); + chan_reg_rule_print_dbg(regd, chan, reg_rule); power_rule = ®_rule->power_rule; freq_range = ®_rule->freq_range; max_bandwidth_khz = freq_range->max_bandwidth_khz; /* Check if auto calculation requested */ - if (!max_bandwidth_khz) { - regd = reg_get_regdomain(wiphy); + if (reg_rule->flags & NL80211_RRF_AUTO_BW) max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); - } if (max_bandwidth_khz < MHZ_TO_KHZ(40)) bw_flags = IEEE80211_CHAN_NO_HT40; @@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy, return; } - chan_reg_rule_print_dbg(chan, reg_rule); + chan_reg_rule_print_dbg(regd, chan, reg_rule); power_rule = ®_rule->power_rule; freq_range = ®_rule->freq_range; max_bandwidth_khz = freq_range->max_bandwidth_khz; /* Check if auto calculation requested */ - if (!max_bandwidth_khz) + if (reg_rule->flags & NL80211_RRF_AUTO_BW) max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); if (max_bandwidth_khz < MHZ_TO_KHZ(40)) @@ -2254,11 +2264,12 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) freq_range = ®_rule->freq_range; power_rule = ®_rule->power_rule; - if (!freq_range->max_bandwidth_khz) - snprintf(bw, 32, "%d KHz, AUTO", + if (reg_rule->flags & NL80211_RRF_AUTO_BW) + snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", + freq_range->max_bandwidth_khz, reg_get_max_bandwidth(rd, reg_rule)); else - snprintf(bw, 32, "%d KHz", + snprintf(bw, sizeof(bw), "%d KHz", freq_range->max_bandwidth_khz); /* -- cgit v1.2.3-71-gd317