aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2011-11-16 16:58:00 -0500
committerDavid S. Miller <davem@davemloft.net>2011-11-17 03:13:41 -0500
commit19e30c14371f7afd38d1d35a693b96423a4db144 (patch)
treeb1e30774ec0ff4e3f13ec5f8c2cf05b6c807a075 /drivers
parentc5b9b4e4b9076089fe7f9d4f5d1f2bba776646d2 (diff)
stmmac: parameters auto-tuning through HW cap reg
New GMAC devices (newer than the databook 3.50a) have the HW capability register that provides which features are actually supported by the hardware. On old devices many information have to be passed through the platform, for example: enhanced descriptor structure, TX COE etc. These are mandatory to properly configure the driver. This remains still valid because the driver has to support old Synopsys devices but now it's also able to override them using the values from the HW capability register if supported. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c93
3 files changed, 72 insertions, 29 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 9bafa6cf9e8..a140a8fbf05 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -72,7 +72,6 @@ struct stmmac_priv {
72 spinlock_t lock; 72 spinlock_t lock;
73 spinlock_t tx_lock; 73 spinlock_t tx_lock;
74 int wolopts; 74 int wolopts;
75 int wolenabled;
76 int wol_irq; 75 int wol_irq;
77#ifdef CONFIG_STMMAC_TIMER 76#ifdef CONFIG_STMMAC_TIMER
78 struct stmmac_timer *tm; 77 struct stmmac_timer *tm;
@@ -80,6 +79,7 @@ struct stmmac_priv {
80 struct plat_stmmacenet_data *plat; 79 struct plat_stmmacenet_data *plat;
81 struct stmmac_counters mmc; 80 struct stmmac_counters mmc;
82 struct dma_features dma_cap; 81 struct dma_features dma_cap;
82 int hw_cap_support;
83}; 83};
84 84
85extern int stmmac_mdio_unregister(struct net_device *ndev); 85extern int stmmac_mdio_unregister(struct net_device *ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index e8eff09bbbd..0395f9eba80 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -430,6 +430,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
430 struct stmmac_priv *priv = netdev_priv(dev); 430 struct stmmac_priv *priv = netdev_priv(dev);
431 u32 support = WAKE_MAGIC | WAKE_UCAST; 431 u32 support = WAKE_MAGIC | WAKE_UCAST;
432 432
433 /* By default almost all GMAC devices support the WoL via
434 * magic frame but we can disable it if the HW capability
435 * register shows no support for pmt_magic_frame. */
436 if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
437 wol->wolopts &= ~WAKE_MAGIC;
438
433 if (!device_can_wakeup(priv->device)) 439 if (!device_can_wakeup(priv->device))
434 return -EINVAL; 440 return -EINVAL;
435 441
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e079762a796..7f3ffd3742d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -805,8 +805,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
805 return 0; 805 return 0;
806} 806}
807 807
808/* New GMAC chips support a new register to indicate the 808/**
809 * presence of the optional feature/functions. 809 * stmmac_selec_desc_mode
810 * @dev : device pointer
811 * Description: select the Enhanced/Alternate or Normal descriptors */
812static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
813{
814 if (priv->plat->enh_desc) {
815 pr_info(" Enhanced/Alternate descriptors\n");
816 priv->hw->desc = &enh_desc_ops;
817 } else {
818 pr_info(" Normal descriptors\n");
819 priv->hw->desc = &ndesc_ops;
820 }
821}
822
823/**
824 * stmmac_get_hw_features
825 * @priv : private device pointer
826 * Description:
827 * new GMAC chip generations have a new register to indicate the
828 * presence of the optional feature/functions.
829 * This can be also used to override the value passed through the
830 * platform and necessary for old MAC10/100 and GMAC chips.
810 */ 831 */
811static int stmmac_get_hw_features(struct stmmac_priv *priv) 832static int stmmac_get_hw_features(struct stmmac_priv *priv)
812{ 833{
@@ -827,7 +848,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
827 (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 848 (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
828 priv->dma_cap.pmt_magic_frame = 849 priv->dma_cap.pmt_magic_frame =
829 (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 850 (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
830 /*MMC*/ 851 /* MMC */
831 priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 852 priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
832 /* IEEE 1588-2002*/ 853 /* IEEE 1588-2002*/
833 priv->dma_cap.time_stamp = 854 priv->dma_cap.time_stamp =
@@ -855,8 +876,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
855 priv->dma_cap.enh_desc = 876 priv->dma_cap.enh_desc =
856 (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 877 (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
857 878
858 } else 879 }
859 pr_debug("\tNo HW DMA feature register supported");
860 880
861 return hw_cap; 881 return hw_cap;
862} 882}
@@ -911,6 +931,44 @@ static int stmmac_open(struct net_device *dev)
911 goto open_error; 931 goto open_error;
912 } 932 }
913 933
934 stmmac_get_synopsys_id(priv);
935
936 priv->hw_cap_support = stmmac_get_hw_features(priv);
937
938 if (priv->hw_cap_support) {
939 pr_info(" Support DMA HW capability register");
940
941 /* We can override some gmac/dma configuration fields: e.g.
942 * enh_desc, tx_coe (e.g. that are passed through the
943 * platform) with the values from the HW capability
944 * register (if supported).
945 */
946 priv->plat->enh_desc = priv->dma_cap.enh_desc;
947 priv->plat->tx_coe = priv->dma_cap.tx_coe;
948 priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
949
950 /* By default disable wol on magic frame if not supported */
951 if (!priv->dma_cap.pmt_magic_frame)
952 priv->wolopts &= ~WAKE_MAGIC;
953
954 } else
955 pr_info(" No HW DMA feature register supported");
956
957 /* Select the enhnaced/normal descriptor structures */
958 stmmac_selec_desc_mode(priv);
959
960 /* PMT module is not integrated in all the MAC devices. */
961 if (priv->plat->pmt) {
962 pr_info(" Remote wake-up capable\n");
963 device_set_wakeup_capable(priv->device, 1);
964 }
965
966 priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
967 if (priv->rx_coe)
968 pr_info(" Checksum Offload Engine supported\n");
969 if (priv->plat->tx_coe)
970 pr_info(" Checksum insertion supported\n");
971
914 /* Create and initialize the TX/RX descriptors chains. */ 972 /* Create and initialize the TX/RX descriptors chains. */
915 priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 973 priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
916 priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 974 priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
@@ -933,15 +991,6 @@ static int stmmac_open(struct net_device *dev)
933 /* Initialize the MAC Core */ 991 /* Initialize the MAC Core */
934 priv->hw->mac->core_init(priv->ioaddr); 992 priv->hw->mac->core_init(priv->ioaddr);
935 993
936 stmmac_get_synopsys_id(priv);
937
938 stmmac_get_hw_features(priv);
939
940 priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
941 if (priv->rx_coe)
942 pr_info("stmmac: Rx Checksum Offload Engine supported\n");
943 if (priv->plat->tx_coe)
944 pr_info("\tTX Checksum insertion supported\n");
945 netdev_update_features(dev); 994 netdev_update_features(dev);
946 995
947 /* Request the IRQ lines */ 996 /* Request the IRQ lines */
@@ -1556,7 +1605,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
1556 struct net_device *dev = seq->private; 1605 struct net_device *dev = seq->private;
1557 struct stmmac_priv *priv = netdev_priv(dev); 1606 struct stmmac_priv *priv = netdev_priv(dev);
1558 1607
1559 if (!stmmac_get_hw_features(priv)) { 1608 if (!priv->hw_cap_support) {
1560 seq_printf(seq, "DMA HW features not supported\n"); 1609 seq_printf(seq, "DMA HW features not supported\n");
1561 return 0; 1610 return 0;
1562 } 1611 }
@@ -1764,12 +1813,6 @@ static int stmmac_mac_device_setup(struct net_device *dev)
1764 if (!device) 1813 if (!device)
1765 return -ENOMEM; 1814 return -ENOMEM;
1766 1815
1767 if (priv->plat->enh_desc) {
1768 device->desc = &enh_desc_ops;
1769 pr_info("\tEnhanced descriptor structure\n");
1770 } else
1771 device->desc = &ndesc_ops;
1772
1773 priv->hw = device; 1816 priv->hw = device;
1774 priv->hw->ring = &ring_mode_ops; 1817 priv->hw->ring = &ring_mode_ops;
1775 1818
@@ -1843,11 +1886,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1843 1886
1844 priv->ioaddr = addr; 1887 priv->ioaddr = addr;
1845 1888
1846 /* PMT module is not integrated in all the MAC devices. */
1847 if (plat_dat->pmt) {
1848 pr_info("\tPMT module supported\n");
1849 device_set_wakeup_capable(&pdev->dev, 1);
1850 }
1851 /* 1889 /*
1852 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq 1890 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
1853 * The external wake up irq can be passed through the platform code 1891 * The external wake up irq can be passed through the platform code
@@ -1860,7 +1898,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1860 if (priv->wol_irq == -ENXIO) 1898 if (priv->wol_irq == -ENXIO)
1861 priv->wol_irq = ndev->irq; 1899 priv->wol_irq = ndev->irq;
1862 1900
1863
1864 platform_set_drvdata(pdev, ndev); 1901 platform_set_drvdata(pdev, ndev);
1865 1902
1866 /* Set the I/O base addr */ 1903 /* Set the I/O base addr */
@@ -1873,7 +1910,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1873 goto out_free_ndev; 1910 goto out_free_ndev;
1874 } 1911 }
1875 1912
1876 /* MAC HW revice detection */ 1913 /* MAC HW device detection */
1877 ret = stmmac_mac_device_setup(ndev); 1914 ret = stmmac_mac_device_setup(ndev);
1878 if (ret < 0) 1915 if (ret < 0)
1879 goto out_plat_exit; 1916 goto out_plat_exit;