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 * @dev: struct device of the platform device
  37 * @mcast_bins: Multicast filtering bins
  38 * Description:
  39 * this function validates the number of Multicast filtering bins specified
  40 * by the configuration through the device tree. The Synopsys GMAC supports
  41 * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC
  42 * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds
  43 * to 7 bits, and 256 refers to 8 bits of the CRC. Any other setting is
  44 * invalid and will cause the filtering algorithm to use Multicast
  45 * promiscuous mode.
  46 */
  47static int dwmac1000_validate_mcast_bins(struct device *dev, int mcast_bins)
  48{
  49        int x = mcast_bins;
  50
  51        switch (x) {
  52        case HASH_TABLE_SIZE:
  53        case 128:
  54        case 256:
  55                break;
  56        default:
  57                x = 0;
  58                dev_info(dev, "Hash table entries set to unexpected value %d\n",
  59                         mcast_bins);
  60                break;
  61        }
  62        return x;
  63}
  64
  65/**
  66 * dwmac1000_validate_ucast_entries - validate the Unicast address entries
  67 * @dev: struct device of the platform device
  68 * @ucast_entries: number of Unicast address entries
  69 * Description:
  70 * This function validates the number of Unicast address entries supported
  71 * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
  72 * supports 1..32, 64, or 128 Unicast filter entries for it's Unicast filter
  73 * logic. This function validates a valid, supported configuration is
  74 * selected, and defaults to 1 Unicast address if an unsupported
  75 * configuration is selected.
  76 */
  77static int dwmac1000_validate_ucast_entries(struct device *dev,
  78                                            int ucast_entries)
  79{
  80        int x = ucast_entries;
  81
  82        switch (x) {
  83        case 1 ... 32:
  84        case 64:
  85        case 128:
  86                break;
  87        default:
  88                x = 1;
  89                dev_info(dev, "Unicast table entries set to unexpected value %d\n",
  90                         ucast_entries);
  91                break;
  92        }
  93        return x;
  94}
  95
  96/**
  97 * stmmac_axi_setup - parse DT parameters for programming the AXI register
  98 * @pdev: platform device
  99 * Description:
 100 * if required, from device-tree the AXI internal register can be tuned
 101 * by using platform parameters.
 102 */
 103static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
 104{
 105        struct device_node *np;
 106        struct stmmac_axi *axi;
 107
 108        np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
 109        if (!np)
 110                return NULL;
 111
 112        axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
 113        if (!axi) {
 114                of_node_put(np);
 115                return ERR_PTR(-ENOMEM);
 116        }
 117
 118        axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
 119        axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
 120        axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe");
 121        axi->axi_fb = of_property_read_bool(np, "snps,axi_fb");
 122        axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
 123        axi->axi_rb =  of_property_read_bool(np, "snps,axi_rb");
 124
 125        if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
 126                axi->axi_wr_osr_lmt = 1;
 127        if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
 128                axi->axi_rd_osr_lmt = 1;
 129        of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
 130        of_node_put(np);
 131
 132        return axi;
 133}
 134
 135/**
 136 * stmmac_mtl_setup - parse DT parameters for multiple queues configuration
 137 * @pdev: platform device
 138 */
 139static int stmmac_mtl_setup(struct platform_device *pdev,
 140                            struct plat_stmmacenet_data *plat)
 141{
 142        struct device_node *q_node;
 143        struct device_node *rx_node;
 144        struct device_node *tx_node;
 145        u8 queue = 0;
 146        int ret = 0;
 147
 148        /* For backwards-compatibility with device trees that don't have any
 149         * snps,mtl-rx-config or snps,mtl-tx-config properties, we fall back
 150         * to one RX and TX queues each.
 151         */
 152        plat->rx_queues_to_use = 1;
 153        plat->tx_queues_to_use = 1;
 154
 155        /* First Queue must always be in DCB mode. As MTL_QUEUE_DCB = 1 we need
 156         * to always set this, otherwise Queue will be classified as AVB
 157         * (because MTL_QUEUE_AVB = 0).
 158         */
 159        plat->rx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
 160        plat->tx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
 161
 162        rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0);
 163        if (!rx_node)
 164                return ret;
 165
 166        tx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-tx-config", 0);
 167        if (!tx_node) {
 168                of_node_put(rx_node);
 169                return ret;
 170        }
 171
 172        /* Processing RX queues common config */
 173        if (of_property_read_u32(rx_node, "snps,rx-queues-to-use",
 174                                 &plat->rx_queues_to_use))
 175                plat->rx_queues_to_use = 1;
 176
 177        if (of_property_read_bool(rx_node, "snps,rx-sched-sp"))
 178                plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
 179        else if (of_property_read_bool(rx_node, "snps,rx-sched-wsp"))
 180                plat->rx_sched_algorithm = MTL_RX_ALGORITHM_WSP;
 181        else
 182                plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
 183
 184        /* Processing individual RX queue config */
 185        for_each_child_of_node(rx_node, q_node) {
 186                if (queue >= plat->rx_queues_to_use)
 187                        break;
 188
 189                if (of_property_read_bool(q_node, "snps,dcb-algorithm"))
 190                        plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
 191                else if (of_property_read_bool(q_node, "snps,avb-algorithm"))
 192                        plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
 193                else
 194                        plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
 195
 196                if (of_property_read_u32(q_node, "snps,map-to-dma-channel",
 197                                         &plat->rx_queues_cfg[queue].chan))
 198                        plat->rx_queues_cfg[queue].chan = queue;
 199                /* TODO: Dynamic mapping to be included in the future */
 200
 201                if (of_property_read_u32(q_node, "snps,priority",
 202                                        &plat->rx_queues_cfg[queue].prio)) {
 203                        plat->rx_queues_cfg[queue].prio = 0;
 204                        plat->rx_queues_cfg[queue].use_prio = false;
 205                } else {
 206                        plat->rx_queues_cfg[queue].use_prio = true;
 207                }
 208
 209                /* RX queue specific packet type routing */
 210                if (of_property_read_bool(q_node, "snps,route-avcp"))
 211                        plat->rx_queues_cfg[queue].pkt_route = PACKET_AVCPQ;
 212                else if (of_property_read_bool(q_node, "snps,route-ptp"))
 213                        plat->rx_queues_cfg[queue].pkt_route = PACKET_PTPQ;
 214                else if (of_property_read_bool(q_node, "snps,route-dcbcp"))
 215                        plat->rx_queues_cfg[queue].pkt_route = PACKET_DCBCPQ;
 216                else if (of_property_read_bool(q_node, "snps,route-up"))
 217                        plat->rx_queues_cfg[queue].pkt_route = PACKET_UPQ;
 218                else if (of_property_read_bool(q_node, "snps,route-multi-broad"))
 219                        plat->rx_queues_cfg[queue].pkt_route = PACKET_MCBCQ;
 220                else
 221                        plat->rx_queues_cfg[queue].pkt_route = 0x0;
 222
 223                queue++;
 224        }
 225        if (queue != plat->rx_queues_to_use) {
 226                ret = -EINVAL;
 227                dev_err(&pdev->dev, "Not all RX queues were configured\n");
 228                goto out;
 229        }
 230
 231        /* Processing TX queues common config */
 232        if (of_property_read_u32(tx_node, "snps,tx-queues-to-use",
 233                                 &plat->tx_queues_to_use))
 234                plat->tx_queues_to_use = 1;
 235
 236        if (of_property_read_bool(tx_node, "snps,tx-sched-wrr"))
 237                plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR;
 238        else if (of_property_read_bool(tx_node, "snps,tx-sched-wfq"))
 239                plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WFQ;
 240        else if (of_property_read_bool(tx_node, "snps,tx-sched-dwrr"))
 241                plat->tx_sched_algorithm = MTL_TX_ALGORITHM_DWRR;
 242        else if (of_property_read_bool(tx_node, "snps,tx-sched-sp"))
 243                plat->tx_sched_algorithm = MTL_TX_ALGORITHM_SP;
 244        else
 245                plat->tx_sched_algorithm = MTL_TX_ALGORITHM_SP;
 246
 247        queue = 0;
 248
 249        /* Processing individual TX queue config */
 250        for_each_child_of_node(tx_node, q_node) {
 251                if (queue >= plat->tx_queues_to_use)
 252                        break;
 253
 254                if (of_property_read_u32(q_node, "snps,weight",
 255                                         &plat->tx_queues_cfg[queue].weight))
 256                        plat->tx_queues_cfg[queue].weight = 0x10 + queue;
 257
 258                if (of_property_read_bool(q_node, "snps,dcb-algorithm")) {
 259                        plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
 260                } else if (of_property_read_bool(q_node,
 261                                                 "snps,avb-algorithm")) {
 262                        plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
 263
 264                        /* Credit Base Shaper parameters used by AVB */
 265                        if (of_property_read_u32(q_node, "snps,send_slope",
 266                                &plat->tx_queues_cfg[queue].send_slope))
 267                                plat->tx_queues_cfg[queue].send_slope = 0x0;
 268                        if (of_property_read_u32(q_node, "snps,idle_slope",
 269                                &plat->tx_queues_cfg[queue].idle_slope))
 270                                plat->tx_queues_cfg[queue].idle_slope = 0x0;
 271                        if (of_property_read_u32(q_node, "snps,high_credit",
 272                                &plat->tx_queues_cfg[queue].high_credit))
 273                                plat->tx_queues_cfg[queue].high_credit = 0x0;
 274                        if (of_property_read_u32(q_node, "snps,low_credit",
 275                                &plat->tx_queues_cfg[queue].low_credit))
 276                                plat->tx_queues_cfg[queue].low_credit = 0x0;
 277                } else {
 278                        plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
 279                }
 280
 281                if (of_property_read_u32(q_node, "snps,priority",
 282                                        &plat->tx_queues_cfg[queue].prio)) {
 283                        plat->tx_queues_cfg[queue].prio = 0;
 284                        plat->tx_queues_cfg[queue].use_prio = false;
 285                } else {
 286                        plat->tx_queues_cfg[queue].use_prio = true;
 287                }
 288
 289                queue++;
 290        }
 291        if (queue != plat->tx_queues_to_use) {
 292                ret = -EINVAL;
 293                dev_err(&pdev->dev, "Not all TX queues were configured\n");
 294                goto out;
 295        }
 296
 297out:
 298        of_node_put(rx_node);
 299        of_node_put(tx_node);
 300        of_node_put(q_node);
 301
 302        return ret;
 303}
 304
 305/**
 306 * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources
 307 * @plat: driver data platform structure
 308 * @np: device tree node
 309 * @dev: device pointer
 310 * Description:
 311 * The mdio bus will be allocated in case of a phy transceiver is on board;
 312 * it will be NULL if the fixed-link is configured.
 313 * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated
 314 * in any case (for DSA, mdio must be registered even if fixed-link).
 315 * The table below sums the supported configurations:
 316 *      -------------------------------
 317 *      snps,phy-addr   |     Y
 318 *      -------------------------------
 319 *      phy-handle      |     Y
 320 *      -------------------------------
 321 *      fixed-link      |     N
 322 *      -------------------------------
 323 *      snps,dwmac-mdio |
 324 *        even if       |     Y
 325 *      fixed-link      |
 326 *      -------------------------------
 327 *
 328 * It returns 0 in case of success otherwise -ENODEV.
 329 */
 330static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
 331                         struct device_node *np, struct device *dev)
 332{
 333        bool mdio = !of_phy_is_fixed_link(np);
 334        static const struct of_device_id need_mdio_ids[] = {
 335                { .compatible = "snps,dwc-qos-ethernet-4.10" },
 336                {},
 337        };
 338
 339        if (of_match_node(need_mdio_ids, np)) {
 340                plat->mdio_node = of_get_child_by_name(np, "mdio");
 341        } else {
 342                /**
 343                 * If snps,dwmac-mdio is passed from DT, always register
 344                 * the MDIO
 345                 */
 346                for_each_child_of_node(np, plat->mdio_node) {
 347                        if (of_device_is_compatible(plat->mdio_node,
 348                                                    "snps,dwmac-mdio"))
 349                                break;
 350                }
 351        }
 352
 353        if (plat->mdio_node) {
 354                dev_dbg(dev, "Found MDIO subnode\n");
 355                mdio = true;
 356        }
 357
 358        if (mdio) {
 359                plat->mdio_bus_data =
 360                        devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data),
 361                                     GFP_KERNEL);
 362                if (!plat->mdio_bus_data)
 363                        return -ENOMEM;
 364
 365                plat->mdio_bus_data->needs_reset = true;
 366        }
 367
 368        return 0;
 369}
 370
 371/**
 372 * stmmac_of_get_mac_mode - retrieves the interface of the MAC
 373 * @np - device-tree node
 374 * Description:
 375 * Similar to `of_get_phy_mode()`, this function will retrieve (from
 376 * the device-tree) the interface mode on the MAC side. This assumes
 377 * that there is mode converter in-between the MAC & PHY
 378 * (e.g. GMII-to-RGMII).
 379 */
 380static int stmmac_of_get_mac_mode(struct device_node *np)
 381{
 382        const char *pm;
 383        int err, i;
 384
 385        err = of_property_read_string(np, "mac-mode", &pm);
 386        if (err < 0)
 387                return err;
 388
 389        for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
 390                if (!strcasecmp(pm, phy_modes(i)))
 391                        return i;
 392        }
 393
 394        return -ENODEV;
 395}
 396
 397/**
 398 * stmmac_probe_config_dt - parse device-tree driver parameters
 399 * @pdev: platform_device structure
 400 * @mac: MAC address to use
 401 * Description:
 402 * this function is to read the driver parameters from device-tree and
 403 * set some private fields that will be used by the main at runtime.
 404 */
 405struct plat_stmmacenet_data *
 406stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 407{
 408        struct device_node *np = pdev->dev.of_node;
 409        struct plat_stmmacenet_data *plat;
 410        struct stmmac_dma_cfg *dma_cfg;
 411        int rc;
 412
 413        plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
 414        if (!plat)
 415                return ERR_PTR(-ENOMEM);
 416
 417        rc = of_get_mac_address(np, mac);
 418        if (rc) {
 419                if (rc == -EPROBE_DEFER)
 420                        return ERR_PTR(rc);
 421
 422                eth_zero_addr(mac);
 423        }
 424
 425        plat->phy_interface = device_get_phy_mode(&pdev->dev);
 426        if (plat->phy_interface < 0)
 427                return ERR_PTR(plat->phy_interface);
 428
 429        plat->interface = stmmac_of_get_mac_mode(np);
 430        if (plat->interface < 0)
 431                plat->interface = plat->phy_interface;
 432
 433        /* Some wrapper drivers still rely on phy_node. Let's save it while
 434         * they are not converted to phylink. */
 435        plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
 436
 437        /* PHYLINK automatically parses the phy-handle property */
 438        plat->phylink_node = np;
 439
 440        /* Get max speed of operation from device tree */
 441        if (of_property_read_u32(np, "max-speed", &plat->max_speed))
 442                plat->max_speed = -1;
 443
 444        plat->bus_id = of_alias_get_id(np, "ethernet");
 445        if (plat->bus_id < 0)
 446                plat->bus_id = 0;
 447
 448        /* Default to phy auto-detection */
 449        plat->phy_addr = -1;
 450
 451        /* Default to get clk_csr from stmmac_clk_crs_set(),
 452         * or get clk_csr from device tree.
 453         */
 454        plat->clk_csr = -1;
 455        of_property_read_u32(np, "clk_csr", &plat->clk_csr);
 456
 457        /* "snps,phy-addr" is not a standard property. Mark it as deprecated
 458         * and warn of its use. Remove this when phy node support is added.
 459         */
 460        if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
 461                dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
 462
 463        /* To Configure PHY by using all device-tree supported properties */
 464        rc = stmmac_dt_phy(plat, np, &pdev->dev);
 465        if (rc)
 466                return ERR_PTR(rc);
 467
 468        of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
 469
 470        of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size);
 471
 472        plat->force_sf_dma_mode =
 473                of_property_read_bool(np, "snps,force_sf_dma_mode");
 474
 475        plat->en_tx_lpi_clockgating =
 476                of_property_read_bool(np, "snps,en-tx-lpi-clockgating");
 477
 478        /* Set the maxmtu to a default of JUMBO_LEN in case the
 479         * parameter is not present in the device tree.
 480         */
 481        plat->maxmtu = JUMBO_LEN;
 482
 483        /* Set default value for multicast hash bins */
 484        plat->multicast_filter_bins = HASH_TABLE_SIZE;
 485
 486        /* Set default value for unicast filter entries */
 487        plat->unicast_filter_entries = 1;
 488
 489        /*
 490         * Currently only the properties needed on SPEAr600
 491         * are provided. All other properties should be added
 492         * once needed on other platforms.
 493         */
 494        if (of_device_is_compatible(np, "st,spear600-gmac") ||
 495                of_device_is_compatible(np, "snps,dwmac-3.50a") ||
 496                of_device_is_compatible(np, "snps,dwmac-3.70a") ||
 497                of_device_is_compatible(np, "snps,dwmac")) {
 498                /* Note that the max-frame-size parameter as defined in the
 499                 * ePAPR v1.1 spec is defined as max-frame-size, it's
 500                 * actually used as the IEEE definition of MAC Client
 501                 * data, or MTU. The ePAPR specification is confusing as
 502                 * the definition is max-frame-size, but usage examples
 503                 * are clearly MTUs
 504                 */
 505                of_property_read_u32(np, "max-frame-size", &plat->maxmtu);
 506                of_property_read_u32(np, "snps,multicast-filter-bins",
 507                                     &plat->multicast_filter_bins);
 508                of_property_read_u32(np, "snps,perfect-filter-entries",
 509                                     &plat->unicast_filter_entries);
 510                plat->unicast_filter_entries = dwmac1000_validate_ucast_entries(
 511                                &pdev->dev, plat->unicast_filter_entries);
 512                plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
 513                                &pdev->dev, plat->multicast_filter_bins);
 514                plat->has_gmac = 1;
 515                plat->pmt = 1;
 516        }
 517
 518        if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
 519            of_device_is_compatible(np, "snps,dwmac-4.10a") ||
 520            of_device_is_compatible(np, "snps,dwmac-4.20a")) {
 521                plat->has_gmac4 = 1;
 522                plat->has_gmac = 0;
 523                plat->pmt = 1;
 524                plat->tso_en = of_property_read_bool(np, "snps,tso");
 525        }
 526
 527        if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
 528                of_device_is_compatible(np, "snps,dwmac-3.710")) {
 529                plat->enh_desc = 1;
 530                plat->bugged_jumbo = 1;
 531                plat->force_sf_dma_mode = 1;
 532        }
 533
 534        dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
 535                               GFP_KERNEL);
 536        if (!dma_cfg) {
 537                stmmac_remove_config_dt(pdev, plat);
 538                return ERR_PTR(-ENOMEM);
 539        }
 540        plat->dma_cfg = dma_cfg;
 541
 542        of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
 543        if (!dma_cfg->pbl)
 544                dma_cfg->pbl = DEFAULT_DMA_PBL;
 545        of_property_read_u32(np, "snps,txpbl", &dma_cfg->txpbl);
 546        of_property_read_u32(np, "snps,rxpbl", &dma_cfg->rxpbl);
 547        dma_cfg->pblx8 = !of_property_read_bool(np, "snps,no-pbl-x8");
 548
 549        dma_cfg->aal = of_property_read_bool(np, "snps,aal");
 550        dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
 551        dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
 552
 553        plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
 554        if (plat->force_thresh_dma_mode) {
 555                plat->force_sf_dma_mode = 0;
 556                dev_warn(&pdev->dev,
 557                         "force_sf_dma_mode is ignored if force_thresh_dma_mode is set.\n");
 558        }
 559
 560        of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
 561
 562        plat->axi = stmmac_axi_setup(pdev);
 563
 564        rc = stmmac_mtl_setup(pdev, plat);
 565        if (rc) {
 566                stmmac_remove_config_dt(pdev, plat);
 567                return ERR_PTR(rc);
 568        }
 569
 570        /* clock setup */
 571        if (!of_device_is_compatible(np, "snps,dwc-qos-ethernet-4.10")) {
 572                plat->stmmac_clk = devm_clk_get(&pdev->dev,
 573                                                STMMAC_RESOURCE_NAME);
 574                if (IS_ERR(plat->stmmac_clk)) {
 575                        dev_warn(&pdev->dev, "Cannot get CSR clock\n");
 576                        plat->stmmac_clk = NULL;
 577                }
 578                clk_prepare_enable(plat->stmmac_clk);
 579        }
 580
 581        plat->pclk = devm_clk_get(&pdev->dev, "pclk");
 582        if (IS_ERR(plat->pclk)) {
 583                if (PTR_ERR(plat->pclk) == -EPROBE_DEFER)
 584                        goto error_pclk_get;
 585
 586                plat->pclk = NULL;
 587        }
 588        clk_prepare_enable(plat->pclk);
 589
 590        /* Fall-back to main clock in case of no PTP ref is passed */
 591        plat->clk_ptp_ref = devm_clk_get(&pdev->dev, "ptp_ref");
 592        if (IS_ERR(plat->clk_ptp_ref)) {
 593                plat->clk_ptp_rate = clk_get_rate(plat->stmmac_clk);
 594                plat->clk_ptp_ref = NULL;
 595                dev_info(&pdev->dev, "PTP uses main clock\n");
 596        } else {
 597                plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
 598                dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate);
 599        }
 600
 601        plat->stmmac_rst = devm_reset_control_get(&pdev->dev,
 602                                                  STMMAC_RESOURCE_NAME);
 603        if (IS_ERR(plat->stmmac_rst)) {
 604                if (PTR_ERR(plat->stmmac_rst) == -EPROBE_DEFER)
 605                        goto error_hw_init;
 606
 607                dev_info(&pdev->dev, "no reset control found\n");
 608                plat->stmmac_rst = NULL;
 609        }
 610
 611        return plat;
 612
 613error_hw_init:
 614        clk_disable_unprepare(plat->pclk);
 615error_pclk_get:
 616        clk_disable_unprepare(plat->stmmac_clk);
 617
 618        return ERR_PTR(-EPROBE_DEFER);
 619}
 620
 621/**
 622 * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
 623 * @pdev: platform_device structure
 624 * @plat: driver data platform structure
 625 *
 626 * Release resources claimed by stmmac_probe_config_dt().
 627 */
 628void stmmac_remove_config_dt(struct platform_device *pdev,
 629                             struct plat_stmmacenet_data *plat)
 630{
 631        of_node_put(plat->phy_node);
 632        of_node_put(plat->mdio_node);
 633}
 634#else
 635struct plat_stmmacenet_data *
 636stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 637{
 638        return ERR_PTR(-EINVAL);
 639}
 640
 641void stmmac_remove_config_dt(struct platform_device *pdev,
 642                             struct plat_stmmacenet_data *plat)
 643{
 644}
 645#endif /* CONFIG_OF */
 646EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
 647EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
 648
 649int stmmac_get_platform_resources(struct platform_device *pdev,
 650                                  struct stmmac_resources *stmmac_res)
 651{
 652        memset(stmmac_res, 0, sizeof(*stmmac_res));
 653
 654        /* Get IRQ information early to have an ability to ask for deferred
 655         * probe if needed before we went too far with resource allocation.
 656         */
 657        stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
 658        if (stmmac_res->irq < 0) {
 659                if (stmmac_res->irq != -EPROBE_DEFER) {
 660                        dev_err(&pdev->dev,
 661                                "MAC IRQ configuration information not found\n");
 662                }
 663                return stmmac_res->irq;
 664        }
 665
 666        /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
 667         * The external wake up irq can be passed through the platform code
 668         * named as "eth_wake_irq"
 669         *
 670         * In case the wake up interrupt is not passed from the platform
 671         * so the driver will continue to use the mac irq (ndev->irq)
 672         */
 673        stmmac_res->wol_irq =
 674                platform_get_irq_byname_optional(pdev, "eth_wake_irq");
 675        if (stmmac_res->wol_irq < 0) {
 676                if (stmmac_res->wol_irq == -EPROBE_DEFER)
 677                        return -EPROBE_DEFER;
 678                dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n");
 679                stmmac_res->wol_irq = stmmac_res->irq;
 680        }
 681
 682        stmmac_res->lpi_irq =
 683                platform_get_irq_byname_optional(pdev, "eth_lpi");
 684        if (stmmac_res->lpi_irq < 0) {
 685                if (stmmac_res->lpi_irq == -EPROBE_DEFER)
 686                        return -EPROBE_DEFER;
 687                dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
 688        }
 689
 690        stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0);
 691
 692        return PTR_ERR_OR_ZERO(stmmac_res->addr);
 693}
 694EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
 695
 696/**
 697 * stmmac_pltfr_remove
 698 * @pdev: platform device pointer
 699 * Description: this function calls the main to free the net resources
 700 * and calls the platforms hook and release the resources (e.g. mem).
 701 */
 702int stmmac_pltfr_remove(struct platform_device *pdev)
 703{
 704        struct net_device *ndev = platform_get_drvdata(pdev);
 705        struct stmmac_priv *priv = netdev_priv(ndev);
 706        struct plat_stmmacenet_data *plat = priv->plat;
 707        int ret = stmmac_dvr_remove(&pdev->dev);
 708
 709        if (plat->exit)
 710                plat->exit(pdev, plat->bsp_priv);
 711
 712        stmmac_remove_config_dt(pdev, plat);
 713
 714        return ret;
 715}
 716EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
 717
 718/**
 719 * stmmac_pltfr_suspend
 720 * @dev: device pointer
 721 * Description: this function is invoked when suspend the driver and it direcly
 722 * call the main suspend function and then, if required, on some platform, it
 723 * can call an exit helper.
 724 */
 725static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
 726{
 727        int ret;
 728        struct net_device *ndev = dev_get_drvdata(dev);
 729        struct stmmac_priv *priv = netdev_priv(ndev);
 730        struct platform_device *pdev = to_platform_device(dev);
 731
 732        ret = stmmac_suspend(dev);
 733        if (priv->plat->exit)
 734                priv->plat->exit(pdev, priv->plat->bsp_priv);
 735
 736        return ret;
 737}
 738
 739/**
 740 * stmmac_pltfr_resume
 741 * @dev: device pointer
 742 * Description: this function is invoked when resume the driver before calling
 743 * the main resume function, on some platforms, it can call own init helper
 744 * if required.
 745 */
 746static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
 747{
 748        struct net_device *ndev = dev_get_drvdata(dev);
 749        struct stmmac_priv *priv = netdev_priv(ndev);
 750        struct platform_device *pdev = to_platform_device(dev);
 751
 752        if (priv->plat->init)
 753                priv->plat->init(pdev, priv->plat->bsp_priv);
 754
 755        return stmmac_resume(dev);
 756}
 757
 758static int __maybe_unused stmmac_runtime_suspend(struct device *dev)
 759{
 760        struct net_device *ndev = dev_get_drvdata(dev);
 761        struct stmmac_priv *priv = netdev_priv(ndev);
 762
 763        stmmac_bus_clks_config(priv, false);
 764
 765        return 0;
 766}
 767
 768static int __maybe_unused stmmac_runtime_resume(struct device *dev)
 769{
 770        struct net_device *ndev = dev_get_drvdata(dev);
 771        struct stmmac_priv *priv = netdev_priv(ndev);
 772
 773        return stmmac_bus_clks_config(priv, true);
 774}
 775
 776const struct dev_pm_ops stmmac_pltfr_pm_ops = {
 777        SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume)
 778        SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
 779};
 780EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
 781
 782MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
 783MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
 784MODULE_LICENSE("GPL");
 785