forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl-core.h
This commit is contained in:
commit
9d88477c41
@ -2966,7 +2966,6 @@ F: drivers/net/ixgb/
|
||||
F: drivers/net/ixgbe/
|
||||
|
||||
INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
|
||||
M: Zhu Yi <yi.zhu@intel.com>
|
||||
M: Reinette Chatre <reinette.chatre@intel.com>
|
||||
M: Intel Linux Wireless <ilw@linux.intel.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
@ -2976,7 +2975,6 @@ F: Documentation/networking/README.ipw2100
|
||||
F: drivers/net/wireless/ipw2x00/ipw2100.*
|
||||
|
||||
INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
|
||||
M: Zhu Yi <yi.zhu@intel.com>
|
||||
M: Reinette Chatre <reinette.chatre@intel.com>
|
||||
M: Intel Linux Wireless <ilw@linux.intel.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
@ -3007,8 +3005,8 @@ F: drivers/net/wimax/i2400m/
|
||||
F: include/linux/wimax/i2400m.h
|
||||
|
||||
INTEL WIRELESS WIFI LINK (iwlwifi)
|
||||
M: Zhu Yi <yi.zhu@intel.com>
|
||||
M: Reinette Chatre <reinette.chatre@intel.com>
|
||||
M: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||
M: Intel Linux Wireless <ilw@linux.intel.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://intellinuxwireless.org
|
||||
@ -3018,7 +3016,6 @@ F: drivers/net/wireless/iwlwifi/
|
||||
|
||||
INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi)
|
||||
M: Samuel Ortiz <samuel.ortiz@intel.com>
|
||||
M: Zhu Yi <yi.zhu@intel.com>
|
||||
M: Intel Linux Wireless <ilw@linux.intel.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
|
@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = {
|
||||
static int __devinit ath5k_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id);
|
||||
static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ath5k_pci_suspend(struct device *dev);
|
||||
static int ath5k_pci_resume(struct device *dev);
|
||||
|
||||
@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
|
||||
#define ATH5K_PM_OPS (&ath5k_pm_ops)
|
||||
#else
|
||||
#define ATH5K_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static struct pci_driver ath5k_pci_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
@ -222,7 +222,6 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct ath5k_txq *txq);
|
||||
static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
|
||||
static int ath5k_reset_wake(struct ath5k_softc *sc);
|
||||
static int ath5k_start(struct ieee80211_hw *hw);
|
||||
static void ath5k_stop(struct ieee80211_hw *hw);
|
||||
static int ath5k_add_interface(struct ieee80211_hw *hw,
|
||||
@ -708,7 +707,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
|
||||
ieee80211_free_hw(sc->hw);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ath5k_pci_suspend(struct device *dev)
|
||||
{
|
||||
struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
|
||||
@ -732,7 +731,7 @@ static int ath5k_pci_resume(struct device *dev)
|
||||
ath5k_led_enable(sc);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
|
||||
/***********************\
|
||||
@ -2770,7 +2769,7 @@ ath5k_tasklet_reset(unsigned long data)
|
||||
{
|
||||
struct ath5k_softc *sc = (void *)data;
|
||||
|
||||
ath5k_reset_wake(sc);
|
||||
ath5k_reset(sc, sc->curchan);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2949,23 +2948,13 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
|
||||
ath5k_beacon_config(sc);
|
||||
/* intrs are enabled by ath5k_beacon_config */
|
||||
|
||||
ieee80211_wake_queues(sc->hw);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ath5k_reset_wake(struct ath5k_softc *sc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ath5k_reset(sc, sc->curchan);
|
||||
if (!ret)
|
||||
ieee80211_wake_queues(sc->hw);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath5k_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
return ath5k_init(hw->priv);
|
||||
@ -3159,13 +3148,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
|
||||
|
||||
if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
|
||||
if (*new_flags & FIF_PROMISC_IN_BSS) {
|
||||
rfilt |= AR5K_RX_FILTER_PROM;
|
||||
__set_bit(ATH_STAT_PROMISC, sc->status);
|
||||
} else {
|
||||
__clear_bit(ATH_STAT_PROMISC, sc->status);
|
||||
}
|
||||
}
|
||||
|
||||
if (test_bit(ATH_STAT_PROMISC, sc->status))
|
||||
rfilt |= AR5K_RX_FILTER_PROM;
|
||||
|
||||
/* Note, AR5K_RX_FILTER_MCAST is already enabled */
|
||||
if (*new_flags & FIF_ALLMULTI) {
|
||||
mfilt[0] = ~0;
|
||||
|
@ -1793,6 +1793,13 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
|
||||
u8 def_ant, tx_ant, ee_mode;
|
||||
u32 sta_id1 = 0;
|
||||
|
||||
/* if channel is not initialized yet we can't set the antennas
|
||||
* so just store the mode. it will be set on the next reset */
|
||||
if (channel == NULL) {
|
||||
ah->ah_ant_mode = ant_mode;
|
||||
return;
|
||||
}
|
||||
|
||||
def_ant = ah->ah_def_ant;
|
||||
|
||||
switch (channel->hw_value & CHANNEL_MODES) {
|
||||
|
@ -2618,15 +2618,6 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)
|
||||
int events = 0;
|
||||
u16 ev;
|
||||
|
||||
/* Detect early interrupt before driver is fully configued */
|
||||
if (!dev->base_addr) {
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n",
|
||||
dev->name);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
iface = netdev_priv(dev);
|
||||
local = iface->local;
|
||||
|
||||
|
@ -2699,6 +2699,7 @@ static struct iwl_lib_ops iwl3945_lib = {
|
||||
.isr = iwl_isr_legacy,
|
||||
.config_ap = iwl3945_config_ap,
|
||||
.manage_ibss_station = iwl3945_manage_ibss_station,
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl3945_good_plcp_health,
|
||||
|
||||
.debugfs_ops = {
|
||||
|
@ -1030,10 +1030,9 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
{
|
||||
const struct ieee80211_supported_band *sband;
|
||||
const struct iwl_channel_info *ch_info;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int i, added = 0;
|
||||
int added = 0;
|
||||
u16 channel = 0;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
@ -1048,32 +1047,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
/* only scan single channel, good enough to reset the RF */
|
||||
/* pick the first valid not in-use channel */
|
||||
if (band == IEEE80211_BAND_5GHZ) {
|
||||
for (i = 14; i < priv->channel_count; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel = priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 14; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel =
|
||||
priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
channel = iwl_get_single_channel_number(priv, band);
|
||||
if (channel) {
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
|
@ -1497,6 +1497,156 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* sysfs attributes
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
|
||||
/*
|
||||
* The following adds a new attribute to the sysfs representation
|
||||
* of this device driver (i.e. a new file in /sys/class/net/wlan0/device/)
|
||||
* used for controlling the debug level.
|
||||
*
|
||||
* See the level definitions in iwl for details.
|
||||
*
|
||||
* The debug_level being managed using sysfs below is a per device debug
|
||||
* level that is used instead of the global debug level if it (the per
|
||||
* device debug level) is set.
|
||||
*/
|
||||
static ssize_t show_debug_level(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv));
|
||||
}
|
||||
static ssize_t store_debug_level(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 0, &val);
|
||||
if (ret)
|
||||
IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
|
||||
else {
|
||||
priv->debug_level = val;
|
||||
if (iwl_alloc_traffic_mem(priv))
|
||||
IWL_ERR(priv,
|
||||
"Not enough memory to generate traffic log\n");
|
||||
}
|
||||
return strnlen(buf, count);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
|
||||
show_debug_level, store_debug_level);
|
||||
|
||||
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
|
||||
|
||||
static ssize_t show_temperature(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
return sprintf(buf, "%d\n", priv->temperature);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
|
||||
|
||||
static ssize_t show_tx_power(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
|
||||
if (!iwl_is_ready_rf(priv))
|
||||
return sprintf(buf, "off\n");
|
||||
else
|
||||
return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
|
||||
}
|
||||
|
||||
static ssize_t store_tx_power(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
IWL_INFO(priv, "%s is not in decimal form.\n", buf);
|
||||
else {
|
||||
ret = iwl_set_tx_power(priv, val, false);
|
||||
if (ret)
|
||||
IWL_ERR(priv, "failed setting tx power (0x%d).\n",
|
||||
ret);
|
||||
else
|
||||
ret = count;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
|
||||
|
||||
static ssize_t show_rts_ht_protection(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
|
||||
return sprintf(buf, "%s\n",
|
||||
priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self");
|
||||
}
|
||||
|
||||
static ssize_t store_rts_ht_protection(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
IWL_INFO(priv, "Input is not in decimal form.\n");
|
||||
else {
|
||||
if (!iwl_is_associated(priv))
|
||||
priv->cfg->use_rts_for_ht = val ? true : false;
|
||||
else
|
||||
IWL_ERR(priv, "Sta associated with AP - "
|
||||
"Change protection mechanism is not allowed\n");
|
||||
ret = count;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO,
|
||||
show_rts_ht_protection, store_rts_ht_protection);
|
||||
|
||||
|
||||
static struct attribute *iwl_sysfs_entries[] = {
|
||||
&dev_attr_temperature.attr,
|
||||
&dev_attr_tx_power.attr,
|
||||
&dev_attr_rts_ht_protection.attr,
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
&dev_attr_debug_level.attr,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group iwl_attribute_group = {
|
||||
.name = NULL, /* put in device directory */
|
||||
.attrs = iwl_sysfs_entries,
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* uCode download functions
|
||||
@ -2037,6 +2187,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
if (err)
|
||||
IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
|
||||
|
||||
err = sysfs_create_group(&priv->pci_dev->dev.kobj,
|
||||
&iwl_attribute_group);
|
||||
if (err) {
|
||||
IWL_ERR(priv, "failed to create sysfs device attributes\n");
|
||||
goto out_unbind;
|
||||
}
|
||||
|
||||
/* We have our copies now, allow OS release its copies */
|
||||
release_firmware(ucode_raw);
|
||||
complete(&priv->_agn.firmware_loading_complete);
|
||||
@ -3425,141 +3582,6 @@ out_exit:
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* sysfs attributes
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
|
||||
/*
|
||||
* The following adds a new attribute to the sysfs representation
|
||||
* of this device driver (i.e. a new file in /sys/class/net/wlan0/device/)
|
||||
* used for controlling the debug level.
|
||||
*
|
||||
* See the level definitions in iwl for details.
|
||||
*
|
||||
* The debug_level being managed using sysfs below is a per device debug
|
||||
* level that is used instead of the global debug level if it (the per
|
||||
* device debug level) is set.
|
||||
*/
|
||||
static ssize_t show_debug_level(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv));
|
||||
}
|
||||
static ssize_t store_debug_level(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 0, &val);
|
||||
if (ret)
|
||||
IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
|
||||
else {
|
||||
priv->debug_level = val;
|
||||
if (iwl_alloc_traffic_mem(priv))
|
||||
IWL_ERR(priv,
|
||||
"Not enough memory to generate traffic log\n");
|
||||
}
|
||||
return strnlen(buf, count);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
|
||||
show_debug_level, store_debug_level);
|
||||
|
||||
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
|
||||
|
||||
static ssize_t show_temperature(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
return sprintf(buf, "%d\n", priv->temperature);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
|
||||
|
||||
static ssize_t show_tx_power(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
|
||||
if (!iwl_is_ready_rf(priv))
|
||||
return sprintf(buf, "off\n");
|
||||
else
|
||||
return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
|
||||
}
|
||||
|
||||
static ssize_t store_tx_power(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
IWL_INFO(priv, "%s is not in decimal form.\n", buf);
|
||||
else {
|
||||
ret = iwl_set_tx_power(priv, val, false);
|
||||
if (ret)
|
||||
IWL_ERR(priv, "failed setting tx power (0x%d).\n",
|
||||
ret);
|
||||
else
|
||||
ret = count;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
|
||||
|
||||
static ssize_t show_rts_ht_protection(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
|
||||
return sprintf(buf, "%s\n",
|
||||
priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self");
|
||||
}
|
||||
|
||||
static ssize_t store_rts_ht_protection(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
IWL_INFO(priv, "Input is not in decimal form.\n");
|
||||
else {
|
||||
if (!iwl_is_associated(priv))
|
||||
priv->cfg->use_rts_for_ht = val ? true : false;
|
||||
else
|
||||
IWL_ERR(priv, "Sta associated with AP - "
|
||||
"Change protection mechanism is not allowed\n");
|
||||
ret = count;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO,
|
||||
show_rts_ht_protection, store_rts_ht_protection);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* driver setup and teardown
|
||||
@ -3713,21 +3735,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
|
||||
kfree(priv->scan_cmd);
|
||||
}
|
||||
|
||||
static struct attribute *iwl_sysfs_entries[] = {
|
||||
&dev_attr_temperature.attr,
|
||||
&dev_attr_tx_power.attr,
|
||||
&dev_attr_rts_ht_protection.attr,
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
&dev_attr_debug_level.attr,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group iwl_attribute_group = {
|
||||
.name = NULL, /* put in device directory */
|
||||
.attrs = iwl_sysfs_entries,
|
||||
};
|
||||
|
||||
static struct ieee80211_ops iwl_hw_ops = {
|
||||
.tx = iwl_mac_tx,
|
||||
.start = iwl_mac_start,
|
||||
@ -3912,11 +3919,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
|
||||
goto out_disable_msi;
|
||||
}
|
||||
err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
|
||||
if (err) {
|
||||
IWL_ERR(priv, "failed to create sysfs device attributes\n");
|
||||
goto out_free_irq;
|
||||
}
|
||||
|
||||
iwl_setup_deferred_work(priv);
|
||||
iwl_setup_rx_handlers(priv);
|
||||
@ -3950,15 +3952,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
||||
err = iwl_request_firmware(priv, true);
|
||||
if (err)
|
||||
goto out_remove_sysfs;
|
||||
goto out_destroy_workqueue;
|
||||
|
||||
return 0;
|
||||
|
||||
out_remove_sysfs:
|
||||
out_destroy_workqueue:
|
||||
destroy_workqueue(priv->workqueue);
|
||||
priv->workqueue = NULL;
|
||||
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
|
||||
out_free_irq:
|
||||
free_irq(priv->pci_dev->irq, priv);
|
||||
iwl_free_isr_ict(priv);
|
||||
out_disable_msi:
|
||||
|
@ -855,6 +855,45 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_set_rxon_chain);
|
||||
|
||||
/* Return valid channel */
|
||||
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
|
||||
enum ieee80211_band band)
|
||||
{
|
||||
const struct iwl_channel_info *ch_info;
|
||||
int i;
|
||||
u8 channel = 0;
|
||||
|
||||
/* only scan single channel, good enough to reset the RF */
|
||||
/* pick the first valid not in-use channel */
|
||||
if (band == IEEE80211_BAND_5GHZ) {
|
||||
for (i = 14; i < priv->channel_count; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel = priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 14; i++) {
|
||||
if (priv->channel_info[i].channel !=
|
||||
le16_to_cpu(priv->staging_rxon.channel)) {
|
||||
channel =
|
||||
priv->channel_info[i].channel;
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
band, channel);
|
||||
if (is_channel_valid(ch_info))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_get_single_channel_number);
|
||||
|
||||
/**
|
||||
* iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
|
||||
* @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
|
||||
|
@ -350,6 +350,8 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
|
||||
void iwl_set_flags_for_band(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
struct ieee80211_vif *vif);
|
||||
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
|
||||
enum ieee80211_band band);
|
||||
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
|
||||
u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
|
||||
struct ieee80211_sta_ht_cap *sta_ht_inf);
|
||||
|
@ -1782,6 +1782,49 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_band band,
|
||||
struct iwl3945_scan_channel *scan_ch)
|
||||
{
|
||||
const struct ieee80211_supported_band *sband;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int added = 0;
|
||||
u8 channel = 0;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
if (!sband) {
|
||||
IWL_ERR(priv, "invalid band\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
active_dwell = iwl_get_active_dwell_time(priv, band, 0);
|
||||
passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
|
||||
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
|
||||
channel = iwl_get_single_channel_number(priv, band);
|
||||
|
||||
if (channel) {
|
||||
scan_ch->channel = channel;
|
||||
scan_ch->type = 0; /* passive */
|
||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
/* Set txpower levels to defaults */
|
||||
scan_ch->tpc.dsp_atten = 110;
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||
else
|
||||
scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
|
||||
added++;
|
||||
} else
|
||||
IWL_ERR(priv, "no valid channel found\n");
|
||||
return added;
|
||||
}
|
||||
|
||||
static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
|
||||
enum ieee80211_band band,
|
||||
u8 is_active, u8 n_probes,
|
||||
@ -2932,9 +2975,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
/* select Rx antennas */
|
||||
scan->flags |= iwl3945_get_antenna_flags(priv);
|
||||
|
||||
scan->channel_count =
|
||||
iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
|
||||
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif);
|
||||
if (priv->is_internal_short_scan) {
|
||||
scan->channel_count =
|
||||
iwl3945_get_single_channel_for_scan(priv, vif, band,
|
||||
(void *)&scan->data[le16_to_cpu(
|
||||
scan->tx_cmd.len)]);
|
||||
} else {
|
||||
scan->channel_count =
|
||||
iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
|
||||
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif);
|
||||
}
|
||||
|
||||
if (scan->channel_count == 0) {
|
||||
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
|
||||
|
@ -80,6 +80,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
|
||||
{USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
|
||||
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
|
||||
{USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
|
||||
{USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */
|
||||
{USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
|
||||
{USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
|
||||
{}
|
||||
|
@ -259,6 +259,7 @@ disable:
|
||||
sdio_disable_func(func);
|
||||
release:
|
||||
sdio_release_host(func);
|
||||
wl1251_free_hw(wl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -332,14 +332,16 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
|
||||
IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
|
||||
|
||||
spin_unlock(&local->ampdu_lock);
|
||||
spin_unlock_bh(&sta->lock);
|
||||
|
||||
/* send an addBA request */
|
||||
/* prepare tid data */
|
||||
sta->ampdu_mlme.dialog_token_allocator++;
|
||||
sta->ampdu_mlme.tid_tx[tid]->dialog_token =
|
||||
sta->ampdu_mlme.dialog_token_allocator;
|
||||
sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
|
||||
|
||||
spin_unlock_bh(&sta->lock);
|
||||
|
||||
/* send AddBA request */
|
||||
ieee80211_send_addba_request(sdata, pubsta->addr, tid,
|
||||
sta->ampdu_mlme.tid_tx[tid]->dialog_token,
|
||||
sta->ampdu_mlme.tid_tx[tid]->ssn,
|
||||
|
@ -360,7 +360,7 @@ static inline int drv_get_survey(struct ieee80211_local *local, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
if (local->ops->conf_tx)
|
||||
if (local->ops->get_survey)
|
||||
ret = local->ops->get_survey(&local->hw, idx, survey);
|
||||
/* trace_drv_get_survey(local, idx, survey, ret); */
|
||||
return ret;
|
||||
|
@ -1692,14 +1692,52 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
||||
rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
|
||||
break;
|
||||
case IEEE80211_STYPE_ACTION:
|
||||
if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT)
|
||||
break;
|
||||
switch (mgmt->u.action.category) {
|
||||
case WLAN_CATEGORY_BACK: {
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
int len = skb->len;
|
||||
struct sta_info *sta;
|
||||
|
||||
ieee80211_sta_process_chanswitch(sdata,
|
||||
&mgmt->u.action.u.chan_switch.sw_elem,
|
||||
(void *)ifmgd->associated->priv,
|
||||
rx_status->mactime);
|
||||
break;
|
||||
rcu_read_lock();
|
||||
sta = sta_info_get(sdata, mgmt->sa);
|
||||
if (!sta) {
|
||||
rcu_read_unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
local_bh_disable();
|
||||
|
||||
switch (mgmt->u.action.u.addba_req.action_code) {
|
||||
case WLAN_ACTION_ADDBA_REQ:
|
||||
if (len < (IEEE80211_MIN_ACTION_SIZE +
|
||||
sizeof(mgmt->u.action.u.addba_req)))
|
||||
break;
|
||||
ieee80211_process_addba_request(local, sta, mgmt, len);
|
||||
break;
|
||||
case WLAN_ACTION_ADDBA_RESP:
|
||||
if (len < (IEEE80211_MIN_ACTION_SIZE +
|
||||
sizeof(mgmt->u.action.u.addba_resp)))
|
||||
break;
|
||||
ieee80211_process_addba_resp(local, sta, mgmt, len);
|
||||
break;
|
||||
case WLAN_ACTION_DELBA:
|
||||
if (len < (IEEE80211_MIN_ACTION_SIZE +
|
||||
sizeof(mgmt->u.action.u.delba)))
|
||||
break;
|
||||
ieee80211_process_delba(sdata, sta, mgmt, len);
|
||||
break;
|
||||
}
|
||||
local_bh_enable();
|
||||
rcu_read_unlock();
|
||||
break;
|
||||
}
|
||||
case WLAN_CATEGORY_SPECTRUM_MGMT:
|
||||
ieee80211_sta_process_chanswitch(sdata,
|
||||
&mgmt->u.action.u.chan_switch.sw_elem,
|
||||
(void *)ifmgd->associated->priv,
|
||||
rx_status->mactime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
|
@ -1819,17 +1819,26 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
|
||||
return RX_CONTINUE;
|
||||
|
||||
if (ieee80211_is_back_req(bar->frame_control)) {
|
||||
struct {
|
||||
__le16 control, start_seq_num;
|
||||
} __packed bar_data;
|
||||
|
||||
if (!rx->sta)
|
||||
return RX_DROP_MONITOR;
|
||||
|
||||
if (skb_copy_bits(skb, offsetof(struct ieee80211_bar, control),
|
||||
&bar_data, sizeof(bar_data)))
|
||||
return RX_DROP_MONITOR;
|
||||
|
||||
spin_lock(&rx->sta->lock);
|
||||
tid = le16_to_cpu(bar->control) >> 12;
|
||||
tid = le16_to_cpu(bar_data.control) >> 12;
|
||||
if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
|
||||
spin_unlock(&rx->sta->lock);
|
||||
return RX_DROP_MONITOR;
|
||||
}
|
||||
tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
|
||||
|
||||
start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
|
||||
start_seq_num = le16_to_cpu(bar_data.start_seq_num) >> 4;
|
||||
|
||||
/* reset session timer */
|
||||
if (tid_agg_rx->timeout)
|
||||
@ -1941,6 +1950,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
||||
if (len < IEEE80211_MIN_ACTION_SIZE + 1)
|
||||
break;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
return ieee80211_sta_rx_mgmt(sdata, rx->skb);
|
||||
|
||||
switch (mgmt->u.action.u.addba_req.action_code) {
|
||||
case WLAN_ACTION_ADDBA_REQ:
|
||||
if (len < (IEEE80211_MIN_ACTION_SIZE +
|
||||
|
Loading…
Reference in New Issue
Block a user