Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
This commit is contained in:
commit
518aa1b544
@ -490,7 +490,7 @@ static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
|
||||
|
||||
static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
|
||||
{
|
||||
if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG))
|
||||
if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
|
||||
return 0;
|
||||
if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
|
||||
return 0;
|
||||
|
@ -228,7 +228,7 @@ enum {
|
||||
};
|
||||
|
||||
#define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \
|
||||
(!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
|
||||
(~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
|
||||
#define REG_DOMAIN_5GHZ_MASK REQ_MASK
|
||||
|
||||
static struct reg_dmn_pair_mapping regDomainPairs[] = {
|
||||
|
@ -224,7 +224,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
IWL_ERROR("Error: Response NULL in '%s'\n",
|
||||
get_cmd_string(cmd->id));
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
goto cancel;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
@ -745,7 +745,7 @@ static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_
|
||||
IWL_ERROR("Error: Response NULL in '%s'\n",
|
||||
get_cmd_string(cmd->id));
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
goto cancel;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
@ -32,7 +32,7 @@ struct txpd {
|
||||
u8 pktdelay_2ms;
|
||||
/* reserved */
|
||||
u8 reserved1;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* RxPD Descriptor */
|
||||
struct rxpd {
|
||||
@ -63,7 +63,7 @@ struct rxpd {
|
||||
/* Pkt Priority */
|
||||
u8 priority;
|
||||
u8 reserved[3];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_header {
|
||||
__le16 command;
|
||||
@ -97,7 +97,7 @@ struct enc_key {
|
||||
struct lbs_offset_value {
|
||||
u32 offset;
|
||||
u32 value;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Define general data structure */
|
||||
/* cmd_DS_GEN */
|
||||
@ -107,7 +107,7 @@ struct cmd_ds_gen {
|
||||
__le16 seqnum;
|
||||
__le16 result;
|
||||
void *cmdresp[0];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define S_DS_GEN sizeof(struct cmd_ds_gen)
|
||||
|
||||
@ -163,7 +163,7 @@ struct cmd_ds_802_11_subscribe_event {
|
||||
* bump this up a bit.
|
||||
*/
|
||||
uint8_t tlv[128];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* This scan handle Country Information IE(802.11d compliant)
|
||||
@ -180,7 +180,7 @@ struct cmd_ds_802_11_scan {
|
||||
mrvlietypes_chanlistparamset_t ChanListParamSet;
|
||||
mrvlietypes_ratesparamset_t OpRateSet;
|
||||
#endif
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_scan_rsp {
|
||||
struct cmd_header hdr;
|
||||
@ -188,7 +188,7 @@ struct cmd_ds_802_11_scan_rsp {
|
||||
__le16 bssdescriptsize;
|
||||
uint8_t nr_sets;
|
||||
uint8_t bssdesc_and_tlvbuffer[0];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_get_log {
|
||||
struct cmd_header hdr;
|
||||
@ -206,33 +206,33 @@ struct cmd_ds_802_11_get_log {
|
||||
__le32 fcserror;
|
||||
__le32 txframe;
|
||||
__le32 wepundecryptable;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_mac_control {
|
||||
struct cmd_header hdr;
|
||||
__le16 action;
|
||||
u16 reserved;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_mac_multicast_adr {
|
||||
struct cmd_header hdr;
|
||||
__le16 action;
|
||||
__le16 nr_of_adrs;
|
||||
u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_authenticate {
|
||||
u8 macaddr[ETH_ALEN];
|
||||
u8 authtype;
|
||||
u8 reserved[10];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_deauthenticate {
|
||||
struct cmd_header hdr;
|
||||
|
||||
u8 macaddr[ETH_ALEN];
|
||||
__le16 reasoncode;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_associate {
|
||||
u8 peerstaaddr[6];
|
||||
@ -251,7 +251,7 @@ struct cmd_ds_802_11_associate {
|
||||
|
||||
struct cmd_ds_802_11_associate_rsp {
|
||||
struct ieeetypes_assocrsp assocRsp;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_set_wep {
|
||||
struct cmd_header hdr;
|
||||
@ -265,7 +265,7 @@ struct cmd_ds_802_11_set_wep {
|
||||
/* 40, 128bit or TXWEP */
|
||||
uint8_t keytype[4];
|
||||
uint8_t keymaterial[4][16];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_3_get_stat {
|
||||
__le32 xmitok;
|
||||
@ -274,7 +274,7 @@ struct cmd_ds_802_3_get_stat {
|
||||
__le32 rcverror;
|
||||
__le32 rcvnobuffer;
|
||||
__le32 rcvcrcerror;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_get_stat {
|
||||
__le32 txfragmentcnt;
|
||||
@ -294,7 +294,7 @@ struct cmd_ds_802_11_get_stat {
|
||||
__le32 txbeacon;
|
||||
__le32 rxbeacon;
|
||||
__le32 wepundecryptable;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_snmp_mib {
|
||||
struct cmd_header hdr;
|
||||
@ -303,58 +303,58 @@ struct cmd_ds_802_11_snmp_mib {
|
||||
__le16 oid;
|
||||
__le16 bufsize;
|
||||
u8 value[128];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_mac_reg_map {
|
||||
__le16 buffersize;
|
||||
u8 regmap[128];
|
||||
__le16 reserved;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_bbp_reg_map {
|
||||
__le16 buffersize;
|
||||
u8 regmap[128];
|
||||
__le16 reserved;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_rf_reg_map {
|
||||
__le16 buffersize;
|
||||
u8 regmap[64];
|
||||
__le16 reserved;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_mac_reg_access {
|
||||
__le16 action;
|
||||
__le16 offset;
|
||||
__le32 value;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_bbp_reg_access {
|
||||
__le16 action;
|
||||
__le16 offset;
|
||||
u8 value;
|
||||
u8 reserved[3];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_rf_reg_access {
|
||||
__le16 action;
|
||||
__le16 offset;
|
||||
u8 value;
|
||||
u8 reserved[3];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_radio_control {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 control;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_beacon_control {
|
||||
__le16 action;
|
||||
__le16 beacon_enable;
|
||||
__le16 beacon_period;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_sleep_params {
|
||||
struct cmd_header hdr;
|
||||
@ -379,7 +379,7 @@ struct cmd_ds_802_11_sleep_params {
|
||||
|
||||
/* reserved field, should be set to zero */
|
||||
__le16 reserved;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_inactivity_timeout {
|
||||
struct cmd_header hdr;
|
||||
@ -389,7 +389,7 @@ struct cmd_ds_802_11_inactivity_timeout {
|
||||
|
||||
/* Inactivity timeout in msec */
|
||||
__le16 timeout;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_rf_channel {
|
||||
struct cmd_header hdr;
|
||||
@ -399,7 +399,7 @@ struct cmd_ds_802_11_rf_channel {
|
||||
__le16 rftype; /* unused */
|
||||
__le16 reserved; /* unused */
|
||||
u8 channellist[32]; /* unused */
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_rssi {
|
||||
/* weighting factor */
|
||||
@ -408,21 +408,21 @@ struct cmd_ds_802_11_rssi {
|
||||
__le16 reserved_0;
|
||||
__le16 reserved_1;
|
||||
__le16 reserved_2;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_rssi_rsp {
|
||||
__le16 SNR;
|
||||
__le16 noisefloor;
|
||||
__le16 avgSNR;
|
||||
__le16 avgnoisefloor;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_mac_address {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
u8 macadd[ETH_ALEN];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_rf_tx_power {
|
||||
struct cmd_header hdr;
|
||||
@ -431,7 +431,7 @@ struct cmd_ds_802_11_rf_tx_power {
|
||||
__le16 curlevel;
|
||||
s8 maxlevel;
|
||||
s8 minlevel;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_rf_antenna {
|
||||
__le16 action;
|
||||
@ -439,33 +439,33 @@ struct cmd_ds_802_11_rf_antenna {
|
||||
/* Number of antennas or 0xffff(diversity) */
|
||||
__le16 antennamode;
|
||||
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_monitor_mode {
|
||||
__le16 action;
|
||||
__le16 mode;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_set_boot2_ver {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 version;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_fw_wake_method {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 method;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_sleep_period {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 period;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_ps_mode {
|
||||
__le16 action;
|
||||
@ -473,7 +473,7 @@ struct cmd_ds_802_11_ps_mode {
|
||||
__le16 multipledtim;
|
||||
__le16 reserved;
|
||||
__le16 locallisteninterval;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_confirm_sleep {
|
||||
struct cmd_header hdr;
|
||||
@ -483,7 +483,7 @@ struct cmd_confirm_sleep {
|
||||
__le16 multipledtim;
|
||||
__le16 reserved;
|
||||
__le16 locallisteninterval;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_data_rate {
|
||||
struct cmd_header hdr;
|
||||
@ -491,14 +491,14 @@ struct cmd_ds_802_11_data_rate {
|
||||
__le16 action;
|
||||
__le16 reserved;
|
||||
u8 rates[MAX_RATES];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_rate_adapt_rateset {
|
||||
struct cmd_header hdr;
|
||||
__le16 action;
|
||||
__le16 enablehwauto;
|
||||
__le16 bitmap;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_802_11_ad_hoc_start {
|
||||
struct cmd_header hdr;
|
||||
@ -520,7 +520,7 @@ struct cmd_ds_802_11_ad_hoc_result {
|
||||
|
||||
u8 pad[3];
|
||||
u8 bssid[ETH_ALEN];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct adhoc_bssdesc {
|
||||
u8 bssid[ETH_ALEN];
|
||||
@ -578,7 +578,7 @@ struct MrvlIEtype_keyParamSet {
|
||||
|
||||
/* key material of size keylen */
|
||||
u8 key[32];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define MAX_WOL_RULES 16
|
||||
|
||||
@ -590,7 +590,7 @@ struct host_wol_rule {
|
||||
__le16 reserve;
|
||||
__be32 sig_mask;
|
||||
__be32 signature;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct wol_config {
|
||||
uint8_t action;
|
||||
@ -598,8 +598,7 @@ struct wol_config {
|
||||
uint8_t no_rules_in_cmd;
|
||||
uint8_t result;
|
||||
struct host_wol_rule rule[MAX_WOL_RULES];
|
||||
};
|
||||
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct cmd_ds_host_sleep {
|
||||
struct cmd_header hdr;
|
||||
|
@ -1147,7 +1147,7 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
|
||||
|
||||
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
|
||||
sizeof(struct p54_hdr) + sizeof(*tim),
|
||||
P54_CONTROL_TYPE_TIM, GFP_KERNEL);
|
||||
P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1610,7 +1610,7 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
|
||||
|
||||
err:
|
||||
printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
|
||||
kfree_skb(skb);
|
||||
p54_free_skb(dev, skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -2077,7 +2077,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
|
||||
algo = P54_CRYPTO_AESCCMP;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->flags))
|
||||
if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
|
||||
return;
|
||||
|
||||
cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
|
||||
|
@ -322,7 +322,6 @@ struct ieee80211_tx_rate {
|
||||
* @control: union for control data
|
||||
* @status: union for status data
|
||||
* @driver_data: array of driver_data pointers
|
||||
* @retry_count: number of retries
|
||||
* @ampdu_ack_len: number of aggregated frames.
|
||||
* relevant only if IEEE80211_TX_STATUS_AMPDU was set.
|
||||
* @ampdu_ack_map: block ack bit map for the aggregation.
|
||||
|
@ -195,7 +195,6 @@ struct sta_ampdu_mlme {
|
||||
* @tx_packets: number of RX/TX MSDUs
|
||||
* @tx_bytes: number of bytes transmitted to this STA
|
||||
* @tx_fragments: number of transmitted MPDUs
|
||||
* @last_txrate: description of the last used transmit rate
|
||||
* @tid_seq: per-TID sequence numbers for sending to this STA
|
||||
* @ampdu_mlme: A-MPDU state machine state
|
||||
* @timer_to_tid: identity mapping to ID timers
|
||||
|
@ -421,6 +421,31 @@ static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* freq_in_rule_band - tells us if a frequency is in a frequency band
|
||||
* @freq_range: frequency rule we want to query
|
||||
* @freq_khz: frequency we are inquiring about
|
||||
*
|
||||
* This lets us know if a specific frequency rule is or is not relevant to
|
||||
* a specific frequency's band. Bands are device specific and artificial
|
||||
* definitions (the "2.4 GHz band" and the "5 GHz band"), however it is
|
||||
* safe for now to assume that a frequency rule should not be part of a
|
||||
* frequency's band if the start freq or end freq are off by more than 2 GHz.
|
||||
* This resolution can be lowered and should be considered as we add
|
||||
* regulatory rule support for other "bands".
|
||||
**/
|
||||
static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
|
||||
u32 freq_khz)
|
||||
{
|
||||
#define ONE_GHZ_IN_KHZ 1000000
|
||||
if (abs(freq_khz - freq_range->start_freq_khz) <= (2 * ONE_GHZ_IN_KHZ))
|
||||
return true;
|
||||
if (abs(freq_khz - freq_range->end_freq_khz) <= (2 * ONE_GHZ_IN_KHZ))
|
||||
return true;
|
||||
return false;
|
||||
#undef ONE_GHZ_IN_KHZ
|
||||
}
|
||||
|
||||
/* Converts a country IE to a regulatory domain. A regulatory domain
|
||||
* structure has a lot of information which the IE doesn't yet have,
|
||||
* so for the other values we use upper max values as we will intersect
|
||||
@ -538,6 +563,7 @@ static struct ieee80211_regdomain *country_ie_2_rd(
|
||||
|
||||
/* This time around we fill in the rd */
|
||||
while (country_ie_len >= 3) {
|
||||
int end_channel = 0;
|
||||
struct ieee80211_country_ie_triplet *triplet =
|
||||
(struct ieee80211_country_ie_triplet *) country_ie;
|
||||
struct ieee80211_reg_rule *reg_rule = NULL;
|
||||
@ -559,6 +585,23 @@ static struct ieee80211_regdomain *country_ie_2_rd(
|
||||
|
||||
reg_rule->flags = flags;
|
||||
|
||||
/* 2 GHz */
|
||||
if (triplet->chans.first_channel <= 14)
|
||||
end_channel = triplet->chans.first_channel +
|
||||
triplet->chans.num_channels;
|
||||
else
|
||||
/*
|
||||
* 5 GHz -- For example in country IEs if the first
|
||||
* channel given is 36 and the number of channels is 4
|
||||
* then the individual channel numbers defined for the
|
||||
* 5 GHz PHY by these parameters are: 36, 40, 44, and 48
|
||||
* and not 36, 37, 38, 39.
|
||||
*
|
||||
* See: http://tinyurl.com/11d-clarification
|
||||
*/
|
||||
end_channel = triplet->chans.first_channel +
|
||||
(4 * (triplet->chans.num_channels - 1));
|
||||
|
||||
/* The +10 is since the regulatory domain expects
|
||||
* the actual band edge, not the center of freq for
|
||||
* its start and end freqs, assuming 20 MHz bandwidth on
|
||||
@ -568,8 +611,7 @@ static struct ieee80211_regdomain *country_ie_2_rd(
|
||||
triplet->chans.first_channel) - 10);
|
||||
freq_range->end_freq_khz =
|
||||
MHZ_TO_KHZ(ieee80211_channel_to_frequency(
|
||||
triplet->chans.first_channel +
|
||||
triplet->chans.num_channels) + 10);
|
||||
end_channel) + 10);
|
||||
|
||||
/* Large arbitrary values, we intersect later */
|
||||
/* Increment this if we ever support >= 40 MHz channels
|
||||
@ -748,12 +790,23 @@ static u32 map_regdom_flags(u32 rd_flags)
|
||||
* this value to the maximum allowed bandwidth.
|
||||
* @reg_rule: the regulatory rule which we have for this frequency
|
||||
*
|
||||
* Use this function to get the regulatory rule for a specific frequency.
|
||||
* Use this function to get the regulatory rule for a specific frequency on
|
||||
* a given wireless device. If the device has a specific regulatory domain
|
||||
* it wants to follow we respect that unless a country IE has been received
|
||||
* and processed already.
|
||||
*
|
||||
* Returns 0 if it was able to find a valid regulatory rule which does
|
||||
* apply to the given center_freq otherwise it returns non-zero. It will
|
||||
* also return -ERANGE if we determine the given center_freq does not even have
|
||||
* a regulatory rule for a frequency range in the center_freq's band. See
|
||||
* freq_in_rule_band() for our current definition of a band -- this is purely
|
||||
* subjective and right now its 802.11 specific.
|
||||
*/
|
||||
static int freq_reg_info(u32 center_freq, u32 *bandwidth,
|
||||
const struct ieee80211_reg_rule **reg_rule)
|
||||
{
|
||||
int i;
|
||||
bool band_rule_found = false;
|
||||
u32 max_bandwidth = 0;
|
||||
|
||||
if (!cfg80211_regdomain)
|
||||
@ -767,7 +820,15 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth,
|
||||
rr = &cfg80211_regdomain->reg_rules[i];
|
||||
fr = &rr->freq_range;
|
||||
pr = &rr->power_rule;
|
||||
|
||||
/* We only need to know if one frequency rule was
|
||||
* was in center_freq's band, that's enough, so lets
|
||||
* not overwrite it once found */
|
||||
if (!band_rule_found)
|
||||
band_rule_found = freq_in_rule_band(fr, center_freq);
|
||||
|
||||
max_bandwidth = freq_max_bandwidth(fr, center_freq);
|
||||
|
||||
if (max_bandwidth && *bandwidth <= max_bandwidth) {
|
||||
*reg_rule = rr;
|
||||
*bandwidth = max_bandwidth;
|
||||
@ -775,23 +836,64 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth,
|
||||
}
|
||||
}
|
||||
|
||||
if (!band_rule_found)
|
||||
return -ERANGE;
|
||||
|
||||
return !max_bandwidth;
|
||||
}
|
||||
|
||||
static void handle_channel(struct ieee80211_channel *chan)
|
||||
static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
|
||||
unsigned int chan_idx)
|
||||
{
|
||||
int r;
|
||||
u32 flags = chan->orig_flags;
|
||||
u32 flags;
|
||||
u32 max_bandwidth = 0;
|
||||
const struct ieee80211_reg_rule *reg_rule = NULL;
|
||||
const struct ieee80211_power_rule *power_rule = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *chan;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
BUG_ON(chan_idx >= sband->n_channels);
|
||||
chan = &sband->channels[chan_idx];
|
||||
|
||||
flags = chan->orig_flags;
|
||||
|
||||
r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq),
|
||||
&max_bandwidth, ®_rule);
|
||||
|
||||
if (r) {
|
||||
flags |= IEEE80211_CHAN_DISABLED;
|
||||
chan->flags = flags;
|
||||
/* This means no regulatory rule was found in the country IE
|
||||
* with a frequency range on the center_freq's band, since
|
||||
* IEEE-802.11 allows for a country IE to have a subset of the
|
||||
* regulatory information provided in a country we ignore
|
||||
* disabling the channel unless at least one reg rule was
|
||||
* found on the center_freq's band. For details see this
|
||||
* clarification:
|
||||
*
|
||||
* http://tinyurl.com/11d-clarification
|
||||
*/
|
||||
if (r == -ERANGE &&
|
||||
last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
|
||||
#ifdef CONFIG_CFG80211_REG_DEBUG
|
||||
printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz "
|
||||
"intact on %s - no rule found in band on "
|
||||
"Country IE\n",
|
||||
chan->center_freq, wiphy_name(wiphy));
|
||||
#endif
|
||||
} else {
|
||||
/* In this case we know the country IE has at least one reg rule
|
||||
* for the band so we respect its band definitions */
|
||||
#ifdef CONFIG_CFG80211_REG_DEBUG
|
||||
if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
|
||||
printk(KERN_DEBUG "cfg80211: Disabling "
|
||||
"channel %d MHz on %s due to "
|
||||
"Country IE\n",
|
||||
chan->center_freq, wiphy_name(wiphy));
|
||||
#endif
|
||||
flags |= IEEE80211_CHAN_DISABLED;
|
||||
chan->flags = flags;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -808,12 +910,16 @@ static void handle_channel(struct ieee80211_channel *chan)
|
||||
chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
|
||||
}
|
||||
|
||||
static void handle_band(struct ieee80211_supported_band *sband)
|
||||
static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
BUG_ON(!wiphy->bands[band]);
|
||||
sband = wiphy->bands[band];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++)
|
||||
handle_channel(&sband->channels[i]);
|
||||
handle_channel(wiphy, band, i);
|
||||
}
|
||||
|
||||
static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
|
||||
@ -840,7 +946,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
|
||||
enum ieee80211_band band;
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
if (wiphy->bands[band])
|
||||
handle_band(wiphy->bands[band]);
|
||||
handle_band(wiphy, band);
|
||||
if (wiphy->reg_notifier)
|
||||
wiphy->reg_notifier(wiphy, setby);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user