diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 50 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.h | 34 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_dim.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 12 |
5 files changed, 118 insertions, 12 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/Makefile b/drivers/net/ethernet/broadcom/bnxt/Makefile index 59c8ec9c1cad..7c560d545c03 100644 --- a/drivers/net/ethernet/broadcom/bnxt/Makefile +++ b/drivers/net/ethernet/broadcom/bnxt/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-$(CONFIG_BNXT) += bnxt_en.o | 1 | obj-$(CONFIG_BNXT) += bnxt_en.o |
2 | 2 | ||
3 | bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o bnxt_devlink.o | 3 | bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o |
4 | bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o | 4 | bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 89c3c8760a78..cf6ebf1e324b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -1645,6 +1645,8 @@ next_rx: | |||
1645 | rxr->rx_next_cons = NEXT_RX(cons); | 1645 | rxr->rx_next_cons = NEXT_RX(cons); |
1646 | 1646 | ||
1647 | next_rx_no_prod: | 1647 | next_rx_no_prod: |
1648 | cpr->rx_packets += 1; | ||
1649 | cpr->rx_bytes += len; | ||
1648 | *raw_cons = tmp_raw_cons; | 1650 | *raw_cons = tmp_raw_cons; |
1649 | 1651 | ||
1650 | return rc; | 1652 | return rc; |
@@ -1802,6 +1804,7 @@ static irqreturn_t bnxt_msix(int irq, void *dev_instance) | |||
1802 | struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; | 1804 | struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; |
1803 | u32 cons = RING_CMP(cpr->cp_raw_cons); | 1805 | u32 cons = RING_CMP(cpr->cp_raw_cons); |
1804 | 1806 | ||
1807 | cpr->event_ctr++; | ||
1805 | prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]); | 1808 | prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]); |
1806 | napi_schedule(&bnapi->napi); | 1809 | napi_schedule(&bnapi->napi); |
1807 | return IRQ_HANDLED; | 1810 | return IRQ_HANDLED; |
@@ -2025,6 +2028,15 @@ static int bnxt_poll(struct napi_struct *napi, int budget) | |||
2025 | break; | 2028 | break; |
2026 | } | 2029 | } |
2027 | } | 2030 | } |
2031 | if (bp->flags & BNXT_FLAG_DIM) { | ||
2032 | struct net_dim_sample dim_sample; | ||
2033 | |||
2034 | net_dim_sample(cpr->event_ctr, | ||
2035 | cpr->rx_packets, | ||
2036 | cpr->rx_bytes, | ||
2037 | &dim_sample); | ||
2038 | net_dim(&cpr->dim, dim_sample); | ||
2039 | } | ||
2028 | mmiowb(); | 2040 | mmiowb(); |
2029 | return work_done; | 2041 | return work_done; |
2030 | } | 2042 | } |
@@ -2617,6 +2629,8 @@ static void bnxt_init_cp_rings(struct bnxt *bp) | |||
2617 | struct bnxt_ring_struct *ring = &cpr->cp_ring_struct; | 2629 | struct bnxt_ring_struct *ring = &cpr->cp_ring_struct; |
2618 | 2630 | ||
2619 | ring->fw_ring_id = INVALID_HW_RING_ID; | 2631 | ring->fw_ring_id = INVALID_HW_RING_ID; |
2632 | cpr->rx_ring_coal.coal_ticks = bp->rx_coal.coal_ticks; | ||
2633 | cpr->rx_ring_coal.coal_bufs = bp->rx_coal.coal_bufs; | ||
2620 | } | 2634 | } |
2621 | } | 2635 | } |
2622 | 2636 | ||
@@ -4593,6 +4607,36 @@ static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal, | |||
4593 | req->flags = cpu_to_le16(flags); | 4607 | req->flags = cpu_to_le16(flags); |
4594 | } | 4608 | } |
4595 | 4609 | ||
4610 | int bnxt_hwrm_set_ring_coal(struct bnxt *bp, struct bnxt_napi *bnapi) | ||
4611 | { | ||
4612 | struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0}; | ||
4613 | struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; | ||
4614 | struct bnxt_coal coal; | ||
4615 | unsigned int grp_idx; | ||
4616 | |||
4617 | /* Tick values in micro seconds. | ||
4618 | * 1 coal_buf x bufs_per_record = 1 completion record. | ||
4619 | */ | ||
4620 | memcpy(&coal, &bp->rx_coal, sizeof(struct bnxt_coal)); | ||
4621 | |||
4622 | coal.coal_ticks = cpr->rx_ring_coal.coal_ticks; | ||
4623 | coal.coal_bufs = cpr->rx_ring_coal.coal_bufs; | ||
4624 | |||
4625 | if (!bnapi->rx_ring) | ||
4626 | return -ENODEV; | ||
4627 | |||
4628 | bnxt_hwrm_cmd_hdr_init(bp, &req_rx, | ||
4629 | HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1); | ||
4630 | |||
4631 | bnxt_hwrm_set_coal_params(&coal, &req_rx); | ||
4632 | |||
4633 | grp_idx = bnapi->index; | ||
4634 | req_rx.ring_id = cpu_to_le16(bp->grp_info[grp_idx].cp_fw_ring_id); | ||
4635 | |||
4636 | return hwrm_send_message(bp, &req_rx, sizeof(req_rx), | ||
4637 | HWRM_CMD_TIMEOUT); | ||
4638 | } | ||
4639 | |||
4596 | int bnxt_hwrm_set_coal(struct bnxt *bp) | 4640 | int bnxt_hwrm_set_coal(struct bnxt *bp) |
4597 | { | 4641 | { |
4598 | int i, rc = 0; | 4642 | int i, rc = 0; |
@@ -5715,7 +5759,13 @@ static void bnxt_enable_napi(struct bnxt *bp) | |||
5715 | int i; | 5759 | int i; |
5716 | 5760 | ||
5717 | for (i = 0; i < bp->cp_nr_rings; i++) { | 5761 | for (i = 0; i < bp->cp_nr_rings; i++) { |
5762 | struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring; | ||
5718 | bp->bnapi[i]->in_reset = false; | 5763 | bp->bnapi[i]->in_reset = false; |
5764 | |||
5765 | if (bp->bnapi[i]->rx_ring) { | ||
5766 | INIT_WORK(&cpr->dim.work, bnxt_dim_work); | ||
5767 | cpr->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE; | ||
5768 | } | ||
5719 | napi_enable(&bp->bnapi[i]->napi); | 5769 | napi_enable(&bp->bnapi[i]->napi); |
5720 | } | 5770 | } |
5721 | } | 5771 | } |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 2d268fc26f5e..89887a88b1bd 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <net/dst_metadata.h> | 24 | #include <net/dst_metadata.h> |
25 | #include <net/switchdev.h> | 25 | #include <net/switchdev.h> |
26 | #include <net/xdp.h> | 26 | #include <net/xdp.h> |
27 | #include <linux/net_dim.h> | ||
27 | 28 | ||
28 | struct tx_bd { | 29 | struct tx_bd { |
29 | __le32 tx_bd_len_flags_type; | 30 | __le32 tx_bd_len_flags_type; |
@@ -608,6 +609,17 @@ struct bnxt_tx_ring_info { | |||
608 | struct bnxt_ring_struct tx_ring_struct; | 609 | struct bnxt_ring_struct tx_ring_struct; |
609 | }; | 610 | }; |
610 | 611 | ||
612 | struct bnxt_coal { | ||
613 | u16 coal_ticks; | ||
614 | u16 coal_ticks_irq; | ||
615 | u16 coal_bufs; | ||
616 | u16 coal_bufs_irq; | ||
617 | /* RING_IDLE enabled when coal ticks < idle_thresh */ | ||
618 | u16 idle_thresh; | ||
619 | u8 bufs_per_record; | ||
620 | u8 budget; | ||
621 | }; | ||
622 | |||
611 | struct bnxt_tpa_info { | 623 | struct bnxt_tpa_info { |
612 | void *data; | 624 | void *data; |
613 | u8 *data_ptr; | 625 | u8 *data_ptr; |
@@ -672,6 +684,13 @@ struct bnxt_cp_ring_info { | |||
672 | u32 cp_raw_cons; | 684 | u32 cp_raw_cons; |
673 | void __iomem *cp_doorbell; | 685 | void __iomem *cp_doorbell; |
674 | 686 | ||
687 | struct bnxt_coal rx_ring_coal; | ||
688 | u64 rx_packets; | ||
689 | u64 rx_bytes; | ||
690 | u64 event_ctr; | ||
691 | |||
692 | struct net_dim dim; | ||
693 | |||
675 | struct tx_cmp *cp_desc_ring[MAX_CP_PAGES]; | 694 | struct tx_cmp *cp_desc_ring[MAX_CP_PAGES]; |
676 | 695 | ||
677 | dma_addr_t cp_desc_mapping[MAX_CP_PAGES]; | 696 | dma_addr_t cp_desc_mapping[MAX_CP_PAGES]; |
@@ -946,17 +965,6 @@ struct bnxt_test_info { | |||
946 | #define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014 | 965 | #define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014 |
947 | #define BNXT_CAG_REG_BASE 0x300000 | 966 | #define BNXT_CAG_REG_BASE 0x300000 |
948 | 967 | ||
949 | struct bnxt_coal { | ||
950 | u16 coal_ticks; | ||
951 | u16 coal_ticks_irq; | ||
952 | u16 coal_bufs; | ||
953 | u16 coal_bufs_irq; | ||
954 | /* RING_IDLE enabled when coal ticks < idle_thresh */ | ||
955 | u16 idle_thresh; | ||
956 | u8 bufs_per_record; | ||
957 | u8 budget; | ||
958 | }; | ||
959 | |||
960 | struct bnxt_tc_flow_stats { | 968 | struct bnxt_tc_flow_stats { |
961 | u64 packets; | 969 | u64 packets; |
962 | u64 bytes; | 970 | u64 bytes; |
@@ -1128,6 +1136,7 @@ struct bnxt { | |||
1128 | #define BNXT_FLAG_DOUBLE_DB 0x400000 | 1136 | #define BNXT_FLAG_DOUBLE_DB 0x400000 |
1129 | #define BNXT_FLAG_FW_DCBX_AGENT 0x800000 | 1137 | #define BNXT_FLAG_FW_DCBX_AGENT 0x800000 |
1130 | #define BNXT_FLAG_CHIP_NITRO_A0 0x1000000 | 1138 | #define BNXT_FLAG_CHIP_NITRO_A0 0x1000000 |
1139 | #define BNXT_FLAG_DIM 0x2000000 | ||
1131 | 1140 | ||
1132 | #define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \ | 1141 | #define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \ |
1133 | BNXT_FLAG_RFS | \ | 1142 | BNXT_FLAG_RFS | \ |
@@ -1425,4 +1434,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc); | |||
1425 | int bnxt_get_max_rings(struct bnxt *, int *, int *, bool); | 1434 | int bnxt_get_max_rings(struct bnxt *, int *, int *, bool); |
1426 | void bnxt_restore_pf_fw_resources(struct bnxt *bp); | 1435 | void bnxt_restore_pf_fw_resources(struct bnxt *bp); |
1427 | int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr); | 1436 | int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr); |
1437 | void bnxt_dim_work(struct work_struct *work); | ||
1438 | int bnxt_hwrm_set_ring_coal(struct bnxt *bp, struct bnxt_napi *bnapi); | ||
1439 | |||
1428 | #endif | 1440 | #endif |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dim.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dim.c new file mode 100644 index 000000000000..408dd190331e --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dim.c | |||
@@ -0,0 +1,32 @@ | |||
1 | /* Broadcom NetXtreme-C/E network driver. | ||
2 | * | ||
3 | * Copyright (c) 2017-2018 Broadcom Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/net_dim.h> | ||
11 | #include "bnxt_hsi.h" | ||
12 | #include "bnxt.h" | ||
13 | |||
14 | void bnxt_dim_work(struct work_struct *work) | ||
15 | { | ||
16 | struct net_dim *dim = container_of(work, struct net_dim, | ||
17 | work); | ||
18 | struct bnxt_cp_ring_info *cpr = container_of(dim, | ||
19 | struct bnxt_cp_ring_info, | ||
20 | dim); | ||
21 | struct bnxt_napi *bnapi = container_of(cpr, | ||
22 | struct bnxt_napi, | ||
23 | cp_ring); | ||
24 | struct net_dim_cq_moder cur_profile = net_dim_get_profile(dim->mode, | ||
25 | dim->profile_ix); | ||
26 | |||
27 | cpr->rx_ring_coal.coal_ticks = cur_profile.usec; | ||
28 | cpr->rx_ring_coal.coal_bufs = cur_profile.pkts; | ||
29 | |||
30 | bnxt_hwrm_set_ring_coal(bnapi->bp, bnapi); | ||
31 | dim->state = NET_DIM_START_MEASURE; | ||
32 | } | ||
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index fe7599f404bf..1801582076be 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | |||
@@ -49,6 +49,8 @@ static int bnxt_get_coalesce(struct net_device *dev, | |||
49 | 49 | ||
50 | memset(coal, 0, sizeof(*coal)); | 50 | memset(coal, 0, sizeof(*coal)); |
51 | 51 | ||
52 | coal->use_adaptive_rx_coalesce = bp->flags & BNXT_FLAG_DIM; | ||
53 | |||
52 | hw_coal = &bp->rx_coal; | 54 | hw_coal = &bp->rx_coal; |
53 | mult = hw_coal->bufs_per_record; | 55 | mult = hw_coal->bufs_per_record; |
54 | coal->rx_coalesce_usecs = hw_coal->coal_ticks; | 56 | coal->rx_coalesce_usecs = hw_coal->coal_ticks; |
@@ -77,6 +79,15 @@ static int bnxt_set_coalesce(struct net_device *dev, | |||
77 | int rc = 0; | 79 | int rc = 0; |
78 | u16 mult; | 80 | u16 mult; |
79 | 81 | ||
82 | if (coal->use_adaptive_rx_coalesce) { | ||
83 | bp->flags |= BNXT_FLAG_DIM; | ||
84 | } else { | ||
85 | if (bp->flags & BNXT_FLAG_DIM) { | ||
86 | bp->flags &= ~(BNXT_FLAG_DIM); | ||
87 | goto reset_coalesce; | ||
88 | } | ||
89 | } | ||
90 | |||
80 | hw_coal = &bp->rx_coal; | 91 | hw_coal = &bp->rx_coal; |
81 | mult = hw_coal->bufs_per_record; | 92 | mult = hw_coal->bufs_per_record; |
82 | hw_coal->coal_ticks = coal->rx_coalesce_usecs; | 93 | hw_coal->coal_ticks = coal->rx_coalesce_usecs; |
@@ -104,6 +115,7 @@ static int bnxt_set_coalesce(struct net_device *dev, | |||
104 | update_stats = true; | 115 | update_stats = true; |
105 | } | 116 | } |
106 | 117 | ||
118 | reset_coalesce: | ||
107 | if (netif_running(dev)) { | 119 | if (netif_running(dev)) { |
108 | if (update_stats) { | 120 | if (update_stats) { |
109 | rc = bnxt_close_nic(bp, true, false); | 121 | rc = bnxt_close_nic(bp, true, false); |