diff options
author | Julian Wiedmann <jwi@linux.ibm.com> | 2019-11-14 11:19:15 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-11-14 18:16:50 -0800 |
commit | 5fd3fcbb8af8f9bc82afd84937393c193b95c204 (patch) | |
tree | d86689584d7d385cf01565441d21e766faa07fc0 /drivers/s390/net/qeth_core_main.c | |
parent | s390/qeth: gather more detailed RX dropped/error statistics (diff) | |
download | linux-dev-5fd3fcbb8af8f9bc82afd84937393c193b95c204.tar.xz linux-dev-5fd3fcbb8af8f9bc82afd84937393c193b95c204.zip |
s390/qeth: support per-frame invalidation
Each RX buffer may contain up to 64KB worth of data. In case the device
needs to discard a packet _after_ already having reserved space for it
in the buffer, the whole buffer gets set to ERROR state. As the buffer
might contain any number of good packets, this can result in collateral
packet loss.
qeth can provide relief by enabling per-frame invalidation. The RX
buffer is then presented as usual, we just need to spot & drop any
individual packet that was flagged as invalid.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net/qeth_core_main.c')
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 4e113f359be9..c52241df980b 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1956,6 +1956,7 @@ static void qeth_idx_setup_activate_cmd(struct qeth_card *card, ccw_device_get_id(CARD_DDEV(card), &dev_id); iob->finalize = qeth_idx_finalize_cmd; + port |= QETH_IDX_ACT_INVAL_FRAME; memcpy(QETH_IDX_ACT_PNO(iob->data), &port, 1); memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data), &card->token.issuer_rm_w, QETH_MPC_TOKEN_LENGTH); @@ -4346,7 +4347,9 @@ static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) case MII_NWAYTEST: /* N-way auto-neg test register */ break; case MII_RERRCOUNTER: /* rx error counter */ - rc = card->stats.rx_length_errors + card->stats.rx_fifo_errors; + rc = card->stats.rx_length_errors + + card->stats.rx_frame_errors + + card->stats.rx_fifo_errors; break; case MII_SREVISION: /* silicon revision */ break; @@ -5092,7 +5095,11 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, headroom = sizeof(struct qeth_hdr); break; default: - QETH_CARD_STAT_INC(card, rx_dropped_notsupp); + if ((*hdr)->hdr.l2.id & QETH_HEADER_MASK_INVAL) + QETH_CARD_STAT_INC(card, rx_frame_errors); + else + QETH_CARD_STAT_INC(card, rx_dropped_notsupp); + break; } @@ -6238,11 +6245,13 @@ void qeth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) stats->rx_packets = card->stats.rx_packets; stats->rx_bytes = card->stats.rx_bytes; stats->rx_errors = card->stats.rx_length_errors + + card->stats.rx_frame_errors + card->stats.rx_fifo_errors; stats->rx_dropped = card->stats.rx_dropped_nomem + card->stats.rx_dropped_notsupp; stats->multicast = card->stats.rx_multicast; stats->rx_length_errors = card->stats.rx_length_errors; + stats->rx_frame_errors = card->stats.rx_frame_errors; stats->rx_fifo_errors = card->stats.rx_fifo_errors; for (i = 0; i < card->qdio.no_out_queues; i++) { |