linux/drivers/net/ethernet/freescale/fman/mac.c
<<
>>
Prefs
   1/* Copyright 2008-2015 Freescale Semiconductor, Inc.
   2 *
   3 * Redistribution and use in source and binary forms, with or without
   4 * modification, are permitted provided that the following conditions are met:
   5 *     * Redistributions of source code must retain the above copyright
   6 *       notice, this list of conditions and the following disclaimer.
   7 *     * Redistributions in binary form must reproduce the above copyright
   8 *       notice, this list of conditions and the following disclaimer in the
   9 *       documentation and/or other materials provided with the distribution.
  10 *     * Neither the name of Freescale Semiconductor nor the
  11 *       names of its contributors may be used to endorse or promote products
  12 *       derived from this software without specific prior written permission.
  13 *
  14 *
  15 * ALTERNATIVELY, this software may be distributed under the terms of the
  16 * GNU General Public License ("GPL") as published by the Free Software
  17 * Foundation, either version 2 of that License or (at your option) any
  18 * later version.
  19 *
  20 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
  21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
  24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30 */
  31
  32#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  33
  34#include <linux/init.h>
  35#include <linux/module.h>
  36#include <linux/of_address.h>
  37#include <linux/of_platform.h>
  38#include <linux/of_net.h>
  39#include <linux/of_mdio.h>
  40#include <linux/device.h>
  41#include <linux/phy.h>
  42#include <linux/netdevice.h>
  43#include <linux/phy_fixed.h>
  44#include <linux/etherdevice.h>
  45#include <linux/libfdt_env.h>
  46
  47#include "mac.h"
  48#include "fman_mac.h"
  49#include "fman_dtsec.h"
  50#include "fman_tgec.h"
  51#include "fman_memac.h"
  52
  53MODULE_LICENSE("Dual BSD/GPL");
  54MODULE_DESCRIPTION("FSL FMan MAC API based driver");
  55
  56struct mac_priv_s {
  57        struct device                   *dev;
  58        void __iomem                    *vaddr;
  59        u8                              cell_index;
  60        struct fman                     *fman;
  61        struct device_node              *internal_phy_node;
  62        /* List of multicast addresses */
  63        struct list_head                mc_addr_list;
  64        struct platform_device          *eth_dev;
  65        struct fixed_phy_status         *fixed_link;
  66        u16                             speed;
  67        u16                             max_speed;
  68
  69        int (*enable)(struct fman_mac *mac_dev, enum comm_mode mode);
  70        int (*disable)(struct fman_mac *mac_dev, enum comm_mode mode);
  71};
  72
  73struct mac_address {
  74        u8 addr[ETH_ALEN];
  75        struct list_head list;
  76};
  77
  78static void mac_exception(void *handle, enum fman_mac_exceptions ex)
  79{
  80        struct mac_device       *mac_dev;
  81        struct mac_priv_s       *priv;
  82
  83        mac_dev = handle;
  84        priv = mac_dev->priv;
  85
  86        if (ex == FM_MAC_EX_10G_RX_FIFO_OVFL) {
  87                /* don't flag RX FIFO after the first */
  88                mac_dev->set_exception(mac_dev->fman_mac,
  89                                       FM_MAC_EX_10G_RX_FIFO_OVFL, false);
  90                dev_err(priv->dev, "10G MAC got RX FIFO Error = %x\n", ex);
  91        }
  92
  93        dev_dbg(priv->dev, "%s:%s() -> %d\n", KBUILD_BASENAME ".c",
  94                __func__, ex);
  95}
  96
  97static void set_fman_mac_params(struct mac_device *mac_dev,
  98                                struct fman_mac_params *params)
  99{
 100        struct mac_priv_s *priv = mac_dev->priv;
 101
 102        params->base_addr = (typeof(params->base_addr))
 103                devm_ioremap(priv->dev, mac_dev->res->start,
 104                             resource_size(mac_dev->res));
 105        memcpy(&params->addr, mac_dev->addr, sizeof(mac_dev->addr));
 106        params->max_speed       = priv->max_speed;
 107        params->phy_if          = mac_dev->phy_if;
 108        params->basex_if        = false;
 109        params->mac_id          = priv->cell_index;
 110        params->fm              = (void *)priv->fman;
 111        params->exception_cb    = mac_exception;
 112        params->event_cb        = mac_exception;
 113        params->dev_id          = mac_dev;
 114        params->internal_phy_node = priv->internal_phy_node;
 115}
 116
 117static int tgec_initialization(struct mac_device *mac_dev)
 118{
 119        int err;
 120        struct mac_priv_s       *priv;
 121        struct fman_mac_params  params;
 122        u32                     version;
 123
 124        priv = mac_dev->priv;
 125
 126        set_fman_mac_params(mac_dev, &params);
 127
 128        mac_dev->fman_mac = tgec_config(&params);
 129        if (!mac_dev->fman_mac) {
 130                err = -EINVAL;
 131                goto _return;
 132        }
 133
 134        err = tgec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
 135        if (err < 0)
 136                goto _return_fm_mac_free;
 137
 138        err = tgec_init(mac_dev->fman_mac);
 139        if (err < 0)
 140                goto _return_fm_mac_free;
 141
 142        /* For 10G MAC, disable Tx ECC exception */
 143        err = mac_dev->set_exception(mac_dev->fman_mac,
 144                                     FM_MAC_EX_10G_TX_ECC_ER, false);
 145        if (err < 0)
 146                goto _return_fm_mac_free;
 147
 148        err = tgec_get_version(mac_dev->fman_mac, &version);
 149        if (err < 0)
 150                goto _return_fm_mac_free;
 151
 152        dev_info(priv->dev, "FMan XGEC version: 0x%08x\n", version);
 153
 154        goto _return;
 155
 156_return_fm_mac_free:
 157        tgec_free(mac_dev->fman_mac);
 158
 159_return:
 160        return err;
 161}
 162
 163static int dtsec_initialization(struct mac_device *mac_dev)
 164{
 165        int                     err;
 166        struct mac_priv_s       *priv;
 167        struct fman_mac_params  params;
 168        u32                     version;
 169
 170        priv = mac_dev->priv;
 171
 172        set_fman_mac_params(mac_dev, &params);
 173
 174        mac_dev->fman_mac = dtsec_config(&params);
 175        if (!mac_dev->fman_mac) {
 176                err = -EINVAL;
 177                goto _return;
 178        }
 179
 180        err = dtsec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
 181        if (err < 0)
 182                goto _return_fm_mac_free;
 183
 184        err = dtsec_cfg_pad_and_crc(mac_dev->fman_mac, true);
 185        if (err < 0)
 186                goto _return_fm_mac_free;
 187
 188        err = dtsec_init(mac_dev->fman_mac);
 189        if (err < 0)
 190                goto _return_fm_mac_free;
 191
 192        /* For 1G MAC, disable by default the MIB counters overflow interrupt */
 193        err = mac_dev->set_exception(mac_dev->fman_mac,
 194                                     FM_MAC_EX_1G_RX_MIB_CNT_OVFL, false);
 195        if (err < 0)
 196                goto _return_fm_mac_free;
 197
 198        err = dtsec_get_version(mac_dev->fman_mac, &version);
 199        if (err < 0)
 200                goto _return_fm_mac_free;
 201
 202        dev_info(priv->dev, "FMan dTSEC version: 0x%08x\n", version);
 203
 204        goto _return;
 205
 206_return_fm_mac_free:
 207        dtsec_free(mac_dev->fman_mac);
 208
 209_return:
 210        return err;
 211}
 212
 213static int memac_initialization(struct mac_device *mac_dev)
 214{
 215        int                      err;
 216        struct mac_priv_s       *priv;
 217        struct fman_mac_params   params;
 218
 219        priv = mac_dev->priv;
 220
 221        set_fman_mac_params(mac_dev, &params);
 222
 223        if (priv->max_speed == SPEED_10000)
 224                params.phy_if = PHY_INTERFACE_MODE_XGMII;
 225
 226        mac_dev->fman_mac = memac_config(&params);
 227        if (!mac_dev->fman_mac) {
 228                err = -EINVAL;
 229                goto _return;
 230        }
 231
 232        err = memac_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
 233        if (err < 0)
 234                goto _return_fm_mac_free;
 235
 236        err = memac_cfg_reset_on_init(mac_dev->fman_mac, true);
 237        if (err < 0)
 238                goto _return_fm_mac_free;
 239
 240        err = memac_cfg_fixed_link(mac_dev->fman_mac, priv->fixed_link);
 241        if (err < 0)
 242                goto _return_fm_mac_free;
 243
 244        err = memac_init(mac_dev->fman_mac);
 245        if (err < 0)
 246                goto _return_fm_mac_free;
 247
 248        dev_info(priv->dev, "FMan MEMAC\n");
 249
 250        goto _return;
 251
 252_return_fm_mac_free:
 253        memac_free(mac_dev->fman_mac);
 254
 255_return:
 256        return err;
 257}
 258
 259static int start(struct mac_device *mac_dev)
 260{
 261        int      err;
 262        struct phy_device *phy_dev = mac_dev->phy_dev;
 263        struct mac_priv_s *priv = mac_dev->priv;
 264
 265        err = priv->enable(mac_dev->fman_mac, COMM_MODE_RX_AND_TX);
 266        if (!err && phy_dev)
 267                phy_start(phy_dev);
 268
 269        return err;
 270}
 271
 272static int stop(struct mac_device *mac_dev)
 273{
 274        struct mac_priv_s *priv = mac_dev->priv;
 275
 276        if (mac_dev->phy_dev)
 277                phy_stop(mac_dev->phy_dev);
 278
 279        return priv->disable(mac_dev->fman_mac, COMM_MODE_RX_AND_TX);
 280}
 281
 282static int set_multi(struct net_device *net_dev, struct mac_device *mac_dev)
 283{
 284        struct mac_priv_s       *priv;
 285        struct mac_address      *old_addr, *tmp;
 286        struct netdev_hw_addr   *ha;
 287        int                     err;
 288        enet_addr_t             *addr;
 289
 290        priv = mac_dev->priv;
 291
 292        /* Clear previous address list */
 293        list_for_each_entry_safe(old_addr, tmp, &priv->mc_addr_list, list) {
 294                addr = (enet_addr_t *)old_addr->addr;
 295                err = mac_dev->remove_hash_mac_addr(mac_dev->fman_mac, addr);
 296                if (err < 0)
 297                        return err;
 298
 299                list_del(&old_addr->list);
 300                kfree(old_addr);
 301        }
 302
 303        /* Add all the addresses from the new list */
 304        netdev_for_each_mc_addr(ha, net_dev) {
 305                addr = (enet_addr_t *)ha->addr;
 306                err = mac_dev->add_hash_mac_addr(mac_dev->fman_mac, addr);
 307                if (err < 0)
 308                        return err;
 309
 310                tmp = kmalloc(sizeof(*tmp), GFP_ATOMIC);
 311                if (!tmp)
 312                        return -ENOMEM;
 313
 314                ether_addr_copy(tmp->addr, ha->addr);
 315                list_add(&tmp->list, &priv->mc_addr_list);
 316        }
 317        return 0;
 318}
 319
 320/**
 321 * fman_set_mac_active_pause
 322 * @mac_dev:    A pointer to the MAC device
 323 * @rx:         Pause frame setting for RX
 324 * @tx:         Pause frame setting for TX
 325 *
 326 * Set the MAC RX/TX PAUSE frames settings
 327 *
 328 * Avoid redundant calls to FMD, if the MAC driver already contains the desired
 329 * active PAUSE settings. Otherwise, the new active settings should be reflected
 330 * in FMan.
 331 *
 332 * Return: 0 on success; Error code otherwise.
 333 */
 334int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
 335{
 336        struct fman_mac *fman_mac = mac_dev->fman_mac;
 337        int err = 0;
 338
 339        if (rx != mac_dev->rx_pause_active) {
 340                err = mac_dev->set_rx_pause(fman_mac, rx);
 341                if (likely(err == 0))
 342                        mac_dev->rx_pause_active = rx;
 343        }
 344
 345        if (tx != mac_dev->tx_pause_active) {
 346                u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE :
 347                                         FSL_FM_PAUSE_TIME_DISABLE);
 348
 349                err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0);
 350
 351                if (likely(err == 0))
 352                        mac_dev->tx_pause_active = tx;
 353        }
 354
 355        return err;
 356}
 357EXPORT_SYMBOL(fman_set_mac_active_pause);
 358
 359/**
 360 * fman_get_pause_cfg
 361 * @mac_dev:    A pointer to the MAC device
 362 * @rx:         Return value for RX setting
 363 * @tx:         Return value for TX setting
 364 *
 365 * Determine the MAC RX/TX PAUSE frames settings based on PHY
 366 * autonegotiation or values set by eththool.
 367 *
 368 * Return: Pointer to FMan device.
 369 */
 370void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
 371                        bool *tx_pause)
 372{
 373        struct phy_device *phy_dev = mac_dev->phy_dev;
 374        u16 lcl_adv, rmt_adv;
 375        u8 flowctrl;
 376
 377        *rx_pause = *tx_pause = false;
 378
 379        if (!phy_dev->duplex)
 380                return;
 381
 382        /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
 383         * are those set by ethtool.
 384         */
 385        if (!mac_dev->autoneg_pause) {
 386                *rx_pause = mac_dev->rx_pause_req;
 387                *tx_pause = mac_dev->tx_pause_req;
 388                return;
 389        }
 390
 391        /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
 392         * settings depend on the result of the link negotiation.
 393         */
 394
 395        /* get local capabilities */
 396        lcl_adv = 0;
 397        if (phy_dev->advertising & ADVERTISED_Pause)
 398                lcl_adv |= ADVERTISE_PAUSE_CAP;
 399        if (phy_dev->advertising & ADVERTISED_Asym_Pause)
 400                lcl_adv |= ADVERTISE_PAUSE_ASYM;
 401
 402        /* get link partner capabilities */
 403        rmt_adv = 0;
 404        if (phy_dev->pause)
 405                rmt_adv |= LPA_PAUSE_CAP;
 406        if (phy_dev->asym_pause)
 407                rmt_adv |= LPA_PAUSE_ASYM;
 408
 409        /* Calculate TX/RX settings based on local and peer advertised
 410         * symmetric/asymmetric PAUSE capabilities.
 411         */
 412        flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 413        if (flowctrl & FLOW_CTRL_RX)
 414                *rx_pause = true;
 415        if (flowctrl & FLOW_CTRL_TX)
 416                *tx_pause = true;
 417}
 418EXPORT_SYMBOL(fman_get_pause_cfg);
 419
 420static void adjust_link_void(struct mac_device *mac_dev)
 421{
 422}
 423
 424static void adjust_link_dtsec(struct mac_device *mac_dev)
 425{
 426        struct phy_device *phy_dev = mac_dev->phy_dev;
 427        struct fman_mac *fman_mac;
 428        bool rx_pause, tx_pause;
 429        int err;
 430
 431        fman_mac = mac_dev->fman_mac;
 432        if (!phy_dev->link) {
 433                dtsec_restart_autoneg(fman_mac);
 434
 435                return;
 436        }
 437
 438        dtsec_adjust_link(fman_mac, phy_dev->speed);
 439        fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
 440        err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
 441        if (err < 0)
 442                dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
 443                        err);
 444}
 445
 446static void adjust_link_memac(struct mac_device *mac_dev)
 447{
 448        struct phy_device *phy_dev = mac_dev->phy_dev;
 449        struct fman_mac *fman_mac;
 450        bool rx_pause, tx_pause;
 451        int err;
 452
 453        fman_mac = mac_dev->fman_mac;
 454        memac_adjust_link(fman_mac, phy_dev->speed);
 455
 456        fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
 457        err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
 458        if (err < 0)
 459                dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
 460                        err);
 461}
 462
 463static void setup_dtsec(struct mac_device *mac_dev)
 464{
 465        mac_dev->init                   = dtsec_initialization;
 466        mac_dev->set_promisc            = dtsec_set_promiscuous;
 467        mac_dev->change_addr            = dtsec_modify_mac_address;
 468        mac_dev->add_hash_mac_addr      = dtsec_add_hash_mac_address;
 469        mac_dev->remove_hash_mac_addr   = dtsec_del_hash_mac_address;
 470        mac_dev->set_tx_pause           = dtsec_set_tx_pause_frames;
 471        mac_dev->set_rx_pause           = dtsec_accept_rx_pause_frames;
 472        mac_dev->set_exception          = dtsec_set_exception;
 473        mac_dev->set_allmulti           = dtsec_set_allmulti;
 474        mac_dev->set_multi              = set_multi;
 475        mac_dev->start                  = start;
 476        mac_dev->stop                   = stop;
 477        mac_dev->adjust_link            = adjust_link_dtsec;
 478        mac_dev->priv->enable           = dtsec_enable;
 479        mac_dev->priv->disable          = dtsec_disable;
 480}
 481
 482static void setup_tgec(struct mac_device *mac_dev)
 483{
 484        mac_dev->init                   = tgec_initialization;
 485        mac_dev->set_promisc            = tgec_set_promiscuous;
 486        mac_dev->change_addr            = tgec_modify_mac_address;
 487        mac_dev->add_hash_mac_addr      = tgec_add_hash_mac_address;
 488        mac_dev->remove_hash_mac_addr   = tgec_del_hash_mac_address;
 489        mac_dev->set_tx_pause           = tgec_set_tx_pause_frames;
 490        mac_dev->set_rx_pause           = tgec_accept_rx_pause_frames;
 491        mac_dev->set_exception          = tgec_set_exception;
 492        mac_dev->set_allmulti           = tgec_set_allmulti;
 493        mac_dev->set_multi              = set_multi;
 494        mac_dev->start                  = start;
 495        mac_dev->stop                   = stop;
 496        mac_dev->adjust_link            = adjust_link_void;
 497        mac_dev->priv->enable           = tgec_enable;
 498        mac_dev->priv->disable          = tgec_disable;
 499}
 500
 501static void setup_memac(struct mac_device *mac_dev)
 502{
 503        mac_dev->init                   = memac_initialization;
 504        mac_dev->set_promisc            = memac_set_promiscuous;
 505        mac_dev->change_addr            = memac_modify_mac_address;
 506        mac_dev->add_hash_mac_addr      = memac_add_hash_mac_address;
 507        mac_dev->remove_hash_mac_addr   = memac_del_hash_mac_address;
 508        mac_dev->set_tx_pause           = memac_set_tx_pause_frames;
 509        mac_dev->set_rx_pause           = memac_accept_rx_pause_frames;
 510        mac_dev->set_exception          = memac_set_exception;
 511        mac_dev->set_allmulti           = memac_set_allmulti;
 512        mac_dev->set_multi              = set_multi;
 513        mac_dev->start                  = start;
 514        mac_dev->stop                   = stop;
 515        mac_dev->adjust_link            = adjust_link_memac;
 516        mac_dev->priv->enable           = memac_enable;
 517        mac_dev->priv->disable          = memac_disable;
 518}
 519
 520#define DTSEC_SUPPORTED \
 521        (SUPPORTED_10baseT_Half \
 522        | SUPPORTED_10baseT_Full \
 523        | SUPPORTED_100baseT_Half \
 524        | SUPPORTED_100baseT_Full \
 525        | SUPPORTED_Autoneg \
 526        | SUPPORTED_Pause \
 527        | SUPPORTED_Asym_Pause \
 528        | SUPPORTED_MII)
 529
 530static DEFINE_MUTEX(eth_lock);
 531
 532static const u16 phy2speed[] = {
 533        [PHY_INTERFACE_MODE_MII]                = SPEED_100,
 534        [PHY_INTERFACE_MODE_GMII]               = SPEED_1000,
 535        [PHY_INTERFACE_MODE_SGMII]              = SPEED_1000,
 536        [PHY_INTERFACE_MODE_TBI]                = SPEED_1000,
 537        [PHY_INTERFACE_MODE_RMII]               = SPEED_100,
 538        [PHY_INTERFACE_MODE_RGMII]              = SPEED_1000,
 539        [PHY_INTERFACE_MODE_RGMII_ID]           = SPEED_1000,
 540        [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
 541        [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
 542        [PHY_INTERFACE_MODE_RTBI]               = SPEED_1000,
 543        [PHY_INTERFACE_MODE_QSGMII]             = SPEED_1000,
 544        [PHY_INTERFACE_MODE_XGMII]              = SPEED_10000
 545};
 546
 547static struct platform_device *dpaa_eth_add_device(int fman_id,
 548                                                   struct mac_device *mac_dev)
 549{
 550        struct platform_device *pdev;
 551        struct dpaa_eth_data data;
 552        struct mac_priv_s       *priv;
 553        static int dpaa_eth_dev_cnt;
 554        int ret;
 555
 556        priv = mac_dev->priv;
 557
 558        data.mac_dev = mac_dev;
 559        data.mac_hw_id = priv->cell_index;
 560        data.fman_hw_id = fman_id;
 561
 562        mutex_lock(&eth_lock);
 563        pdev = platform_device_alloc("dpaa-ethernet", dpaa_eth_dev_cnt);
 564        if (!pdev) {
 565                ret = -ENOMEM;
 566                goto no_mem;
 567        }
 568
 569        pdev->dev.parent = priv->dev;
 570
 571        ret = platform_device_add_data(pdev, &data, sizeof(data));
 572        if (ret)
 573                goto err;
 574
 575        ret = platform_device_add(pdev);
 576        if (ret)
 577                goto err;
 578
 579        dpaa_eth_dev_cnt++;
 580        mutex_unlock(&eth_lock);
 581
 582        return pdev;
 583
 584err:
 585        platform_device_put(pdev);
 586no_mem:
 587        mutex_unlock(&eth_lock);
 588
 589        return ERR_PTR(ret);
 590}
 591
 592static const struct of_device_id mac_match[] = {
 593        { .compatible   = "fsl,fman-dtsec" },
 594        { .compatible   = "fsl,fman-xgec" },
 595        { .compatible   = "fsl,fman-memac" },
 596        {}
 597};
 598MODULE_DEVICE_TABLE(of, mac_match);
 599
 600static int mac_probe(struct platform_device *_of_dev)
 601{
 602        int                      err, i, nph;
 603        struct device           *dev;
 604        struct device_node      *mac_node, *dev_node;
 605        struct mac_device       *mac_dev;
 606        struct platform_device  *of_dev;
 607        struct resource          res;
 608        struct mac_priv_s       *priv;
 609        const u8                *mac_addr;
 610        u32                      val;
 611        u8                      fman_id;
 612        int                     phy_if;
 613
 614        dev = &_of_dev->dev;
 615        mac_node = dev->of_node;
 616
 617        mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
 618        if (!mac_dev) {
 619                err = -ENOMEM;
 620                goto _return;
 621        }
 622        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 623        if (!priv) {
 624                err = -ENOMEM;
 625                goto _return;
 626        }
 627
 628        /* Save private information */
 629        mac_dev->priv = priv;
 630        priv->dev = dev;
 631
 632        if (of_device_is_compatible(mac_node, "fsl,fman-dtsec")) {
 633                setup_dtsec(mac_dev);
 634                priv->internal_phy_node = of_parse_phandle(mac_node,
 635                                                          "tbi-handle", 0);
 636        } else if (of_device_is_compatible(mac_node, "fsl,fman-xgec")) {
 637                setup_tgec(mac_dev);
 638        } else if (of_device_is_compatible(mac_node, "fsl,fman-memac")) {
 639                setup_memac(mac_dev);
 640                priv->internal_phy_node = of_parse_phandle(mac_node,
 641                                                          "pcsphy-handle", 0);
 642        } else {
 643                dev_err(dev, "MAC node (%pOF) contains unsupported MAC\n",
 644                        mac_node);
 645                err = -EINVAL;
 646                goto _return;
 647        }
 648
 649        INIT_LIST_HEAD(&priv->mc_addr_list);
 650
 651        /* Get the FM node */
 652        dev_node = of_get_parent(mac_node);
 653        if (!dev_node) {
 654                dev_err(dev, "of_get_parent(%pOF) failed\n",
 655                        mac_node);
 656                err = -EINVAL;
 657                goto _return_of_get_parent;
 658        }
 659
 660        of_dev = of_find_device_by_node(dev_node);
 661        if (!of_dev) {
 662                dev_err(dev, "of_find_device_by_node(%pOF) failed\n", dev_node);
 663                err = -EINVAL;
 664                goto _return_of_node_put;
 665        }
 666
 667        /* Get the FMan cell-index */
 668        err = of_property_read_u32(dev_node, "cell-index", &val);
 669        if (err) {
 670                dev_err(dev, "failed to read cell-index for %pOF\n", dev_node);
 671                err = -EINVAL;
 672                goto _return_of_node_put;
 673        }
 674        /* cell-index 0 => FMan id 1 */
 675        fman_id = (u8)(val + 1);
 676
 677        priv->fman = fman_bind(&of_dev->dev);
 678        if (!priv->fman) {
 679                dev_err(dev, "fman_bind(%pOF) failed\n", dev_node);
 680                err = -ENODEV;
 681                goto _return_of_node_put;
 682        }
 683
 684        of_node_put(dev_node);
 685
 686        /* Get the address of the memory mapped registers */
 687        err = of_address_to_resource(mac_node, 0, &res);
 688        if (err < 0) {
 689                dev_err(dev, "of_address_to_resource(%pOF) = %d\n",
 690                        mac_node, err);
 691                goto _return_of_get_parent;
 692        }
 693
 694        mac_dev->res = __devm_request_region(dev,
 695                                             fman_get_mem_region(priv->fman),
 696                                             res.start, res.end + 1 - res.start,
 697                                             "mac");
 698        if (!mac_dev->res) {
 699                dev_err(dev, "__devm_request_mem_region(mac) failed\n");
 700                err = -EBUSY;
 701                goto _return_of_get_parent;
 702        }
 703
 704        priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
 705                                   mac_dev->res->end + 1 - mac_dev->res->start);
 706        if (!priv->vaddr) {
 707                dev_err(dev, "devm_ioremap() failed\n");
 708                err = -EIO;
 709                goto _return_of_get_parent;
 710        }
 711
 712        if (!of_device_is_available(mac_node)) {
 713                err = -ENODEV;
 714                goto _return_of_get_parent;
 715        }
 716
 717        /* Get the cell-index */
 718        err = of_property_read_u32(mac_node, "cell-index", &val);
 719        if (err) {
 720                dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
 721                err = -EINVAL;
 722                goto _return_of_get_parent;
 723        }
 724        priv->cell_index = (u8)val;
 725
 726        /* Get the MAC address */
 727        mac_addr = of_get_mac_address(mac_node);
 728        if (!mac_addr) {
 729                dev_err(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
 730                err = -EINVAL;
 731                goto _return_of_get_parent;
 732        }
 733        memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
 734
 735        /* Get the port handles */
 736        nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
 737        if (unlikely(nph < 0)) {
 738                dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
 739                        mac_node);
 740                err = nph;
 741                goto _return_of_get_parent;
 742        }
 743
 744        if (nph != ARRAY_SIZE(mac_dev->port)) {
 745                dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
 746                        mac_node);
 747                err = -EINVAL;
 748                goto _return_of_get_parent;
 749        }
 750
 751        for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
 752                /* Find the port node */
 753                dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
 754                if (!dev_node) {
 755                        dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n",
 756                                mac_node);
 757                        err = -EINVAL;
 758                        goto _return_of_node_put;
 759                }
 760
 761                of_dev = of_find_device_by_node(dev_node);
 762                if (!of_dev) {
 763                        dev_err(dev, "of_find_device_by_node(%pOF) failed\n",
 764                                dev_node);
 765                        err = -EINVAL;
 766                        goto _return_of_node_put;
 767                }
 768
 769                mac_dev->port[i] = fman_port_bind(&of_dev->dev);
 770                if (!mac_dev->port[i]) {
 771                        dev_err(dev, "dev_get_drvdata(%pOF) failed\n",
 772                                dev_node);
 773                        err = -EINVAL;
 774                        goto _return_of_node_put;
 775                }
 776                of_node_put(dev_node);
 777        }
 778
 779        /* Get the PHY connection type */
 780        phy_if = of_get_phy_mode(mac_node);
 781        if (phy_if < 0) {
 782                dev_warn(dev,
 783                         "of_get_phy_mode() for %pOF failed. Defaulting to SGMII\n",
 784                         mac_node);
 785                phy_if = PHY_INTERFACE_MODE_SGMII;
 786        }
 787        mac_dev->phy_if = phy_if;
 788
 789        priv->speed             = phy2speed[mac_dev->phy_if];
 790        priv->max_speed         = priv->speed;
 791        mac_dev->if_support     = DTSEC_SUPPORTED;
 792        /* We don't support half-duplex in SGMII mode */
 793        if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
 794                mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
 795                                        SUPPORTED_100baseT_Half);
 796
 797        /* Gigabit support (no half-duplex) */
 798        if (priv->max_speed == 1000)
 799                mac_dev->if_support |= SUPPORTED_1000baseT_Full;
 800
 801        /* The 10G interface only supports one mode */
 802        if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
 803                mac_dev->if_support = SUPPORTED_10000baseT_Full;
 804
 805        /* Get the rest of the PHY information */
 806        mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
 807        if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
 808                struct phy_device *phy;
 809
 810                err = of_phy_register_fixed_link(mac_node);
 811                if (err)
 812                        goto _return_of_get_parent;
 813
 814                priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
 815                                           GFP_KERNEL);
 816                if (!priv->fixed_link) {
 817                        err = -ENOMEM;
 818                        goto _return_of_get_parent;
 819                }
 820
 821                mac_dev->phy_node = of_node_get(mac_node);
 822                phy = of_phy_find_device(mac_dev->phy_node);
 823                if (!phy) {
 824                        err = -EINVAL;
 825                        of_node_put(mac_dev->phy_node);
 826                        goto _return_of_get_parent;
 827                }
 828
 829                priv->fixed_link->link = phy->link;
 830                priv->fixed_link->speed = phy->speed;
 831                priv->fixed_link->duplex = phy->duplex;
 832                priv->fixed_link->pause = phy->pause;
 833                priv->fixed_link->asym_pause = phy->asym_pause;
 834
 835                put_device(&phy->mdio.dev);
 836        }
 837
 838        err = mac_dev->init(mac_dev);
 839        if (err < 0) {
 840                dev_err(dev, "mac_dev->init() = %d\n", err);
 841                of_node_put(mac_dev->phy_node);
 842                goto _return_of_get_parent;
 843        }
 844
 845        /* pause frame autonegotiation enabled */
 846        mac_dev->autoneg_pause = true;
 847
 848        /* By intializing the values to false, force FMD to enable PAUSE frames
 849         * on RX and TX
 850         */
 851        mac_dev->rx_pause_req = true;
 852        mac_dev->tx_pause_req = true;
 853        mac_dev->rx_pause_active = false;
 854        mac_dev->tx_pause_active = false;
 855        err = fman_set_mac_active_pause(mac_dev, true, true);
 856        if (err < 0)
 857                dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
 858
 859        dev_info(dev, "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
 860                 mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
 861                 mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
 862
 863        priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
 864        if (IS_ERR(priv->eth_dev)) {
 865                dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
 866                        priv->cell_index);
 867                priv->eth_dev = NULL;
 868        }
 869
 870        goto _return;
 871
 872_return_of_node_put:
 873        of_node_put(dev_node);
 874_return_of_get_parent:
 875        kfree(priv->fixed_link);
 876_return:
 877        return err;
 878}
 879
 880static struct platform_driver mac_driver = {
 881        .driver = {
 882                .name           = KBUILD_MODNAME,
 883                .of_match_table = mac_match,
 884        },
 885        .probe          = mac_probe,
 886};
 887
 888builtin_platform_driver(mac_driver);
 889