struct wil6210_mbox_hdr_wmi wmi;
struct wmi_notify_req_done_event evt;
} __packed reply;
+ struct wil_net_stats *stats = &wil->sta[cid].stats;
int rc;
rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
if (rc)
return rc;
+ wil_dbg_wmi(wil, "Link status for CID %d: {\n"
+ " MCS %d TSF 0x%016llx\n"
+ " BF status 0x%08x SNR 0x%08x\n"
+ " Tx Tpt %d goodput %d Rx goodput %d\n"
+ " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
+ cid, le16_to_cpu(reply.evt.bf_mcs),
+ le64_to_cpu(reply.evt.tsf), reply.evt.status,
+ le32_to_cpu(reply.evt.snr_val),
+ le32_to_cpu(reply.evt.tx_tpt),
+ le32_to_cpu(reply.evt.tx_goodput),
+ le32_to_cpu(reply.evt.rx_goodput),
+ le16_to_cpu(reply.evt.my_rx_sector),
+ le16_to_cpu(reply.evt.my_tx_sector),
+ le16_to_cpu(reply.evt.other_rx_sector),
+ le16_to_cpu(reply.evt.other_tx_sector));
+
sinfo->generation = wil->sinfo_gen;
- sinfo->filled |= STATION_INFO_TX_BITRATE;
+ sinfo->filled = STATION_INFO_RX_BYTES |
+ STATION_INFO_TX_BYTES |
+ STATION_INFO_RX_PACKETS |
+ STATION_INFO_TX_PACKETS |
+ STATION_INFO_RX_BITRATE |
+ STATION_INFO_TX_BITRATE |
+ STATION_INFO_RX_DROP_MISC |
+ STATION_INFO_TX_FAILED;
+
sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
- sinfo->filled |= STATION_INFO_RX_BITRATE;
sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
- sinfo->rxrate.mcs = wil->stats.last_mcs_rx;
+ sinfo->rxrate.mcs = stats->last_mcs_rx;
+ sinfo->rx_bytes = stats->rx_bytes;
+ sinfo->rx_packets = stats->rx_packets;
+ sinfo->rx_dropped_misc = stats->rx_dropped;
+ sinfo->tx_bytes = stats->tx_bytes;
+ sinfo->tx_packets = stats->tx_packets;
+ sinfo->tx_failed = stats->tx_errors;
if (test_bit(wil_status_fwconnected, &wil->status)) {
sinfo->filled |= STATION_INFO_SIGNAL;
u16 dmalen;
u8 ftype;
u8 ds_bits;
+ int cid;
+ struct wil_net_stats *stats;
+
BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb_headlen(skb), false);
-
- wil->stats.last_mcs_rx = wil_rxdesc_mcs(d);
+ cid = wil_rxdesc_cid(d);
+ stats = &wil->sta[cid].stats;
+ stats->last_mcs_rx = wil_rxdesc_mcs(d);
+ wil->stats.last_mcs_rx = stats->last_mcs_rx;
/* use radiotap header only if required */
if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
{
int rc;
+ struct wil6210_priv *wil = ndev_to_wil(ndev);
unsigned int len = skb->len;
+ struct vring_rx_desc *d = wil_skb_rxdesc(skb);
+ int cid = wil_rxdesc_cid(d);
+ struct wil_net_stats *stats = &wil->sta[cid].stats;
skb_orphan(skb);
if (likely(rc == NET_RX_SUCCESS)) {
ndev->stats.rx_packets++;
+ stats->rx_packets++;
ndev->stats.rx_bytes += len;
+ stats->rx_bytes += len;
} else {
ndev->stats.rx_dropped++;
+ stats->rx_dropped++;
}
}
struct device *dev = wil_to_dev(wil);
struct vring *vring = &wil->vring_tx[ringid];
int done = 0;
+ int cid = wil->vring2cid_tid[ringid][0];
+ struct wil_net_stats *stats = &wil->sta[cid].stats;
if (!vring->va) {
wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
if (skb) {
if (d->dma.error == 0) {
ndev->stats.tx_packets++;
+ stats->tx_packets++;
ndev->stats.tx_bytes += skb->len;
+ stats->tx_bytes += skb->len;
} else {
ndev->stats.tx_errors++;
+ stats->tx_errors++;
}
dev_kfree_skb_any(skb);
#define WIL_STA_TID_NUM (16)
+struct wil_net_stats {
+ unsigned long rx_packets;
+ unsigned long tx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_bytes;
+ unsigned long tx_errors;
+ unsigned long rx_dropped;
+ u16 last_mcs_rx;
+};
+
/**
* struct wil_sta_info - data for peer
*
struct wil_sta_info {
u8 addr[ETH_ALEN];
enum wil_sta_status status;
+ struct wil_net_stats stats;
/* Rx BACK */
struct wil_tid_ampdu_rx *tid_rx[WIL_STA_TID_NUM];
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(WIL_STA_TID_NUM)];
int sz = eapol_len + ETH_HLEN;
struct sk_buff *skb;
struct ethhdr *eth;
+ int cid;
+ struct wil_net_stats *stats = NULL;
wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len,
evt->src_mac);
+ cid = wil_find_cid(wil, evt->src_mac);
+ if (cid >= 0)
+ stats = &wil->sta[cid].stats;
+
if (eapol_len > 196) { /* TODO: revisit size limit */
wil_err(wil, "EAPOL too large\n");
return;
wil_err(wil, "Failed to allocate skb\n");
return;
}
+
eth = (struct ethhdr *)skb_put(skb, ETH_HLEN);
memcpy(eth->h_dest, ndev->dev_addr, ETH_ALEN);
memcpy(eth->h_source, evt->src_mac, ETH_ALEN);
skb->protocol = eth_type_trans(skb, ndev);
if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) {
ndev->stats.rx_packets++;
- ndev->stats.rx_bytes += skb->len;
+ ndev->stats.rx_bytes += sz;
+ if (stats) {
+ stats->rx_packets++;
+ stats->rx_bytes += sz;
+ }
} else {
ndev->stats.rx_dropped++;
+ if (stats)
+ stats->rx_dropped++;
}
}