@@ -1715,157 +1715,238 @@ void enetc_get_si_caps(struct enetc_si *si)
1715
1715
si -> hw_features |= ENETC_SI_F_PSFP ;
1716
1716
}
1717
1717
1718
- static int enetc_dma_alloc_bdr (struct enetc_bdr * r , size_t bd_size )
1718
+ static int enetc_dma_alloc_bdr (struct enetc_bdr_resource * res )
1719
1719
{
1720
- r -> bd_base = dma_alloc_coherent (r -> dev , r -> bd_count * bd_size ,
1721
- & r -> bd_dma_base , GFP_KERNEL );
1722
- if (!r -> bd_base )
1720
+ size_t bd_base_size = res -> bd_count * res -> bd_size ;
1721
+
1722
+ res -> bd_base = dma_alloc_coherent (res -> dev , bd_base_size ,
1723
+ & res -> bd_dma_base , GFP_KERNEL );
1724
+ if (!res -> bd_base )
1723
1725
return - ENOMEM ;
1724
1726
1725
1727
/* h/w requires 128B alignment */
1726
- if (!IS_ALIGNED (r -> bd_dma_base , 128 )) {
1727
- dma_free_coherent (r -> dev , r -> bd_count * bd_size , r -> bd_base ,
1728
- r -> bd_dma_base );
1728
+ if (!IS_ALIGNED (res -> bd_dma_base , 128 )) {
1729
+ dma_free_coherent (res -> dev , bd_base_size , res -> bd_base ,
1730
+ res -> bd_dma_base );
1729
1731
return - EINVAL ;
1730
1732
}
1731
1733
1732
1734
return 0 ;
1733
1735
}
1734
1736
1735
- static void enetc_dma_free_bdr (struct enetc_bdr * r , size_t bd_size )
1737
+ static void enetc_dma_free_bdr (const struct enetc_bdr_resource * res )
1736
1738
{
1737
- dma_free_coherent (r -> dev , r -> bd_count * bd_size , r -> bd_base ,
1738
- r -> bd_dma_base );
1739
- r -> bd_base = NULL ;
1739
+ size_t bd_base_size = res -> bd_count * res -> bd_size ;
1740
+
1741
+ dma_free_coherent (res -> dev , bd_base_size , res -> bd_base ,
1742
+ res -> bd_dma_base );
1740
1743
}
1741
1744
1742
- static int enetc_alloc_txbdr (struct enetc_bdr * txr )
1745
+ static int enetc_alloc_tx_resource (struct enetc_bdr_resource * res ,
1746
+ struct device * dev , size_t bd_count )
1743
1747
{
1744
1748
int err ;
1745
1749
1746
- txr -> tx_swbd = vzalloc (txr -> bd_count * sizeof (struct enetc_tx_swbd ));
1747
- if (!txr -> tx_swbd )
1750
+ res -> dev = dev ;
1751
+ res -> bd_count = bd_count ;
1752
+ res -> bd_size = sizeof (union enetc_tx_bd );
1753
+
1754
+ res -> tx_swbd = vzalloc (bd_count * sizeof (* res -> tx_swbd ));
1755
+ if (!res -> tx_swbd )
1748
1756
return - ENOMEM ;
1749
1757
1750
- err = enetc_dma_alloc_bdr (txr , sizeof ( union enetc_tx_bd ) );
1758
+ err = enetc_dma_alloc_bdr (res );
1751
1759
if (err )
1752
1760
goto err_alloc_bdr ;
1753
1761
1754
- txr -> tso_headers = dma_alloc_coherent (txr -> dev ,
1755
- txr -> bd_count * TSO_HEADER_SIZE ,
1756
- & txr -> tso_headers_dma ,
1762
+ res -> tso_headers = dma_alloc_coherent (dev , bd_count * TSO_HEADER_SIZE ,
1763
+ & res -> tso_headers_dma ,
1757
1764
GFP_KERNEL );
1758
- if (!txr -> tso_headers ) {
1765
+ if (!res -> tso_headers ) {
1759
1766
err = - ENOMEM ;
1760
1767
goto err_alloc_tso ;
1761
1768
}
1762
1769
1763
1770
return 0 ;
1764
1771
1765
1772
err_alloc_tso :
1766
- enetc_dma_free_bdr (txr , sizeof ( union enetc_tx_bd ) );
1773
+ enetc_dma_free_bdr (res );
1767
1774
err_alloc_bdr :
1768
- vfree (txr -> tx_swbd );
1769
- txr -> tx_swbd = NULL ;
1775
+ vfree (res -> tx_swbd );
1776
+ res -> tx_swbd = NULL ;
1770
1777
1771
1778
return err ;
1772
1779
}
1773
1780
1774
- static void enetc_free_txbdr ( struct enetc_bdr * txr )
1781
+ static void enetc_free_tx_resource ( const struct enetc_bdr_resource * res )
1775
1782
{
1776
- dma_free_coherent (txr -> dev , txr -> bd_count * TSO_HEADER_SIZE ,
1777
- txr -> tso_headers , txr -> tso_headers_dma );
1778
- txr -> tso_headers = NULL ;
1779
-
1780
- enetc_dma_free_bdr (txr , sizeof (union enetc_tx_bd ));
1781
-
1782
- vfree (txr -> tx_swbd );
1783
- txr -> tx_swbd = NULL ;
1783
+ dma_free_coherent (res -> dev , res -> bd_count * TSO_HEADER_SIZE ,
1784
+ res -> tso_headers , res -> tso_headers_dma );
1785
+ enetc_dma_free_bdr (res );
1786
+ vfree (res -> tx_swbd );
1784
1787
}
1785
1788
1786
- static int enetc_alloc_tx_resources (struct enetc_ndev_priv * priv )
1789
+ static struct enetc_bdr_resource *
1790
+ enetc_alloc_tx_resources (struct enetc_ndev_priv * priv )
1787
1791
{
1792
+ struct enetc_bdr_resource * tx_res ;
1788
1793
int i , err ;
1789
1794
1795
+ tx_res = kcalloc (priv -> num_tx_rings , sizeof (* tx_res ), GFP_KERNEL );
1796
+ if (!tx_res )
1797
+ return ERR_PTR (- ENOMEM );
1798
+
1790
1799
for (i = 0 ; i < priv -> num_tx_rings ; i ++ ) {
1791
- err = enetc_alloc_txbdr ( priv -> tx_ring [i ]) ;
1800
+ struct enetc_bdr * tx_ring = priv -> tx_ring [i ];
1792
1801
1802
+ err = enetc_alloc_tx_resource (& tx_res [i ], tx_ring -> dev ,
1803
+ tx_ring -> bd_count );
1793
1804
if (err )
1794
1805
goto fail ;
1795
1806
}
1796
1807
1797
- return 0 ;
1808
+ return tx_res ;
1798
1809
1799
1810
fail :
1800
1811
while (i -- > 0 )
1801
- enetc_free_txbdr ( priv -> tx_ring [i ]);
1812
+ enetc_free_tx_resource ( & tx_res [i ]);
1802
1813
1803
- return err ;
1814
+ kfree (tx_res );
1815
+
1816
+ return ERR_PTR (err );
1804
1817
}
1805
1818
1806
- static void enetc_free_tx_resources (struct enetc_ndev_priv * priv )
1819
+ static void enetc_free_tx_resources (const struct enetc_bdr_resource * tx_res ,
1820
+ size_t num_resources )
1807
1821
{
1808
- int i ;
1822
+ size_t i ;
1809
1823
1810
- for (i = 0 ; i < priv -> num_tx_rings ; i ++ )
1811
- enetc_free_txbdr (priv -> tx_ring [i ]);
1824
+ for (i = 0 ; i < num_resources ; i ++ )
1825
+ enetc_free_tx_resource (& tx_res [i ]);
1826
+
1827
+ kfree (tx_res );
1812
1828
}
1813
1829
1814
- static int enetc_alloc_rxbdr (struct enetc_bdr * rxr , bool extended )
1830
+ static int enetc_alloc_rx_resource (struct enetc_bdr_resource * res ,
1831
+ struct device * dev , size_t bd_count ,
1832
+ bool extended )
1815
1833
{
1816
- size_t size = sizeof (union enetc_rx_bd );
1817
1834
int err ;
1818
1835
1819
- rxr -> rx_swbd = vzalloc (rxr -> bd_count * sizeof (struct enetc_rx_swbd ));
1820
- if (!rxr -> rx_swbd )
1821
- return - ENOMEM ;
1822
-
1836
+ res -> dev = dev ;
1837
+ res -> bd_count = bd_count ;
1838
+ res -> bd_size = sizeof (union enetc_rx_bd );
1823
1839
if (extended )
1824
- size *= 2 ;
1840
+ res -> bd_size *= 2 ;
1825
1841
1826
- err = enetc_dma_alloc_bdr (rxr , size );
1842
+ res -> rx_swbd = vzalloc (bd_count * sizeof (struct enetc_rx_swbd ));
1843
+ if (!res -> rx_swbd )
1844
+ return - ENOMEM ;
1845
+
1846
+ err = enetc_dma_alloc_bdr (res );
1827
1847
if (err ) {
1828
- vfree (rxr -> rx_swbd );
1848
+ vfree (res -> rx_swbd );
1829
1849
return err ;
1830
1850
}
1831
1851
1832
1852
return 0 ;
1833
1853
}
1834
1854
1835
- static void enetc_free_rxbdr ( struct enetc_bdr * rxr )
1855
+ static void enetc_free_rx_resource ( const struct enetc_bdr_resource * res )
1836
1856
{
1837
- enetc_dma_free_bdr (rxr , sizeof (union enetc_rx_bd ));
1838
-
1839
- vfree (rxr -> rx_swbd );
1840
- rxr -> rx_swbd = NULL ;
1857
+ enetc_dma_free_bdr (res );
1858
+ vfree (res -> rx_swbd );
1841
1859
}
1842
1860
1843
- static int enetc_alloc_rx_resources (struct enetc_ndev_priv * priv , bool extended )
1861
+ static struct enetc_bdr_resource *
1862
+ enetc_alloc_rx_resources (struct enetc_ndev_priv * priv , bool extended )
1844
1863
{
1864
+ struct enetc_bdr_resource * rx_res ;
1845
1865
int i , err ;
1846
1866
1867
+ rx_res = kcalloc (priv -> num_rx_rings , sizeof (* rx_res ), GFP_KERNEL );
1868
+ if (!rx_res )
1869
+ return ERR_PTR (- ENOMEM );
1870
+
1847
1871
for (i = 0 ; i < priv -> num_rx_rings ; i ++ ) {
1848
- err = enetc_alloc_rxbdr ( priv -> rx_ring [i ], extended ) ;
1872
+ struct enetc_bdr * rx_ring = priv -> rx_ring [i ];
1849
1873
1874
+ err = enetc_alloc_rx_resource (& rx_res [i ], rx_ring -> dev ,
1875
+ rx_ring -> bd_count , extended );
1850
1876
if (err )
1851
1877
goto fail ;
1852
1878
}
1853
1879
1854
- return 0 ;
1880
+ return rx_res ;
1855
1881
1856
1882
fail :
1857
1883
while (i -- > 0 )
1858
- enetc_free_rxbdr ( priv -> rx_ring [i ]);
1884
+ enetc_free_rx_resource ( & rx_res [i ]);
1859
1885
1860
- return err ;
1886
+ kfree (rx_res );
1887
+
1888
+ return ERR_PTR (err );
1889
+ }
1890
+
1891
+ static void enetc_free_rx_resources (const struct enetc_bdr_resource * rx_res ,
1892
+ size_t num_resources )
1893
+ {
1894
+ size_t i ;
1895
+
1896
+ for (i = 0 ; i < num_resources ; i ++ )
1897
+ enetc_free_rx_resource (& rx_res [i ]);
1898
+
1899
+ kfree (rx_res );
1861
1900
}
1862
1901
1863
- static void enetc_free_rx_resources (struct enetc_ndev_priv * priv )
1902
+ static void enetc_assign_tx_resource (struct enetc_bdr * tx_ring ,
1903
+ const struct enetc_bdr_resource * res )
1904
+ {
1905
+ tx_ring -> bd_base = res ? res -> bd_base : NULL ;
1906
+ tx_ring -> bd_dma_base = res ? res -> bd_dma_base : 0 ;
1907
+ tx_ring -> tx_swbd = res ? res -> tx_swbd : NULL ;
1908
+ tx_ring -> tso_headers = res ? res -> tso_headers : NULL ;
1909
+ tx_ring -> tso_headers_dma = res ? res -> tso_headers_dma : 0 ;
1910
+ }
1911
+
1912
+ static void enetc_assign_rx_resource (struct enetc_bdr * rx_ring ,
1913
+ const struct enetc_bdr_resource * res )
1914
+ {
1915
+ rx_ring -> bd_base = res ? res -> bd_base : NULL ;
1916
+ rx_ring -> bd_dma_base = res ? res -> bd_dma_base : 0 ;
1917
+ rx_ring -> rx_swbd = res ? res -> rx_swbd : NULL ;
1918
+ }
1919
+
1920
+ static void enetc_assign_tx_resources (struct enetc_ndev_priv * priv ,
1921
+ const struct enetc_bdr_resource * res )
1864
1922
{
1865
1923
int i ;
1866
1924
1867
- for (i = 0 ; i < priv -> num_rx_rings ; i ++ )
1868
- enetc_free_rxbdr (priv -> rx_ring [i ]);
1925
+ if (priv -> tx_res )
1926
+ enetc_free_tx_resources (priv -> tx_res , priv -> num_tx_rings );
1927
+
1928
+ for (i = 0 ; i < priv -> num_tx_rings ; i ++ ) {
1929
+ enetc_assign_tx_resource (priv -> tx_ring [i ],
1930
+ res ? & res [i ] : NULL );
1931
+ }
1932
+
1933
+ priv -> tx_res = res ;
1934
+ }
1935
+
1936
+ static void enetc_assign_rx_resources (struct enetc_ndev_priv * priv ,
1937
+ const struct enetc_bdr_resource * res )
1938
+ {
1939
+ int i ;
1940
+
1941
+ if (priv -> rx_res )
1942
+ enetc_free_rx_resources (priv -> rx_res , priv -> num_rx_rings );
1943
+
1944
+ for (i = 0 ; i < priv -> num_rx_rings ; i ++ ) {
1945
+ enetc_assign_rx_resource (priv -> rx_ring [i ],
1946
+ res ? & res [i ] : NULL );
1947
+ }
1948
+
1949
+ priv -> rx_res = res ;
1869
1950
}
1870
1951
1871
1952
static void enetc_free_tx_ring (struct enetc_bdr * tx_ring )
@@ -2306,6 +2387,7 @@ void enetc_start(struct net_device *ndev)
2306
2387
int enetc_open (struct net_device * ndev )
2307
2388
{
2308
2389
struct enetc_ndev_priv * priv = netdev_priv (ndev );
2390
+ struct enetc_bdr_resource * tx_res , * rx_res ;
2309
2391
int num_stack_tx_queues ;
2310
2392
bool extended ;
2311
2393
int err ;
@@ -2320,13 +2402,17 @@ int enetc_open(struct net_device *ndev)
2320
2402
if (err )
2321
2403
goto err_phy_connect ;
2322
2404
2323
- err = enetc_alloc_tx_resources (priv );
2324
- if (err )
2405
+ tx_res = enetc_alloc_tx_resources (priv );
2406
+ if (IS_ERR (tx_res )) {
2407
+ err = PTR_ERR (tx_res );
2325
2408
goto err_alloc_tx ;
2409
+ }
2326
2410
2327
- err = enetc_alloc_rx_resources (priv , extended );
2328
- if (err )
2411
+ rx_res = enetc_alloc_rx_resources (priv , extended );
2412
+ if (IS_ERR (rx_res )) {
2413
+ err = PTR_ERR (rx_res );
2329
2414
goto err_alloc_rx ;
2415
+ }
2330
2416
2331
2417
num_stack_tx_queues = enetc_num_stack_tx_queues (priv );
2332
2418
@@ -2339,15 +2425,17 @@ int enetc_open(struct net_device *ndev)
2339
2425
goto err_set_queues ;
2340
2426
2341
2427
enetc_tx_onestep_tstamp_init (priv );
2428
+ enetc_assign_tx_resources (priv , tx_res );
2429
+ enetc_assign_rx_resources (priv , rx_res );
2342
2430
enetc_setup_bdrs (priv , extended );
2343
2431
enetc_start (ndev );
2344
2432
2345
2433
return 0 ;
2346
2434
2347
2435
err_set_queues :
2348
- enetc_free_rx_resources (priv );
2436
+ enetc_free_rx_resources (rx_res , priv -> num_rx_rings );
2349
2437
err_alloc_rx :
2350
- enetc_free_tx_resources (priv );
2438
+ enetc_free_tx_resources (tx_res , priv -> num_tx_rings );
2351
2439
err_alloc_tx :
2352
2440
if (priv -> phylink )
2353
2441
phylink_disconnect_phy (priv -> phylink );
@@ -2391,8 +2479,11 @@ int enetc_close(struct net_device *ndev)
2391
2479
if (priv -> phylink )
2392
2480
phylink_disconnect_phy (priv -> phylink );
2393
2481
enetc_free_rxtx_rings (priv );
2394
- enetc_free_rx_resources (priv );
2395
- enetc_free_tx_resources (priv );
2482
+
2483
+ /* Avoids dangling pointers and also frees old resources */
2484
+ enetc_assign_rx_resources (priv , NULL );
2485
+ enetc_assign_tx_resources (priv , NULL );
2486
+
2396
2487
enetc_free_irqs (priv );
2397
2488
2398
2489
return 0 ;
0 commit comments