diff options
author | Michael Chan <michael.chan@broadcom.com> | 2018-03-31 13:54:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-31 23:24:20 -0400 |
commit | 08654eb213a8066b30c41e22067a9f066b40c80f (patch) | |
tree | 338d028ccfec82f033ab04c8109b4fa0637f7b8a | |
parent | 9899bb59ff08a50aef033b4d388d223adca58a7f (diff) |
bnxt_en: Change IRQ assignment for RDMA driver.
In the current code, the range of MSIX vectors allocated for the RDMA
driver is disjoint from the network driver. This creates a problem
for the new firmware ring reservation scheme. The new scheme requires
the reserved completion rings/MSIX vectors to be in a contiguous
range.
Change the logic to allocate RDMA MSIX vectors to be contiguous with
the vectors used by bnxt_en on new firmware using the new scheme.
The new function bnxt_get_num_msix() calculates the exact number of
vectors needed by both drivers.
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h | 3 |
3 files changed, 61 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 8c8ef6b6ca91..041b800e6734 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -4720,6 +4720,21 @@ static int bnxt_hwrm_reserve_rings(struct bnxt *bp, int tx, int rx, int grp, | |||
4720 | return bnxt_hwrm_reserve_vf_rings(bp, tx, rx, grp, cp, vnic); | 4720 | return bnxt_hwrm_reserve_vf_rings(bp, tx, rx, grp, cp, vnic); |
4721 | } | 4721 | } |
4722 | 4722 | ||
4723 | static int bnxt_cp_rings_in_use(struct bnxt *bp) | ||
4724 | { | ||
4725 | int cp = bp->cp_nr_rings; | ||
4726 | int ulp_msix, ulp_base; | ||
4727 | |||
4728 | ulp_msix = bnxt_get_ulp_msix_num(bp); | ||
4729 | if (ulp_msix) { | ||
4730 | ulp_base = bnxt_get_ulp_msix_base(bp); | ||
4731 | cp += ulp_msix; | ||
4732 | if ((ulp_base + ulp_msix) > cp) | ||
4733 | cp = ulp_base + ulp_msix; | ||
4734 | } | ||
4735 | return cp; | ||
4736 | } | ||
4737 | |||
4723 | static int bnxt_trim_rings(struct bnxt *bp, int *rx, int *tx, int max, | 4738 | static int bnxt_trim_rings(struct bnxt *bp, int *rx, int *tx, int max, |
4724 | bool shared); | 4739 | bool shared); |
4725 | 4740 | ||
@@ -5893,12 +5908,24 @@ void bnxt_set_max_func_irqs(struct bnxt *bp, unsigned int max_irqs) | |||
5893 | bp->hw_resc.max_irqs = max_irqs; | 5908 | bp->hw_resc.max_irqs = max_irqs; |
5894 | } | 5909 | } |
5895 | 5910 | ||
5911 | static int bnxt_get_num_msix(struct bnxt *bp) | ||
5912 | { | ||
5913 | if (!(bp->flags & BNXT_FLAG_NEW_RM)) | ||
5914 | return bnxt_get_max_func_irqs(bp); | ||
5915 | |||
5916 | return bnxt_cp_rings_in_use(bp); | ||
5917 | } | ||
5918 | |||
5896 | static int bnxt_init_msix(struct bnxt *bp) | 5919 | static int bnxt_init_msix(struct bnxt *bp) |
5897 | { | 5920 | { |
5898 | int i, total_vecs, rc = 0, min = 1; | 5921 | int i, total_vecs, max, rc = 0, min = 1; |
5899 | struct msix_entry *msix_ent; | 5922 | struct msix_entry *msix_ent; |
5900 | 5923 | ||
5901 | total_vecs = bnxt_get_max_func_irqs(bp); | 5924 | total_vecs = bnxt_get_num_msix(bp); |
5925 | max = bnxt_get_max_func_irqs(bp); | ||
5926 | if (total_vecs > max) | ||
5927 | total_vecs = max; | ||
5928 | |||
5902 | msix_ent = kcalloc(total_vecs, sizeof(struct msix_entry), GFP_KERNEL); | 5929 | msix_ent = kcalloc(total_vecs, sizeof(struct msix_entry), GFP_KERNEL); |
5903 | if (!msix_ent) | 5930 | if (!msix_ent) |
5904 | return -ENOMEM; | 5931 | return -ENOMEM; |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index 997e10e8b863..62636cd44331 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | |||
@@ -116,6 +116,9 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id, | |||
116 | if (!(bp->flags & BNXT_FLAG_USING_MSIX)) | 116 | if (!(bp->flags & BNXT_FLAG_USING_MSIX)) |
117 | return -ENODEV; | 117 | return -ENODEV; |
118 | 118 | ||
119 | if (edev->ulp_tbl[ulp_id].msix_requested) | ||
120 | return -EAGAIN; | ||
121 | |||
119 | max_cp_rings = bnxt_get_max_func_cp_rings(bp); | 122 | max_cp_rings = bnxt_get_max_func_cp_rings(bp); |
120 | max_idx = min_t(int, bp->total_irqs, max_cp_rings); | 123 | max_idx = min_t(int, bp->total_irqs, max_cp_rings); |
121 | avail_msix = max_idx - bp->cp_nr_rings; | 124 | avail_msix = max_idx - bp->cp_nr_rings; |
@@ -124,7 +127,11 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id, | |||
124 | if (avail_msix > num_msix) | 127 | if (avail_msix > num_msix) |
125 | avail_msix = num_msix; | 128 | avail_msix = num_msix; |
126 | 129 | ||
127 | idx = max_idx - avail_msix; | 130 | if (bp->flags & BNXT_FLAG_NEW_RM) |
131 | idx = bp->cp_nr_rings; | ||
132 | else | ||
133 | idx = max_idx - avail_msix; | ||
134 | edev->ulp_tbl[ulp_id].msix_base = idx; | ||
128 | for (i = 0; i < avail_msix; i++) { | 135 | for (i = 0; i < avail_msix; i++) { |
129 | ent[i].vector = bp->irq_tbl[idx + i].vector; | 136 | ent[i].vector = bp->irq_tbl[idx + i].vector; |
130 | ent[i].ring_idx = idx + i; | 137 | ent[i].ring_idx = idx + i; |
@@ -154,6 +161,27 @@ static int bnxt_free_msix_vecs(struct bnxt_en_dev *edev, int ulp_id) | |||
154 | return 0; | 161 | return 0; |
155 | } | 162 | } |
156 | 163 | ||
164 | int bnxt_get_ulp_msix_num(struct bnxt *bp) | ||
165 | { | ||
166 | if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { | ||
167 | struct bnxt_en_dev *edev = bp->edev; | ||
168 | |||
169 | return edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested; | ||
170 | } | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | int bnxt_get_ulp_msix_base(struct bnxt *bp) | ||
175 | { | ||
176 | if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { | ||
177 | struct bnxt_en_dev *edev = bp->edev; | ||
178 | |||
179 | if (edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested) | ||
180 | return edev->ulp_tbl[BNXT_ROCE_ULP].msix_base; | ||
181 | } | ||
182 | return 0; | ||
183 | } | ||
184 | |||
157 | void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id) | 185 | void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id) |
158 | { | 186 | { |
159 | ASSERT_RTNL(); | 187 | ASSERT_RTNL(); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h index d2471067dc37..c9fa7eb56a08 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h | |||
@@ -49,6 +49,7 @@ struct bnxt_ulp { | |||
49 | unsigned long *async_events_bmap; | 49 | unsigned long *async_events_bmap; |
50 | u16 max_async_event_id; | 50 | u16 max_async_event_id; |
51 | u16 msix_requested; | 51 | u16 msix_requested; |
52 | u16 msix_base; | ||
52 | atomic_t ref_count; | 53 | atomic_t ref_count; |
53 | }; | 54 | }; |
54 | 55 | ||
@@ -84,6 +85,8 @@ static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev, int ulp_id) | |||
84 | return false; | 85 | return false; |
85 | } | 86 | } |
86 | 87 | ||
88 | int bnxt_get_ulp_msix_num(struct bnxt *bp); | ||
89 | int bnxt_get_ulp_msix_base(struct bnxt *bp); | ||
87 | void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id); | 90 | void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id); |
88 | void bnxt_ulp_stop(struct bnxt *bp); | 91 | void bnxt_ulp_stop(struct bnxt *bp); |
89 | void bnxt_ulp_start(struct bnxt *bp); | 92 | void bnxt_ulp_start(struct bnxt *bp); |