linux/drivers/staging/octeon/ethernet-xaui.c
<<
>>
Prefs
   1/**********************************************************************
   2 * Author: Cavium Networks
   3 *
   4 * Contact: support@caviumnetworks.com
   5 * This file is part of the OCTEON SDK
   6 *
   7 * Copyright (c) 2003-2007 Cavium Networks
   8 *
   9 * This file is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License, Version 2, as
  11 * published by the Free Software Foundation.
  12 *
  13 * This file is distributed in the hope that it will be useful, but
  14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
  15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  16 * NONINFRINGEMENT.  See the GNU General Public License for more
  17 * details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this file; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22 * or visit http://www.gnu.org/licenses/.
  23 *
  24 * This file may also be available under a different license from Cavium.
  25 * Contact Cavium Networks for more information
  26**********************************************************************/
  27#include <linux/kernel.h>
  28#include <linux/netdevice.h>
  29#include <linux/ratelimit.h>
  30#include <net/dst.h>
  31
  32#include <asm/octeon/octeon.h>
  33
  34#include "ethernet-defines.h"
  35#include "octeon-ethernet.h"
  36#include "ethernet-util.h"
  37
  38#include <asm/octeon/cvmx-helper.h>
  39
  40#include <asm/octeon/cvmx-gmxx-defs.h>
  41
  42int cvm_oct_xaui_open(struct net_device *dev)
  43{
  44        union cvmx_gmxx_prtx_cfg gmx_cfg;
  45        struct octeon_ethernet *priv = netdev_priv(dev);
  46        int interface = INTERFACE(priv->port);
  47        int index = INDEX(priv->port);
  48        cvmx_helper_link_info_t link_info;
  49
  50        gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  51        gmx_cfg.s.en = 1;
  52        cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  53
  54        if (!octeon_is_simulation()) {
  55                link_info = cvmx_helper_link_get(priv->port);
  56                if (!link_info.s.link_up)
  57                        netif_carrier_off(dev);
  58        }
  59        return 0;
  60}
  61
  62int cvm_oct_xaui_stop(struct net_device *dev)
  63{
  64        union cvmx_gmxx_prtx_cfg gmx_cfg;
  65        struct octeon_ethernet *priv = netdev_priv(dev);
  66        int interface = INTERFACE(priv->port);
  67        int index = INDEX(priv->port);
  68
  69        gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  70        gmx_cfg.s.en = 0;
  71        cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  72        return 0;
  73}
  74
  75static void cvm_oct_xaui_poll(struct net_device *dev)
  76{
  77        struct octeon_ethernet *priv = netdev_priv(dev);
  78        cvmx_helper_link_info_t link_info;
  79
  80        link_info = cvmx_helper_link_get(priv->port);
  81        if (link_info.u64 == priv->link_info)
  82                return;
  83
  84        link_info = cvmx_helper_link_autoconf(priv->port);
  85        priv->link_info = link_info.u64;
  86
  87        /* Tell Linux */
  88        if (link_info.s.link_up) {
  89
  90                if (!netif_carrier_ok(dev))
  91                        netif_carrier_on(dev);
  92                if (priv->queue != -1)
  93                        printk_ratelimited
  94                                ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
  95                                 dev->name, link_info.s.speed,
  96                                 (link_info.s.full_duplex) ? "Full" : "Half",
  97                                 priv->port, priv->queue);
  98                else
  99                        printk_ratelimited
 100                                ("%s: %u Mbps %s duplex, port %2d, POW\n",
 101                                 dev->name, link_info.s.speed,
 102                                 (link_info.s.full_duplex) ? "Full" : "Half",
 103                                 priv->port);
 104        } else {
 105                if (netif_carrier_ok(dev))
 106                        netif_carrier_off(dev);
 107                printk_ratelimited("%s: Link down\n", dev->name);
 108        }
 109}
 110
 111int cvm_oct_xaui_init(struct net_device *dev)
 112{
 113        struct octeon_ethernet *priv = netdev_priv(dev);
 114        cvm_oct_common_init(dev);
 115        dev->netdev_ops->ndo_stop(dev);
 116        if (!octeon_is_simulation() && priv->phydev == NULL)
 117                priv->poll = cvm_oct_xaui_poll;
 118
 119        return 0;
 120}
 121
 122void cvm_oct_xaui_uninit(struct net_device *dev)
 123{
 124        cvm_oct_common_uninit(dev);
 125}
 126