@@ -494,7 +494,7 @@ static void nfp_net_irqs_assign(struct net_device *netdev)
494494 nn -> lsc_handler = nfp_net_irq_lsc ;
495495 nn -> exn_handler = nfp_net_irq_exn ;
496496
497- for (r = 0 ; r < nn -> num_r_vecs ; r ++ ) {
497+ for (r = 0 ; r < nn -> max_r_vecs ; r ++ ) {
498498 r_vec = & nn -> r_vecs [r ];
499499 r_vec -> nfp_net = nn ;
500500 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)
15781578 struct nfp_net_tx_ring * rings ;
15791579 unsigned int r ;
15801580
1581- rings = kcalloc (nn -> num_tx_rings , sizeof (* rings ), GFP_KERNEL );
1581+ rings = kcalloc (s -> n_rings , sizeof (* rings ), GFP_KERNEL );
15821582 if (!rings )
15831583 return NULL ;
15841584
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 );
15871587
15881588 if (nfp_net_tx_ring_alloc (& rings [r ], s -> dcnt ))
15891589 goto err_free_prev ;
@@ -1605,9 +1605,11 @@ nfp_net_tx_ring_set_swap(struct nfp_net *nn, struct nfp_net_ring_set *s)
16051605
16061606 s -> dcnt = nn -> txd_cnt ;
16071607 s -> rings = nn -> tx_rings ;
1608+ s -> n_rings = nn -> num_tx_rings ;
16081609
16091610 nn -> txd_cnt = new .dcnt ;
16101611 nn -> tx_rings = new .rings ;
1612+ nn -> num_tx_rings = new .n_rings ;
16111613}
16121614
16131615static void
@@ -1616,7 +1618,7 @@ nfp_net_tx_ring_set_free(struct nfp_net *nn, struct nfp_net_ring_set *s)
16161618 struct nfp_net_tx_ring * rings = s -> rings ;
16171619 unsigned int r ;
16181620
1619- for (r = 0 ; r < nn -> num_tx_rings ; r ++ )
1621+ for (r = 0 ; r < s -> n_rings ; r ++ )
16201622 nfp_net_tx_ring_free (& rings [r ]);
16211623
16221624 kfree (rings );
@@ -1694,12 +1696,12 @@ nfp_net_rx_ring_set_prepare(struct nfp_net *nn, struct nfp_net_ring_set *s)
16941696 struct nfp_net_rx_ring * rings ;
16951697 unsigned int r ;
16961698
1697- rings = kcalloc (nn -> num_rx_rings , sizeof (* rings ), GFP_KERNEL );
1699+ rings = kcalloc (s -> n_rings , sizeof (* rings ), GFP_KERNEL );
16981700 if (!rings )
16991701 return NULL ;
17001702
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 );
17031705
17041706 if (nfp_net_rx_ring_alloc (& rings [r ], fl_bufsz , s -> dcnt ))
17051707 goto err_free_prev ;
@@ -1728,11 +1730,13 @@ nfp_net_rx_ring_set_swap(struct nfp_net *nn, struct nfp_net_ring_set *s)
17281730 s -> mtu = nn -> netdev -> mtu ;
17291731 s -> dcnt = nn -> rxd_cnt ;
17301732 s -> rings = nn -> rx_rings ;
1733+ s -> n_rings = nn -> num_rx_rings ;
17311734
17321735 nn -> netdev -> mtu = new .mtu ;
17331736 nn -> fl_bufsz = nfp_net_calc_fl_bufsz (nn , new .mtu );
17341737 nn -> rxd_cnt = new .dcnt ;
17351738 nn -> rx_rings = new .rings ;
1739+ nn -> num_rx_rings = new .n_rings ;
17361740}
17371741
17381742static void
@@ -1741,7 +1745,7 @@ nfp_net_rx_ring_set_free(struct nfp_net *nn, struct nfp_net_ring_set *s)
17411745 struct nfp_net_rx_ring * rings = s -> rings ;
17421746 unsigned int r ;
17431747
1744- for (r = 0 ; r < nn -> num_rx_rings ; r ++ ) {
1748+ for (r = 0 ; r < s -> n_rings ; r ++ ) {
17451749 nfp_net_rx_ring_bufs_free (nn , & rings [r ]);
17461750 nfp_net_rx_ring_free (& rings [r ]);
17471751 }
@@ -1764,19 +1768,20 @@ nfp_net_prepare_vector(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,
17641768 struct msix_entry * entry = & nn -> irq_entries [r_vec -> irq_idx ];
17651769 int err ;
17661770
1771+ /* Setup NAPI */
1772+ netif_napi_add (nn -> netdev , & r_vec -> napi ,
1773+ nfp_net_poll , NAPI_POLL_WEIGHT );
1774+
17671775 snprintf (r_vec -> name , sizeof (r_vec -> name ),
17681776 "%s-rxtx-%d" , nn -> netdev -> name , idx );
17691777 err = request_irq (entry -> vector , r_vec -> handler , 0 , r_vec -> name , r_vec );
17701778 if (err ) {
1779+ netif_napi_del (& r_vec -> napi );
17711780 nn_err (nn , "Error requesting IRQ %d\n" , entry -> vector );
17721781 return err ;
17731782 }
17741783 disable_irq (entry -> vector );
17751784
1776- /* Setup NAPI */
1777- netif_napi_add (nn -> netdev , & r_vec -> napi ,
1778- nfp_net_poll , NAPI_POLL_WEIGHT );
1779-
17801785 irq_set_affinity_hint (entry -> vector , & r_vec -> affinity_mask );
17811786
17821787 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)
20362041{
20372042 struct nfp_net * nn = netdev_priv (netdev );
20382043 struct nfp_net_ring_set rx = {
2044+ .n_rings = nn -> num_rx_rings ,
20392045 .mtu = nn -> netdev -> mtu ,
20402046 .dcnt = nn -> rxd_cnt ,
20412047 };
20422048 struct nfp_net_ring_set tx = {
2049+ .n_rings = nn -> num_tx_rings ,
20432050 .dcnt = nn -> txd_cnt ,
20442051 };
20452052 int err , r ;
@@ -2239,49 +2246,89 @@ static void nfp_net_rss_init_itbl(struct nfp_net *nn)
22392246}
22402247
22412248static 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 ,
22432250 struct nfp_net_ring_set * rx ,
22442251 struct nfp_net_ring_set * tx )
22452252{
22462253 unsigned int r ;
2254+ int err ;
22472255
22482256 if (rx )
22492257 nfp_net_rx_ring_set_swap (nn , rx );
22502258 if (tx )
22512259 nfp_net_tx_ring_set_swap (nn , tx );
22522260
2261+ swap (* num_vecs , nn -> num_r_vecs );
2262+
22532263 for (r = 0 ; r < nn -> max_r_vecs ; r ++ )
22542264 nfp_net_vector_assign_rings (nn , & nn -> r_vecs [r ], r );
22552265
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+
22562283 return __nfp_net_set_config_and_enable (nn );
22572284}
22582285
22592286static void
22602287nfp_net_ring_reconfig_down (struct nfp_net * nn ,
22612288 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 )
22632291{
22642292 nn -> netdev -> mtu = rx ? rx -> mtu : nn -> netdev -> mtu ;
22652293 nn -> fl_bufsz = nfp_net_calc_fl_bufsz (nn , nn -> netdev -> mtu );
22662294 nn -> rxd_cnt = rx ? rx -> dcnt : nn -> rxd_cnt ;
22672295 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 );
22682302}
22692303
22702304int
22712305nfp_net_ring_reconfig (struct nfp_net * nn , struct nfp_net_ring_set * rx ,
22722306 struct nfp_net_ring_set * tx )
22732307{
2308+ unsigned int num_vecs , r ;
22742309 int err ;
22752310
2311+ num_vecs = max (rx ? rx -> n_rings : nn -> num_rx_rings ,
2312+ tx ? tx -> n_rings : nn -> num_tx_rings );
2313+
22762314 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 );
22782316 return 0 ;
22792317 }
22802318
22812319 /* 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+ }
22822327 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+ }
22852332 }
22862333 if (tx ) {
22872334 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,
22942341 nfp_net_close_stack (nn );
22952342 nfp_net_clear_config_and_disable (nn );
22962343
2297- err = nfp_net_ring_swap_enable (nn , rx , tx );
2344+ err = nfp_net_ring_swap_enable (nn , & num_vecs , rx , tx );
22982345 if (err ) {
22992346 int err2 ;
23002347
23012348 nfp_net_clear_config_and_disable (nn );
23022349
23032350 /* 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 );
23052352 if (err2 )
23062353 nn_err (nn , "Can't restore ring config - FW communication failed (%d,%d)\n" ,
23072354 err , err2 );
23082355 }
2356+ for (r = num_vecs - 1 ; r >= nn -> num_r_vecs ; r -- )
2357+ nfp_net_cleanup_vector (nn , & nn -> r_vecs [r ]);
23092358
23102359 if (rx )
23112360 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,
23192368err_free_rx :
23202369 if (rx )
23212370 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 ]);
23222374 return err ;
23232375}
23242376
23252377static int nfp_net_change_mtu (struct net_device * netdev , int new_mtu )
23262378{
23272379 struct nfp_net * nn = netdev_priv (netdev );
23282380 struct nfp_net_ring_set rx = {
2381+ .n_rings = nn -> num_rx_rings ,
23292382 .mtu = new_mtu ,
23302383 .dcnt = nn -> rxd_cnt ,
23312384 };
0 commit comments