Commit 518aa1b5 authored by David S. Miller's avatar David S. Miller
parents 66f9a259 67474303
......@@ -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, &reg_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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment