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_multi              = set_multi;
 474        mac_dev->start                  = start;
 475        mac_dev->stop                   = stop;
 476        mac_dev->adjust_link            = adjust_link_dtsec;
 477        mac_dev->priv->enable           = dtsec_enable;
 478        mac_dev->priv->disable          = dtsec_disable;
 479}
 480
 481static void setup_tgec(struct mac_device *mac_dev)
 482{
 483        mac_dev->init                   = tgec_initialization;
 484        mac_dev->set_promisc            = tgec_set_promiscuous;
 485        mac_dev->change_addr            = tgec_modify_mac_address;
 486        mac_dev->add_hash_mac_addr      = tgec_add_hash_mac_address;
 487        mac_dev->remove_hash_mac_addr   = tgec_del_hash_mac_address;
 488        mac_dev->set_tx_pause           = tgec_set_tx_pause_frames;
 489        mac_dev->set_rx_pause           = tgec_accept_rx_pause_frames;
 490        mac_dev->set_exception          = tgec_set_exception;
 491        mac_dev->set_multi              = set_multi;
 492        mac_dev->start                  = start;
 493        mac_dev->stop                   = stop;
 494        mac_dev->adjust_link            = adjust_link_void;
 495        mac_dev->priv->enable           = tgec_enable;
 496        mac_dev->priv->disable          = tgec_disable;
 497}
 498
 499static void setup_memac(struct mac_device *mac_dev)
 500{
 501        mac_dev->init                   = memac_initialization;
 502        mac_dev->set_promisc            = memac_set_promiscuous;
 503        mac_dev->change_addr            = memac_modify_mac_address;
 504        mac_dev->add_hash_mac_addr      = memac_add_hash_mac_address;
 505        mac_dev->remove_hash_mac_addr   = memac_del_hash_mac_address;
 506        mac_dev->set_tx_pause           = memac_set_tx_pause_frames;
 507        mac_dev->set_rx_pause           = memac_accept_rx_pause_frames;
 508        mac_dev->set_exception          = memac_set_exception;
 509        mac_dev->set_multi              = set_multi;
 510        mac_dev->start                  = start;
 511        mac_dev->stop                   = stop;
 512        mac_dev->adjust_link            = adjust_link_memac;
 513        mac_dev->priv->enable           = memac_enable;
 514        mac_dev->priv->disable          = memac_disable;
 515}
 516
 517#define DTSEC_SUPPORTED \
 518        (SUPPORTED_10baseT_Half \
 519        | SUPPORTED_10baseT_Full \
 520        | SUPPORTED_100baseT_Half \
 521        | SUPPORTED_100baseT_Full \
 522        | SUPPORTED_Autoneg \
 523        | SUPPORTED_Pause \
 524        | SUPPORTED_Asym_Pause \
 525        | SUPPORTED_MII)
 526
 527static DEFINE_MUTEX(eth_lock);
 528
 529static const u16 phy2speed[] = {
 530        [PHY_INTERFACE_MODE_MII]                = SPEED_100,
 531        [PHY_INTERFACE_MODE_GMII]               = SPEED_1000,
 532        [PHY_INTERFACE_MODE_SGMII]              = SPEED_1000,
 533        [PHY_INTERFACE_MODE_TBI]                = SPEED_1000,
 534        [PHY_INTERFACE_MODE_RMII]               = SPEED_100,
 535        [PHY_INTERFACE_MODE_RGMII]              = SPEED_1000,
 536        [PHY_INTERFACE_MODE_RGMII_ID]           = SPEED_1000,
 537        [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
 538        [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
 539        [PHY_INTERFACE_MODE_RTBI]               = SPEED_1000,
 540        [PHY_INTERFACE_MODE_QSGMII]             = SPEED_1000,
 541        [PHY_INTERFACE_MODE_XGMII]              = SPEED_10000
 542};
 543
 544static struct platform_device *dpaa_eth_add_device(int fman_id,
 545                                                   struct mac_device *mac_dev)
 546{
 547        struct platform_device *pdev;
 548        struct dpaa_eth_data data;
 549        struct mac_priv_s       *priv;
 550        static int dpaa_eth_dev_cnt;
 551        int ret;
 552
 553        priv = mac_dev->priv;
 554
 555        data.mac_dev = mac_dev;
 556        data.mac_hw_id = priv->cell_index;
 557        data.fman_hw_id = fman_id;
 558
 559        mutex_lock(&eth_lock);
 560        pdev = platform_device_alloc("dpaa-ethernet", dpaa_eth_dev_cnt);
 561        if (!pdev) {
 562                ret = -ENOMEM;
 563                goto no_mem;
 564        }
 565
 566        pdev->dev.parent = priv->dev;
 567        set_dma_ops(&pdev->dev, get_dma_ops(priv->dev));
 568
 569        ret = platform_device_add_data(pdev, &data, sizeof(data));
 570        if (ret)
 571                goto err;
 572
 573        ret = platform_device_add(pdev);
 574        if (ret)
 575                goto err;
 576
 577        dpaa_eth_dev_cnt++;
 578        mutex_unlock(&eth_lock);
 579
 580        return pdev;
 581
 582err:
 583        platform_device_put(pdev);
 584no_mem:
 585        mutex_unlock(&eth_lock);
 586
 587        return ERR_PTR(ret);
 588}
 589
 590static const struct of_device_id mac_match[] = {
 591        { .compatible   = "fsl,fman-dtsec" },
 592        { .compatible   = "fsl,fman-xgec" },
 593        { .compatible   = "fsl,fman-memac" },
 594        {}
 595};
 596MODULE_DEVICE_TABLE(of, mac_match);
 597
 598static int mac_probe(struct platform_device *_of_dev)
 599{
 600        int                      err, i, nph;
 601        struct device           *dev;
 602        struct device_node      *mac_node, *dev_node;
 603        struct mac_device       *mac_dev;
 604        struct platform_device  *of_dev;
 605        struct resource          res;
 606        struct mac_priv_s       *priv;
 607        const u8                *mac_addr;
 608        u32                      val;
 609        u8                      fman_id;
 610        int                     phy_if;
 611
 612        dev = &_of_dev->dev;
 613        mac_node = dev->of_node;
 614
 615        mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
 616        if (!mac_dev) {
 617                err = -ENOMEM;
 618                goto _return;
 619        }
 620        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 621        if (!priv) {
 622                err = -ENOMEM;
 623                goto _return;
 624        }
 625
 626        /* Save private information */
 627        mac_dev->priv = priv;
 628        priv->dev = dev;
 629
 630        if (of_device_is_compatible(mac_node, "fsl,fman-dtsec")) {
 631                setup_dtsec(mac_dev);
 632                priv->internal_phy_node = of_parse_phandle(mac_node,
 633                                                          "tbi-handle", 0);
 634        } else if (of_device_is_compatible(mac_node, "fsl,fman-xgec")) {
 635                setup_tgec(mac_dev);
 636        } else if (of_device_is_compatible(mac_node, "fsl,fman-memac")) {
 637                setup_memac(mac_dev);
 638                priv->internal_phy_node = of_parse_phandle(mac_node,
 639                                                          "pcsphy-handle", 0);
 640        } else {
 641                dev_err(dev, "MAC node (%pOF) contains unsupported MAC\n",
 642                        mac_node);
 643                err = -EINVAL;
 644                goto _return;
 645        }
 646
 647        INIT_LIST_HEAD(&priv->mc_addr_list);
 648
 649        /* Get the FM node */
 650        dev_node = of_get_parent(mac_node);
 651        if (!dev_node) {
 652                dev_err(dev, "of_get_parent(%pOF) failed\n",
 653                        mac_node);
 654                err = -EINVAL;
 655                goto _return_of_get_parent;
 656        }
 657
 658        of_dev = of_find_device_by_node(dev_node);
 659        if (!of_dev) {
 660                dev_err(dev, "of_find_device_by_node(%pOF) failed\n", dev_node);
 661                err = -EINVAL;
 662                goto _return_of_node_put;
 663        }
 664
 665        /* Get the FMan cell-index */
 666        err = of_property_read_u32(dev_node, "cell-index", &val);
 667        if (err) {
 668                dev_err(dev, "failed to read cell-index for %pOF\n", dev_node);
 669                err = -EINVAL;
 670                goto _return_of_node_put;
 671        }
 672        /* cell-index 0 => FMan id 1 */
 673        fman_id = (u8)(val + 1);
 674
 675        priv->fman = fman_bind(&of_dev->dev);
 676        if (!priv->fman) {
 677                dev_err(dev, "fman_bind(%pOF) failed\n", dev_node);
 678                err = -ENODEV;
 679                goto _return_of_node_put;
 680        }
 681
 682        of_node_put(dev_node);
 683
 684        /* Get the address of the memory mapped registers */
 685        err = of_address_to_resource(mac_node, 0, &res);
 686        if (err < 0) {
 687                dev_err(dev, "of_address_to_resource(%pOF) = %d\n",
 688                        mac_node, err);
 689                goto _return_of_get_parent;
 690        }
 691
 692        mac_dev->res = __devm_request_region(dev,
 693                                             fman_get_mem_region(priv->fman),
 694                                             res.start, res.end + 1 - res.start,
 695                                             "mac");
 696        if (!mac_dev->res) {
 697                dev_err(dev, "__devm_request_mem_region(mac) failed\n");
 698                err = -EBUSY;
 699                goto _return_of_get_parent;
 700        }
 701
 702        priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
 703                                   mac_dev->res->end + 1 - mac_dev->res->start);
 704        if (!priv->vaddr) {
 705                dev_err(dev, "devm_ioremap() failed\n");
 706                err = -EIO;
 707                goto _return_of_get_parent;
 708        }
 709
 710        if (!of_device_is_available(mac_node)) {
 711                err = -ENODEV;
 712                goto _return_of_get_parent;
 713        }
 714
 715        /* Get the cell-index */
 716        err = of_property_read_u32(mac_node, "cell-index", &val);
 717        if (err) {
 718                dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
 719                err = -EINVAL;
 720                goto _return_of_get_parent;
 721        }
 722        priv->cell_index = (u8)val;
 723
 724        /* Get the MAC address */
 725        mac_addr = of_get_mac_address(mac_node);
 726        if (!mac_addr) {
 727                dev_err(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
 728                err = -EINVAL;
 729                goto _return_of_get_parent;
 730        }
 731        memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
 732
 733        /* Get the port handles */
 734        nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
 735        if (unlikely(nph < 0)) {
 736                dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
 737                        mac_node);
 738                err = nph;
 739                goto _return_of_get_parent;
 740        }
 741
 742        if (nph != ARRAY_SIZE(mac_dev->port)) {
 743                dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
 744                        mac_node);
 745                err = -EINVAL;
 746                goto _return_of_get_parent;
 747        }
 748
 749        for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
 750                /* Find the port node */
 751                dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
 752                if (!dev_node) {
 753                        dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n",
 754                                mac_node);
 755                        err = -EINVAL;
 756                        goto _return_of_node_put;
 757                }
 758
 759                of_dev = of_find_device_by_node(dev_node);
 760                if (!of_dev) {
 761                        dev_err(dev, "of_find_device_by_node(%pOF) failed\n",
 762                                dev_node);
 763                        err = -EINVAL;
 764                        goto _return_of_node_put;
 765                }
 766
 767                mac_dev->port[i] = fman_port_bind(&of_dev->dev);
 768                if (!mac_dev->port[i]) {
 769                        dev_err(dev, "dev_get_drvdata(%pOF) failed\n",
 770                                dev_node);
 771                        err = -EINVAL;
 772                        goto _return_of_node_put;
 773                }
 774                of_node_put(dev_node);
 775        }
 776
 777        /* Get the PHY connection type */
 778        phy_if = of_get_phy_mode(mac_node);
 779        if (phy_if < 0) {
 780                dev_warn(dev,
 781                         "of_get_phy_mode() for %pOF failed. Defaulting to SGMII\n",
 782                         mac_node);
 783                phy_if = PHY_INTERFACE_MODE_SGMII;
 784        }
 785        mac_dev->phy_if = phy_if;
 786
 787        priv->speed             = phy2speed[mac_dev->phy_if];
 788        priv->max_speed         = priv->speed;
 789        mac_dev->if_support     = DTSEC_SUPPORTED;
 790        /* We don't support half-duplex in SGMII mode */
 791        if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
 792                mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
 793                                        SUPPORTED_100baseT_Half);
 794
 795        /* Gigabit support (no half-duplex) */
 796        if (priv->max_speed == 1000)
 797                mac_dev->if_support |= SUPPORTED_1000baseT_Full;
 798
 799        /* The 10G interface only supports one mode */
 800        if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
 801                mac_dev->if_support = SUPPORTED_10000baseT_Full;
 802
 803        /* Get the rest of the PHY information */
 804        mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
 805        if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
 806                struct phy_device *phy;
 807
 808                err = of_phy_register_fixed_link(mac_node);
 809                if (err)
 810                        goto _return_of_get_parent;
 811
 812                priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
 813                                           GFP_KERNEL);
 814                if (!priv->fixed_link) {
 815                        err = -ENOMEM;
 816                        goto _return_of_get_parent;
 817                }
 818
 819                mac_dev->phy_node = of_node_get(mac_node);
 820                phy = of_phy_find_device(mac_dev->phy_node);
 821                if (!phy) {
 822                        err = -EINVAL;
 823                        of_node_put(mac_dev->phy_node);
 824                        goto _return_of_get_parent;
 825                }
 826
 827                priv->fixed_link->link = phy->link;
 828                priv->fixed_link->speed = phy->speed;
 829                priv->fixed_link->duplex = phy->duplex;
 830                priv->fixed_link->pause = phy->pause;
 831                priv->fixed_link->asym_pause = phy->asym_pause;
 832
 833                put_device(&phy->mdio.dev);
 834        }
 835
 836        err = mac_dev->init(mac_dev);
 837        if (err < 0) {
 838                dev_err(dev, "mac_dev->init() = %d\n", err);
 839                of_node_put(mac_dev->phy_node);
 840                goto _return_of_get_parent;
 841        }
 842
 843        /* pause frame autonegotiation enabled */
 844        mac_dev->autoneg_pause = true;
 845
 846        /* By intializing the values to false, force FMD to enable PAUSE frames
 847         * on RX and TX
 848         */
 849        mac_dev->rx_pause_req = true;
 850        mac_dev->tx_pause_req = true;
 851        mac_dev->rx_pause_active = false;
 852        mac_dev->tx_pause_active = false;
 853        err = fman_set_mac_active_pause(mac_dev, true, true);
 854        if (err < 0)
 855                dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
 856
 857        dev_info(dev, "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
 858                 mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
 859                 mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
 860
 861        priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
 862        if (IS_ERR(priv->eth_dev)) {
 863                dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
 864                        priv->cell_index);
 865                priv->eth_dev = NULL;
 866        }
 867
 868        goto _return;
 869
 870_return_of_node_put:
 871        of_node_put(dev_node);
 872_return_of_get_parent:
 873        kfree(priv->fixed_link);
 874_return:
 875        return err;
 876}
 877
 878static struct platform_driver mac_driver = {
 879        .driver = {
 880                .name           = KBUILD_MODNAME,
 881                .of_match_table = mac_match,
 882        },
 883        .probe          = mac_probe,
 884};
 885
 886builtin_platform_driver(mac_driver);
 887