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