Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6

This commit is contained in:
David S. Miller
2009-06-07 04:24:21 -07:00
133 changed files with 4503 additions and 4736 deletions
@@ -437,3 +437,10 @@ Why: Superseded by tdfxfb. I2C/DDC support used to live in a separate
driver but this caused driver conflicts.
Who: Jean Delvare <khali@linux-fr.org>
Krzysztof Helt <krzysztof.h1@wp.pl>
---------------------------
What: CONFIG_RFKILL_INPUT
When: 2.6.33
Why: Should be implemented in userspace, policy daemon.
Who: Johannes Berg <johannes@sipsolutions.net>
+80 -515
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -4753,9 +4753,9 @@ S: Supported
F: fs/reiserfs/
RFKILL
P: Ivo van Doorn
M: IvDoorn@gmail.com
L: netdev@vger.kernel.org
P: Johannes Berg
M: johannes@sipsolutions.net
L: linux-wireless@vger.kernel.org
S: Maintained
F Documentation/rfkill.txt
F: net/rfkill/
+15 -15
View File
@@ -35,21 +35,25 @@ static void tosa_bt_off(struct tosa_bt_data *data)
gpio_set_value(data->gpio_reset, 0);
}
static int tosa_bt_toggle_radio(void *data, enum rfkill_state state)
static int tosa_bt_set_block(void *data, bool blocked)
{
pr_info("BT_RADIO going: %s\n",
state == RFKILL_STATE_UNBLOCKED ? "on" : "off");
pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on");
if (state == RFKILL_STATE_UNBLOCKED) {
if (!blocked) {
pr_info("TOSA_BT: going ON\n");
tosa_bt_on(data);
} else {
pr_info("TOSA_BT: going OFF\n");
tosa_bt_off(data);
}
return 0;
}
static const struct rfkill_ops tosa_bt_rfkill_ops = {
.set_block = tosa_bt_set_block,
};
static int tosa_bt_probe(struct platform_device *dev)
{
int rc;
@@ -70,18 +74,14 @@ static int tosa_bt_probe(struct platform_device *dev)
if (rc)
goto err_pwr_dir;
rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH);
rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH,
&tosa_bt_rfkill_ops, data);
if (!rfk) {
rc = -ENOMEM;
goto err_rfk_alloc;
}
rfk->name = "tosa-bt";
rfk->toggle_radio = tosa_bt_toggle_radio;
rfk->data = data;
#ifdef CONFIG_RFKILL_LEDS
rfk->led_trigger.name = "tosa-bt";
#endif
rfkill_set_led_trigger_name(rfk, "tosa-bt");
rc = rfkill_register(rfk);
if (rc)
@@ -92,9 +92,7 @@ static int tosa_bt_probe(struct platform_device *dev)
return 0;
err_rfkill:
if (rfk)
rfkill_free(rfk);
rfk = NULL;
rfkill_destroy(rfk);
err_rfk_alloc:
tosa_bt_off(data);
err_pwr_dir:
@@ -113,8 +111,10 @@ static int __devexit tosa_bt_remove(struct platform_device *dev)
platform_set_drvdata(dev, NULL);
if (rfk)
if (rfk) {
rfkill_unregister(rfk);
rfkill_destroy(rfk);
}
rfk = NULL;
tosa_bt_off(data);
-1
View File
@@ -31,7 +31,6 @@
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/pda_power.h>
#include <linux/rfkill.h>
#include <linux/spi/spi.h>
#include <asm/setup.h>
+22 -20
View File
@@ -2481,10 +2481,10 @@ static int add_net_device(struct hso_device *hso_dev)
return 0;
}
static int hso_radio_toggle(void *data, enum rfkill_state state)
static int hso_rfkill_set_block(void *data, bool blocked)
{
struct hso_device *hso_dev = data;
int enabled = (state == RFKILL_STATE_UNBLOCKED);
int enabled = !blocked;
int rv;
mutex_lock(&hso_dev->mutex);
@@ -2498,6 +2498,10 @@ static int hso_radio_toggle(void *data, enum rfkill_state state)
return rv;
}
static const struct rfkill_ops hso_rfkill_ops = {
.set_block = hso_rfkill_set_block,
};
/* Creates and sets up everything for rfkill */
static void hso_create_rfkill(struct hso_device *hso_dev,
struct usb_interface *interface)
@@ -2506,29 +2510,25 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
struct device *dev = &hso_net->net->dev;
char *rfkn;
hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,
RFKILL_TYPE_WWAN);
if (!hso_net->rfkill) {
dev_err(dev, "%s - Out of memory\n", __func__);
return;
}
rfkn = kzalloc(20, GFP_KERNEL);
if (!rfkn) {
rfkill_free(hso_net->rfkill);
hso_net->rfkill = NULL;
if (!rfkn)
dev_err(dev, "%s - Out of memory\n", __func__);
return;
}
snprintf(rfkn, 20, "hso-%d",
interface->altsetting->desc.bInterfaceNumber);
hso_net->rfkill->name = rfkn;
hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED;
hso_net->rfkill->data = hso_dev;
hso_net->rfkill->toggle_radio = hso_radio_toggle;
hso_net->rfkill = rfkill_alloc(rfkn,
&interface_to_usbdev(interface)->dev,
RFKILL_TYPE_WWAN,
&hso_rfkill_ops, hso_dev);
if (!hso_net->rfkill) {
dev_err(dev, "%s - Out of memory\n", __func__);
kfree(rfkn);
return;
}
if (rfkill_register(hso_net->rfkill) < 0) {
rfkill_destroy(hso_net->rfkill);
kfree(rfkn);
hso_net->rfkill->name = NULL;
rfkill_free(hso_net->rfkill);
hso_net->rfkill = NULL;
dev_err(dev, "%s - Failed to register rfkill\n", __func__);
return;
@@ -3165,8 +3165,10 @@ static void hso_free_interface(struct usb_interface *interface)
hso_stop_net_device(network_table[i]);
cancel_work_sync(&network_table[i]->async_put_intf);
cancel_work_sync(&network_table[i]->async_get_intf);
if (rfk)
if (rfk) {
rfkill_unregister(rfk);
rfkill_destroy(rfk);
}
hso_free_net_device(network_table[i]);
}
}
+1 -1
View File
@@ -333,11 +333,11 @@ config USB_ZD1201
config USB_NET_RNDIS_WLAN
tristate "Wireless RNDIS USB support"
depends on USB && WLAN_80211 && EXPERIMENTAL
depends on CFG80211
select USB_USBNET
select USB_NET_CDCETHER
select USB_NET_RNDIS_HOST
select WIRELESS_EXT
select CFG80211
---help---
This is a driver for wireless RNDIS devices.
These are USB based adapters found in devices such as:
+7 -3
View File
@@ -91,6 +91,7 @@ struct ar9170_led {
struct led_classdev l;
char name[32];
unsigned int toggled;
bool last_state;
bool registered;
};
@@ -101,7 +102,6 @@ enum ar9170_device_state {
AR9170_STOPPED,
AR9170_IDLE,
AR9170_STARTED,
AR9170_ASSOCIATED,
};
struct ar9170_rxstream_mpdu_merge {
@@ -140,7 +140,7 @@ struct ar9170 {
struct work_struct filter_config_work;
u64 cur_mc_hash, want_mc_hash;
u32 cur_filter, want_filter;
unsigned int filter_changed;
unsigned long filter_changed;
unsigned int filter_state;
bool sniffer_enabled;
@@ -195,7 +195,7 @@ struct ar9170_sta_info {
#define IS_STARTED(a) (a->state >= AR9170_STARTED)
#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE)
#define AR9170_FILTER_CHANGED_PROMISC BIT(0)
#define AR9170_FILTER_CHANGED_MODE BIT(0)
#define AR9170_FILTER_CHANGED_MULTICAST BIT(1)
#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2)
@@ -206,6 +206,7 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
void ar9170_unregister(struct ar9170 *ar);
void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
bool update_statistics, u16 tx_status);
void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
/* MAC */
int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -215,6 +216,9 @@ int ar9170_update_multicast(struct ar9170 *ar);
int ar9170_update_frame_filter(struct ar9170 *ar);
int ar9170_set_operating_mode(struct ar9170 *ar);
int ar9170_set_beacon_timers(struct ar9170 *ar);
int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
int ar9170_set_slot_time(struct ar9170 *ar);
int ar9170_set_basic_rates(struct ar9170 *ar);
int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
int ar9170_update_beacon(struct ar9170 *ar);
void ar9170_new_beacon(struct work_struct *work);
+3 -2
View File
@@ -207,7 +207,8 @@ enum ar9170_cmd {
#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
#define AR9170_MAC_REG_AMPDU_SET (AR9170_MAC_REG_BASE + 0xba0)
#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C)
#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0)
#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
@@ -376,7 +377,6 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
#define AR9170_RX_ERROR_FATAL 0x80
struct ar9170_cmd_tx_status {
__le16 unkn;
u8 dst[ETH_ALEN];
__le32 rate;
__le16 status;
@@ -394,6 +394,7 @@ struct ar9170_cmd_ba_failed_count {
struct ar9170_cmd_response {
u8 flag;
u8 type;
__le16 padding;
union {
struct ar9170_cmd_tx_status tx_status;
+12 -5
View File
@@ -74,7 +74,7 @@ static void ar9170_update_leds(struct work_struct *work)
mutex_lock(&ar->mutex);
for (i = 0; i < AR9170_NUM_LEDS; i++)
if (ar->leds[i].toggled) {
if (ar->leds[i].registered && ar->leds[i].toggled) {
led_val |= 1 << i;
tmp = 70 + 200 / (ar->leds[i].toggled);
@@ -101,9 +101,15 @@ static void ar9170_led_brightness_set(struct led_classdev *led,
struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
struct ar9170 *ar = arl->ar;
arl->toggled++;
if (unlikely(!arl->registered))
return ;
if (likely(IS_ACCEPTING_CMD(ar) && brightness))
if (arl->last_state != !!brightness) {
arl->toggled++;
arl->last_state = !!brightness;
}
if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
}
@@ -136,13 +142,14 @@ void ar9170_unregister_leds(struct ar9170 *ar)
{
int i;
cancel_delayed_work_sync(&ar->led_work);
for (i = 0; i < AR9170_NUM_LEDS; i++)
if (ar->leds[i].registered) {
led_classdev_unregister(&ar->leds[i].l);
ar->leds[i].registered = false;
ar->leds[i].toggled = 0;
}
cancel_delayed_work_sync(&ar->led_work);
}
int ar9170_register_leds(struct ar9170 *ar)
+52 -3
View File
@@ -38,6 +38,55 @@
#include "ar9170.h"
#include "cmd.h"
int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
{
u32 val;
if (conf_is_ht40(&ar->hw->conf))
val = 0x010a;
else {
if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
val = 0x105;
else
val = 0x104;
}
return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
}
int ar9170_set_slot_time(struct ar9170 *ar)
{
u32 slottime = 20;
if (!ar->vif)
return 0;
if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
ar->vif->bss_conf.use_short_slot)
slottime = 9;
return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
}
int ar9170_set_basic_rates(struct ar9170 *ar)
{
u8 cck, ofdm;
if (!ar->vif)
return 0;
ofdm = ar->vif->bss_conf.basic_rates >> 4;
/* FIXME: is still necessary? */
if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
cck = 0;
else
cck = ar->vif->bss_conf.basic_rates & 0xf;
return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
ofdm << 8 | cck);
}
int ar9170_set_qos(struct ar9170 *ar)
{
ar9170_regwrite_begin(ar);
@@ -84,7 +133,7 @@ static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
ar9170_regwrite_begin(ar);
ar9170_regwrite(AR9170_MAC_REG_AMPDU_SET, val);
ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
ar9170_regwrite_finish();
return ar9170_regwrite_result();
@@ -398,10 +447,10 @@ int ar9170_update_beacon(struct ar9170 *ar)
/* XXX: use skb->cb info */
if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
((skb->len + 4) << (3+16)) + 0x0400);
((skb->len + 4) << (3 + 16)) + 0x0400);
else
ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
((skb->len + 4) << (3+16)) + 0x0400);
((skb->len + 4) << 16) + 0x001b);
ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
+48 -50
View File
@@ -146,7 +146,6 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
{ \
.ht_supported = true, \
.cap = IEEE80211_HT_CAP_MAX_AMSDU | \
IEEE80211_HT_CAP_SM_PS | \
IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
IEEE80211_HT_CAP_SGI_40 | \
IEEE80211_HT_CAP_DSSSCCK40 | \
@@ -344,7 +343,6 @@ static void ar9170_tx_status_janitor(struct work_struct *work)
if (unlikely(!IS_STARTED(ar)))
return ;
mutex_lock(&ar->mutex);
/* recycle the garbage back to mac80211... one by one. */
while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
#ifdef AR9170_QUEUE_DEBUG
@@ -370,12 +368,9 @@ static void ar9170_tx_status_janitor(struct work_struct *work)
if (skb_queue_len(&ar->global_tx_status_waste) > 0)
queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
msecs_to_jiffies(100));
mutex_unlock(&ar->mutex);
}
static void ar9170_handle_command_response(struct ar9170 *ar,
void *buf, u32 len)
void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
{
struct ar9170_cmd_response *cmd = (void *) buf;
@@ -957,6 +952,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
mutex_lock(&ar->mutex);
ar->filter_changed = 0;
/* reinitialize queues statistics */
memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
@@ -1012,10 +1009,10 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
flush_workqueue(ar->hw->workqueue);
mutex_lock(&ar->mutex);
cancel_delayed_work_sync(&ar->tx_status_janitor);
cancel_work_sync(&ar->filter_config_work);
cancel_work_sync(&ar->beacon_work);
mutex_lock(&ar->mutex);
skb_queue_purge(&ar->global_tx_status_waste);
skb_queue_purge(&ar->global_tx_status);
@@ -1306,11 +1303,6 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&ar->mutex);
if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
/* TODO */
err = 0;
}
if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
/* TODO */
err = 0;
@@ -1344,15 +1336,21 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
/* adjust slot time for 5 GHz */
err = ar9170_set_slot_time(ar);
if (err)
goto out;
err = ar9170_set_dyn_sifs_ack(ar);
if (err)
goto out;
err = ar9170_set_channel(ar, hw->conf.channel,
AR9170_RFI_NONE,
nl80211_to_ar9170(hw->conf.channel_type));
if (err)
goto out;
/* adjust slot time for 5 GHz */
if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
9 << 10);
}
out:
@@ -1370,20 +1368,26 @@ static void ar9170_set_filters(struct work_struct *work)
return ;
mutex_lock(&ar->mutex);
if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
&ar->filter_changed)) {
err = ar9170_set_operating_mode(ar);
if (err)
goto unlock;
}
if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
&ar->filter_changed)) {
err = ar9170_update_multicast(ar);
if (err)
goto unlock;
}
if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
&ar->filter_changed)) {
err = ar9170_update_frame_filter(ar);
if (err)
goto unlock;
}
unlock:
mutex_unlock(&ar->mutex);
@@ -1413,7 +1417,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
int i;
/* always get broadcast frames */
mchash = 1ULL << (0xff>>2);
mchash = 1ULL << (0xff >> 2);
for (i = 0; i < mc_count; i++) {
if (WARN_ON(!mclist))
@@ -1423,7 +1427,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
}
ar->want_mc_hash = mchash;
}
ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
}
if (changed_flags & FIF_CONTROL) {
@@ -1439,12 +1443,14 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
else
ar->want_filter = ar->cur_filter & ~filter;
ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
&ar->filter_changed);
}
if (changed_flags & FIF_PROMISC_IN_BSS) {
ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
set_bit(AR9170_FILTER_CHANGED_MODE,
&ar->filter_changed);
}
if (likely(IS_STARTED(ar)))
@@ -1464,27 +1470,32 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BSSID) {
memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
err = ar9170_set_operating_mode(ar);
if (err)
goto out;
}
if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
err = ar9170_update_beacon(ar);
if (!err)
ar9170_set_beacon_timers(ar);
if (err)
goto out;
err = ar9170_set_beacon_timers(ar);
if (err)
goto out;
}
ar9170_regwrite_begin(ar);
if (changed & BSS_CHANGED_ASSOC) {
ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
#ifndef CONFIG_AR9170_LEDS
/* enable assoc LED. */
err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
#endif /* CONFIG_AR9170_LEDS */
}
if (changed & BSS_CHANGED_BEACON_INT)
if (changed & BSS_CHANGED_BEACON_INT) {
err = ar9170_set_beacon_timers(ar);
if (err)
goto out;
}
if (changed & BSS_CHANGED_HT) {
/* TODO */
@@ -1492,31 +1503,18 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_ERP_SLOT) {
u32 slottime = 20;
if (bss_conf->use_short_slot)
slottime = 9;
ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
err = ar9170_set_slot_time(ar);
if (err)
goto out;
}
if (changed & BSS_CHANGED_BASIC_RATES) {
u32 cck, ofdm;
if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
ofdm = bss_conf->basic_rates;
cck = 0;
} else {
/* four cck rates */
cck = bss_conf->basic_rates & 0xf;
ofdm = bss_conf->basic_rates >> 4;
}
ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
ofdm << 8 | cck);
err = ar9170_set_basic_rates(ar);
if (err)
goto out;
}
ar9170_regwrite_finish();
err = ar9170_regwrite_result();
out:
mutex_unlock(&ar->mutex);
}
+3 -3
View File
@@ -401,7 +401,7 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
int i, err;
u32 val;
bool is_2ghz = band == IEEE80211_BAND_2GHZ;
bool is_40mhz = false; /* XXX: for now */
bool is_40mhz = conf_is_ht40(&ar->hw->conf);
ar9170_regwrite_begin(ar);
@@ -1200,7 +1200,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
return -ENOSYS;
}
if (0 /* 2 streams capable */)
if (ar->eeprom.tx_mask != 1)
tmp |= 0x100;
err = ar9170_write_reg(ar, 0x1c5804, tmp);
@@ -1214,7 +1214,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
freqpar = ar9170_get_hw_dyn_params(channel, bw);
vals[0] = cpu_to_le32(channel->center_freq * 1000);
vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
vals[2] = cpu_to_le32(offs << 2 | 1);
vals[3] = cpu_to_le32(freqpar->coeff_exp);
vals[4] = cpu_to_le32(freqpar->coeff_man);
+50 -19
View File
@@ -51,9 +51,14 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
MODULE_FIRMWARE("ar9170.fw");
MODULE_FIRMWARE("ar9170-1.fw");
MODULE_FIRMWARE("ar9170-2.fw");
enum ar9170_requirements {
AR9170_REQ_FW1_ONLY = 1,
};
static struct usb_device_id ar9170_usb_ids[] = {
/* Atheros 9170 */
{ USB_DEVICE(0x0cf3, 0x9170) },
@@ -81,6 +86,10 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x2019, 0x5304) },
/* IO-Data WNGDNUS2 */
{ USB_DEVICE(0x04bb, 0x093f) },
/* AVM FRITZ!WLAN USB Stick N */
{ USB_DEVICE(0x057C, 0x8401) },
/* AVM FRITZ!WLAN USB Stick N 2.4 */
{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
/* terminate */
{}
@@ -93,7 +102,7 @@ static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
struct ar9170_usb *aru = (struct ar9170_usb *)
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
if (!aru) {
if (unlikely(!aru)) {
dev_kfree_skb_irq(skb);
return ;
}
@@ -126,8 +135,8 @@ static void ar9170_usb_irq_completed(struct urb *urb)
goto resubmit;
}
print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
urb->transfer_buffer, urb->actual_length);
ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
urb->actual_length);
resubmit:
usb_anchor_urb(urb, &aru->rx_submitted);
@@ -177,16 +186,15 @@ resubmit:
usb_anchor_urb(urb, &aru->rx_submitted);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
if (unlikely(err)) {
usb_unanchor_urb(urb);
dev_kfree_skb_irq(skb);
goto free;
}
return ;
free:
dev_kfree_skb_irq(skb);
return;
}
static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
@@ -337,7 +345,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
usb_anchor_urb(urb, &aru->tx_submitted);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
if (unlikely(err)) {
usb_unanchor_urb(urb);
usb_free_urb(urb);
goto err_unbuf;
@@ -418,7 +426,7 @@ static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
unsigned long flags;
u32 in, out;
if (!buffer)
if (unlikely(!buffer))
return ;
in = le32_to_cpup((__le32 *)buffer);
@@ -504,17 +512,29 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
{
int err = 0;
err = request_firmware(&aru->firmware, "ar9170.fw",
&aru->udev->dev);
if (!err) {
aru->init_values = NULL;
return 0;
}
if (aru->req_one_stage_fw) {
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
"not found and is required for this device\n");
return -EINVAL;
}
dev_err(&aru->udev->dev, "ar9170.fw firmware file "
"not found, trying old firmware...\n");
err = request_firmware(&aru->init_values, "ar9170-1.fw",
&aru->udev->dev);
if (err) {
dev_err(&aru->udev->dev, "file with init values not found.\n");
return err;
}
err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
if (err) {
release_firmware(aru->init_values);
dev_err(&aru->udev->dev, "firmware file not found.\n");
dev_err(&aru->udev->dev, "file with init values not found.\n");
return err;
}
@@ -548,6 +568,9 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
{
int err;
if (!aru->init_values)
goto upload_fw_start;
/* First, upload initial values to device RAM */
err = ar9170_usb_upload(aru, aru->init_values->data,
aru->init_values->size, 0x102800, false);
@@ -557,6 +580,8 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
return err;
}
upload_fw_start:
/* Then, upload the firmware itself and start it */
return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
0x200000, true);
@@ -656,6 +681,15 @@ err_out:
return err;
}
static bool ar9170_requires_one_stage(const struct usb_device_id *id)
{
if (!id->driver_info)
return false;
if (id->driver_info == AR9170_REQ_FW1_ONLY)
return true;
return false;
}
static int ar9170_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -676,6 +710,8 @@ static int ar9170_usb_probe(struct usb_interface *intf,
aru->intf = intf;
ar = &aru->common;
aru->req_one_stage_fw = ar9170_requires_one_stage(id);
usb_set_intfdata(intf, aru);
SET_IEEE80211_DEV(ar->hw, &udev->dev);
@@ -691,7 +727,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
#ifdef CONFIG_PM
udev->reset_resume = 1;
#endif
#endif /* CONFIG_PM */
err = ar9170_usb_reset(aru);
if (err)
goto err_freehw;
@@ -776,11 +812,6 @@ static int ar9170_resume(struct usb_interface *intf)
usb_unpoison_anchored_urbs(&aru->rx_submitted);
usb_unpoison_anchored_urbs(&aru->tx_submitted);
/*
* FIXME: firmware upload will fail on resume.
* but this is better than a hang!
*/
err = ar9170_usb_init_device(aru);
if (err)
goto err_unrx;
+2
View File
@@ -62,6 +62,8 @@ struct ar9170_usb {
struct usb_anchor rx_submitted;
struct usb_anchor tx_submitted;
bool req_one_stage_fw;
spinlock_t cmdlock;
struct completion cmd_wait;
int readlen;
+19 -5
View File
@@ -2070,6 +2070,13 @@ err_unmap:
return ret;
}
static void ath5k_beacon_disable(struct ath5k_softc *sc)
{
sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
ath5k_hw_set_imr(sc->ah, sc->imask);
ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
}
/*
* Transmit a beacon frame at SWBA. Dynamic updates to the
* frame contents are done as needed and the slot time is
@@ -2757,6 +2764,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
goto end;
ath5k_hw_set_lladdr(sc->ah, mac);
ath5k_beacon_disable(sc);
sc->vif = NULL;
end:
mutex_unlock(&sc->lock);
@@ -2775,11 +2783,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&sc->lock);
sc->bintval = conf->beacon_int;
ret = ath5k_chan_set(sc, conf->channel);
if (ret < 0)
return ret;
goto unlock;
if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
(sc->power_level != conf->power_level)) {
@@ -2808,8 +2814,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
*/
ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
unlock:
mutex_unlock(&sc->lock);
return 0;
return ret;
}
#define SUPPORTED_FIF_FLAGS \
@@ -3061,7 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
int ret;
struct ath5k_softc *sc = hw->priv;
struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
struct sk_buff *skb;
if (WARN_ON(!vif)) {
ret = -EINVAL;
goto out;
}
skb = ieee80211_beacon_get(hw, vif);
if (!skb) {
ret = -ENOMEM;
+1 -6
View File
@@ -460,12 +460,9 @@ struct ath_led {
bool registered;
};
/* Rfkill */
#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
struct ath_rfkill {
struct rfkill *rfkill;
struct delayed_work rfkill_poll;
struct rfkill_ops ops;
char rfkill_name[32];
};
@@ -509,8 +506,6 @@ struct ath_rfkill {
#define SC_OP_RXFLUSH BIT(7)
#define SC_OP_LED_ASSOCIATED BIT(8)
#define SC_OP_RFKILL_REGISTERED BIT(9)
#define SC_OP_RFKILL_SW_BLOCKED BIT(10)
#define SC_OP_RFKILL_HW_BLOCKED BIT(11)
#define SC_OP_WAIT_FOR_BEACON BIT(12)
#define SC_OP_LED_ON BIT(13)
#define SC_OP_SCANNING BIT(14)
+9
View File
@@ -411,6 +411,7 @@ void ath_beacon_tasklet(unsigned long data)
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
DPRINTF(sc, ATH_DBG_BEACON,
"beacon is officially stuck\n");
sc->sc_flags |= SC_OP_TSF_RESET;
ath_reset(sc, false);
}
@@ -673,6 +674,14 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
/*
* It looks like mac80211 may end up using beacon interval of zero in
* some cases (at least for mesh point). Avoid getting into an
* infinite loop by using a bit safer value instead..
*/
if (intval == 0)
intval = 100;
/* Pull nexttbtt forward to reflect the current TSF */
nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+79 -80
View File
@@ -44,6 +44,44 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file)
return 0;
}
static ssize_t read_file_debug(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
char buf[32];
unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
unsigned long mask;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EINVAL;
buf[len] = '\0';
if (strict_strtoul(buf, 0, &mask))
return -EINVAL;
sc->debug.debug_mask = mask;
return count;
}
static const struct file_operations fops_debug = {
.read = read_file_debug,
.write = write_file_debug,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -224,111 +262,66 @@ static const struct file_operations fops_interrupt = {
.owner = THIS_MODULE
};
static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
{
struct ath_tx_info_priv *tx_info_priv = NULL;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->status.rates;
int final_ts_idx, idx;
tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
final_ts_idx = tx_info_priv->tx.ts_rateindex;
idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
sc->debug.stats.n_rcstats[idx].success++;
}
static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
{
struct ath_tx_info_priv *tx_info_priv = NULL;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->status.rates;
int final_ts_idx, idx;
struct ath_rc_stats *stats;
tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
final_ts_idx = tx_info_priv->tx.ts_rateindex;
idx = rates[final_ts_idx].idx;
sc->debug.stats.legacy_rcstats[idx].success++;
stats = &sc->debug.stats.rcstats[idx];
stats->success++;
}
void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
{
if (conf_is_ht(&sc->hw->conf))
ath_debug_stat_11n_rc(sc, skb);
else
ath_debug_stat_legacy_rc(sc, skb);
}
/* FIXME: legacy rates, later on .. */
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
int xretries, int retries, u8 per)
{
if (conf_is_ht(&sc->hw->conf)) {
int idx = sc->cur_rate_table->info[rix].dot11rate;
struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
sc->debug.stats.n_rcstats[idx].xretries += xretries;
sc->debug.stats.n_rcstats[idx].retries += retries;
sc->debug.stats.n_rcstats[idx].per = per;
}
}
static ssize_t ath_read_file_stat_11n_rc(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
char buf[1024];
unsigned int len = 0;
int i = 0;
len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
"Retries", "XRetries", "PER");
for (i = 0; i <= 15; i++) {
len += snprintf(buf + len, sizeof(buf) - len,
"%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
sc->debug.stats.n_rcstats[i].success,
sc->debug.stats.n_rcstats[i].retries,
sc->debug.stats.n_rcstats[i].xretries,
sc->debug.stats.n_rcstats[i].per);
}
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
char buf[512];
unsigned int len = 0;
int i = 0;
len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
sc->cur_rate_table->info[i].ratekbps / 1000,
sc->debug.stats.legacy_rcstats[i].success);
}
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
stats->xretries += xretries;
stats->retries += retries;
stats->per = per;
}
static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
char *buf;
unsigned int len = 0, max;
int i = 0;
ssize_t retval;
if (sc->cur_rate_table == NULL)
return 0;
if (conf_is_ht(&sc->hw->conf))
return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
else
return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
max = 80 + sc->cur_rate_table->rate_cnt * 64;
buf = kmalloc(max + 1, GFP_KERNEL);
if (buf == NULL)
return 0;
buf[max] = 0;
len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success",
"Retries", "XRetries", "PER");
for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
len += snprintf(buf + len, max - len,
"%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000,
(ratekbps % 1000) / 100, stats->success,
stats->retries, stats->xretries,
stats->per);
}
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
}
static const struct file_operations fops_rcstat = {
@@ -506,6 +499,11 @@ int ath9k_init_debug(struct ath_softc *sc)
if (!sc->debug.debugfs_phy)
goto err;
sc->debug.debugfs_debug = debugfs_create_file("debug",
S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
if (!sc->debug.debugfs_debug)
goto err;
sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
sc->debug.debugfs_phy, sc, &fops_dma);
if (!sc->debug.debugfs_dma)
@@ -543,6 +541,7 @@ void ath9k_exit_debug(struct ath_softc *sc)
debugfs_remove(sc->debug.debugfs_rcstat);
debugfs_remove(sc->debug.debugfs_interrupt);
debugfs_remove(sc->debug.debugfs_dma);
debugfs_remove(sc->debug.debugfs_debug);
debugfs_remove(sc->debug.debugfs_phy);
}
+3 -7
View File
@@ -80,11 +80,7 @@ struct ath_interrupt_stats {
u32 dtim;
};
struct ath_legacy_rc_stats {
u32 success;
};
struct ath_11n_rc_stats {
struct ath_rc_stats {
u32 success;
u32 retries;
u32 xretries;
@@ -93,13 +89,13 @@ struct ath_11n_rc_stats {
struct ath_stats {
struct ath_interrupt_stats istats;
struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */
struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
};
struct ath9k_debug {
int debug_mask;
struct dentry *debugfs_phy;
struct dentry *debugfs_debug;
struct dentry *debugfs_dma;
struct dentry *debugfs_interrupt;
struct dentry *debugfs_rcstat;

Some files were not shown because too many files have changed in this diff Show More