PageRenderTime 26ms CodeModel.GetById 20ms app.highlight 5ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/octeon/ethernet-sgmii.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t
C | 127 lines | 81 code | 18 blank | 28 comment | 13 complexity | 139dbdb6777b00745f895ea743ccc7cb MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  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 "cvmx-helper.h"
 39
 40#include "cvmx-gmxx-defs.h"
 41
 42int cvm_oct_sgmii_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
 60	return 0;
 61}
 62
 63int cvm_oct_sgmii_stop(struct net_device *dev)
 64{
 65	union cvmx_gmxx_prtx_cfg gmx_cfg;
 66	struct octeon_ethernet *priv = netdev_priv(dev);
 67	int interface = INTERFACE(priv->port);
 68	int index = INDEX(priv->port);
 69
 70	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
 71	gmx_cfg.s.en = 0;
 72	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
 73	return 0;
 74}
 75
 76static void cvm_oct_sgmii_poll(struct net_device *dev)
 77{
 78	struct octeon_ethernet *priv = netdev_priv(dev);
 79	cvmx_helper_link_info_t link_info;
 80
 81	link_info = cvmx_helper_link_get(priv->port);
 82	if (link_info.u64 == priv->link_info)
 83		return;
 84
 85	link_info = cvmx_helper_link_autoconf(priv->port);
 86	priv->link_info = link_info.u64;
 87
 88	/* Tell Linux */
 89	if (link_info.s.link_up) {
 90
 91		if (!netif_carrier_ok(dev))
 92			netif_carrier_on(dev);
 93		if (priv->queue != -1)
 94			printk_ratelimited
 95			    ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
 96			     dev->name, link_info.s.speed,
 97			     (link_info.s.full_duplex) ? "Full" : "Half",
 98			     priv->port, priv->queue);
 99		else
100			printk_ratelimited
101				("%s: %u Mbps %s duplex, port %2d, POW\n",
102				 dev->name, link_info.s.speed,
103				 (link_info.s.full_duplex) ? "Full" : "Half",
104				 priv->port);
105	} else {
106		if (netif_carrier_ok(dev))
107			netif_carrier_off(dev);
108		printk_ratelimited("%s: Link down\n", dev->name);
109	}
110}
111
112int cvm_oct_sgmii_init(struct net_device *dev)
113{
114	struct octeon_ethernet *priv = netdev_priv(dev);
115	cvm_oct_common_init(dev);
116	dev->netdev_ops->ndo_stop(dev);
117	if (!octeon_is_simulation() && priv->phydev == NULL)
118		priv->poll = cvm_oct_sgmii_poll;
119
120	/* FIXME: Need autoneg logic */
121	return 0;
122}
123
124void cvm_oct_sgmii_uninit(struct net_device *dev)
125{
126	cvm_oct_common_uninit(dev);
127}