|
@@ -903,16 +903,21 @@ static int fill_ctrlset(struct zd_mac *mac,
|
|
|
static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri)
|
|
|
{
|
|
|
int i, r;
|
|
|
+ struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
|
|
|
|
|
|
for (i = 0; i < txb->nr_frags; i++) {
|
|
|
struct sk_buff *skb = txb->fragments[i];
|
|
|
|
|
|
r = fill_ctrlset(mac, txb, i);
|
|
|
- if (r)
|
|
|
+ if (r) {
|
|
|
+ ieee->stats.tx_dropped++;
|
|
|
return r;
|
|
|
+ }
|
|
|
r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len);
|
|
|
- if (r)
|
|
|
+ if (r) {
|
|
|
+ ieee->stats.tx_dropped++;
|
|
|
return r;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* FIXME: shouldn't this be handled by the upper layers? */
|
|
@@ -1062,9 +1067,23 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats,
|
|
|
|
|
|
*pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status));
|
|
|
if (status->frame_status & ZD_RX_ERROR) {
|
|
|
- /* FIXME: update? */
|
|
|
+ struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
|
|
|
+ ieee->stats.rx_errors++;
|
|
|
+ if (status->frame_status & ZD_RX_TIMEOUT_ERROR)
|
|
|
+ ieee->stats.rx_missed_errors++;
|
|
|
+ else if (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR)
|
|
|
+ ieee->stats.rx_fifo_errors++;
|
|
|
+ else if (status->frame_status & ZD_RX_DECRYPTION_ERROR)
|
|
|
+ ieee->ieee_stats.rx_discards_undecryptable++;
|
|
|
+ else if (status->frame_status & ZD_RX_CRC32_ERROR) {
|
|
|
+ ieee->stats.rx_crc_errors++;
|
|
|
+ ieee->ieee_stats.rx_fcs_errors++;
|
|
|
+ }
|
|
|
+ else if (status->frame_status & ZD_RX_CRC16_ERROR)
|
|
|
+ ieee->stats.rx_crc_errors++;
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+
|
|
|
memset(stats, 0, sizeof(struct ieee80211_rx_stats));
|
|
|
stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN +
|
|
|
+ sizeof(struct rx_status));
|
|
@@ -1093,6 +1112,8 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb)
|
|
|
if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
|
|
|
IEEE80211_FCS_LEN + sizeof(struct rx_status))
|
|
|
{
|
|
|
+ ieee->stats.rx_errors++;
|
|
|
+ ieee->stats.rx_length_errors++;
|
|
|
dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n",
|
|
|
skb->len);
|
|
|
goto free_skb;
|
|
@@ -1100,7 +1121,9 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb)
|
|
|
|
|
|
r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len);
|
|
|
if (r) {
|
|
|
- /* Only packets with rx errors are included here. */
|
|
|
+ /* Only packets with rx errors are included here.
|
|
|
+ * The error stats have already been set in fill_rx_stats.
|
|
|
+ */
|
|
|
goto free_skb;
|
|
|
}
|
|
|
|
|
@@ -1113,8 +1136,10 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb)
|
|
|
|
|
|
r = filter_rx(ieee, skb->data, skb->len, &stats);
|
|
|
if (r <= 0) {
|
|
|
- if (r < 0)
|
|
|
+ if (r < 0) {
|
|
|
+ ieee->stats.rx_errors++;
|
|
|
dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n");
|
|
|
+ }
|
|
|
goto free_skb;
|
|
|
}
|
|
|
|
|
@@ -1145,7 +1170,9 @@ int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length)
|
|
|
|
|
|
skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length);
|
|
|
if (!skb) {
|
|
|
+ struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
|
|
|
dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n");
|
|
|
+ ieee->stats.rx_dropped++;
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
skb_reserve(skb, sizeof(struct zd_rt_hdr));
|