1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2025 Broadcom.
3
4 #include <linux/init.h>
5 #include <linux/module.h>
6 #include <linux/pci.h>
7 #include <linux/ethtool.h>
8 #include <linux/netdevice.h>
9
10 #include "bnge.h"
11 #include "bnge_hwrm.h"
12 #include "bnge_hwrm_lib.h"
13 #include "bnge_resc.h"
14
bnge_num_tx_to_cp(struct bnge_dev * bd,u16 tx)15 static u16 bnge_num_tx_to_cp(struct bnge_dev *bd, u16 tx)
16 {
17 u16 tcs = bd->num_tc;
18
19 if (!tcs)
20 tcs = 1;
21
22 return tx / tcs;
23 }
24
bnge_get_max_func_irqs(struct bnge_dev * bd)25 static u16 bnge_get_max_func_irqs(struct bnge_dev *bd)
26 {
27 struct bnge_hw_resc *hw_resc = &bd->hw_resc;
28
29 return min_t(u16, hw_resc->max_irqs, hw_resc->max_nqs);
30 }
31
bnge_get_max_func_stat_ctxs(struct bnge_dev * bd)32 static unsigned int bnge_get_max_func_stat_ctxs(struct bnge_dev *bd)
33 {
34 return bd->hw_resc.max_stat_ctxs;
35 }
36
bnge_aux_has_enough_resources(struct bnge_dev * bd)37 bool bnge_aux_has_enough_resources(struct bnge_dev *bd)
38 {
39 unsigned int max_stat_ctxs;
40
41 max_stat_ctxs = bnge_get_max_func_stat_ctxs(bd);
42 if (max_stat_ctxs <= BNGE_MIN_ROCE_STAT_CTXS ||
43 bd->nq_nr_rings == max_stat_ctxs)
44 return false;
45
46 return true;
47 }
48
bnge_get_max_func_cp_rings(struct bnge_dev * bd)49 static unsigned int bnge_get_max_func_cp_rings(struct bnge_dev *bd)
50 {
51 return bd->hw_resc.max_cp_rings;
52 }
53
bnge_aux_get_dflt_msix(struct bnge_dev * bd)54 static int bnge_aux_get_dflt_msix(struct bnge_dev *bd)
55 {
56 int roce_msix = BNGE_MAX_ROCE_MSIX;
57
58 return min_t(int, roce_msix, num_online_cpus() + 1);
59 }
60
bnge_aux_get_msix(struct bnge_dev * bd)61 u16 bnge_aux_get_msix(struct bnge_dev *bd)
62 {
63 if (bnge_is_roce_en(bd))
64 return bd->aux_num_msix;
65
66 return 0;
67 }
68
bnge_aux_set_msix_num(struct bnge_dev * bd,u16 num)69 static void bnge_aux_set_msix_num(struct bnge_dev *bd, u16 num)
70 {
71 if (bnge_is_roce_en(bd))
72 bd->aux_num_msix = num;
73 }
74
bnge_aux_get_stat_ctxs(struct bnge_dev * bd)75 static u16 bnge_aux_get_stat_ctxs(struct bnge_dev *bd)
76 {
77 if (bnge_is_roce_en(bd))
78 return bd->aux_num_stat_ctxs;
79
80 return 0;
81 }
82
bnge_aux_set_stat_ctxs(struct bnge_dev * bd,u16 num_aux_ctx)83 static void bnge_aux_set_stat_ctxs(struct bnge_dev *bd, u16 num_aux_ctx)
84 {
85 if (bnge_is_roce_en(bd))
86 bd->aux_num_stat_ctxs = num_aux_ctx;
87 }
88
bnge_func_stat_ctxs_demand(struct bnge_dev * bd)89 static u16 bnge_func_stat_ctxs_demand(struct bnge_dev *bd)
90 {
91 return bd->nq_nr_rings + bnge_aux_get_stat_ctxs(bd);
92 }
93
bnge_get_dflt_aux_stat_ctxs(struct bnge_dev * bd)94 static int bnge_get_dflt_aux_stat_ctxs(struct bnge_dev *bd)
95 {
96 int stat_ctx = 0;
97
98 if (bnge_is_roce_en(bd)) {
99 stat_ctx = BNGE_MIN_ROCE_STAT_CTXS;
100
101 if (!bd->pf.port_id && bd->port_count > 1)
102 stat_ctx++;
103 }
104
105 return stat_ctx;
106 }
107
bnge_nqs_demand(struct bnge_dev * bd)108 static u16 bnge_nqs_demand(struct bnge_dev *bd)
109 {
110 return bd->nq_nr_rings + bnge_aux_get_msix(bd);
111 }
112
bnge_cprs_demand(struct bnge_dev * bd)113 static u16 bnge_cprs_demand(struct bnge_dev *bd)
114 {
115 return bd->tx_nr_rings + bd->rx_nr_rings;
116 }
117
bnge_get_avail_msix(struct bnge_dev * bd,int num)118 static u16 bnge_get_avail_msix(struct bnge_dev *bd, int num)
119 {
120 u16 max_irq = bnge_get_max_func_irqs(bd);
121 u16 total_demand = bd->nq_nr_rings + num;
122
123 if (max_irq < total_demand) {
124 num = max_irq - bd->nq_nr_rings;
125 if (num <= 0)
126 return 0;
127 }
128
129 return num;
130 }
131
bnge_num_cp_to_tx(struct bnge_dev * bd,u16 tx_chunks)132 static u16 bnge_num_cp_to_tx(struct bnge_dev *bd, u16 tx_chunks)
133 {
134 return tx_chunks * bd->num_tc;
135 }
136
bnge_fix_rings_count(u16 * rx,u16 * tx,u16 max,bool shared)137 int bnge_fix_rings_count(u16 *rx, u16 *tx, u16 max, bool shared)
138 {
139 u16 _rx = *rx, _tx = *tx;
140
141 if (shared) {
142 *rx = min_t(u16, _rx, max);
143 *tx = min_t(u16, _tx, max);
144 } else {
145 if (max < 2)
146 return -ENOMEM;
147 while (_rx + _tx > max) {
148 if (_rx > _tx && _rx > 1)
149 _rx--;
150 else if (_tx > 1)
151 _tx--;
152 }
153 *rx = _rx;
154 *tx = _tx;
155 }
156
157 return 0;
158 }
159
bnge_adjust_rings(struct bnge_dev * bd,u16 * rx,u16 * tx,u16 max_nq,bool sh)160 static int bnge_adjust_rings(struct bnge_dev *bd, u16 *rx,
161 u16 *tx, u16 max_nq, bool sh)
162 {
163 u16 tx_chunks = bnge_num_tx_to_cp(bd, *tx);
164
165 if (tx_chunks != *tx) {
166 u16 tx_saved = tx_chunks;
167 int rc;
168
169 rc = bnge_fix_rings_count(rx, &tx_chunks, max_nq, sh);
170 if (rc)
171 return rc;
172 if (tx_chunks != tx_saved)
173 *tx = bnge_num_cp_to_tx(bd, tx_chunks);
174 return 0;
175 }
176
177 return bnge_fix_rings_count(rx, tx, max_nq, sh);
178 }
179
bnge_cal_nr_rss_ctxs(u16 rx_rings)180 int bnge_cal_nr_rss_ctxs(u16 rx_rings)
181 {
182 if (!rx_rings)
183 return 0;
184
185 return bnge_adjust_pow_two(rx_rings - 1,
186 BNGE_RSS_TABLE_ENTRIES);
187 }
188
bnge_rss_ctxs_in_use(struct bnge_dev * bd,struct bnge_hw_rings * hwr)189 static u16 bnge_rss_ctxs_in_use(struct bnge_dev *bd,
190 struct bnge_hw_rings *hwr)
191 {
192 return bnge_cal_nr_rss_ctxs(hwr->grp);
193 }
194
bnge_get_total_vnics(struct bnge_dev * bd,u16 rx_rings)195 static u16 bnge_get_total_vnics(struct bnge_dev *bd, u16 rx_rings)
196 {
197 return 1;
198 }
199
bnge_get_rxfh_indir_size(struct bnge_dev * bd)200 u32 bnge_get_rxfh_indir_size(struct bnge_dev *bd)
201 {
202 return bnge_cal_nr_rss_ctxs(bd->rx_nr_rings) *
203 BNGE_RSS_TABLE_ENTRIES;
204 }
205
bnge_set_dflt_rss_indir_tbl(struct bnge_dev * bd)206 static void bnge_set_dflt_rss_indir_tbl(struct bnge_dev *bd)
207 {
208 u16 max_entries, pad;
209 u32 *rss_indir_tbl;
210 int i;
211
212 max_entries = bnge_get_rxfh_indir_size(bd);
213 rss_indir_tbl = &bd->rss_indir_tbl[0];
214
215 for (i = 0; i < max_entries; i++)
216 rss_indir_tbl[i] = ethtool_rxfh_indir_default(i,
217 bd->rx_nr_rings);
218
219 pad = bd->rss_indir_tbl_entries - max_entries;
220 if (pad)
221 memset(&rss_indir_tbl[i], 0, pad * sizeof(*rss_indir_tbl));
222 }
223
bnge_copy_reserved_rings(struct bnge_dev * bd,struct bnge_hw_rings * hwr)224 static void bnge_copy_reserved_rings(struct bnge_dev *bd,
225 struct bnge_hw_rings *hwr)
226 {
227 struct bnge_hw_resc *hw_resc = &bd->hw_resc;
228
229 hwr->tx = hw_resc->resv_tx_rings;
230 hwr->rx = hw_resc->resv_rx_rings;
231 hwr->nq = hw_resc->resv_irqs;
232 hwr->cmpl = hw_resc->resv_cp_rings;
233 hwr->grp = hw_resc->resv_hw_ring_grps;
234 hwr->vnic = hw_resc->resv_vnics;
235 hwr->stat = hw_resc->resv_stat_ctxs;
236 hwr->rss_ctx = hw_resc->resv_rsscos_ctxs;
237 }
238
bnge_rings_ok(struct bnge_hw_rings * hwr)239 static bool bnge_rings_ok(struct bnge_hw_rings *hwr)
240 {
241 return hwr->tx && hwr->rx && hwr->nq && hwr->grp && hwr->vnic &&
242 hwr->stat && hwr->cmpl;
243 }
244
bnge_need_reserve_rings(struct bnge_dev * bd)245 static bool bnge_need_reserve_rings(struct bnge_dev *bd)
246 {
247 struct bnge_hw_resc *hw_resc = &bd->hw_resc;
248 u16 cprs = bnge_cprs_demand(bd);
249 u16 rx = bd->rx_nr_rings, stat;
250 u16 nqs = bnge_nqs_demand(bd);
251 u16 vnic;
252
253 if (hw_resc->resv_tx_rings != bd->tx_nr_rings)
254 return true;
255
256 vnic = bnge_get_total_vnics(bd, rx);
257
258 if (bnge_is_agg_reqd(bd))
259 rx <<= 1;
260 stat = bnge_func_stat_ctxs_demand(bd);
261 if (hw_resc->resv_rx_rings != rx || hw_resc->resv_cp_rings != cprs ||
262 hw_resc->resv_vnics != vnic || hw_resc->resv_stat_ctxs != stat)
263 return true;
264 if (hw_resc->resv_irqs != nqs)
265 return true;
266
267 return false;
268 }
269
bnge_reserve_rings(struct bnge_dev * bd)270 int bnge_reserve_rings(struct bnge_dev *bd)
271 {
272 u16 aux_dflt_msix = bnge_aux_get_dflt_msix(bd);
273 struct bnge_hw_rings hwr = {0};
274 u16 rx_rings, old_rx_rings;
275 u16 nq = bd->nq_nr_rings;
276 u16 aux_msix = 0;
277 bool sh = false;
278 u16 tx_cp;
279 int rc;
280
281 if (!bnge_need_reserve_rings(bd))
282 return 0;
283
284 if (!bnge_aux_registered(bd)) {
285 aux_msix = bnge_get_avail_msix(bd, aux_dflt_msix);
286 if (!aux_msix)
287 bnge_aux_set_stat_ctxs(bd, 0);
288
289 if (aux_msix > aux_dflt_msix)
290 aux_msix = aux_dflt_msix;
291 hwr.nq = nq + aux_msix;
292 } else {
293 hwr.nq = bnge_nqs_demand(bd);
294 }
295
296 hwr.tx = bd->tx_nr_rings;
297 hwr.rx = bd->rx_nr_rings;
298 if (bd->flags & BNGE_EN_SHARED_CHNL)
299 sh = true;
300 hwr.cmpl = hwr.rx + hwr.tx;
301
302 hwr.vnic = bnge_get_total_vnics(bd, hwr.rx);
303
304 if (bnge_is_agg_reqd(bd))
305 hwr.rx <<= 1;
306 hwr.grp = bd->rx_nr_rings;
307 hwr.rss_ctx = bnge_rss_ctxs_in_use(bd, &hwr);
308 hwr.stat = bnge_func_stat_ctxs_demand(bd);
309 old_rx_rings = bd->hw_resc.resv_rx_rings;
310
311 rc = bnge_hwrm_reserve_rings(bd, &hwr);
312 if (rc)
313 return rc;
314
315 bnge_copy_reserved_rings(bd, &hwr);
316
317 rx_rings = hwr.rx;
318 if (bnge_is_agg_reqd(bd)) {
319 if (hwr.rx >= 2)
320 rx_rings = hwr.rx >> 1;
321 else
322 return -ENOMEM;
323 }
324
325 rx_rings = min_t(u16, rx_rings, hwr.grp);
326 hwr.nq = min_t(u16, hwr.nq, bd->nq_nr_rings);
327 if (hwr.stat > bnge_aux_get_stat_ctxs(bd))
328 hwr.stat -= bnge_aux_get_stat_ctxs(bd);
329 hwr.nq = min_t(u16, hwr.nq, hwr.stat);
330
331 /* Adjust the rings */
332 rc = bnge_adjust_rings(bd, &rx_rings, &hwr.tx, hwr.nq, sh);
333 if (bnge_is_agg_reqd(bd))
334 hwr.rx = rx_rings << 1;
335 tx_cp = hwr.tx;
336 hwr.nq = sh ? max_t(u16, tx_cp, rx_rings) : tx_cp + rx_rings;
337 bd->tx_nr_rings = hwr.tx;
338
339 if (rx_rings != bd->rx_nr_rings)
340 dev_warn(bd->dev, "RX rings resv reduced to %d than earlier %d requested\n",
341 rx_rings, bd->rx_nr_rings);
342
343 bd->rx_nr_rings = rx_rings;
344 bd->nq_nr_rings = hwr.nq;
345
346 if (!bnge_rings_ok(&hwr))
347 return -ENOMEM;
348
349 if (old_rx_rings != bd->hw_resc.resv_rx_rings)
350 bnge_set_dflt_rss_indir_tbl(bd);
351
352 if (!bnge_aux_registered(bd)) {
353 u16 resv_msix, resv_ctx, aux_ctxs;
354 struct bnge_hw_resc *hw_resc;
355
356 hw_resc = &bd->hw_resc;
357 resv_msix = hw_resc->resv_irqs - bd->nq_nr_rings;
358 aux_msix = min_t(u16, resv_msix, aux_msix);
359 bnge_aux_set_msix_num(bd, aux_msix);
360 resv_ctx = hw_resc->resv_stat_ctxs - bd->nq_nr_rings;
361 aux_ctxs = min(resv_ctx, bnge_aux_get_stat_ctxs(bd));
362 bnge_aux_set_stat_ctxs(bd, aux_ctxs);
363 }
364
365 return rc;
366 }
367
bnge_alloc_irqs(struct bnge_dev * bd)368 int bnge_alloc_irqs(struct bnge_dev *bd)
369 {
370 u16 aux_msix, tx_cp, num_entries;
371 int i, irqs_demand, rc;
372 u16 max, min = 1;
373
374 irqs_demand = bnge_nqs_demand(bd);
375 max = bnge_get_max_func_irqs(bd);
376 if (irqs_demand > max)
377 irqs_demand = max;
378
379 if (!(bd->flags & BNGE_EN_SHARED_CHNL))
380 min = 2;
381
382 irqs_demand = pci_alloc_irq_vectors(bd->pdev, min, irqs_demand,
383 PCI_IRQ_MSIX);
384 aux_msix = bnge_aux_get_msix(bd);
385 if (irqs_demand < 0 || irqs_demand < aux_msix) {
386 rc = -ENODEV;
387 goto err_free_irqs;
388 }
389
390 num_entries = irqs_demand;
391 if (pci_msix_can_alloc_dyn(bd->pdev))
392 num_entries = max;
393 bd->irq_tbl = kzalloc_objs(*bd->irq_tbl, num_entries);
394 if (!bd->irq_tbl) {
395 rc = -ENOMEM;
396 goto err_free_irqs;
397 }
398
399 for (i = 0; i < irqs_demand; i++)
400 bd->irq_tbl[i].vector = pci_irq_vector(bd->pdev, i);
401
402 bd->irqs_acquired = irqs_demand;
403 /* Reduce rings based upon num of vectors allocated.
404 * We dont need to consider NQs as they have been calculated
405 * and must be more than irqs_demand.
406 */
407 rc = bnge_adjust_rings(bd, &bd->rx_nr_rings,
408 &bd->tx_nr_rings,
409 irqs_demand - aux_msix, min == 1);
410 if (rc)
411 goto err_free_irqs;
412
413 tx_cp = bnge_num_tx_to_cp(bd, bd->tx_nr_rings);
414 bd->nq_nr_rings = (min == 1) ?
415 max_t(u16, tx_cp, bd->rx_nr_rings) :
416 tx_cp + bd->rx_nr_rings;
417
418 /* Readjust tx_nr_rings_per_tc */
419 if (!bd->num_tc)
420 bd->tx_nr_rings_per_tc = bd->tx_nr_rings;
421
422 return 0;
423
424 err_free_irqs:
425 dev_err(bd->dev, "Failed to allocate IRQs err = %d\n", rc);
426 bnge_free_irqs(bd);
427 return rc;
428 }
429
bnge_free_irqs(struct bnge_dev * bd)430 void bnge_free_irqs(struct bnge_dev *bd)
431 {
432 pci_free_irq_vectors(bd->pdev);
433 kfree(bd->irq_tbl);
434 bd->irq_tbl = NULL;
435 }
436
_bnge_get_max_rings(struct bnge_dev * bd,u16 * max_rx,u16 * max_tx,u16 * max_nq)437 static void _bnge_get_max_rings(struct bnge_dev *bd, u16 *max_rx,
438 u16 *max_tx, u16 *max_nq)
439 {
440 struct bnge_hw_resc *hw_resc = &bd->hw_resc;
441 u16 max_ring_grps = 0, max_cp;
442 int rc;
443
444 *max_tx = hw_resc->max_tx_rings;
445 *max_rx = hw_resc->max_rx_rings;
446 *max_nq = min_t(int, bnge_get_max_func_irqs(bd),
447 hw_resc->max_stat_ctxs);
448 max_ring_grps = hw_resc->max_hw_ring_grps;
449 if (bnge_is_agg_reqd(bd))
450 *max_rx >>= 1;
451
452 max_cp = bnge_get_max_func_cp_rings(bd);
453
454 /* Fix RX and TX rings according to number of CPs available */
455 rc = bnge_fix_rings_count(max_rx, max_tx, max_cp, false);
456 if (rc) {
457 *max_rx = 0;
458 *max_tx = 0;
459 }
460
461 *max_rx = min_t(int, *max_rx, max_ring_grps);
462 }
463
bnge_get_max_rings(struct bnge_dev * bd,u16 * max_rx,u16 * max_tx,bool shared)464 static int bnge_get_max_rings(struct bnge_dev *bd, u16 *max_rx,
465 u16 *max_tx, bool shared)
466 {
467 u16 rx, tx, nq;
468
469 _bnge_get_max_rings(bd, &rx, &tx, &nq);
470 *max_rx = rx;
471 *max_tx = tx;
472 if (!rx || !tx || !nq)
473 return -ENOMEM;
474
475 return bnge_fix_rings_count(max_rx, max_tx, nq, shared);
476 }
477
bnge_get_dflt_rings(struct bnge_dev * bd,u16 * max_rx,u16 * max_tx,bool shared)478 static int bnge_get_dflt_rings(struct bnge_dev *bd, u16 *max_rx, u16 *max_tx,
479 bool shared)
480 {
481 int rc;
482
483 rc = bnge_get_max_rings(bd, max_rx, max_tx, shared);
484 if (rc) {
485 dev_info(bd->dev, "Not enough rings available\n");
486 return rc;
487 }
488
489 if (bnge_is_roce_en(bd)) {
490 int max_cp, max_stat, max_irq;
491
492 /* Reserve minimum resources for RoCE */
493 max_cp = bnge_get_max_func_cp_rings(bd);
494 max_stat = bnge_get_max_func_stat_ctxs(bd);
495 max_irq = bnge_get_max_func_irqs(bd);
496 if (max_cp <= BNGE_MIN_ROCE_CP_RINGS ||
497 max_irq <= BNGE_MIN_ROCE_CP_RINGS ||
498 max_stat <= BNGE_MIN_ROCE_STAT_CTXS)
499 return 0;
500
501 max_cp -= BNGE_MIN_ROCE_CP_RINGS;
502 max_irq -= BNGE_MIN_ROCE_CP_RINGS;
503 max_stat -= BNGE_MIN_ROCE_STAT_CTXS;
504 max_cp = min_t(u16, max_cp, max_irq);
505 max_cp = min_t(u16, max_cp, max_stat);
506 rc = bnge_adjust_rings(bd, max_rx, max_tx, max_cp, shared);
507 if (rc)
508 rc = 0;
509 }
510
511 return rc;
512 }
513
514 /* In initial default shared ring setting, each shared ring must have a
515 * RX/TX ring pair.
516 */
bnge_trim_dflt_sh_rings(struct bnge_dev * bd)517 static void bnge_trim_dflt_sh_rings(struct bnge_dev *bd)
518 {
519 bd->nq_nr_rings = min_t(u16, bd->tx_nr_rings_per_tc, bd->rx_nr_rings);
520 bd->rx_nr_rings = bd->nq_nr_rings;
521 bd->tx_nr_rings_per_tc = bd->nq_nr_rings;
522 bd->tx_nr_rings = bd->tx_nr_rings_per_tc;
523 }
524
bnge_net_init_dflt_rings(struct bnge_dev * bd,bool sh)525 static int bnge_net_init_dflt_rings(struct bnge_dev *bd, bool sh)
526 {
527 u16 dflt_rings, max_rx_rings, max_tx_rings;
528 int rc;
529
530 if (sh)
531 bd->flags |= BNGE_EN_SHARED_CHNL;
532
533 dflt_rings = netif_get_num_default_rss_queues();
534
535 rc = bnge_get_dflt_rings(bd, &max_rx_rings, &max_tx_rings, sh);
536 if (rc)
537 return rc;
538 bd->rx_nr_rings = min_t(u16, dflt_rings, max_rx_rings);
539 bd->tx_nr_rings_per_tc = min_t(u16, dflt_rings, max_tx_rings);
540 if (sh)
541 bnge_trim_dflt_sh_rings(bd);
542 else
543 bd->nq_nr_rings = bd->tx_nr_rings_per_tc + bd->rx_nr_rings;
544 bd->tx_nr_rings = bd->tx_nr_rings_per_tc;
545
546 rc = bnge_reserve_rings(bd);
547 if (rc && rc != -ENODEV)
548 dev_warn(bd->dev, "Unable to reserve tx rings\n");
549 bd->tx_nr_rings_per_tc = bd->tx_nr_rings;
550 if (sh)
551 bnge_trim_dflt_sh_rings(bd);
552
553 /* Rings may have been reduced, re-reserve them again */
554 if (bnge_need_reserve_rings(bd)) {
555 rc = bnge_reserve_rings(bd);
556 if (rc && rc != -ENODEV)
557 dev_warn(bd->dev, "Fewer rings reservation failed\n");
558 bd->tx_nr_rings_per_tc = bd->tx_nr_rings;
559 }
560 if (rc) {
561 bd->tx_nr_rings = 0;
562 bd->rx_nr_rings = 0;
563 }
564
565 return rc;
566 }
567
bnge_alloc_rss_indir_tbl(struct bnge_dev * bd)568 static int bnge_alloc_rss_indir_tbl(struct bnge_dev *bd)
569 {
570 u16 entries;
571
572 entries = BNGE_MAX_RSS_TABLE_ENTRIES;
573
574 bd->rss_indir_tbl_entries = entries;
575 bd->rss_indir_tbl =
576 kmalloc_array(entries, sizeof(*bd->rss_indir_tbl), GFP_KERNEL);
577 if (!bd->rss_indir_tbl)
578 return -ENOMEM;
579
580 return 0;
581 }
582
bnge_net_init_dflt_config(struct bnge_dev * bd)583 int bnge_net_init_dflt_config(struct bnge_dev *bd)
584 {
585 struct bnge_hw_resc *hw_resc;
586 int rc;
587
588 rc = bnge_alloc_rss_indir_tbl(bd);
589 if (rc)
590 return rc;
591
592 rc = bnge_net_init_dflt_rings(bd, true);
593 if (rc)
594 goto err_free_tbl;
595
596 hw_resc = &bd->hw_resc;
597 bd->max_fltr = hw_resc->max_rx_em_flows + hw_resc->max_rx_wm_flows +
598 BNGE_L2_FLTR_MAX_FLTR;
599
600 return 0;
601
602 err_free_tbl:
603 kfree(bd->rss_indir_tbl);
604 bd->rss_indir_tbl = NULL;
605 return rc;
606 }
607
bnge_net_uninit_dflt_config(struct bnge_dev * bd)608 void bnge_net_uninit_dflt_config(struct bnge_dev *bd)
609 {
610 kfree(bd->rss_indir_tbl);
611 bd->rss_indir_tbl = NULL;
612 }
613
bnge_aux_init_dflt_config(struct bnge_dev * bd)614 void bnge_aux_init_dflt_config(struct bnge_dev *bd)
615 {
616 bd->aux_num_msix = bnge_aux_get_dflt_msix(bd);
617 bd->aux_num_stat_ctxs = bnge_get_dflt_aux_stat_ctxs(bd);
618 }
619