From: Chr <chunkeey@web.de>
To: linux-wireless@vger.kernel.org
Cc: Michael Wu <flamingice@sourmilk.net>
Subject: [RFC][PATCH 2/2] p54: statistic readback and other changes
Date: Sun, 30 Mar 2008 23:49:27 +0200 [thread overview]
Message-ID: <200803302349.27450.chunkeey@web.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 239 bytes --]
This patch brings some of the new features for both
(PCI and USB) devices... unfortunately I don't know if
the readback works on USB.
So please, drop me a line, if it works... or not!
Signed-off-by: Christian Lamparter <chunkeey@web.de>
[-- Attachment #2: p54-wlan-stats.diff --]
[-- Type: text/x-diff, Size: 18941 bytes --]
diff -Nurp a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c
--- a/drivers/net/wireless/p54common.c 2008-03-30 14:23:00.000000000 +0200
+++ b/drivers/net/wireless/p54common.c 2008-03-30 22:47:33.000000000 +0200
@@ -296,10 +296,6 @@ int p54_parse_eeprom(struct ieee80211_hw
/* make it overrun */
entry_len = len;
break;
- default:
- printk(KERN_INFO "p54: unknown eeprom code : 0x%x\n",
- le16_to_cpu(entry->code));
- break;
}
entry = (void *)entry + (entry_len + 1)*2;
@@ -334,6 +330,11 @@ int p54_parse_eeprom(struct ieee80211_hw
}
EXPORT_SYMBOL_GPL(p54_parse_eeprom);
+static inline int p54_rssi_to_dbm(u8 rssi)
+{
+ return rssi / 2 - 100;
+}
+
void p54_fill_eeprom_readback(struct p54_control_hdr *hdr)
{
struct p54_eeprom_lm86 *eeprom_hdr;
@@ -348,16 +349,28 @@ void p54_fill_eeprom_readback(struct p54
}
EXPORT_SYMBOL_GPL(p54_fill_eeprom_readback);
-static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
+static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
{
+ struct p54_common *priv = dev->priv;
struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
struct ieee80211_rx_status rx_status = {0};
- u16 freq = le16_to_cpu(hdr->freq);
- rx_status.ssi = hdr->rssi;
- /* XX correct? */
+ if (!(hdr->magic & cpu_to_le16(0x01))) {
+ if (priv->rx_filter == P54_RX_FILTER_FCSFAIL)
+ rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+ else
+ /* reuse skb */
+ return 0;
+ }
+ rx_status.ssi = p54_rssi_to_dbm(hdr->rssi);
+ rx_status.noise = priv->stats.noise_floor;
+ if (rx_status.ssi > rx_status.noise)
+ rx_status.signal = rx_status.ssi - rx_status.noise;
+
+ /* FIX MAC80211: for now we remove the short preamble flag */
rx_status.rate_idx = hdr->rate & 0xf;
- rx_status.freq = freq;
+
+ rx_status.freq = le16_to_cpu(hdr->freq);
rx_status.band = IEEE80211_BAND_2GHZ;
rx_status.antenna = hdr->antenna;
rx_status.mactime = le64_to_cpu(hdr->timestamp);
@@ -367,6 +380,8 @@ static void p54_rx_data(struct ieee80211
skb_trim(skb, le16_to_cpu(hdr->len));
ieee80211_rx_irqsafe(dev, skb, &rx_status);
+
+ return -1;
}
static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
@@ -395,7 +410,7 @@ static void p54_rx_frame_sent(struct iee
u32 last_addr = priv->rx_start;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
- entry = (struct sk_buff *) priv->tx_queue.next;
+ entry = (struct sk_buff *) priv->tx_queue.next;
while (entry != (struct sk_buff *)&priv->tx_queue) {
range = (struct memrecord *)&entry->cb;
if (range->start_addr == addr) {
@@ -421,7 +436,6 @@ static void p54_rx_frame_sent(struct iee
memcpy(&status.control, range->control,
sizeof(status.control));
kfree(range->control);
-
priv->tx_stats.data[status.control.queue].len--;
entry_hdr = (struct p54_control_hdr *) entry->data;
@@ -446,13 +460,27 @@ static void p54_rx_frame_sent(struct iee
}
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-
out:
if (freed >= IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
sizeof(struct p54_control_hdr))
p54_wake_free_queues(dev);
}
+static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+ struct p54_common *priv = dev->priv;
+ struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
+ struct p54_statistics *hw_stats = (struct p54_statistics *)hdr->data;
+
+ priv->stats.rx_success = le32_to_cpu(priv->stats.rx_success);
+ priv->stats.rx_errors = le32_to_cpu(priv->stats.rx_errors);
+ priv->stats.rx_aborts = le32_to_cpu(hw_stats->rx_aborts);
+ priv->stats.rx_aborts_phy = le32_to_cpu(hw_stats->rx_aborts_phy);
+ priv->stats.rx_rts_success = le32_to_cpu(hw_stats->rx_rts_success);
+ priv->stats.rx_rts_failed = le32_to_cpu(hw_stats->rx_rts_failed);
+ priv->stats.noise_floor = p54_rssi_to_dbm(hw_stats->noise_floor);
+}
+
static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
@@ -461,6 +489,9 @@ static void p54_rx_control(struct ieee80
case P54_CONTROL_TYPE_TXDONE:
p54_rx_frame_sent(dev, skb);
break;
+ case P54_CONTROL_TYPE_STAT_READBACK:
+ p54_rx_stats(dev, skb);
+ break;
case P54_CONTROL_TYPE_BBP:
break;
default:
@@ -477,8 +508,7 @@ int p54_rx(struct ieee80211_hw *dev, str
switch (type) {
case 0x00:
case 0x01:
- p54_rx_data(dev, skb);
- return -1;
+ return p54_rx_data(dev, skb);
case 0x4d:
/* TODO: do something better... but then again, I've never seen this happen */
printk(KERN_ERR "%s: Received fault. Probably need to restart hardware now..\n",
@@ -599,28 +629,26 @@ static int p54_tx(struct ieee80211_hw *d
hdr->retry1 = hdr->retry2 = control->retry_limit;
p54_assign_address(dev, skb, hdr, skb->len, control_copy);
- memset(txhdr->wep_key, 0x0, 16);
- txhdr->padding = 0;
- txhdr->padding2 = 0;
-
/* TODO: add support for alternate retry TX rates */
rate = control->tx_rate->hw_value;
- if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
- rate |= 0x10;
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
rate |= 0x40;
else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
rate |= 0x20;
memset(txhdr->rateset, rate, 8);
- txhdr->wep_key_present = 0;
- txhdr->wep_key_len = 0;
+ txhdr->key_type = 0;
+ txhdr->key_len = 0;
txhdr->frame_type = cpu_to_le32(control->queue + 4);
- txhdr->magic4 = 0;
txhdr->antenna = (control->antenna_sel_tx == 0) ?
2 : control->antenna_sel_tx - 1;
- txhdr->output_power = 0x7f;
- txhdr->magic5 = (control->flags & IEEE80211_TXCTL_NO_ACK) ?
- 0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
+ txhdr->output_power = 0x7f; /* 0.25 dbm / unit */
+ if (control->rts_cts_rate)
+ txhdr->cts_rate = (control->flags & IEEE80211_TXCTL_NO_ACK) ?
+ 0 : (control->rts_cts_rate->hw_value | 0x20);
+ else
+ txhdr->cts_rate = (control->flags & IEEE80211_TXCTL_NO_ACK) ?
+ 0 : (0x23);
+
if (padding)
txhdr->align[0] = padding;
@@ -628,9 +656,10 @@ static int p54_tx(struct ieee80211_hw *d
return 0;
}
-static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
- const u8 *dst, const u8 *src, u8 antenna,
- u32 magic3, u32 magic8, u32 magic9)
+const static unsigned char p54_client_rts_rates[8] = { 8, 6, 4, 1, 0, 0, 0, 0 };
+const static unsigned char p54_ap_rts_rates[8] = { 3, 3, 1, 0, 0, 0, 0, 0 };
+
+static int p54_set_filter(struct ieee80211_hw *dev, u8 filter_type)
{
struct p54_common *priv = dev->priv;
struct p54_control_hdr *hdr;
@@ -649,19 +678,23 @@ static int p54_set_filter(struct ieee802
p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter), NULL);
hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
- filter->filter_type = cpu_to_le16(filter_type);
- memcpy(filter->dst, dst, ETH_ALEN);
- if (!src)
- memset(filter->src, ~0, ETH_ALEN);
- else
- memcpy(filter->src, src, ETH_ALEN);
- filter->antenna = antenna;
- filter->magic3 = cpu_to_le32(magic3);
+ filter->filter_type = filter_type;
+ memcpy(filter->our_mac, priv->mac_addr, ETH_ALEN);
+
+ memcpy(filter->rts_rates, p54_client_rts_rates, 8);
+ memset(filter->bss_filter_mac, ~0, ETH_ALEN);
+
+ filter->rx_antenna = (dev->conf.antenna_sel_rx == 0) ? 2 :
+ dev->conf.antenna_sel_rx - 1;
+ filter->bss_basic_rates = cpu_to_le32(0x15F);
filter->rx_addr = cpu_to_le32(priv->rx_end);
filter->max_rx = cpu_to_le16(0x0620); /* FIXME: for usb ver 1.. maybe */
filter->rxhw = priv->rxhw;
- filter->magic8 = cpu_to_le16(magic8);
- filter->magic9 = cpu_to_le16(magic9);
+
+ /* that's beacon_int * dtim_period * 5, unless
+ * there's a way to get these values here, let's
+ * use the standard ones */
+ filter->dtim_timer = cpu_to_le16(500);
priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*filter), 1);
return 0;
@@ -740,6 +773,7 @@ static int p54_set_freq(struct ieee80211
memcpy(hdr->data + payload_len - 4, &chan->val_bpsk, 4);
priv->tx(dev, hdr, sizeof(*hdr) + payload_len, 1);
+ priv->freq = freq;
return 0;
err:
@@ -801,7 +835,7 @@ static void p54_init_vdcf(struct ieee802
P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 47);
P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 94);
- P54_SET_QUEUE(vdcf->queue[2], 0x0003, 0x000f, 0x03ff, 0);
+ P54_SET_QUEUE(vdcf->queue[2], 0x0002, 0x000f, 0x03ff, 0);
P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0);
}
@@ -877,20 +911,24 @@ static int p54_add_interface(struct ieee
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
- p54_set_filter(dev, 0, priv->mac_addr, NULL, 0, 1, 0, 0xF642);
- p54_set_filter(dev, 0, priv->mac_addr, NULL, 1, 0, 0, 0xF642);
+ p54_set_filter(dev, P54_FILTER_TYPE_NONE);
switch (conf->type) {
case IEEE80211_IF_TYPE_STA:
- p54_set_filter(dev, 1, priv->mac_addr, NULL, 0, 0x15F, 0x1F4, 0);
+ priv->filter_type = P54_FILTER_TYPE_STA;
break;
default:
BUG(); /* impossible */
break;
}
+ p54_set_filter(dev, priv->filter_type);
+
p54_set_leds(dev, 1, 0, 0);
+ /* start statistics readback timer */
+ mod_timer(&priv->stats.timer, jiffies + HZ);
+
return 0;
}
@@ -898,9 +936,12 @@ static void p54_remove_interface(struct
struct ieee80211_if_init_conf *conf)
{
struct p54_common *priv = dev->priv;
+
+ del_timer(&priv->stats.timer);
priv->mode = IEEE80211_IF_TYPE_MNTR;
+ priv->filter_type = P54_FILTER_TYPE_NONE;
memset(priv->mac_addr, 0, ETH_ALEN);
- p54_set_filter(dev, 0, priv->mac_addr, NULL, 2, 0, 0, 0);
+ p54_set_filter(dev, P54_FILTER_TYPE_NONE);
}
static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
@@ -918,10 +959,14 @@ static int p54_config_interface(struct i
{
struct p54_common *priv = dev->priv;
- p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642);
- p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
- p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+ switch (conf->type) {
+ case IEEE80211_IF_TYPE_STA:
+ memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+ p54_set_filter(dev, P54_FILTER_TYPE_STA);
+ p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
+ break;
+ }
+
return 0;
}
@@ -931,16 +976,34 @@ static void p54_configure_filter(struct
int mc_count, struct dev_mc_list *mclist)
{
struct p54_common *priv = dev->priv;
+ unsigned flags = FIF_BCN_PRBRESP_PROMISC | FIF_PROMISC_IN_BSS;
+
+ if (priv->filter_type & P54_FILTER_TYPE_PROMISC)
+ flags |= FIF_FCSFAIL;
- *total_flags &= FIF_BCN_PRBRESP_PROMISC;
+ *total_flags &= flags;
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- p54_set_filter(dev, 0, priv->mac_addr,
- NULL, 2, 0, 0, 0);
+ p54_set_filter(dev, P54_FILTER_TYPE_NONE);
else
- p54_set_filter(dev, 0, priv->mac_addr,
- priv->bssid, 2, 0, 0, 0);
+ p54_set_filter(dev, priv->filter_type);
+ }
+
+ if (changed_flags & FIF_PROMISC_IN_BSS) {
+ if (*total_flags & FIF_PROMISC_IN_BSS)
+ priv->filter_type |= P54_FILTER_TYPE_PROMISC;
+ else
+ priv->filter_type &= ~P54_FILTER_TYPE_PROMISC;
+
+ p54_set_filter(dev, priv->filter_type);
+ }
+
+ if (changed_flags & FIF_FCSFAIL) {
+ if (*total_flags & FIF_FCSFAIL)
+ priv->rx_filter |= P54_RX_FILTER_FCSFAIL;
+ else
+ priv->rx_filter &= ~P54_RX_FILTER_FCSFAIL;
}
}
@@ -964,10 +1027,38 @@ static int p54_conf_tx(struct ieee80211_
return 0;
}
+static void p54_stats_timer(unsigned long data)
+{
+ struct ieee80211_hw *dev = (struct ieee80211_hw *)data;
+ struct p54_common *priv = dev->priv;
+ struct p54_control_hdr *hdr;
+ struct p54_statistics *stat;
+
+ hdr = (void *)priv->stats.cached_stats + priv->tx_hdr_len;
+ hdr->magic1 = cpu_to_le16(0x8000);
+ hdr->len = cpu_to_le16(sizeof(*stat));
+ hdr->type = cpu_to_le16(P54_CONTROL_TYPE_STAT_READBACK);
+ hdr->retry1 = hdr->retry2 = 0;
+ p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*stat), NULL);
+
+ stat = (struct p54_statistics *)hdr->data;
+ memset(stat, 0x0, sizeof(*stat));
+
+ priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*stat), 0);
+
+ /* get stats every 5 seconds */
+ mod_timer(&priv->stats.timer, jiffies + 5*HZ);
+}
+
static int p54_get_stats(struct ieee80211_hw *dev,
struct ieee80211_low_level_stats *stats)
{
- /* TODO */
+ struct p54_common *priv = dev->priv;
+
+ stats->dot11RTSFailureCount = priv->stats.rx_rts_failed;
+ stats->dot11RTSSuccessCount = priv->stats.rx_rts_success;
+ stats->dot11FCSErrorCount = priv->stats.rx_errors;
+
return 0;
}
@@ -1011,25 +1102,37 @@ struct ieee80211_hw *p54_init_common(siz
priv->mode = IEEE80211_IF_TYPE_INVALID;
skb_queue_head_init(&priv->tx_queue);
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
- dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
+ dev->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
IEEE80211_HW_RX_INCLUDES_FCS;
- dev->channel_change_time = 1000; /* TODO: find actual value */
- dev->max_rssi = 127;
+
+ dev->channel_change_time = 5000;
+ priv->stats.noise_floor = -93;
+ dev->max_signal = 64;
+ dev->max_rssi = -36;
+ dev->max_noise = -36;
priv->tx_stats.data[0].limit = 5;
+ priv->filter_type = P54_FILTER_TYPE_NONE;
+ priv->rx_filter = P54_RX_FILTER_NOTHING;
dev->queues = 1;
dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
sizeof(struct p54_tx_control_allocdata);
priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) +
- priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
-
- if (!priv->cached_vdcf) {
+ priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
+ priv->stats.cached_stats = kzalloc(sizeof(struct p54_statistics) +
+ priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
+
+ if (!priv->cached_vdcf || !priv->stats.cached_stats) {
+ kfree(priv->cached_vdcf);
+ kfree(priv->stats.cached_stats);
ieee80211_free_hw(dev);
return NULL;
}
+ setup_timer(&priv->stats.timer, p54_stats_timer, (unsigned long)dev);
p54_init_vdcf(dev);
return dev;
@@ -1043,6 +1146,7 @@ void p54_free_common(struct ieee80211_hw
kfree(priv->output_limit);
kfree(priv->curve_data);
kfree(priv->cached_vdcf);
+ kfree(priv->stats.cached_stats);
}
EXPORT_SYMBOL_GPL(p54_free_common);
diff -Nurp a/drivers/net/wireless/p54common.h b/drivers/net/wireless/p54common.h
--- a/drivers/net/wireless/p54common.h 2008-03-29 16:06:06.000000000 +0100
+++ b/drivers/net/wireless/p54common.h 2008-03-30 22:42:52.000000000 +0200
@@ -53,10 +53,10 @@ struct pda_entry {
} __attribute__ ((packed));
struct eeprom_pda_wrap {
- __le32 magic;
- __le16 pad;
- __le16 len;
- __le32 arm_opcode;
+ u32 magic;
+ u16 pad;
+ u16 len;
+ u32 arm_opcode;
u8 data[0];
} __attribute__ ((packed));
@@ -89,14 +89,14 @@ struct pda_pa_curve_data_sample_rev1 {
u8 data_qpsk;
u8 data_16qam;
u8 data_64qam;
- u8 padding;
+ u8 :8;
} __attribute__ ((packed));
struct pda_pa_curve_data {
u8 cal_method_rev;
u8 channels;
u8 points_per_channel;
- u8 padding;
+ u8 :8;
u8 data[0];
} __attribute__ ((packed));
@@ -161,6 +161,14 @@ struct p54_eeprom_lm86 {
u8 data[0];
} __attribute__ ((packed));
+enum {
+ P54_KEY_TYPE_NONE = 0,
+ P54_KEY_TYPE_WEP,
+ P54_KEY_TYPE_EAPOL,
+ P54_KEY_TYPE_TKIP,
+ P54_KEY_TYPE_CCX = 6
+};
+
struct p54_rx_hdr {
__le16 magic;
__le16 len;
@@ -169,7 +177,8 @@ struct p54_rx_hdr {
u8 rate;
u8 rssi;
u8 quality;
- u16 unknown2;
+ u8 key_type;
+ u8 channel_activity;
__le64 timestamp;
u8 data[0];
} __attribute__ ((packed));
@@ -182,34 +191,49 @@ struct p54_frame_sent_hdr {
u16 rate;
} __attribute__ ((packed));
+#define P54_FILTER_TYPE_NONE 0
+#define P54_FILTER_TYPE_STA 1
+#define P54_FILTER_TYPE_ADHOC 2
+#define P54_FILTER_TYPE_AP 4
+#define P54_FILTER_TYPE_PROMISC 8
+#define P54_FILTER_TYPE_MONITOR 16
+#define P54_FILTER_TYPE_SLEEP 32
+
+#define P54_RX_FILTER_NOTHING 0
+#define P54_RX_FILTER_FCSFAIL 1
+#define P54_RX_FILTER_OTHER_BSS 2
+
struct p54_tx_control_allocdata {
u8 rateset[8];
- u16 padding;
- u8 wep_key_present;
- u8 wep_key_len;
- u8 wep_key[16];
- __le32 frame_type;
- u32 padding2;
- __le16 magic4;
+ u16 :16;
+ u8 key_type;
+ u8 key_len;
+ u8 key[16];
+ u8 frame_type;
+ u32 :24;
+ u32 :32;
+ u16 :16;
u8 antenna;
u8 output_power;
- __le32 magic5;
+ u8 cts_rate;
+ u32 :24;
u8 align[0];
} __attribute__ ((packed));
struct p54_tx_control_filter {
- __le16 filter_type;
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 antenna;
- u8 debug;
- __le32 magic3;
- u8 rates[8]; // FIXME: what's this for?
+ u8 filter_type;
+ u8 :8;
+ u8 our_mac[ETH_ALEN];
+ u8 bss_filter_mac[ETH_ALEN];
+ u8 rx_antenna;
+ u8 rx_align;
+ __le32 bss_basic_rates;
+ u8 rts_rates[8];
__le32 rx_addr;
__le16 max_rx;
__le16 rxhw;
- __le16 magic8;
- __le16 magic9;
+ __le16 dtim_timer;
+ u16 :16;
} __attribute__ ((packed));
struct p54_tx_control_channel {
@@ -242,13 +266,29 @@ struct p54_tx_vdcf_queues {
} __attribute__ ((packed));
struct p54_tx_control_vdcf {
- u8 padding;
+ u8 :8;
u8 slottime;
u8 magic1;
u8 magic2;
struct p54_tx_vdcf_queues queue[8];
- u8 pad2[4];
+ u8 offset1;
+ u8 offset2;
+ u16 :16;
__le16 frameburst;
} __attribute__ ((packed));
+struct p54_statistics {
+ __le32 rx_success;
+ __le32 rx_errors;
+ __le32 rx_aborts;
+ __le32 rx_aborts_phy;
+ __le32 rx_rts_success;
+ __le32 rx_rts_failed;
+ __le32 tsf;
+ __le32 unknown_stat;
+ u8 noise_floor;
+ u32 :24;
+ u8 unknown[40]; /* CCA / CCQ / RADAR data */
+} __attribute__ ((packed));
+
#endif /* PRISM54COMMON_H */
diff -Nurp a/drivers/net/wireless/p54.h b/drivers/net/wireless/p54.h
--- a/drivers/net/wireless/p54.h 2008-03-29 16:06:06.000000000 +0100
+++ b/drivers/net/wireless/p54.h 2008-03-30 17:42:17.000000000 +0200
@@ -14,6 +14,8 @@
* published by the Free Software Foundation.
*/
+#include <linux/timer.h>
+
enum control_frame_types {
P54_CONTROL_TYPE_FILTER_SET = 0,
P54_CONTROL_TYPE_CHANNEL_CHANGE,
@@ -38,6 +40,19 @@ struct p54_control_hdr {
u8 data[0];
} __attribute__ ((packed));
+struct p54_stats {
+ void *cached_stats;
+ struct timer_list timer;
+ unsigned int rx_success;
+ unsigned int rx_errors;
+ unsigned int rx_aborts;
+ unsigned int rx_aborts_phy;
+ unsigned int rx_rts_success;
+ unsigned int rx_rts_failed;
+ unsigned int tsf;
+ unsigned int noise_floor;
+};
+
#define EEPROM_READBACK_LEN (sizeof(struct p54_control_hdr) + 4 /* p54_eeprom_lm86 */)
#define MAX_RX_SIZE (IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct p54_control_hdr) + 20 /* length of struct p54_rx_hdr */ + 16 )
@@ -60,10 +75,14 @@ struct p54_common {
unsigned int output_limit_len;
struct pda_pa_curve_data *curve_data;
__le16 rxhw;
+ __le16 freq;
+ u8 filter_type;
u8 version;
+ unsigned int rx_filter;
unsigned int tx_hdr_len;
void *cached_vdcf;
unsigned int fw_var;
+ struct p54_stats stats;
struct ieee80211_tx_queue_stats tx_stats;
};
next reply other threads:[~2008-03-30 21:49 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-30 21:49 Chr [this message]
2008-03-30 22:02 ` [RFC][PATCH 2/2] p54: statistic readback and other changes Florian Fainelli
2008-03-31 12:29 ` Chr
2008-03-31 12:48 ` Florian Fainelli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200803302349.27450.chunkeey@web.de \
--to=chunkeey@web.de \
--cc=flamingice@sourmilk.net \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.