linux/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
<<
>>
Prefs
   1/*******************************************************************************
   2  This contains the functions to handle the platform driver.
   3
   4  Copyright (C) 2007-2011  STMicroelectronics Ltd
   5
   6  This program is free software; you can redistribute it and/or modify it
   7  under the terms and conditions of the GNU General Public License,
   8  version 2, as published by the Free Software Foundation.
   9
  10  This program is distributed in the hope it will be useful, but WITHOUT
  11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13  more details.
  14
  15  The full GNU General Public License is included in this distribution in
  16  the file called "COPYING".
  17
  18  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
  19*******************************************************************************/
  20
  21#include <linux/platform_device.h>
  22#include <linux/module.h>
  23#include <linux/io.h>
  24#include <linux/of.h>
  25#include <linux/of_net.h>
  26#include <linux/of_device.h>
  27#include <linux/of_mdio.h>
  28
  29#include "stmmac.h"
  30#include "stmmac_platform.h"
  31
  32#ifdef CONFIG_OF
  33
  34/**
  35 * dwmac1000_validate_mcast_bins - validates the number of Multicast filter bins
  36 * @mcast_bins: Multicast filtering bins
  37 * Description:
  38 * this function validates the number of Multicast filtering bins specified
  39 * by the configuration through the device tree. The Synopsys GMAC supports
  40 * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC
  41 * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds
  42 * to 7 bits, and 256 refers to 8 bits of the CRC. Any other setting is
  43 * invalid and will cause the filtering algorithm to use Multicast
  44 * promiscuous mode.
  45 */
  46static int dwmac1000_validate_mcast_bins(int mcast_bins)
  47{
  48        int x = mcast_bins;
  49
  50        switch (x) {
  51        case HASH_TABLE_SIZE:
  52        case 128:
  53        case 256:
  54                break;
  55        default:
  56                x = 0;
  57                pr_info("Hash table entries set to unexpected value %d",
  58                        mcast_bins);
  59                break;
  60        }
  61        return x;
  62}
  63
  64/**
  65 * dwmac1000_validate_ucast_entries - validate the Unicast address entries
  66 * @ucast_entries: number of Unicast address entries
  67 * Description:
  68 * This function validates the number of Unicast address entries supported
  69 * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
  70 * supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter
  71 * logic. This function validates a valid, supported configuration is
  72 * selected, and defaults to 1 Unicast address if an unsupported
  73 * configuration is selected.
  74 */
  75static int dwmac1000_validate_ucast_entries(int ucast_entries)
  76{
  77        int x = ucast_entries;
  78
  79        switch (x) {
  80        case 1:
  81        case 32:
  82        case 64:
  83        case 128:
  84                break;
  85        default:
  86                x = 1;
  87                pr_info("Unicast table entries set to unexpected value %d\n",
  88                        ucast_entries);
  89                break;
  90        }
  91        return x;
  92}
  93
  94/**
  95 * stmmac_axi_setup - parse DT parameters for programming the AXI register
  96 * @pdev: platform device
  97 * @priv: driver private struct.
  98 * Description:
  99 * if required, from device-tree the AXI internal register can be tuned
 100 * by using platform parameters.
 101 */
 102static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
 103{
 104        struct device_node *np;
 105        struct stmmac_axi *axi;
 106
 107        np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
 108        if (!np)
 109                return NULL;
 110
 111        axi = kzalloc(sizeof(*axi), GFP_KERNEL);
 112        if (!axi) {
 113                of_node_put(np);
 114                return ERR_PTR(-ENOMEM);
 115        }
 116
 117        axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
 118        axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
 119        axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe");
 120        axi->axi_fb = of_property_read_bool(np, "snps,axi_fb");
 121        axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
 122        axi->axi_rb =  of_property_read_bool(np, "snps,axi_rb");
 123
 124        if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
 125                axi->axi_wr_osr_lmt = 1;
 126        if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
 127                axi->axi_rd_osr_lmt = 1;
 128        of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
 129        of_node_put(np);
 130
 131        return axi;
 132}
 133
 134/**
 135 * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources
 136 * @plat: driver data platform structure
 137 * @np: device tree node
 138 * @dev: device pointer
 139 * Description:
 140 * The mdio bus will be allocated in case of a phy transceiver is on board;
 141 * it will be NULL if the fixed-link is configured.
 142 * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated
 143 * in any case (for DSA, mdio must be registered even if fixed-link).
 144 * The table below sums the supported configurations:
 145 *      -------------------------------
 146 *      snps,phy-addr   |     Y
 147 *      -------------------------------
 148 *      phy-handle      |     Y
 149 *      -------------------------------
 150 *      fixed-link      |     N
 151 *      -------------------------------
 152 *      snps,dwmac-mdio |
 153 *        even if       |     Y
 154 *      fixed-link      |
 155 *      -------------------------------
 156 *
 157 * It returns 0 in case of success otherwise -ENODEV.
 158 */
 159static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
 160                         struct device_node *np, struct device *dev)
 161{
 162        bool mdio = true;
 163
 164        /* If phy-handle property is passed from DT, use it as the PHY */
 165        plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
 166        if (plat->phy_node)
 167                dev_dbg(dev, "Found phy-handle subnode\n");
 168
 169        /* If phy-handle is not specified, check if we have a fixed-phy */
 170        if (!plat->phy_node && of_phy_is_fixed_link(np)) {
 171                if ((of_phy_register_fixed_link(np) < 0))
 172                        return -ENODEV;
 173
 174                dev_dbg(dev, "Found fixed-link subnode\n");
 175                plat->phy_node = of_node_get(np);
 176                mdio = false;
 177        }
 178
 179        /* exception for dwmac-dwc-qos-eth glue logic */
 180        if (of_device_is_compatible(np, "snps,dwc-qos-ethernet-4.10")) {
 181                plat->mdio_node = of_get_child_by_name(np, "mdio");
 182        } else {
 183                /**
 184                 * If snps,dwmac-mdio is passed from DT, always register
 185                 * the MDIO
 186                 */
 187                for_each_child_of_node(np, plat->mdio_node) {
 188                        if (of_device_is_compatible(plat->mdio_node,
 189                                                    "snps,dwmac-mdio"))
 190                                break;
 191                }
 192        }
 193
 194        if (plat->mdio_node) {
 195                dev_dbg(dev, "Found MDIO subnode\n");
 196                mdio = true;
 197        }
 198
 199        if (mdio)
 200                plat->mdio_bus_data =
 201                        devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data),
 202                                     GFP_KERNEL);
 203        return 0;
 204}
 205
 206/**
 207 * stmmac_probe_config_dt - parse device-tree driver parameters
 208 * @pdev: platform_device structure
 209 * @mac: MAC address to use
 210 * Description:
 211 * this function is to read the driver parameters from device-tree and
 212 * set some private fields that will be used by the main at runtime.
 213 */
 214struct plat_stmmacenet_data *
 215stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
 216{
 217        struct device_node *np = pdev->dev.of_node;
 218        struct plat_stmmacenet_data *plat;
 219        struct stmmac_dma_cfg *dma_cfg;
 220
 221        plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
 222        if (!plat)
 223                return ERR_PTR(-ENOMEM);
 224
 225        *mac = of_get_mac_address(np);
 226        plat->interface = of_get_phy_mode(np);
 227
 228        /* Get max speed of operation from device tree */
 229        if (of_property_read_u32(np, "max-speed", &plat->max_speed))
 230                plat->max_speed = -1;
 231
 232        plat->bus_id = of_alias_get_id(np, "ethernet");
 233        if (plat->bus_id < 0)
 234                plat->bus_id = 0;
 235
 236        /* Default to phy auto-detection */
 237        plat->phy_addr = -1;
 238
 239        /* "snps,phy-addr" is not a standard property. Mark it as deprecated
 240         * and warn of its use. Remove this when phy node support is added.
 241         */
 242        if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
 243                dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
 244
 245        /* To Configure PHY by using all device-tree supported properties */
 246        if (stmmac_dt_phy(plat, np, &pdev->dev))
 247                return ERR_PTR(-ENODEV);
 248
 249        of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
 250
 251        of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size);
 252
 253        plat->force_sf_dma_mode =
 254                of_property_read_bool(np, "snps,force_sf_dma_mode");
 255
 256        plat->en_tx_lpi_clockgating =
 257                of_property_read_bool(np, "snps,en-tx-lpi-clockgating");
 258
 259        /* Set the maxmtu to a default of JUMBO_LEN in case the
 260         * parameter is not present in the device tree.
 261         */
 262        plat->maxmtu = JUMBO_LEN;
 263
 264        /* Set default value for multicast hash bins */
 265        plat->multicast_filter_bins = HASH_TABLE_SIZE;
 266
 267        /* Set default value for unicast filter entries */
 268        plat->unicast_filter_entries = 1;
 269
 270        /*
 271         * Currently only the properties needed on SPEAr600
 272         * are provided. All other properties should be added
 273         * once needed on other platforms.
 274         */
 275        if (of_device_is_compatible(np, "st,spear600-gmac") ||
 276                of_device_is_compatible(np, "snps,dwmac-3.50a") ||
 277                of_device_is_compatible(np, "snps,dwmac-3.70a") ||
 278                of_device_is_compatible(np, "snps,dwmac")) {
 279                /* Note that the max-frame-size parameter as defined in the
 280                 * ePAPR v1.1 spec is defined as max-frame-size, it's
 281                 * actually used as the IEEE definition of MAC Client
 282                 * data, or MTU. The ePAPR specification is confusing as
 283                 * the definition is max-frame-size, but usage examples
 284                 * are clearly MTUs
 285                 */
 286                of_property_read_u32(np, "max-frame-size", &plat->maxmtu);
 287                of_property_read_u32(np, "snps,multicast-filter-bins",
 288                                     &plat->multicast_filter_bins);
 289                of_property_read_u32(np, "snps,perfect-filter-entries",
 290                                     &plat->unicast_filter_entries);
 291                plat->unicast_filter_entries = dwmac1000_validate_ucast_entries(
 292                                               plat->unicast_filter_entries);
 293                plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
 294                                              plat->multicast_filter_bins);
 295                plat->has_gmac = 1;
 296                plat->pmt = 1;
 297        }
 298
 299        if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
 300            of_device_is_compatible(np, "snps,dwmac-4.10a")) {
 301                plat->has_gmac4 = 1;
 302                plat->has_gmac = 0;
 303                plat->pmt = 1;
 304                plat->tso_en = of_property_read_bool(np, "snps,tso");
 305        }
 306
 307        if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
 308                of_device_is_compatible(np, "snps,dwmac-3.710")) {
 309                plat->enh_desc = 1;
 310                plat->bugged_jumbo = 1;
 311                plat->force_sf_dma_mode = 1;
 312        }
 313
 314        dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
 315                               GFP_KERNEL);
 316        if (!dma_cfg) {
 317                stmmac_remove_config_dt(pdev, plat);
 318                return ERR_PTR(-ENOMEM);
 319        }
 320        plat->dma_cfg = dma_cfg;
 321
 322        of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
 323        if (!dma_cfg->pbl)
 324                dma_cfg->pbl = DEFAULT_DMA_PBL;
 325        of_property_read_u32(np, "snps,txpbl", &dma_cfg->txpbl);
 326        of_property_read_u32(np, "snps,rxpbl", &dma_cfg->rxpbl);
 327        dma_cfg->pblx8 = !of_property_read_bool(np, "snps,no-pbl-x8");
 328
 329        dma_cfg->aal = of_property_read_bool(np, "snps,aal");
 330        dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
 331        dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
 332
 333        plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
 334        if (plat->force_thresh_dma_mode) {
 335                plat->force_sf_dma_mode = 0;
 336                pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
 337        }
 338
 339        of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
 340
 341        plat->axi = stmmac_axi_setup(pdev);
 342
 343        /* clock setup */
 344        plat->stmmac_clk = devm_clk_get(&pdev->dev,
 345                                        STMMAC_RESOURCE_NAME);
 346        if (IS_ERR(plat->stmmac_clk)) {
 347                dev_warn(&pdev->dev, "Cannot get CSR clock\n");
 348                plat->stmmac_clk = NULL;
 349        }
 350        clk_prepare_enable(plat->stmmac_clk);
 351
 352        plat->pclk = devm_clk_get(&pdev->dev, "pclk");
 353        if (IS_ERR(plat->pclk)) {
 354                if (PTR_ERR(plat->pclk) == -EPROBE_DEFER)
 355                        goto error_pclk_get;
 356
 357                plat->pclk = NULL;
 358        }
 359        clk_prepare_enable(plat->pclk);
 360
 361        /* Fall-back to main clock in case of no PTP ref is passed */
 362        plat->clk_ptp_ref = devm_clk_get(&pdev->dev, "clk_ptp_ref");
 363        if (IS_ERR(plat->clk_ptp_ref)) {
 364                plat->clk_ptp_rate = clk_get_rate(plat->stmmac_clk);
 365                plat->clk_ptp_ref = NULL;
 366                dev_warn(&pdev->dev, "PTP uses main clock\n");
 367        } else {
 368                clk_prepare_enable(plat->clk_ptp_ref);
 369                plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
 370                dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate);
 371        }
 372
 373        plat->stmmac_rst = devm_reset_control_get(&pdev->dev,
 374                                                  STMMAC_RESOURCE_NAME);
 375        if (IS_ERR(plat->stmmac_rst)) {
 376                if (PTR_ERR(plat->stmmac_rst) == -EPROBE_DEFER)
 377                        goto error_hw_init;
 378
 379                dev_info(&pdev->dev, "no reset control found\n");
 380                plat->stmmac_rst = NULL;
 381        }
 382
 383        return plat;
 384
 385error_hw_init:
 386        clk_disable_unprepare(plat->pclk);
 387error_pclk_get:
 388        clk_disable_unprepare(plat->stmmac_clk);
 389
 390        return ERR_PTR(-EPROBE_DEFER);
 391}
 392
 393/**
 394 * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
 395 * @pdev: platform_device structure
 396 * @plat: driver data platform structure
 397 *
 398 * Release resources claimed by stmmac_probe_config_dt().
 399 */
 400void stmmac_remove_config_dt(struct platform_device *pdev,
 401                             struct plat_stmmacenet_data *plat)
 402{
 403        struct device_node *np = pdev->dev.of_node;
 404
 405        if (of_phy_is_fixed_link(np))
 406                of_phy_deregister_fixed_link(np);
 407        of_node_put(plat->phy_node);
 408        of_node_put(plat->mdio_node);
 409}
 410#else
 411struct plat_stmmacenet_data *
 412stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
 413{
 414        return ERR_PTR(-EINVAL);
 415}
 416
 417void stmmac_remove_config_dt(struct platform_device *pdev,
 418                             struct plat_stmmacenet_data *plat)
 419{
 420}
 421#endif /* CONFIG_OF */
 422EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
 423EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
 424
 425int stmmac_get_platform_resources(struct platform_device *pdev,
 426                                  struct stmmac_resources *stmmac_res)
 427{
 428        struct resource *res;
 429
 430        memset(stmmac_res, 0, sizeof(*stmmac_res));
 431
 432        /* Get IRQ information early to have an ability to ask for deferred
 433         * probe if needed before we went too far with resource allocation.
 434         */
 435        stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
 436        if (stmmac_res->irq < 0) {
 437                if (stmmac_res->irq != -EPROBE_DEFER) {
 438                        dev_err(&pdev->dev,
 439                                "MAC IRQ configuration information not found\n");
 440                }
 441                return stmmac_res->irq;
 442        }
 443
 444        /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
 445         * The external wake up irq can be passed through the platform code
 446         * named as "eth_wake_irq"
 447         *
 448         * In case the wake up interrupt is not passed from the platform
 449         * so the driver will continue to use the mac irq (ndev->irq)
 450         */
 451        stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
 452        if (stmmac_res->wol_irq < 0) {
 453                if (stmmac_res->wol_irq == -EPROBE_DEFER)
 454                        return -EPROBE_DEFER;
 455                stmmac_res->wol_irq = stmmac_res->irq;
 456        }
 457
 458        stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
 459        if (stmmac_res->lpi_irq == -EPROBE_DEFER)
 460                return -EPROBE_DEFER;
 461
 462        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 463        stmmac_res->addr = devm_ioremap_resource(&pdev->dev, res);
 464
 465        return PTR_ERR_OR_ZERO(stmmac_res->addr);
 466}
 467EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
 468
 469/**
 470 * stmmac_pltfr_remove
 471 * @pdev: platform device pointer
 472 * Description: this function calls the main to free the net resources
 473 * and calls the platforms hook and release the resources (e.g. mem).
 474 */
 475int stmmac_pltfr_remove(struct platform_device *pdev)
 476{
 477        struct net_device *ndev = platform_get_drvdata(pdev);
 478        struct stmmac_priv *priv = netdev_priv(ndev);
 479        struct plat_stmmacenet_data *plat = priv->plat;
 480        int ret = stmmac_dvr_remove(&pdev->dev);
 481
 482        if (plat->exit)
 483                plat->exit(pdev, plat->bsp_priv);
 484
 485        stmmac_remove_config_dt(pdev, plat);
 486
 487        return ret;
 488}
 489EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
 490
 491#ifdef CONFIG_PM_SLEEP
 492/**
 493 * stmmac_pltfr_suspend
 494 * @dev: device pointer
 495 * Description: this function is invoked when suspend the driver and it direcly
 496 * call the main suspend function and then, if required, on some platform, it
 497 * can call an exit helper.
 498 */
 499static int stmmac_pltfr_suspend(struct device *dev)
 500{
 501        int ret;
 502        struct net_device *ndev = dev_get_drvdata(dev);
 503        struct stmmac_priv *priv = netdev_priv(ndev);
 504        struct platform_device *pdev = to_platform_device(dev);
 505
 506        ret = stmmac_suspend(dev);
 507        if (priv->plat->exit)
 508                priv->plat->exit(pdev, priv->plat->bsp_priv);
 509
 510        return ret;
 511}
 512
 513/**
 514 * stmmac_pltfr_resume
 515 * @dev: device pointer
 516 * Description: this function is invoked when resume the driver before calling
 517 * the main resume function, on some platforms, it can call own init helper
 518 * if required.
 519 */
 520static int stmmac_pltfr_resume(struct device *dev)
 521{
 522        struct net_device *ndev = dev_get_drvdata(dev);
 523        struct stmmac_priv *priv = netdev_priv(ndev);
 524        struct platform_device *pdev = to_platform_device(dev);
 525
 526        if (priv->plat->init)
 527                priv->plat->init(pdev, priv->plat->bsp_priv);
 528
 529        return stmmac_resume(dev);
 530}
 531#endif /* CONFIG_PM_SLEEP */
 532
 533SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
 534                                       stmmac_pltfr_resume);
 535EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
 536
 537MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
 538MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
 539MODULE_LICENSE("GPL");
 540