ethernet-sgmii.c revision 7a2eaf9358250706672783eb8511835706b0922b
180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney/********************************************************************** 280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * Author: Cavium Networks 380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * 480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * Contact: support@caviumnetworks.com 580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * This file is part of the OCTEON SDK 680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * 780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * Copyright (c) 2003-2007 Cavium Networks 880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * 980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * This file is free software; you can redistribute it and/or modify 1080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * it under the terms of the GNU General Public License, Version 2, as 1180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * published by the Free Software Foundation. 1280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * 1380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * This file is distributed in the hope that it will be useful, but 1480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 1580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 1680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * NONINFRINGEMENT. See the GNU General Public License for more 1780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * details. 1880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * 1980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * You should have received a copy of the GNU General Public License 2080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * along with this file; if not, write to the Free Software 2180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * or visit http://www.gnu.org/licenses/. 2380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * 2480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * This file may also be available under a different license from Cavium. 2580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney * Contact Cavium Networks for more information 2680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney**********************************************************************/ 2780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include <linux/kernel.h> 2880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include <linux/netdevice.h> 297a2eaf9358250706672783eb8511835706b0922bChristian Dietrich#include <linux/ratelimit.h> 3080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include <net/dst.h> 3180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 3280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include <asm/octeon/octeon.h> 3380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 3480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include "ethernet-defines.h" 3580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include "octeon-ethernet.h" 3680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include "ethernet-util.h" 3780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 3880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include "cvmx-helper.h" 3980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 4080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney#include "cvmx-gmxx-defs.h" 4180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 42f696a10838ffab85e5bc07e7cff0d0e1870a30d7David Daneyint cvm_oct_sgmii_open(struct net_device *dev) 4380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney{ 4480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney union cvmx_gmxx_prtx_cfg gmx_cfg; 4580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney struct octeon_ethernet *priv = netdev_priv(dev); 4680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney int interface = INTERFACE(priv->port); 4780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney int index = INDEX(priv->port); 4880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney cvmx_helper_link_info_t link_info; 4980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 5080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 5180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney gmx_cfg.s.en = 1; 5280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 5380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 5480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney if (!octeon_is_simulation()) { 5580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney link_info = cvmx_helper_link_get(priv->port); 5680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney if (!link_info.s.link_up) 5780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney netif_carrier_off(dev); 5880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney } 5980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 6080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney return 0; 6180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney} 6280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 63f696a10838ffab85e5bc07e7cff0d0e1870a30d7David Daneyint cvm_oct_sgmii_stop(struct net_device *dev) 6480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney{ 6580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney union cvmx_gmxx_prtx_cfg gmx_cfg; 6680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney struct octeon_ethernet *priv = netdev_priv(dev); 6780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney int interface = INTERFACE(priv->port); 6880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney int index = INDEX(priv->port); 6980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 7080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 7180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney gmx_cfg.s.en = 0; 7280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 7380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney return 0; 7480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney} 7580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 7680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daneystatic void cvm_oct_sgmii_poll(struct net_device *dev) 7780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney{ 7880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney struct octeon_ethernet *priv = netdev_priv(dev); 7980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney cvmx_helper_link_info_t link_info; 8080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 8180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney link_info = cvmx_helper_link_get(priv->port); 8280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney if (link_info.u64 == priv->link_info) 8380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney return; 8480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 8580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney link_info = cvmx_helper_link_autoconf(priv->port); 8680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney priv->link_info = link_info.u64; 8780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 8880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney /* Tell Linux */ 8980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney if (link_info.s.link_up) { 9080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 9180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney if (!netif_carrier_ok(dev)) 9280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney netif_carrier_on(dev); 9380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney if (priv->queue != -1) 947a2eaf9358250706672783eb8511835706b0922bChristian Dietrich printk_ratelimited 9580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", 9680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney dev->name, link_info.s.speed, 9780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney (link_info.s.full_duplex) ? "Full" : "Half", 9880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney priv->port, priv->queue); 9980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney else 1007a2eaf9358250706672783eb8511835706b0922bChristian Dietrich printk_ratelimited 1017a2eaf9358250706672783eb8511835706b0922bChristian Dietrich ("%s: %u Mbps %s duplex, port %2d, POW\n", 1027a2eaf9358250706672783eb8511835706b0922bChristian Dietrich dev->name, link_info.s.speed, 1037a2eaf9358250706672783eb8511835706b0922bChristian Dietrich (link_info.s.full_duplex) ? "Full" : "Half", 1047a2eaf9358250706672783eb8511835706b0922bChristian Dietrich priv->port); 10580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney } else { 10680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney if (netif_carrier_ok(dev)) 10780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney netif_carrier_off(dev); 1087a2eaf9358250706672783eb8511835706b0922bChristian Dietrich printk_ratelimited("%s: Link down\n", dev->name); 10980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney } 11080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney} 11180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 11280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daneyint cvm_oct_sgmii_init(struct net_device *dev) 11380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney{ 11480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney struct octeon_ethernet *priv = netdev_priv(dev); 11580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney cvm_oct_common_init(dev); 116f696a10838ffab85e5bc07e7cff0d0e1870a30d7David Daney dev->netdev_ops->ndo_stop(dev); 117f6ed1b3b3579db5c8c3aaf6fd3010c706973a35dDavid Daney if (!octeon_is_simulation() && priv->phydev == NULL) 11880ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney priv->poll = cvm_oct_sgmii_poll; 11980ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 12080ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney /* FIXME: Need autoneg logic */ 12180ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney return 0; 12280ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney} 12380ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney 12480ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daneyvoid cvm_oct_sgmii_uninit(struct net_device *dev) 12580ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney{ 12680ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney cvm_oct_common_uninit(dev); 12780ff0fd3ab6451407a20c19b80c1643c4a6d6434David Daney} 128