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