@@ -494,7 +494,7 @@ static void nfp_net_irqs_assign(struct net_device *netdev)
494
494
nn -> lsc_handler = nfp_net_irq_lsc ;
495
495
nn -> exn_handler = nfp_net_irq_exn ;
496
496
497
- for (r = 0 ; r < nn -> num_r_vecs ; r ++ ) {
497
+ for (r = 0 ; r < nn -> max_r_vecs ; r ++ ) {
498
498
r_vec = & nn -> r_vecs [r ];
499
499
r_vec -> nfp_net = nn ;
500
500
r_vec -> handler = nfp_net_irq_rxtx ;
@@ -1578,12 +1578,12 @@ nfp_net_tx_ring_set_prepare(struct nfp_net *nn, struct nfp_net_ring_set *s)
1578
1578
struct nfp_net_tx_ring * rings ;
1579
1579
unsigned int r ;
1580
1580
1581
- rings = kcalloc (nn -> num_tx_rings , sizeof (* rings ), GFP_KERNEL );
1581
+ rings = kcalloc (s -> n_rings , sizeof (* rings ), GFP_KERNEL );
1582
1582
if (!rings )
1583
1583
return NULL ;
1584
1584
1585
- for (r = 0 ; r < nn -> num_tx_rings ; r ++ ) {
1586
- nfp_net_tx_ring_init (& rings [r ], nn -> tx_rings [r ]. r_vec , r );
1585
+ for (r = 0 ; r < s -> n_rings ; r ++ ) {
1586
+ nfp_net_tx_ring_init (& rings [r ], & nn -> r_vecs [r ], r );
1587
1587
1588
1588
if (nfp_net_tx_ring_alloc (& rings [r ], s -> dcnt ))
1589
1589
goto err_free_prev ;
@@ -1605,9 +1605,11 @@ nfp_net_tx_ring_set_swap(struct nfp_net *nn, struct nfp_net_ring_set *s)
1605
1605
1606
1606
s -> dcnt = nn -> txd_cnt ;
1607
1607
s -> rings = nn -> tx_rings ;
1608
+ s -> n_rings = nn -> num_tx_rings ;
1608
1609
1609
1610
nn -> txd_cnt = new .dcnt ;
1610
1611
nn -> tx_rings = new .rings ;
1612
+ nn -> num_tx_rings = new .n_rings ;
1611
1613
}
1612
1614
1613
1615
static void
@@ -1616,7 +1618,7 @@ nfp_net_tx_ring_set_free(struct nfp_net *nn, struct nfp_net_ring_set *s)
1616
1618
struct nfp_net_tx_ring * rings = s -> rings ;
1617
1619
unsigned int r ;
1618
1620
1619
- for (r = 0 ; r < nn -> num_tx_rings ; r ++ )
1621
+ for (r = 0 ; r < s -> n_rings ; r ++ )
1620
1622
nfp_net_tx_ring_free (& rings [r ]);
1621
1623
1622
1624
kfree (rings );
@@ -1694,12 +1696,12 @@ nfp_net_rx_ring_set_prepare(struct nfp_net *nn, struct nfp_net_ring_set *s)
1694
1696
struct nfp_net_rx_ring * rings ;
1695
1697
unsigned int r ;
1696
1698
1697
- rings = kcalloc (nn -> num_rx_rings , sizeof (* rings ), GFP_KERNEL );
1699
+ rings = kcalloc (s -> n_rings , sizeof (* rings ), GFP_KERNEL );
1698
1700
if (!rings )
1699
1701
return NULL ;
1700
1702
1701
- for (r = 0 ; r < nn -> num_rx_rings ; r ++ ) {
1702
- nfp_net_rx_ring_init (& rings [r ], nn -> rx_rings [r ]. r_vec , r );
1703
+ for (r = 0 ; r < s -> n_rings ; r ++ ) {
1704
+ nfp_net_rx_ring_init (& rings [r ], & nn -> r_vecs [r ], r );
1703
1705
1704
1706
if (nfp_net_rx_ring_alloc (& rings [r ], fl_bufsz , s -> dcnt ))
1705
1707
goto err_free_prev ;
@@ -1728,11 +1730,13 @@ nfp_net_rx_ring_set_swap(struct nfp_net *nn, struct nfp_net_ring_set *s)
1728
1730
s -> mtu = nn -> netdev -> mtu ;
1729
1731
s -> dcnt = nn -> rxd_cnt ;
1730
1732
s -> rings = nn -> rx_rings ;
1733
+ s -> n_rings = nn -> num_rx_rings ;
1731
1734
1732
1735
nn -> netdev -> mtu = new .mtu ;
1733
1736
nn -> fl_bufsz = nfp_net_calc_fl_bufsz (nn , new .mtu );
1734
1737
nn -> rxd_cnt = new .dcnt ;
1735
1738
nn -> rx_rings = new .rings ;
1739
+ nn -> num_rx_rings = new .n_rings ;
1736
1740
}
1737
1741
1738
1742
static void
@@ -1741,7 +1745,7 @@ nfp_net_rx_ring_set_free(struct nfp_net *nn, struct nfp_net_ring_set *s)
1741
1745
struct nfp_net_rx_ring * rings = s -> rings ;
1742
1746
unsigned int r ;
1743
1747
1744
- for (r = 0 ; r < nn -> num_rx_rings ; r ++ ) {
1748
+ for (r = 0 ; r < s -> n_rings ; r ++ ) {
1745
1749
nfp_net_rx_ring_bufs_free (nn , & rings [r ]);
1746
1750
nfp_net_rx_ring_free (& rings [r ]);
1747
1751
}
@@ -1764,19 +1768,20 @@ nfp_net_prepare_vector(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,
1764
1768
struct msix_entry * entry = & nn -> irq_entries [r_vec -> irq_idx ];
1765
1769
int err ;
1766
1770
1771
+ /* Setup NAPI */
1772
+ netif_napi_add (nn -> netdev , & r_vec -> napi ,
1773
+ nfp_net_poll , NAPI_POLL_WEIGHT );
1774
+
1767
1775
snprintf (r_vec -> name , sizeof (r_vec -> name ),
1768
1776
"%s-rxtx-%d" , nn -> netdev -> name , idx );
1769
1777
err = request_irq (entry -> vector , r_vec -> handler , 0 , r_vec -> name , r_vec );
1770
1778
if (err ) {
1779
+ netif_napi_del (& r_vec -> napi );
1771
1780
nn_err (nn , "Error requesting IRQ %d\n" , entry -> vector );
1772
1781
return err ;
1773
1782
}
1774
1783
disable_irq (entry -> vector );
1775
1784
1776
- /* Setup NAPI */
1777
- netif_napi_add (nn -> netdev , & r_vec -> napi ,
1778
- nfp_net_poll , NAPI_POLL_WEIGHT );
1779
-
1780
1785
irq_set_affinity_hint (entry -> vector , & r_vec -> affinity_mask );
1781
1786
1782
1787
nn_dbg (nn , "RV%02d: irq=%03d/%03d\n" , idx , entry -> vector , entry -> entry );
@@ -2036,10 +2041,12 @@ static int nfp_net_netdev_open(struct net_device *netdev)
2036
2041
{
2037
2042
struct nfp_net * nn = netdev_priv (netdev );
2038
2043
struct nfp_net_ring_set rx = {
2044
+ .n_rings = nn -> num_rx_rings ,
2039
2045
.mtu = nn -> netdev -> mtu ,
2040
2046
.dcnt = nn -> rxd_cnt ,
2041
2047
};
2042
2048
struct nfp_net_ring_set tx = {
2049
+ .n_rings = nn -> num_tx_rings ,
2043
2050
.dcnt = nn -> txd_cnt ,
2044
2051
};
2045
2052
int err , r ;
@@ -2239,49 +2246,89 @@ static void nfp_net_rss_init_itbl(struct nfp_net *nn)
2239
2246
}
2240
2247
2241
2248
static int
2242
- nfp_net_ring_swap_enable (struct nfp_net * nn ,
2249
+ nfp_net_ring_swap_enable (struct nfp_net * nn , unsigned int * num_vecs ,
2243
2250
struct nfp_net_ring_set * rx ,
2244
2251
struct nfp_net_ring_set * tx )
2245
2252
{
2246
2253
unsigned int r ;
2254
+ int err ;
2247
2255
2248
2256
if (rx )
2249
2257
nfp_net_rx_ring_set_swap (nn , rx );
2250
2258
if (tx )
2251
2259
nfp_net_tx_ring_set_swap (nn , tx );
2252
2260
2261
+ swap (* num_vecs , nn -> num_r_vecs );
2262
+
2253
2263
for (r = 0 ; r < nn -> max_r_vecs ; r ++ )
2254
2264
nfp_net_vector_assign_rings (nn , & nn -> r_vecs [r ], r );
2255
2265
2266
+ if (nn -> netdev -> real_num_rx_queues != nn -> num_rx_rings ) {
2267
+ if (!netif_is_rxfh_configured (nn -> netdev ))
2268
+ nfp_net_rss_init_itbl (nn );
2269
+
2270
+ err = netif_set_real_num_rx_queues (nn -> netdev ,
2271
+ nn -> num_rx_rings );
2272
+ if (err )
2273
+ return err ;
2274
+ }
2275
+
2276
+ if (nn -> netdev -> real_num_tx_queues != nn -> num_tx_rings ) {
2277
+ err = netif_set_real_num_tx_queues (nn -> netdev ,
2278
+ nn -> num_tx_rings );
2279
+ if (err )
2280
+ return err ;
2281
+ }
2282
+
2256
2283
return __nfp_net_set_config_and_enable (nn );
2257
2284
}
2258
2285
2259
2286
static void
2260
2287
nfp_net_ring_reconfig_down (struct nfp_net * nn ,
2261
2288
struct nfp_net_ring_set * rx ,
2262
- struct nfp_net_ring_set * tx )
2289
+ struct nfp_net_ring_set * tx ,
2290
+ unsigned int num_vecs )
2263
2291
{
2264
2292
nn -> netdev -> mtu = rx ? rx -> mtu : nn -> netdev -> mtu ;
2265
2293
nn -> fl_bufsz = nfp_net_calc_fl_bufsz (nn , nn -> netdev -> mtu );
2266
2294
nn -> rxd_cnt = rx ? rx -> dcnt : nn -> rxd_cnt ;
2267
2295
nn -> txd_cnt = tx ? tx -> dcnt : nn -> txd_cnt ;
2296
+ nn -> num_rx_rings = rx ? rx -> n_rings : nn -> num_rx_rings ;
2297
+ nn -> num_tx_rings = tx ? tx -> n_rings : nn -> num_tx_rings ;
2298
+ nn -> num_r_vecs = num_vecs ;
2299
+
2300
+ if (!netif_is_rxfh_configured (nn -> netdev ))
2301
+ nfp_net_rss_init_itbl (nn );
2268
2302
}
2269
2303
2270
2304
int
2271
2305
nfp_net_ring_reconfig (struct nfp_net * nn , struct nfp_net_ring_set * rx ,
2272
2306
struct nfp_net_ring_set * tx )
2273
2307
{
2308
+ unsigned int num_vecs , r ;
2274
2309
int err ;
2275
2310
2311
+ num_vecs = max (rx ? rx -> n_rings : nn -> num_rx_rings ,
2312
+ tx ? tx -> n_rings : nn -> num_tx_rings );
2313
+
2276
2314
if (!netif_running (nn -> netdev )) {
2277
- nfp_net_ring_reconfig_down (nn , rx , tx );
2315
+ nfp_net_ring_reconfig_down (nn , rx , tx , num_vecs );
2278
2316
return 0 ;
2279
2317
}
2280
2318
2281
2319
/* Prepare new rings */
2320
+ for (r = nn -> num_r_vecs ; r < num_vecs ; r ++ ) {
2321
+ err = nfp_net_prepare_vector (nn , & nn -> r_vecs [r ], r );
2322
+ if (err ) {
2323
+ num_vecs = r ;
2324
+ goto err_cleanup_vecs ;
2325
+ }
2326
+ }
2282
2327
if (rx ) {
2283
- if (!nfp_net_rx_ring_set_prepare (nn , rx ))
2284
- return - ENOMEM ;
2328
+ if (!nfp_net_rx_ring_set_prepare (nn , rx )) {
2329
+ err = - ENOMEM ;
2330
+ goto err_cleanup_vecs ;
2331
+ }
2285
2332
}
2286
2333
if (tx ) {
2287
2334
if (!nfp_net_tx_ring_set_prepare (nn , tx )) {
@@ -2294,18 +2341,20 @@ nfp_net_ring_reconfig(struct nfp_net *nn, struct nfp_net_ring_set *rx,
2294
2341
nfp_net_close_stack (nn );
2295
2342
nfp_net_clear_config_and_disable (nn );
2296
2343
2297
- err = nfp_net_ring_swap_enable (nn , rx , tx );
2344
+ err = nfp_net_ring_swap_enable (nn , & num_vecs , rx , tx );
2298
2345
if (err ) {
2299
2346
int err2 ;
2300
2347
2301
2348
nfp_net_clear_config_and_disable (nn );
2302
2349
2303
2350
/* Try with old configuration and old rings */
2304
- err2 = nfp_net_ring_swap_enable (nn , rx , tx );
2351
+ err2 = nfp_net_ring_swap_enable (nn , & num_vecs , rx , tx );
2305
2352
if (err2 )
2306
2353
nn_err (nn , "Can't restore ring config - FW communication failed (%d,%d)\n" ,
2307
2354
err , err2 );
2308
2355
}
2356
+ for (r = num_vecs - 1 ; r >= nn -> num_r_vecs ; r -- )
2357
+ nfp_net_cleanup_vector (nn , & nn -> r_vecs [r ]);
2309
2358
2310
2359
if (rx )
2311
2360
nfp_net_rx_ring_set_free (nn , rx );
@@ -2319,13 +2368,17 @@ nfp_net_ring_reconfig(struct nfp_net *nn, struct nfp_net_ring_set *rx,
2319
2368
err_free_rx :
2320
2369
if (rx )
2321
2370
nfp_net_rx_ring_set_free (nn , rx );
2371
+ err_cleanup_vecs :
2372
+ for (r = num_vecs - 1 ; r >= nn -> num_r_vecs ; r -- )
2373
+ nfp_net_cleanup_vector (nn , & nn -> r_vecs [r ]);
2322
2374
return err ;
2323
2375
}
2324
2376
2325
2377
static int nfp_net_change_mtu (struct net_device * netdev , int new_mtu )
2326
2378
{
2327
2379
struct nfp_net * nn = netdev_priv (netdev );
2328
2380
struct nfp_net_ring_set rx = {
2381
+ .n_rings = nn -> num_rx_rings ,
2329
2382
.mtu = new_mtu ,
2330
2383
.dcnt = nn -> rxd_cnt ,
2331
2384
};
0 commit comments