linux/drivers/net/ethernet/amd/xgbe/xgbe-main.c
<<
>>
Prefs
   1/*
   2 * AMD 10Gb Ethernet driver
   3 *
   4 * This file is available to you under your choice of the following two
   5 * licenses:
   6 *
   7 * License 1: GPLv2
   8 *
   9 * Copyright (c) 2014 Advanced Micro Devices, Inc.
  10 *
  11 * This file is free software; you may copy, redistribute and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation, either version 2 of the License, or (at
  14 * your option) any later version.
  15 *
  16 * This file is distributed in the hope that it will be useful, but
  17 * WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19 * General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23 *
  24 * This file incorporates work covered by the following copyright and
  25 * permission notice:
  26 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  27 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  28 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  29 *     and you.
  30 *
  31 *     The Software IS NOT an item of Licensed Software or Licensed Product
  32 *     under any End User Software License Agreement or Agreement for Licensed
  33 *     Product with Synopsys or any supplement thereto.  Permission is hereby
  34 *     granted, free of charge, to any person obtaining a copy of this software
  35 *     annotated with this license and the Software, to deal in the Software
  36 *     without restriction, including without limitation the rights to use,
  37 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  38 *     of the Software, and to permit persons to whom the Software is furnished
  39 *     to do so, subject to the following conditions:
  40 *
  41 *     The above copyright notice and this permission notice shall be included
  42 *     in all copies or substantial portions of the Software.
  43 *
  44 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
  45 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  46 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  47 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
  48 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  49 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  50 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  51 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  52 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  53 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  54 *     THE POSSIBILITY OF SUCH DAMAGE.
  55 *
  56 *
  57 * License 2: Modified BSD
  58 *
  59 * Copyright (c) 2014 Advanced Micro Devices, Inc.
  60 * All rights reserved.
  61 *
  62 * Redistribution and use in source and binary forms, with or without
  63 * modification, are permitted provided that the following conditions are met:
  64 *     * Redistributions of source code must retain the above copyright
  65 *       notice, this list of conditions and the following disclaimer.
  66 *     * Redistributions in binary form must reproduce the above copyright
  67 *       notice, this list of conditions and the following disclaimer in the
  68 *       documentation and/or other materials provided with the distribution.
  69 *     * Neither the name of Advanced Micro Devices, Inc. nor the
  70 *       names of its contributors may be used to endorse or promote products
  71 *       derived from this software without specific prior written permission.
  72 *
  73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  83 *
  84 * This file incorporates work covered by the following copyright and
  85 * permission notice:
  86 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  87 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  88 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  89 *     and you.
  90 *
  91 *     The Software IS NOT an item of Licensed Software or Licensed Product
  92 *     under any End User Software License Agreement or Agreement for Licensed
  93 *     Product with Synopsys or any supplement thereto.  Permission is hereby
  94 *     granted, free of charge, to any person obtaining a copy of this software
  95 *     annotated with this license and the Software, to deal in the Software
  96 *     without restriction, including without limitation the rights to use,
  97 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  98 *     of the Software, and to permit persons to whom the Software is furnished
  99 *     to do so, subject to the following conditions:
 100 *
 101 *     The above copyright notice and this permission notice shall be included
 102 *     in all copies or substantial portions of the Software.
 103 *
 104 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
 105 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 106 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 107 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
 108 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 109 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 110 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 111 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 112 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 113 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 114 *     THE POSSIBILITY OF SUCH DAMAGE.
 115 */
 116
 117#include <linux/module.h>
 118#include <linux/device.h>
 119#include <linux/platform_device.h>
 120#include <linux/spinlock.h>
 121#include <linux/netdevice.h>
 122#include <linux/etherdevice.h>
 123#include <linux/io.h>
 124#include <linux/of.h>
 125#include <linux/of_net.h>
 126#include <linux/clk.h>
 127
 128#include "xgbe.h"
 129#include "xgbe-common.h"
 130
 131MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
 132MODULE_LICENSE("Dual BSD/GPL");
 133MODULE_VERSION(XGBE_DRV_VERSION);
 134MODULE_DESCRIPTION(XGBE_DRV_DESC);
 135
 136static void xgbe_default_config(struct xgbe_prv_data *pdata)
 137{
 138        DBGPR("-->xgbe_default_config\n");
 139
 140        pdata->pblx8 = DMA_PBL_X8_ENABLE;
 141        pdata->tx_sf_mode = MTL_TSF_ENABLE;
 142        pdata->tx_threshold = MTL_TX_THRESHOLD_64;
 143        pdata->tx_pbl = DMA_PBL_16;
 144        pdata->tx_osp_mode = DMA_OSP_ENABLE;
 145        pdata->rx_sf_mode = MTL_RSF_DISABLE;
 146        pdata->rx_threshold = MTL_RX_THRESHOLD_64;
 147        pdata->rx_pbl = DMA_PBL_16;
 148        pdata->pause_autoneg = 1;
 149        pdata->tx_pause = 1;
 150        pdata->rx_pause = 1;
 151        pdata->power_down = 0;
 152        pdata->default_autoneg = AUTONEG_ENABLE;
 153        pdata->default_speed = SPEED_10000;
 154
 155        DBGPR("<--xgbe_default_config\n");
 156}
 157
 158static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
 159{
 160        xgbe_init_function_ptrs_dev(&pdata->hw_if);
 161        xgbe_init_function_ptrs_desc(&pdata->desc_if);
 162}
 163
 164static int xgbe_probe(struct platform_device *pdev)
 165{
 166        struct xgbe_prv_data *pdata;
 167        struct xgbe_hw_if *hw_if;
 168        struct xgbe_desc_if *desc_if;
 169        struct net_device *netdev;
 170        struct device *dev = &pdev->dev;
 171        struct resource *res;
 172        const u8 *mac_addr;
 173        unsigned int i;
 174        int ret;
 175
 176        DBGPR("--> xgbe_probe\n");
 177
 178        netdev = alloc_etherdev_mq(sizeof(struct xgbe_prv_data),
 179                                   XGBE_MAX_DMA_CHANNELS);
 180        if (!netdev) {
 181                dev_err(dev, "alloc_etherdev failed\n");
 182                ret = -ENOMEM;
 183                goto err_alloc;
 184        }
 185        SET_NETDEV_DEV(netdev, dev);
 186        pdata = netdev_priv(netdev);
 187        pdata->netdev = netdev;
 188        pdata->pdev = pdev;
 189        pdata->dev = dev;
 190        platform_set_drvdata(pdev, netdev);
 191
 192        spin_lock_init(&pdata->lock);
 193        mutex_init(&pdata->xpcs_mutex);
 194        mutex_init(&pdata->rss_mutex);
 195        spin_lock_init(&pdata->tstamp_lock);
 196
 197        /* Set and validate the number of descriptors for a ring */
 198        BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_TX_DESC_CNT);
 199        pdata->tx_desc_count = XGBE_TX_DESC_CNT;
 200        if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) {
 201                dev_err(dev, "tx descriptor count (%d) is not valid\n",
 202                        pdata->tx_desc_count);
 203                ret = -EINVAL;
 204                goto err_io;
 205        }
 206        BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_RX_DESC_CNT);
 207        pdata->rx_desc_count = XGBE_RX_DESC_CNT;
 208        if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) {
 209                dev_err(dev, "rx descriptor count (%d) is not valid\n",
 210                        pdata->rx_desc_count);
 211                ret = -EINVAL;
 212                goto err_io;
 213        }
 214
 215        /* Obtain the system clock setting */
 216        pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
 217        if (IS_ERR(pdata->sysclk)) {
 218                dev_err(dev, "dma devm_clk_get failed\n");
 219                ret = PTR_ERR(pdata->sysclk);
 220                goto err_io;
 221        }
 222
 223        /* Obtain the PTP clock setting */
 224        pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
 225        if (IS_ERR(pdata->ptpclk)) {
 226                dev_err(dev, "ptp devm_clk_get failed\n");
 227                ret = PTR_ERR(pdata->ptpclk);
 228                goto err_io;
 229        }
 230
 231        /* Obtain the mmio areas for the device */
 232        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 233        pdata->xgmac_regs = devm_ioremap_resource(dev, res);
 234        if (IS_ERR(pdata->xgmac_regs)) {
 235                dev_err(dev, "xgmac ioremap failed\n");
 236                ret = PTR_ERR(pdata->xgmac_regs);
 237                goto err_io;
 238        }
 239        DBGPR("  xgmac_regs = %p\n", pdata->xgmac_regs);
 240
 241        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 242        pdata->xpcs_regs = devm_ioremap_resource(dev, res);
 243        if (IS_ERR(pdata->xpcs_regs)) {
 244                dev_err(dev, "xpcs ioremap failed\n");
 245                ret = PTR_ERR(pdata->xpcs_regs);
 246                goto err_io;
 247        }
 248        DBGPR("  xpcs_regs  = %p\n", pdata->xpcs_regs);
 249
 250        /* Set the DMA mask */
 251        if (!dev->dma_mask)
 252                dev->dma_mask = &dev->coherent_dma_mask;
 253        ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
 254        if (ret) {
 255                dev_err(dev, "dma_set_mask_and_coherent failed\n");
 256                goto err_io;
 257        }
 258
 259        if (of_property_read_bool(dev->of_node, "dma-coherent")) {
 260                pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
 261                pdata->arcache = XGBE_DMA_OS_ARCACHE;
 262                pdata->awcache = XGBE_DMA_OS_AWCACHE;
 263        } else {
 264                pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN;
 265                pdata->arcache = XGBE_DMA_SYS_ARCACHE;
 266                pdata->awcache = XGBE_DMA_SYS_AWCACHE;
 267        }
 268
 269        /* Check for per channel interrupt support */
 270        if (of_property_read_bool(dev->of_node, XGBE_DMA_IRQS))
 271                pdata->per_channel_irq = 1;
 272
 273        ret = platform_get_irq(pdev, 0);
 274        if (ret < 0) {
 275                dev_err(dev, "platform_get_irq 0 failed\n");
 276                goto err_io;
 277        }
 278        pdata->dev_irq = ret;
 279
 280        netdev->irq = pdata->dev_irq;
 281        netdev->base_addr = (unsigned long)pdata->xgmac_regs;
 282
 283        /* Set all the function pointers */
 284        xgbe_init_all_fptrs(pdata);
 285        hw_if = &pdata->hw_if;
 286        desc_if = &pdata->desc_if;
 287
 288        /* Issue software reset to device */
 289        hw_if->exit(pdata);
 290
 291        /* Populate the hardware features */
 292        xgbe_get_all_hw_features(pdata);
 293
 294        /* Retrieve the MAC address */
 295        mac_addr = of_get_mac_address(dev->of_node);
 296        if (!mac_addr) {
 297                dev_err(dev, "invalid mac address for this device\n");
 298                ret = -EINVAL;
 299                goto err_io;
 300        }
 301        memcpy(netdev->dev_addr, mac_addr, netdev->addr_len);
 302
 303        /* Retrieve the PHY mode - it must be "xgmii" */
 304        pdata->phy_mode = of_get_phy_mode(dev->of_node);
 305        if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
 306                dev_err(dev, "invalid phy-mode specified for this device\n");
 307                ret = -EINVAL;
 308                goto err_io;
 309        }
 310
 311        /* Set default configuration data */
 312        xgbe_default_config(pdata);
 313
 314        /* Calculate the number of Tx and Rx rings to be created
 315         *  -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
 316         *   the number of Tx queues to the number of Tx channels
 317         *   enabled
 318         *  -Rx (DMA) Channels do not map 1-to-1 so use the actual
 319         *   number of Rx queues
 320         */
 321        pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(),
 322                                     pdata->hw_feat.tx_ch_cnt);
 323        pdata->tx_q_count = pdata->tx_ring_count;
 324        ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count);
 325        if (ret) {
 326                dev_err(dev, "error setting real tx queue count\n");
 327                goto err_io;
 328        }
 329
 330        pdata->rx_ring_count = min_t(unsigned int,
 331                                     netif_get_num_default_rss_queues(),
 332                                     pdata->hw_feat.rx_ch_cnt);
 333        pdata->rx_q_count = pdata->hw_feat.rx_q_cnt;
 334        ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count);
 335        if (ret) {
 336                dev_err(dev, "error setting real rx queue count\n");
 337                goto err_io;
 338        }
 339
 340        /* Initialize RSS hash key and lookup table */
 341        netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key));
 342
 343        for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++)
 344                XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH,
 345                               i % pdata->rx_ring_count);
 346
 347        XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
 348        XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
 349        XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
 350
 351        /* Prepare to regsiter with MDIO */
 352        pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name);
 353        if (!pdata->mii_bus_id) {
 354                dev_err(dev, "failed to allocate mii bus id\n");
 355                ret = -ENOMEM;
 356                goto err_io;
 357        }
 358        ret = xgbe_mdio_register(pdata);
 359        if (ret)
 360                goto err_bus_id;
 361
 362        /* Set device operations */
 363        netdev->netdev_ops = xgbe_get_netdev_ops();
 364        netdev->ethtool_ops = xgbe_get_ethtool_ops();
 365#ifdef CONFIG_AMD_XGBE_DCB
 366        netdev->dcbnl_ops = xgbe_get_dcbnl_ops();
 367#endif
 368
 369        /* Set device features */
 370        netdev->hw_features = NETIF_F_SG |
 371                              NETIF_F_IP_CSUM |
 372                              NETIF_F_IPV6_CSUM |
 373                              NETIF_F_RXCSUM |
 374                              NETIF_F_TSO |
 375                              NETIF_F_TSO6 |
 376                              NETIF_F_GRO |
 377                              NETIF_F_HW_VLAN_CTAG_RX |
 378                              NETIF_F_HW_VLAN_CTAG_TX |
 379                              NETIF_F_HW_VLAN_CTAG_FILTER;
 380
 381        if (pdata->hw_feat.rss)
 382                netdev->hw_features |= NETIF_F_RXHASH;
 383
 384        netdev->vlan_features |= NETIF_F_SG |
 385                                 NETIF_F_IP_CSUM |
 386                                 NETIF_F_IPV6_CSUM |
 387                                 NETIF_F_TSO |
 388                                 NETIF_F_TSO6;
 389
 390        netdev->features |= netdev->hw_features;
 391        pdata->netdev_features = netdev->features;
 392
 393        netdev->priv_flags |= IFF_UNICAST_FLT;
 394
 395        xgbe_init_rx_coalesce(pdata);
 396        xgbe_init_tx_coalesce(pdata);
 397
 398        netif_carrier_off(netdev);
 399        ret = register_netdev(netdev);
 400        if (ret) {
 401                dev_err(dev, "net device registration failed\n");
 402                goto err_reg_netdev;
 403        }
 404
 405        xgbe_ptp_register(pdata);
 406
 407        xgbe_debugfs_init(pdata);
 408
 409        netdev_notice(netdev, "net device enabled\n");
 410
 411        DBGPR("<-- xgbe_probe\n");
 412
 413        return 0;
 414
 415err_reg_netdev:
 416        xgbe_mdio_unregister(pdata);
 417
 418err_bus_id:
 419        kfree(pdata->mii_bus_id);
 420
 421err_io:
 422        free_netdev(netdev);
 423
 424err_alloc:
 425        dev_notice(dev, "net device not enabled\n");
 426
 427        return ret;
 428}
 429
 430static int xgbe_remove(struct platform_device *pdev)
 431{
 432        struct net_device *netdev = platform_get_drvdata(pdev);
 433        struct xgbe_prv_data *pdata = netdev_priv(netdev);
 434
 435        DBGPR("-->xgbe_remove\n");
 436
 437        xgbe_debugfs_exit(pdata);
 438
 439        xgbe_ptp_unregister(pdata);
 440
 441        unregister_netdev(netdev);
 442
 443        xgbe_mdio_unregister(pdata);
 444
 445        kfree(pdata->mii_bus_id);
 446
 447        free_netdev(netdev);
 448
 449        DBGPR("<--xgbe_remove\n");
 450
 451        return 0;
 452}
 453
 454#ifdef CONFIG_PM
 455static int xgbe_suspend(struct device *dev)
 456{
 457        struct net_device *netdev = dev_get_drvdata(dev);
 458        int ret;
 459
 460        DBGPR("-->xgbe_suspend\n");
 461
 462        if (!netif_running(netdev)) {
 463                DBGPR("<--xgbe_dev_suspend\n");
 464                return -EINVAL;
 465        }
 466
 467        ret = xgbe_powerdown(netdev, XGMAC_DRIVER_CONTEXT);
 468
 469        DBGPR("<--xgbe_suspend\n");
 470
 471        return ret;
 472}
 473
 474static int xgbe_resume(struct device *dev)
 475{
 476        struct net_device *netdev = dev_get_drvdata(dev);
 477        int ret;
 478
 479        DBGPR("-->xgbe_resume\n");
 480
 481        if (!netif_running(netdev)) {
 482                DBGPR("<--xgbe_dev_resume\n");
 483                return -EINVAL;
 484        }
 485
 486        ret = xgbe_powerup(netdev, XGMAC_DRIVER_CONTEXT);
 487
 488        DBGPR("<--xgbe_resume\n");
 489
 490        return ret;
 491}
 492#endif /* CONFIG_PM */
 493
 494static const struct of_device_id xgbe_of_match[] = {
 495        { .compatible = "amd,xgbe-seattle-v1a", },
 496        {},
 497};
 498
 499MODULE_DEVICE_TABLE(of, xgbe_of_match);
 500static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume);
 501
 502static struct platform_driver xgbe_driver = {
 503        .driver = {
 504                .name = "amd-xgbe",
 505                .of_match_table = xgbe_of_match,
 506                .pm = &xgbe_pm_ops,
 507        },
 508        .probe = xgbe_probe,
 509        .remove = xgbe_remove,
 510};
 511
 512module_platform_driver(xgbe_driver);
 513
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.