diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2018-03-22 21:19:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-25 20:48:25 -0400 |
commit | b6e0e875421ef6debfbe05d3aa99ac788d886074 (patch) | |
tree | 6622c4c4151faad1627de5ce223c10e419043fe1 | |
parent | 9259f134a7dd1372ab142b2860994b993db34917 (diff) |
net: systemport: Implement adaptive interrupt coalescing
Implement support for adaptive RX and TX interrupt coalescing using
net_dim. We have each of our TX ring and our single RX ring implement a
bcm_sysport_net_dim structure which holds an interrupt counter, number
of packets, bytes, and a container for a net_dim instance.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bcmsysport.c | 141 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bcmsysport.h | 14 |
2 files changed, 140 insertions, 15 deletions
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 3fc549b88c43..4e26f606a7f2 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
18 | #include <linux/net_dim.h> | ||
18 | #include <linux/etherdevice.h> | 19 | #include <linux/etherdevice.h> |
19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
@@ -574,21 +575,55 @@ static int bcm_sysport_set_wol(struct net_device *dev, | |||
574 | return 0; | 575 | return 0; |
575 | } | 576 | } |
576 | 577 | ||
578 | static void bcm_sysport_set_rx_coalesce(struct bcm_sysport_priv *priv) | ||
579 | { | ||
580 | u32 reg; | ||
581 | |||
582 | reg = rdma_readl(priv, RDMA_MBDONE_INTR); | ||
583 | reg &= ~(RDMA_INTR_THRESH_MASK | | ||
584 | RDMA_TIMEOUT_MASK << RDMA_TIMEOUT_SHIFT); | ||
585 | reg |= priv->dim.coal_pkts; | ||
586 | reg |= DIV_ROUND_UP(priv->dim.coal_usecs * 1000, 8192) << | ||
587 | RDMA_TIMEOUT_SHIFT; | ||
588 | rdma_writel(priv, reg, RDMA_MBDONE_INTR); | ||
589 | } | ||
590 | |||
591 | static void bcm_sysport_set_tx_coalesce(struct bcm_sysport_tx_ring *ring) | ||
592 | { | ||
593 | struct bcm_sysport_priv *priv = ring->priv; | ||
594 | u32 reg; | ||
595 | |||
596 | reg = tdma_readl(priv, TDMA_DESC_RING_INTR_CONTROL(ring->index)); | ||
597 | reg &= ~(RING_INTR_THRESH_MASK | | ||
598 | RING_TIMEOUT_MASK << RING_TIMEOUT_SHIFT); | ||
599 | reg |= ring->dim.coal_pkts; | ||
600 | reg |= DIV_ROUND_UP(ring->dim.coal_usecs * 1000, 8192) << | ||
601 | RING_TIMEOUT_SHIFT; | ||
602 | tdma_writel(priv, reg, TDMA_DESC_RING_INTR_CONTROL(ring->index)); | ||
603 | } | ||
604 | |||
577 | static int bcm_sysport_get_coalesce(struct net_device *dev, | 605 | static int bcm_sysport_get_coalesce(struct net_device *dev, |
578 | struct ethtool_coalesce *ec) | 606 | struct ethtool_coalesce *ec) |
579 | { | 607 | { |
580 | struct bcm_sysport_priv *priv = netdev_priv(dev); | 608 | struct bcm_sysport_priv *priv = netdev_priv(dev); |
609 | struct bcm_sysport_tx_ring *ring; | ||
610 | unsigned int i; | ||
581 | u32 reg; | 611 | u32 reg; |
582 | 612 | ||
583 | reg = tdma_readl(priv, TDMA_DESC_RING_INTR_CONTROL(0)); | 613 | reg = tdma_readl(priv, TDMA_DESC_RING_INTR_CONTROL(0)); |
584 | 614 | ||
585 | ec->tx_coalesce_usecs = (reg >> RING_TIMEOUT_SHIFT) * 8192 / 1000; | 615 | ec->tx_coalesce_usecs = (reg >> RING_TIMEOUT_SHIFT) * 8192 / 1000; |
586 | ec->tx_max_coalesced_frames = reg & RING_INTR_THRESH_MASK; | 616 | ec->tx_max_coalesced_frames = reg & RING_INTR_THRESH_MASK; |
617 | for (i = 0; i < dev->num_tx_queues; i++) { | ||
618 | ring = &priv->tx_rings[i]; | ||
619 | ec->use_adaptive_tx_coalesce |= ring->dim.use_dim; | ||
620 | } | ||
587 | 621 | ||
588 | reg = rdma_readl(priv, RDMA_MBDONE_INTR); | 622 | reg = rdma_readl(priv, RDMA_MBDONE_INTR); |
589 | 623 | ||
590 | ec->rx_coalesce_usecs = (reg >> RDMA_TIMEOUT_SHIFT) * 8192 / 1000; | 624 | ec->rx_coalesce_usecs = (reg >> RDMA_TIMEOUT_SHIFT) * 8192 / 1000; |
591 | ec->rx_max_coalesced_frames = reg & RDMA_INTR_THRESH_MASK; | 625 | ec->rx_max_coalesced_frames = reg & RDMA_INTR_THRESH_MASK; |
626 | ec->use_adaptive_rx_coalesce = priv->dim.use_dim; | ||
592 | 627 | ||
593 | return 0; | 628 | return 0; |
594 | } | 629 | } |
@@ -597,8 +632,8 @@ static int bcm_sysport_set_coalesce(struct net_device *dev, | |||
597 | struct ethtool_coalesce *ec) | 632 | struct ethtool_coalesce *ec) |
598 | { | 633 | { |
599 | struct bcm_sysport_priv *priv = netdev_priv(dev); | 634 | struct bcm_sysport_priv *priv = netdev_priv(dev); |
635 | struct bcm_sysport_tx_ring *ring; | ||
600 | unsigned int i; | 636 | unsigned int i; |
601 | u32 reg; | ||
602 | 637 | ||
603 | /* Base system clock is 125Mhz, DMA timeout is this reference clock | 638 | /* Base system clock is 125Mhz, DMA timeout is this reference clock |
604 | * divided by 1024, which yield roughly 8.192 us, our maximum value has | 639 | * divided by 1024, which yield roughly 8.192 us, our maximum value has |
@@ -615,22 +650,26 @@ static int bcm_sysport_set_coalesce(struct net_device *dev, | |||
615 | return -EINVAL; | 650 | return -EINVAL; |
616 | 651 | ||
617 | for (i = 0; i < dev->num_tx_queues; i++) { | 652 | for (i = 0; i < dev->num_tx_queues; i++) { |
618 | reg = tdma_readl(priv, TDMA_DESC_RING_INTR_CONTROL(i)); | 653 | ring = &priv->tx_rings[i]; |
619 | reg &= ~(RING_INTR_THRESH_MASK | | 654 | ring->dim.coal_pkts = ec->tx_max_coalesced_frames; |
620 | RING_TIMEOUT_MASK << RING_TIMEOUT_SHIFT); | 655 | ring->dim.coal_usecs = ec->tx_coalesce_usecs; |
621 | reg |= ec->tx_max_coalesced_frames; | 656 | if (!ec->use_adaptive_tx_coalesce && ring->dim.use_dim) { |
622 | reg |= DIV_ROUND_UP(ec->tx_coalesce_usecs * 1000, 8192) << | 657 | ring->dim.coal_pkts = 1; |
623 | RING_TIMEOUT_SHIFT; | 658 | ring->dim.coal_usecs = 0; |
624 | tdma_writel(priv, reg, TDMA_DESC_RING_INTR_CONTROL(i)); | 659 | } |
660 | ring->dim.use_dim = ec->use_adaptive_tx_coalesce; | ||
661 | bcm_sysport_set_tx_coalesce(ring); | ||
625 | } | 662 | } |
626 | 663 | ||
627 | reg = rdma_readl(priv, RDMA_MBDONE_INTR); | 664 | priv->dim.coal_usecs = ec->rx_coalesce_usecs; |
628 | reg &= ~(RDMA_INTR_THRESH_MASK | | 665 | priv->dim.coal_pkts = ec->rx_max_coalesced_frames; |
629 | RDMA_TIMEOUT_MASK << RDMA_TIMEOUT_SHIFT); | 666 | |
630 | reg |= ec->rx_max_coalesced_frames; | 667 | if (!ec->use_adaptive_rx_coalesce && priv->dim.use_dim) { |
631 | reg |= DIV_ROUND_UP(ec->rx_coalesce_usecs * 1000, 8192) << | 668 | priv->dim.coal_pkts = 1; |
632 | RDMA_TIMEOUT_SHIFT; | 669 | priv->dim.coal_usecs = 0; |
633 | rdma_writel(priv, reg, RDMA_MBDONE_INTR); | 670 | } |
671 | priv->dim.use_dim = ec->use_adaptive_rx_coalesce; | ||
672 | bcm_sysport_set_rx_coalesce(priv); | ||
634 | 673 | ||
635 | return 0; | 674 | return 0; |
636 | } | 675 | } |
@@ -709,6 +748,7 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv, | |||
709 | struct bcm_sysport_stats64 *stats64 = &priv->stats64; | 748 | struct bcm_sysport_stats64 *stats64 = &priv->stats64; |
710 | struct net_device *ndev = priv->netdev; | 749 | struct net_device *ndev = priv->netdev; |
711 | unsigned int processed = 0, to_process; | 750 | unsigned int processed = 0, to_process; |
751 | unsigned int processed_bytes = 0; | ||
712 | struct bcm_sysport_cb *cb; | 752 | struct bcm_sysport_cb *cb; |
713 | struct sk_buff *skb; | 753 | struct sk_buff *skb; |
714 | unsigned int p_index; | 754 | unsigned int p_index; |
@@ -800,6 +840,7 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv, | |||
800 | */ | 840 | */ |
801 | skb_pull(skb, sizeof(*rsb) + 2); | 841 | skb_pull(skb, sizeof(*rsb) + 2); |
802 | len -= (sizeof(*rsb) + 2); | 842 | len -= (sizeof(*rsb) + 2); |
843 | processed_bytes += len; | ||
803 | 844 | ||
804 | /* UniMAC may forward CRC */ | 845 | /* UniMAC may forward CRC */ |
805 | if (priv->crc_fwd) { | 846 | if (priv->crc_fwd) { |
@@ -824,6 +865,9 @@ next: | |||
824 | priv->rx_read_ptr = 0; | 865 | priv->rx_read_ptr = 0; |
825 | } | 866 | } |
826 | 867 | ||
868 | priv->dim.packets = processed; | ||
869 | priv->dim.bytes = processed_bytes; | ||
870 | |||
827 | return processed; | 871 | return processed; |
828 | } | 872 | } |
829 | 873 | ||
@@ -896,6 +940,8 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv, | |||
896 | ring->packets += pkts_compl; | 940 | ring->packets += pkts_compl; |
897 | ring->bytes += bytes_compl; | 941 | ring->bytes += bytes_compl; |
898 | u64_stats_update_end(&priv->syncp); | 942 | u64_stats_update_end(&priv->syncp); |
943 | ring->dim.packets = pkts_compl; | ||
944 | ring->dim.bytes = bytes_compl; | ||
899 | 945 | ||
900 | ring->c_index = c_index; | 946 | ring->c_index = c_index; |
901 | 947 | ||
@@ -941,6 +987,7 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget) | |||
941 | { | 987 | { |
942 | struct bcm_sysport_tx_ring *ring = | 988 | struct bcm_sysport_tx_ring *ring = |
943 | container_of(napi, struct bcm_sysport_tx_ring, napi); | 989 | container_of(napi, struct bcm_sysport_tx_ring, napi); |
990 | struct net_dim_sample dim_sample; | ||
944 | unsigned int work_done = 0; | 991 | unsigned int work_done = 0; |
945 | 992 | ||
946 | work_done = bcm_sysport_tx_reclaim(ring->priv, ring); | 993 | work_done = bcm_sysport_tx_reclaim(ring->priv, ring); |
@@ -957,6 +1004,12 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget) | |||
957 | return 0; | 1004 | return 0; |
958 | } | 1005 | } |
959 | 1006 | ||
1007 | if (ring->dim.use_dim) { | ||
1008 | net_dim_sample(ring->dim.event_ctr, ring->dim.packets, | ||
1009 | ring->dim.bytes, &dim_sample); | ||
1010 | net_dim(&ring->dim.dim, dim_sample); | ||
1011 | } | ||
1012 | |||
960 | return budget; | 1013 | return budget; |
961 | } | 1014 | } |
962 | 1015 | ||
@@ -972,6 +1025,7 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget) | |||
972 | { | 1025 | { |
973 | struct bcm_sysport_priv *priv = | 1026 | struct bcm_sysport_priv *priv = |
974 | container_of(napi, struct bcm_sysport_priv, napi); | 1027 | container_of(napi, struct bcm_sysport_priv, napi); |
1028 | struct net_dim_sample dim_sample; | ||
975 | unsigned int work_done = 0; | 1029 | unsigned int work_done = 0; |
976 | 1030 | ||
977 | work_done = bcm_sysport_desc_rx(priv, budget); | 1031 | work_done = bcm_sysport_desc_rx(priv, budget); |
@@ -994,6 +1048,12 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget) | |||
994 | intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE); | 1048 | intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE); |
995 | } | 1049 | } |
996 | 1050 | ||
1051 | if (priv->dim.use_dim) { | ||
1052 | net_dim_sample(priv->dim.event_ctr, priv->dim.packets, | ||
1053 | priv->dim.bytes, &dim_sample); | ||
1054 | net_dim(&priv->dim.dim, dim_sample); | ||
1055 | } | ||
1056 | |||
997 | return work_done; | 1057 | return work_done; |
998 | } | 1058 | } |
999 | 1059 | ||
@@ -1012,6 +1072,40 @@ static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv) | |||
1012 | netif_dbg(priv, wol, priv->netdev, "resumed from WOL\n"); | 1072 | netif_dbg(priv, wol, priv->netdev, "resumed from WOL\n"); |
1013 | } | 1073 | } |
1014 | 1074 | ||
1075 | static void bcm_sysport_dim_work(struct work_struct *work) | ||
1076 | { | ||
1077 | struct net_dim *dim = container_of(work, struct net_dim, work); | ||
1078 | struct bcm_sysport_net_dim *ndim = | ||
1079 | container_of(dim, struct bcm_sysport_net_dim, dim); | ||
1080 | struct bcm_sysport_priv *priv = | ||
1081 | container_of(ndim, struct bcm_sysport_priv, dim); | ||
1082 | struct net_dim_cq_moder cur_profile = | ||
1083 | net_dim_get_profile(dim->mode, dim->profile_ix); | ||
1084 | |||
1085 | priv->dim.coal_usecs = cur_profile.usec; | ||
1086 | priv->dim.coal_pkts = cur_profile.pkts; | ||
1087 | |||
1088 | bcm_sysport_set_rx_coalesce(priv); | ||
1089 | dim->state = NET_DIM_START_MEASURE; | ||
1090 | } | ||
1091 | |||
1092 | static void bcm_sysport_dim_tx_work(struct work_struct *work) | ||
1093 | { | ||
1094 | struct net_dim *dim = container_of(work, struct net_dim, work); | ||
1095 | struct bcm_sysport_net_dim *ndim = | ||
1096 | container_of(dim, struct bcm_sysport_net_dim, dim); | ||
1097 | struct bcm_sysport_tx_ring *ring = | ||
1098 | container_of(ndim, struct bcm_sysport_tx_ring, dim); | ||
1099 | struct net_dim_cq_moder cur_profile = | ||
1100 | net_dim_get_profile(dim->mode, dim->profile_ix); | ||
1101 | |||
1102 | ring->dim.coal_usecs = cur_profile.usec; | ||
1103 | ring->dim.coal_pkts = cur_profile.pkts; | ||
1104 | |||
1105 | bcm_sysport_set_tx_coalesce(ring); | ||
1106 | dim->state = NET_DIM_START_MEASURE; | ||
1107 | } | ||
1108 | |||
1015 | /* RX and misc interrupt routine */ | 1109 | /* RX and misc interrupt routine */ |
1016 | static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id) | 1110 | static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id) |
1017 | { | 1111 | { |
@@ -1030,6 +1124,7 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id) | |||
1030 | } | 1124 | } |
1031 | 1125 | ||
1032 | if (priv->irq0_stat & INTRL2_0_RDMA_MBDONE) { | 1126 | if (priv->irq0_stat & INTRL2_0_RDMA_MBDONE) { |
1127 | priv->dim.event_ctr++; | ||
1033 | if (likely(napi_schedule_prep(&priv->napi))) { | 1128 | if (likely(napi_schedule_prep(&priv->napi))) { |
1034 | /* disable RX interrupts */ | 1129 | /* disable RX interrupts */ |
1035 | intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE); | 1130 | intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE); |
@@ -1057,6 +1152,7 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id) | |||
1057 | continue; | 1152 | continue; |
1058 | 1153 | ||
1059 | txr = &priv->tx_rings[ring]; | 1154 | txr = &priv->tx_rings[ring]; |
1155 | txr->dim.event_ctr++; | ||
1060 | 1156 | ||
1061 | if (likely(napi_schedule_prep(&txr->napi))) { | 1157 | if (likely(napi_schedule_prep(&txr->napi))) { |
1062 | intrl2_0_mask_set(priv, ring_bit); | 1158 | intrl2_0_mask_set(priv, ring_bit); |
@@ -1089,6 +1185,7 @@ static irqreturn_t bcm_sysport_tx_isr(int irq, void *dev_id) | |||
1089 | continue; | 1185 | continue; |
1090 | 1186 | ||
1091 | txr = &priv->tx_rings[ring]; | 1187 | txr = &priv->tx_rings[ring]; |
1188 | txr->dim.event_ctr++; | ||
1092 | 1189 | ||
1093 | if (likely(napi_schedule_prep(&txr->napi))) { | 1190 | if (likely(napi_schedule_prep(&txr->napi))) { |
1094 | intrl2_1_mask_set(priv, BIT(ring)); | 1191 | intrl2_1_mask_set(priv, BIT(ring)); |
@@ -1354,6 +1451,16 @@ out: | |||
1354 | phy_print_status(phydev); | 1451 | phy_print_status(phydev); |
1355 | } | 1452 | } |
1356 | 1453 | ||
1454 | static void bcm_sysport_init_dim(struct bcm_sysport_net_dim *dim, | ||
1455 | void (*cb)(struct work_struct *work)) | ||
1456 | { | ||
1457 | INIT_WORK(&dim->dim.work, cb); | ||
1458 | dim->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE; | ||
1459 | dim->event_ctr = 0; | ||
1460 | dim->packets = 0; | ||
1461 | dim->bytes = 0; | ||
1462 | } | ||
1463 | |||
1357 | static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, | 1464 | static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, |
1358 | unsigned int index) | 1465 | unsigned int index) |
1359 | { | 1466 | { |
@@ -1444,6 +1551,7 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, | |||
1444 | reg |= (1 << index); | 1551 | reg |= (1 << index); |
1445 | tdma_writel(priv, reg, TDMA_TIER1_ARB_0_QUEUE_EN); | 1552 | tdma_writel(priv, reg, TDMA_TIER1_ARB_0_QUEUE_EN); |
1446 | 1553 | ||
1554 | bcm_sysport_init_dim(&ring->dim, bcm_sysport_dim_tx_work); | ||
1447 | napi_enable(&ring->napi); | 1555 | napi_enable(&ring->napi); |
1448 | 1556 | ||
1449 | netif_dbg(priv, hw, priv->netdev, | 1557 | netif_dbg(priv, hw, priv->netdev, |
@@ -1474,6 +1582,7 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv, | |||
1474 | return; | 1582 | return; |
1475 | 1583 | ||
1476 | napi_disable(&ring->napi); | 1584 | napi_disable(&ring->napi); |
1585 | cancel_work_sync(&ring->dim.dim.work); | ||
1477 | netif_napi_del(&ring->napi); | 1586 | netif_napi_del(&ring->napi); |
1478 | 1587 | ||
1479 | bcm_sysport_tx_clean(priv, ring); | 1588 | bcm_sysport_tx_clean(priv, ring); |
@@ -1763,6 +1872,7 @@ static void bcm_sysport_netif_start(struct net_device *dev) | |||
1763 | struct bcm_sysport_priv *priv = netdev_priv(dev); | 1872 | struct bcm_sysport_priv *priv = netdev_priv(dev); |
1764 | 1873 | ||
1765 | /* Enable NAPI */ | 1874 | /* Enable NAPI */ |
1875 | bcm_sysport_init_dim(&priv->dim, bcm_sysport_dim_work); | ||
1766 | napi_enable(&priv->napi); | 1876 | napi_enable(&priv->napi); |
1767 | 1877 | ||
1768 | /* Enable RX interrupt and TX ring full interrupt */ | 1878 | /* Enable RX interrupt and TX ring full interrupt */ |
@@ -1948,6 +2058,7 @@ static void bcm_sysport_netif_stop(struct net_device *dev) | |||
1948 | /* stop all software from updating hardware */ | 2058 | /* stop all software from updating hardware */ |
1949 | netif_tx_stop_all_queues(dev); | 2059 | netif_tx_stop_all_queues(dev); |
1950 | napi_disable(&priv->napi); | 2060 | napi_disable(&priv->napi); |
2061 | cancel_work_sync(&priv->dim.dim.work); | ||
1951 | phy_stop(dev->phydev); | 2062 | phy_stop(dev->phydev); |
1952 | 2063 | ||
1953 | /* mask all interrupts */ | 2064 | /* mask all interrupts */ |
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h index 19c91c76e327..e1c97d4a82b4 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.h +++ b/drivers/net/ethernet/broadcom/bcmsysport.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define __BCM_SYSPORT_H | 12 | #define __BCM_SYSPORT_H |
13 | 13 | ||
14 | #include <linux/if_vlan.h> | 14 | #include <linux/if_vlan.h> |
15 | #include <linux/net_dim.h> | ||
15 | 16 | ||
16 | /* Receive/transmit descriptor format */ | 17 | /* Receive/transmit descriptor format */ |
17 | #define DESC_ADDR_HI_STATUS_LEN 0x00 | 18 | #define DESC_ADDR_HI_STATUS_LEN 0x00 |
@@ -695,6 +696,16 @@ struct bcm_sysport_hw_params { | |||
695 | unsigned int num_rx_desc_words; | 696 | unsigned int num_rx_desc_words; |
696 | }; | 697 | }; |
697 | 698 | ||
699 | struct bcm_sysport_net_dim { | ||
700 | u16 use_dim; | ||
701 | u16 event_ctr; | ||
702 | unsigned long packets; | ||
703 | unsigned long bytes; | ||
704 | u32 coal_usecs; | ||
705 | u32 coal_pkts; | ||
706 | struct net_dim dim; | ||
707 | }; | ||
708 | |||
698 | /* Software view of the TX ring */ | 709 | /* Software view of the TX ring */ |
699 | struct bcm_sysport_tx_ring { | 710 | struct bcm_sysport_tx_ring { |
700 | spinlock_t lock; /* Ring lock for tx reclaim/xmit */ | 711 | spinlock_t lock; /* Ring lock for tx reclaim/xmit */ |
@@ -712,6 +723,7 @@ struct bcm_sysport_tx_ring { | |||
712 | struct bcm_sysport_priv *priv; /* private context backpointer */ | 723 | struct bcm_sysport_priv *priv; /* private context backpointer */ |
713 | unsigned long packets; /* packets statistics */ | 724 | unsigned long packets; /* packets statistics */ |
714 | unsigned long bytes; /* bytes statistics */ | 725 | unsigned long bytes; /* bytes statistics */ |
726 | struct bcm_sysport_net_dim dim; /* Net DIM context */ | ||
715 | unsigned int switch_queue; /* switch port queue number */ | 727 | unsigned int switch_queue; /* switch port queue number */ |
716 | unsigned int switch_port; /* switch port queue number */ | 728 | unsigned int switch_port; /* switch port queue number */ |
717 | bool inspect; /* inspect switch port and queue */ | 729 | bool inspect; /* inspect switch port and queue */ |
@@ -743,6 +755,8 @@ struct bcm_sysport_priv { | |||
743 | unsigned int rx_read_ptr; | 755 | unsigned int rx_read_ptr; |
744 | unsigned int rx_c_index; | 756 | unsigned int rx_c_index; |
745 | 757 | ||
758 | struct bcm_sysport_net_dim dim; | ||
759 | |||
746 | /* PHY device */ | 760 | /* PHY device */ |
747 | struct device_node *phy_dn; | 761 | struct device_node *phy_dn; |
748 | phy_interface_t phy_interface; | 762 | phy_interface_t phy_interface; |