|
@@ -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)
|
|
if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz)
|
|
break;
|
|
break;
|
|
|
|
|
|
- if (freq_range_tmp->max_bandwidth_khz)
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
freq_range = freq_range_tmp;
|
|
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)
|
|
if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz)
|
|
break;
|
|
break;
|
|
|
|
|
|
- if (freq_range_tmp->max_bandwidth_khz)
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
freq_range = freq_range_tmp;
|
|
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_bandwidth1 = freq_range1->max_bandwidth_khz;
|
|
max_bandwidth2 = freq_range2->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);
|
|
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;
|
|
freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
|
|
if (freq_range->max_bandwidth_khz > freq_diff)
|
|
if (freq_range->max_bandwidth_khz > freq_diff)
|
|
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_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
|
|
power_rule2->max_antenna_gain);
|
|
power_rule2->max_antenna_gain);
|
|
|
|
|
|
- intersected_rule->flags = rule1->flags | rule2->flags;
|
|
|
|
-
|
|
|
|
if (!is_valid_reg_rule(intersected_rule))
|
|
if (!is_valid_reg_rule(intersected_rule))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
@@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
|
|
EXPORT_SYMBOL(reg_initiator_name);
|
|
EXPORT_SYMBOL(reg_initiator_name);
|
|
|
|
|
|
#ifdef CONFIG_CFG80211_REG_DEBUG
|
|
#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_reg_rule *reg_rule)
|
|
{
|
|
{
|
|
const struct ieee80211_power_rule *power_rule;
|
|
const struct ieee80211_power_rule *power_rule;
|
|
const struct ieee80211_freq_range *freq_range;
|
|
const struct ieee80211_freq_range *freq_range;
|
|
- char max_antenna_gain[32];
|
|
|
|
|
|
+ char max_antenna_gain[32], bw[32];
|
|
|
|
|
|
power_rule = ®_rule->power_rule;
|
|
power_rule = ®_rule->power_rule;
|
|
freq_range = ®_rule->freq_range;
|
|
freq_range = ®_rule->freq_range;
|
|
|
|
|
|
if (!power_rule->max_antenna_gain)
|
|
if (!power_rule->max_antenna_gain)
|
|
- snprintf(max_antenna_gain, 32, "N/A");
|
|
|
|
|
|
+ snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A");
|
|
else
|
|
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",
|
|
REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
|
|
chan->center_freq);
|
|
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->start_freq_khz, freq_range->end_freq_khz,
|
|
- freq_range->max_bandwidth_khz, max_antenna_gain,
|
|
|
|
|
|
+ bw, max_antenna_gain,
|
|
power_rule->max_eirp);
|
|
power_rule->max_eirp);
|
|
}
|
|
}
|
|
#else
|
|
#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)
|
|
const struct ieee80211_reg_rule *reg_rule)
|
|
{
|
|
{
|
|
return;
|
|
return;
|
|
@@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy,
|
|
return;
|
|
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;
|
|
power_rule = ®_rule->power_rule;
|
|
freq_range = ®_rule->freq_range;
|
|
freq_range = ®_rule->freq_range;
|
|
|
|
|
|
max_bandwidth_khz = freq_range->max_bandwidth_khz;
|
|
max_bandwidth_khz = freq_range->max_bandwidth_khz;
|
|
/* Check if auto calculation requested */
|
|
/* 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);
|
|
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
|
|
- }
|
|
|
|
|
|
|
|
if (max_bandwidth_khz < MHZ_TO_KHZ(40))
|
|
if (max_bandwidth_khz < MHZ_TO_KHZ(40))
|
|
bw_flags = IEEE80211_CHAN_NO_HT40;
|
|
bw_flags = IEEE80211_CHAN_NO_HT40;
|
|
@@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- chan_reg_rule_print_dbg(chan, reg_rule);
|
|
|
|
|
|
+ chan_reg_rule_print_dbg(regd, chan, reg_rule);
|
|
|
|
|
|
power_rule = ®_rule->power_rule;
|
|
power_rule = ®_rule->power_rule;
|
|
freq_range = ®_rule->freq_range;
|
|
freq_range = ®_rule->freq_range;
|
|
|
|
|
|
max_bandwidth_khz = freq_range->max_bandwidth_khz;
|
|
max_bandwidth_khz = freq_range->max_bandwidth_khz;
|
|
/* Check if auto calculation requested */
|
|
/* 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);
|
|
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
|
|
|
|
|
|
if (max_bandwidth_khz < MHZ_TO_KHZ(40))
|
|
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;
|
|
freq_range = ®_rule->freq_range;
|
|
power_rule = ®_rule->power_rule;
|
|
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));
|
|
reg_get_max_bandwidth(rd, reg_rule));
|
|
else
|
|
else
|
|
- snprintf(bw, 32, "%d KHz",
|
|
|
|
|
|
+ snprintf(bw, sizeof(bw), "%d KHz",
|
|
freq_range->max_bandwidth_khz);
|
|
freq_range->max_bandwidth_khz);
|
|
|
|
|
|
/*
|
|
/*
|