diff options
author | David Daney <ddaney@caviumnetworks.com> | 2009-05-06 04:35:21 +0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-06-17 14:06:30 +0400 |
commit | 80ff0fd3ab6451407a20c19b80c1643c4a6d6434 (patch) | |
tree | 2d7021ac34269f0bce3ac18f7347bf6946640f36 /drivers/staging/octeon/ethernet-sgmii.c | |
parent | 38295fb2a09264671c82d490ce77c17d492378e0 (diff) | |
download | linux-80ff0fd3ab6451407a20c19b80c1643c4a6d6434.tar.xz |
Staging: Add octeon-ethernet driver files.
The octeon-ethernet driver supports the sgmii, rgmii, spi, and xaui
ports present on the Cavium OCTEON family of SOCs. These SOCs are
multi-core mips64 processors with existing support over in arch/mips.
The driver files can be categorized into three basic groups:
1) Register definitions, these are named cvmx-*-defs.h
2) Main driver code, these have names that don't start cvmx-.
3) Interface specific functions and other utility code, names starting
with cvmx-
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/staging/octeon/ethernet-sgmii.c')
-rw-r--r-- | drivers/staging/octeon/ethernet-sgmii.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c new file mode 100644 index 000000000000..58fa39c1d675 --- /dev/null +++ b/drivers/staging/octeon/ethernet-sgmii.c @@ -0,0 +1,129 @@ +/********************************************************************** + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2007 Cavium Networks + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information +**********************************************************************/ +#include <linux/kernel.h> +#include <linux/netdevice.h> +#include <linux/mii.h> +#include <net/dst.h> + +#include <asm/octeon/octeon.h> + +#include "ethernet-defines.h" +#include "octeon-ethernet.h" +#include "ethernet-util.h" +#include "ethernet-common.h" + +#include "cvmx-helper.h" + +#include "cvmx-gmxx-defs.h" + +static int cvm_oct_sgmii_open(struct net_device *dev) +{ + union cvmx_gmxx_prtx_cfg gmx_cfg; + struct octeon_ethernet *priv = netdev_priv(dev); + int interface = INTERFACE(priv->port); + int index = INDEX(priv->port); + cvmx_helper_link_info_t link_info; + + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); + gmx_cfg.s.en = 1; + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); + + if (!octeon_is_simulation()) { + link_info = cvmx_helper_link_get(priv->port); + if (!link_info.s.link_up) + netif_carrier_off(dev); + } + + return 0; +} + +static int cvm_oct_sgmii_stop(struct net_device *dev) +{ + union cvmx_gmxx_prtx_cfg gmx_cfg; + struct octeon_ethernet *priv = netdev_priv(dev); + int interface = INTERFACE(priv->port); + int index = INDEX(priv->port); + + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); + gmx_cfg.s.en = 0; + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); + return 0; +} + +static void cvm_oct_sgmii_poll(struct net_device *dev) +{ + struct octeon_ethernet *priv = netdev_priv(dev); + cvmx_helper_link_info_t link_info; + + link_info = cvmx_helper_link_get(priv->port); + if (link_info.u64 == priv->link_info) + return; + + link_info = cvmx_helper_link_autoconf(priv->port); + priv->link_info = link_info.u64; + + /* Tell Linux */ + if (link_info.s.link_up) { + + if (!netif_carrier_ok(dev)) + netif_carrier_on(dev); + if (priv->queue != -1) + DEBUGPRINT + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? "Full" : "Half", + priv->port, priv->queue); + else + DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? "Full" : "Half", + priv->port); + } else { + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); + DEBUGPRINT("%s: Link down\n", dev->name); + } +} + +int cvm_oct_sgmii_init(struct net_device *dev) +{ + struct octeon_ethernet *priv = netdev_priv(dev); + cvm_oct_common_init(dev); + dev->open = cvm_oct_sgmii_open; + dev->stop = cvm_oct_sgmii_stop; + dev->stop(dev); + if (!octeon_is_simulation()) + priv->poll = cvm_oct_sgmii_poll; + + /* FIXME: Need autoneg logic */ + return 0; +} + +void cvm_oct_sgmii_uninit(struct net_device *dev) +{ + cvm_oct_common_uninit(dev); +} |