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_pause:   Return value for RX setting
 363 * @tx_pause:   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 = linkmode_adv_to_lcl_adv_t(phy_dev->advertising);
 397
 398        /* get link partner capabilities */
 399        rmt_adv = 0;
 400        if (phy_dev->pause)
 401                rmt_adv |= LPA_PAUSE_CAP;
 402        if (phy_dev->asym_pause)
 403                rmt_adv |= LPA_PAUSE_ASYM;
 404
 405        /* Calculate TX/RX settings based on local and peer advertised
 406         * symmetric/asymmetric PAUSE capabilities.
 407         */
 408        flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 409        if (flowctrl & FLOW_CTRL_RX)
 410                *rx_pause = true;
 411        if (flowctrl & FLOW_CTRL_TX)
 412                *tx_pause = true;
 413}
 414EXPORT_SYMBOL(fman_get_pause_cfg);
 415
 416static void adjust_link_void(struct mac_device *mac_dev)
 417{
 418}
 419
 420static void adjust_link_dtsec(struct mac_device *mac_dev)
 421{
 422        struct phy_device *phy_dev = mac_dev->phy_dev;
 423        struct fman_mac *fman_mac;
 424        bool rx_pause, tx_pause;
 425        int err;
 426
 427        fman_mac = mac_dev->fman_mac;
 428        if (!phy_dev->link) {
 429                dtsec_restart_autoneg(fman_mac);
 430
 431                return;
 432        }
 433
 434        dtsec_adjust_link(fman_mac, phy_dev->speed);
 435        fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
 436        err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
 437        if (err < 0)
 438                dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
 439                        err);
 440}
 441
 442static void adjust_link_memac(struct mac_device *mac_dev)
 443{
 444        struct phy_device *phy_dev = mac_dev->phy_dev;
 445        struct fman_mac *fman_mac;
 446        bool rx_pause, tx_pause;
 447        int err;
 448
 449        fman_mac = mac_dev->fman_mac;
 450        memac_adjust_link(fman_mac, phy_dev->speed);
 451
 452        fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
 453        err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
 454        if (err < 0)
 455                dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
 456                        err);
 457}
 458
 459static void setup_dtsec(struct mac_device *mac_dev)
 460{
 461        mac_dev->init                   = dtsec_initialization;
 462        mac_dev->set_promisc            = dtsec_set_promiscuous;
 463        mac_dev->change_addr            = dtsec_modify_mac_address;
 464        mac_dev->add_hash_mac_addr      = dtsec_add_hash_mac_address;
 465        mac_dev->remove_hash_mac_addr   = dtsec_del_hash_mac_address;
 466        mac_dev->set_tx_pause           = dtsec_set_tx_pause_frames;
 467        mac_dev->set_rx_pause           = dtsec_accept_rx_pause_frames;
 468        mac_dev->set_exception          = dtsec_set_exception;
 469        mac_dev->set_allmulti           = dtsec_set_allmulti;
 470        mac_dev->set_tstamp             = dtsec_set_tstamp;
 471        mac_dev->set_multi              = set_multi;
 472        mac_dev->start                  = start;
 473        mac_dev->stop                   = stop;
 474        mac_dev->adjust_link            = adjust_link_dtsec;
 475        mac_dev->priv->enable           = dtsec_enable;
 476        mac_dev->priv->disable          = dtsec_disable;
 477}
 478
 479static void setup_tgec(struct mac_device *mac_dev)
 480{
 481        mac_dev->init                   = tgec_initialization;
 482        mac_dev->set_promisc            = tgec_set_promiscuous;
 483        mac_dev->change_addr            = tgec_modify_mac_address;
 484        mac_dev->add_hash_mac_addr      = tgec_add_hash_mac_address;
 485        mac_dev->remove_hash_mac_addr   = tgec_del_hash_mac_address;
 486        mac_dev->set_tx_pause           = tgec_set_tx_pause_frames;
 487        mac_dev->set_rx_pause           = tgec_accept_rx_pause_frames;
 488        mac_dev->set_exception          = tgec_set_exception;
 489        mac_dev->set_allmulti           = tgec_set_allmulti;
 490        mac_dev->set_tstamp             = tgec_set_tstamp;
 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_allmulti           = memac_set_allmulti;
 510        mac_dev->set_tstamp             = memac_set_tstamp;
 511        mac_dev->set_multi              = set_multi;
 512        mac_dev->start                  = start;
 513        mac_dev->stop                   = stop;
 514        mac_dev->adjust_link            = adjust_link_memac;
 515        mac_dev->priv->enable           = memac_enable;
 516        mac_dev->priv->disable          = memac_disable;
 517}
 518
 519#define DTSEC_SUPPORTED \
 520        (SUPPORTED_10baseT_Half \
 521        | SUPPORTED_10baseT_Full \
 522        | SUPPORTED_100baseT_Half \
 523        | SUPPORTED_100baseT_Full \
 524        | SUPPORTED_Autoneg \
 525        | SUPPORTED_Pause \
 526        | SUPPORTED_Asym_Pause \
 527        | SUPPORTED_FIBRE \
 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        u32                      val;
 610        u8                      fman_id;
 611        phy_interface_t          phy_if;
 612
 613        dev = &_of_dev->dev;
 614        mac_node = dev->of_node;
 615
 616        mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
 617        if (!mac_dev) {
 618                err = -ENOMEM;
 619                goto _return;
 620        }
 621        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 622        if (!priv) {
 623                err = -ENOMEM;
 624                goto _return;
 625        }
 626
 627        /* Save private information */
 628        mac_dev->priv = priv;
 629        priv->dev = dev;
 630
 631        if (of_device_is_compatible(mac_node, "fsl,fman-dtsec")) {
 632                setup_dtsec(mac_dev);
 633                priv->internal_phy_node = of_parse_phandle(mac_node,
 634                                                          "tbi-handle", 0);
 635        } else if (of_device_is_compatible(mac_node, "fsl,fman-xgec")) {
 636                setup_tgec(mac_dev);
 637        } else if (of_device_is_compatible(mac_node, "fsl,fman-memac")) {
 638                setup_memac(mac_dev);
 639                priv->internal_phy_node = of_parse_phandle(mac_node,
 640                                                          "pcsphy-handle", 0);
 641        } else {
 642                dev_err(dev, "MAC node (%pOF) contains unsupported MAC\n",
 643                        mac_node);
 644                err = -EINVAL;
 645                goto _return;
 646        }
 647
 648        INIT_LIST_HEAD(&priv->mc_addr_list);
 649
 650        /* Get the FM node */
 651        dev_node = of_get_parent(mac_node);
 652        if (!dev_node) {
 653                dev_err(dev, "of_get_parent(%pOF) failed\n",
 654                        mac_node);
 655                err = -EINVAL;
 656                goto _return_of_get_parent;
 657        }
 658
 659        of_dev = of_find_device_by_node(dev_node);
 660        if (!of_dev) {
 661                dev_err(dev, "of_find_device_by_node(%pOF) failed\n", dev_node);
 662                err = -EINVAL;
 663                goto _return_of_node_put;
 664        }
 665
 666        /* Get the FMan cell-index */
 667        err = of_property_read_u32(dev_node, "cell-index", &val);
 668        if (err) {
 669                dev_err(dev, "failed to read cell-index for %pOF\n", dev_node);
 670                err = -EINVAL;
 671                goto _return_of_node_put;
 672        }
 673        /* cell-index 0 => FMan id 1 */
 674        fman_id = (u8)(val + 1);
 675
 676        priv->fman = fman_bind(&of_dev->dev);
 677        if (!priv->fman) {
 678                dev_err(dev, "fman_bind(%pOF) failed\n", dev_node);
 679                err = -ENODEV;
 680                goto _return_of_node_put;
 681        }
 682
 683        of_node_put(dev_node);
 684
 685        /* Get the address of the memory mapped registers */
 686        err = of_address_to_resource(mac_node, 0, &res);
 687        if (err < 0) {
 688                dev_err(dev, "of_address_to_resource(%pOF) = %d\n",
 689                        mac_node, err);
 690                goto _return_of_get_parent;
 691        }
 692
 693        mac_dev->res = __devm_request_region(dev,
 694                                             fman_get_mem_region(priv->fman),
 695                                             res.start, resource_size(&res),
 696                                             "mac");
 697        if (!mac_dev->res) {
 698                dev_err(dev, "__devm_request_mem_region(mac) failed\n");
 699                err = -EBUSY;
 700                goto _return_of_get_parent;
 701        }
 702
 703        priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
 704                                   resource_size(mac_dev->res));
 705        if (!priv->vaddr) {
 706                dev_err(dev, "devm_ioremap() failed\n");
 707                err = -EIO;
 708                goto _return_of_get_parent;
 709        }
 710
 711        if (!of_device_is_available(mac_node)) {
 712                err = -ENODEV;
 713                goto _return_of_get_parent;
 714        }
 715
 716        /* Get the cell-index */
 717        err = of_property_read_u32(mac_node, "cell-index", &val);
 718        if (err) {
 719                dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
 720                err = -EINVAL;
 721                goto _return_of_get_parent;
 722        }
 723        priv->cell_index = (u8)val;
 724
 725        /* Get the MAC address */
 726        err = of_get_mac_address(mac_node, mac_dev->addr);
 727        if (err)
 728                dev_warn(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
 729
 730        /* Get the port handles */
 731        nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
 732        if (unlikely(nph < 0)) {
 733                dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
 734                        mac_node);
 735                err = nph;
 736                goto _return_of_get_parent;
 737        }
 738
 739        if (nph != ARRAY_SIZE(mac_dev->port)) {
 740                dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
 741                        mac_node);
 742                err = -EINVAL;
 743                goto _return_of_get_parent;
 744        }
 745
 746        for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
 747                /* Find the port node */
 748                dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
 749                if (!dev_node) {
 750                        dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n",
 751                                mac_node);
 752                        err = -EINVAL;
 753                        goto _return_of_node_put;
 754                }
 755
 756                of_dev = of_find_device_by_node(dev_node);
 757                if (!of_dev) {
 758                        dev_err(dev, "of_find_device_by_node(%pOF) failed\n",
 759                                dev_node);
 760                        err = -EINVAL;
 761                        goto _return_of_node_put;
 762                }
 763
 764                mac_dev->port[i] = fman_port_bind(&of_dev->dev);
 765                if (!mac_dev->port[i]) {
 766                        dev_err(dev, "dev_get_drvdata(%pOF) failed\n",
 767                                dev_node);
 768                        err = -EINVAL;
 769                        goto _return_of_node_put;
 770                }
 771                of_node_put(dev_node);
 772        }
 773
 774        /* Get the PHY connection type */
 775        err = of_get_phy_mode(mac_node, &phy_if);
 776        if (err) {
 777                dev_warn(dev,
 778                         "of_get_phy_mode() for %pOF failed. Defaulting to SGMII\n",
 779                         mac_node);
 780                phy_if = PHY_INTERFACE_MODE_SGMII;
 781        }
 782        mac_dev->phy_if = phy_if;
 783
 784        priv->speed             = phy2speed[mac_dev->phy_if];
 785        priv->max_speed         = priv->speed;
 786        mac_dev->if_support     = DTSEC_SUPPORTED;
 787        /* We don't support half-duplex in SGMII mode */
 788        if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
 789                mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
 790                                        SUPPORTED_100baseT_Half);
 791
 792        /* Gigabit support (no half-duplex) */
 793        if (priv->max_speed == 1000)
 794                mac_dev->if_support |= SUPPORTED_1000baseT_Full;
 795
 796        /* The 10G interface only supports one mode */
 797        if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
 798                mac_dev->if_support = SUPPORTED_10000baseT_Full;
 799
 800        /* Get the rest of the PHY information */
 801        mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
 802        if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
 803                struct phy_device *phy;
 804
 805                err = of_phy_register_fixed_link(mac_node);
 806                if (err)
 807                        goto _return_of_get_parent;
 808
 809                priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
 810                                           GFP_KERNEL);
 811                if (!priv->fixed_link) {
 812                        err = -ENOMEM;
 813                        goto _return_of_get_parent;
 814                }
 815
 816                mac_dev->phy_node = of_node_get(mac_node);
 817                phy = of_phy_find_device(mac_dev->phy_node);
 818                if (!phy) {
 819                        err = -EINVAL;
 820                        of_node_put(mac_dev->phy_node);
 821                        goto _return_of_get_parent;
 822                }
 823
 824                priv->fixed_link->link = phy->link;
 825                priv->fixed_link->speed = phy->speed;
 826                priv->fixed_link->duplex = phy->duplex;
 827                priv->fixed_link->pause = phy->pause;
 828                priv->fixed_link->asym_pause = phy->asym_pause;
 829
 830                put_device(&phy->mdio.dev);
 831        }
 832
 833        err = mac_dev->init(mac_dev);
 834        if (err < 0) {
 835                dev_err(dev, "mac_dev->init() = %d\n", err);
 836                of_node_put(mac_dev->phy_node);
 837                goto _return_of_get_parent;
 838        }
 839
 840        /* pause frame autonegotiation enabled */
 841        mac_dev->autoneg_pause = true;
 842
 843        /* By intializing the values to false, force FMD to enable PAUSE frames
 844         * on RX and TX
 845         */
 846        mac_dev->rx_pause_req = true;
 847        mac_dev->tx_pause_req = true;
 848        mac_dev->rx_pause_active = false;
 849        mac_dev->tx_pause_active = false;
 850        err = fman_set_mac_active_pause(mac_dev, true, true);
 851        if (err < 0)
 852                dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
 853
 854        if (!is_zero_ether_addr(mac_dev->addr))
 855                dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
 856
 857        priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
 858        if (IS_ERR(priv->eth_dev)) {
 859                dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
 860                        priv->cell_index);
 861                priv->eth_dev = NULL;
 862        }
 863
 864        goto _return;
 865
 866_return_of_node_put:
 867        of_node_put(dev_node);
 868_return_of_get_parent:
 869        kfree(priv->fixed_link);
 870_return:
 871        return err;
 872}
 873
 874static struct platform_driver mac_driver = {
 875        .driver = {
 876                .name           = KBUILD_MODNAME,
 877                .of_match_table = mac_match,
 878        },
 879        .probe          = mac_probe,
 880};
 881
 882builtin_platform_driver(mac_driver);
 883