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 <net/dst.h> 30 31#include <asm/octeon/octeon.h> 32 33#include "ethernet-defines.h" 34#include "octeon-ethernet.h" 35#include "ethernet-util.h" 36 37#include "cvmx-helper.h" 38 39#include "cvmx-gmxx-defs.h" 40 41int cvm_oct_xaui_open(struct net_device *dev) 42{ 43 union cvmx_gmxx_prtx_cfg gmx_cfg; 44 struct octeon_ethernet *priv = netdev_priv(dev); 45 int interface = INTERFACE(priv->port); 46 int index = INDEX(priv->port); 47 cvmx_helper_link_info_t link_info; 48 49 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 50 gmx_cfg.s.en = 1; 51 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 52 53 if (!octeon_is_simulation()) { 54 link_info = cvmx_helper_link_get(priv->port); 55 if (!link_info.s.link_up) 56 netif_carrier_off(dev); 57 } 58 return 0; 59} 60 61int cvm_oct_xaui_stop(struct net_device *dev) 62{ 63 union cvmx_gmxx_prtx_cfg gmx_cfg; 64 struct octeon_ethernet *priv = netdev_priv(dev); 65 int interface = INTERFACE(priv->port); 66 int index = INDEX(priv->port); 67 68 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 69 gmx_cfg.s.en = 0; 70 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 71 return 0; 72} 73 74static void cvm_oct_xaui_poll(struct net_device *dev) 75{ 76 struct octeon_ethernet *priv = netdev_priv(dev); 77 cvmx_helper_link_info_t link_info; 78 79 link_info = cvmx_helper_link_get(priv->port); 80 if (link_info.u64 == priv->link_info) 81 return; 82 83 link_info = cvmx_helper_link_autoconf(priv->port); 84 priv->link_info = link_info.u64; 85 86 /* Tell Linux */ 87 if (link_info.s.link_up) { 88 89 if (!netif_carrier_ok(dev)) 90 netif_carrier_on(dev); 91 if (priv->queue != -1) 92 DEBUGPRINT 93 ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", 94 dev->name, link_info.s.speed, 95 (link_info.s.full_duplex) ? "Full" : "Half", 96 priv->port, priv->queue); 97 else 98 DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", 99 dev->name, link_info.s.speed, 100 (link_info.s.full_duplex) ? "Full" : "Half", 101 priv->port); 102 } else { 103 if (netif_carrier_ok(dev)) 104 netif_carrier_off(dev); 105 DEBUGPRINT("%s: Link down\n", dev->name); 106 } 107} 108 109int cvm_oct_xaui_init(struct net_device *dev) 110{ 111 struct octeon_ethernet *priv = netdev_priv(dev); 112 cvm_oct_common_init(dev); 113 dev->netdev_ops->ndo_stop(dev); 114 if (!octeon_is_simulation() && priv->phydev == NULL) 115 priv->poll = cvm_oct_xaui_poll; 116 117 return 0; 118} 119 120void cvm_oct_xaui_uninit(struct net_device *dev) 121{ 122 cvm_oct_common_uninit(dev); 123} 124