You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
@@ -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
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user