Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22d3405f authored by Ulrich Kunitz's avatar Ulrich Kunitz Committed by John W. Linville
Browse files

[PATCH] zd1211rw: Added error stats update



Added update of network device error statistics.

Based on earlier work by Maxime Austruy.

Signed-off-by: default avatarUlrich Kunitz <kune@deine-taler.de>
Signed-off-by: default avatarDaniel Drake <dsd@gentoo.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent fa8e29cf
Loading
Loading
Loading
Loading
+32 −5
Original line number Original line Diff line number Diff line
@@ -903,17 +903,22 @@ static int fill_ctrlset(struct zd_mac *mac,
static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri)
static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri)
{
{
	int i, r;
	int i, r;
	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);


	for (i = 0; i < txb->nr_frags; i++) {
	for (i = 0; i < txb->nr_frags; i++) {
		struct sk_buff *skb = txb->fragments[i];
		struct sk_buff *skb = txb->fragments[i];


		r = fill_ctrlset(mac, txb, i);
		r = fill_ctrlset(mac, txb, i);
		if (r)
		if (r) {
			ieee->stats.tx_dropped++;
			return r;
			return r;
		}
		r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len);
		r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len);
		if (r)
		if (r) {
			ieee->stats.tx_dropped++;
			return r;
			return r;
		}
		}
	}


	/* FIXME: shouldn't this be handled by the upper layers? */
	/* FIXME: shouldn't this be handled by the upper layers? */
	mac->netdev->trans_start = jiffies;
	mac->netdev->trans_start = jiffies;
@@ -1062,9 +1067,23 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats,


	*pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status));
	*pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status));
	if (status->frame_status & ZD_RX_ERROR) {
	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;
		return -EINVAL;
	}
	}

	memset(stats, 0, sizeof(struct ieee80211_rx_stats));
	memset(stats, 0, sizeof(struct ieee80211_rx_stats));
	stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN +
	stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN +
		               + sizeof(struct rx_status));
		               + 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 +
	if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
	               IEEE80211_FCS_LEN + sizeof(struct rx_status))
	               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",
		dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n",
			 skb->len);
			 skb->len);
		goto free_skb;
		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);
	r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len);
	if (r) {
	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;
		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);
	r = filter_rx(ieee, skb->data, skb->len, &stats);
	if (r <= 0) {
	if (r <= 0) {
		if (r < 0)
		if (r < 0) {
			ieee->stats.rx_errors++;
			dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n");
			dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n");
		}
		goto free_skb;
		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);
	skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length);
	if (!skb) {
	if (!skb) {
		struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
		dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n");
		dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n");
		ieee->stats.rx_dropped++;
		return -ENOMEM;
		return -ENOMEM;
	}
	}
	skb_reserve(skb, sizeof(struct zd_rt_hdr));
	skb_reserve(skb, sizeof(struct zd_rt_hdr));
+9 −0
Original line number Original line Diff line number Diff line
@@ -401,6 +401,12 @@ out:


static inline void handle_retry_failed_int(struct urb *urb)
static inline void handle_retry_failed_int(struct urb *urb)
{
{
	struct zd_usb *usb = urb->context;
	struct zd_mac *mac = zd_usb_to_mac(usb);
	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);

	ieee->stats.tx_errors++;
	ieee->ieee_stats.tx_retry_limit_exceeded++;
	dev_dbg_f(urb_dev(urb), "retry failed interrupt\n");
	dev_dbg_f(urb_dev(urb), "retry failed interrupt\n");
}
}


@@ -575,6 +581,9 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,


	if (length < sizeof(struct rx_length_info)) {
	if (length < sizeof(struct rx_length_info)) {
		/* It's not a complete packet anyhow. */
		/* It's not a complete packet anyhow. */
		struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
		ieee->stats.rx_errors++;
		ieee->stats.rx_length_errors++;
		return;
		return;
	}
	}
	length_info = (struct rx_length_info *)
	length_info = (struct rx_length_info *)