1/* 2 * This file is based on code from OCTEON SDK by Cavium Networks. 3 * 4 * Copyright (c) 2003-2007 Cavium Networks 5 * 6 * This file is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, Version 2, as 8 * published by the Free Software Foundation. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/netdevice.h> 13#include <linux/interrupt.h> 14#include <linux/phy.h> 15#include <linux/ratelimit.h> 16#include <net/dst.h> 17 18#include <asm/octeon/octeon.h> 19 20#include "ethernet-defines.h" 21#include "octeon-ethernet.h" 22#include "ethernet-util.h" 23#include "ethernet-mdio.h" 24 25#include <asm/octeon/cvmx-helper.h> 26 27#include <asm/octeon/cvmx-ipd-defs.h> 28#include <asm/octeon/cvmx-npi-defs.h> 29#include <asm/octeon/cvmx-gmxx-defs.h> 30 31static DEFINE_SPINLOCK(global_register_lock); 32 33static int number_rgmii_ports; 34 35static void cvm_oct_set_hw_preamble(struct octeon_ethernet *priv, bool enable) 36{ 37 union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; 38 union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs; 39 union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg; 40 int interface = INTERFACE(priv->port); 41 int index = INDEX(priv->port); 42 43 /* Set preamble checking. */ 44 gmxx_rxx_frm_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, 45 interface)); 46 gmxx_rxx_frm_ctl.s.pre_chk = enable; 47 cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface), 48 gmxx_rxx_frm_ctl.u64); 49 50 /* Set FCS stripping. */ 51 ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS); 52 if (enable) 53 ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port; 54 else 55 ipd_sub_port_fcs.s.port_bit &= 56 0xffffffffull ^ (1ull << priv->port); 57 cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64); 58 59 /* Clear any error bits. */ 60 gmxx_rxx_int_reg.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, 61 interface)); 62 cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), 63 gmxx_rxx_int_reg.u64); 64} 65 66static void cvm_oct_rgmii_poll(struct net_device *dev) 67{ 68 struct octeon_ethernet *priv = netdev_priv(dev); 69 unsigned long flags = 0; 70 cvmx_helper_link_info_t link_info; 71 int use_global_register_lock = (priv->phydev == NULL); 72 73 BUG_ON(in_interrupt()); 74 if (use_global_register_lock) { 75 /* 76 * Take the global register lock since we are going to 77 * touch registers that affect more than one port. 78 */ 79 spin_lock_irqsave(&global_register_lock, flags); 80 } else { 81 mutex_lock(&priv->phydev->bus->mdio_lock); 82 } 83 84 link_info = cvmx_helper_link_get(priv->port); 85 if (link_info.u64 == priv->link_info) { 86 if (link_info.s.speed == 10) { 87 /* 88 * Read the GMXX_RXX_INT_REG[PCTERR] bit and 89 * see if we are getting preamble errors. 90 */ 91 int interface = INTERFACE(priv->port); 92 int index = INDEX(priv->port); 93 union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg; 94 95 gmxx_rxx_int_reg.u64 = 96 cvmx_read_csr(CVMX_GMXX_RXX_INT_REG 97 (index, interface)); 98 if (gmxx_rxx_int_reg.s.pcterr) { 99 /* 100 * We are getting preamble errors at 101 * 10Mbps. Most likely the PHY is 102 * giving us packets with mis aligned 103 * preambles. In order to get these 104 * packets we need to disable preamble 105 * checking and do it in software. 106 */ 107 cvm_oct_set_hw_preamble(priv, false); 108 printk_ratelimited("%s: Using 10Mbps with software preamble removal\n", 109 dev->name); 110 } 111 } 112 113 if (use_global_register_lock) 114 spin_unlock_irqrestore(&global_register_lock, flags); 115 else 116 mutex_unlock(&priv->phydev->bus->mdio_lock); 117 return; 118 } 119 120 /* Since the 10Mbps preamble workaround is allowed we need to enable 121 * preamble checking, FCS stripping, and clear error bits on 122 * every speed change. If errors occur during 10Mbps operation 123 * the above code will change this stuff 124 */ 125 cvm_oct_set_hw_preamble(priv, true); 126 127 if (priv->phydev == NULL) { 128 link_info = cvmx_helper_link_autoconf(priv->port); 129 priv->link_info = link_info.u64; 130 } 131 132 if (use_global_register_lock) 133 spin_unlock_irqrestore(&global_register_lock, flags); 134 else 135 mutex_unlock(&priv->phydev->bus->mdio_lock); 136 137 if (priv->phydev == NULL) { 138 /* Tell core. */ 139 if (link_info.s.link_up) { 140 if (!netif_carrier_ok(dev)) 141 netif_carrier_on(dev); 142 } else if (netif_carrier_ok(dev)) { 143 netif_carrier_off(dev); 144 } 145 cvm_oct_note_carrier(priv, link_info); 146 } 147} 148 149static int cmv_oct_rgmii_gmx_interrupt(int interface) 150{ 151 int index; 152 int count = 0; 153 154 /* Loop through every port of this interface */ 155 for (index = 0; 156 index < cvmx_helper_ports_on_interface(interface); 157 index++) { 158 union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg; 159 160 /* Read the GMX interrupt status bits */ 161 gmx_rx_int_reg.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_REG 162 (index, interface)); 163 gmx_rx_int_reg.u64 &= cvmx_read_csr(CVMX_GMXX_RXX_INT_EN 164 (index, interface)); 165 166 /* Poll the port if inband status changed */ 167 if (gmx_rx_int_reg.s.phy_dupx || gmx_rx_int_reg.s.phy_link || 168 gmx_rx_int_reg.s.phy_spd) { 169 struct net_device *dev = 170 cvm_oct_device[cvmx_helper_get_ipd_port 171 (interface, index)]; 172 struct octeon_ethernet *priv = netdev_priv(dev); 173 174 if (dev && !atomic_read(&cvm_oct_poll_queue_stopping)) 175 queue_work(cvm_oct_poll_queue, 176 &priv->port_work); 177 178 gmx_rx_int_reg.u64 = 0; 179 gmx_rx_int_reg.s.phy_dupx = 1; 180 gmx_rx_int_reg.s.phy_link = 1; 181 gmx_rx_int_reg.s.phy_spd = 1; 182 cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), 183 gmx_rx_int_reg.u64); 184 count++; 185 } 186 } 187 return count; 188} 189 190static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id) 191{ 192 union cvmx_npi_rsl_int_blocks rsl_int_blocks; 193 int count = 0; 194 195 rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS); 196 197 /* Check and see if this interrupt was caused by the GMX0 block */ 198 if (rsl_int_blocks.s.gmx0) 199 count += cmv_oct_rgmii_gmx_interrupt(0); 200 201 /* Check and see if this interrupt was caused by the GMX1 block */ 202 if (rsl_int_blocks.s.gmx1) 203 count += cmv_oct_rgmii_gmx_interrupt(1); 204 205 return count ? IRQ_HANDLED : IRQ_NONE; 206} 207 208int cvm_oct_rgmii_open(struct net_device *dev) 209{ 210 return cvm_oct_common_open(dev, cvm_oct_rgmii_poll); 211} 212 213static void cvm_oct_rgmii_immediate_poll(struct work_struct *work) 214{ 215 struct octeon_ethernet *priv = 216 container_of(work, struct octeon_ethernet, port_work); 217 cvm_oct_rgmii_poll(cvm_oct_device[priv->port]); 218} 219 220int cvm_oct_rgmii_init(struct net_device *dev) 221{ 222 struct octeon_ethernet *priv = netdev_priv(dev); 223 int r; 224 225 cvm_oct_common_init(dev); 226 INIT_WORK(&priv->port_work, cvm_oct_rgmii_immediate_poll); 227 /* 228 * Due to GMX errata in CN3XXX series chips, it is necessary 229 * to take the link down immediately when the PHY changes 230 * state. In order to do this we call the poll function every 231 * time the RGMII inband status changes. This may cause 232 * problems if the PHY doesn't implement inband status 233 * properly. 234 */ 235 if (number_rgmii_ports == 0) { 236 r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt, 237 IRQF_SHARED, "RGMII", &number_rgmii_ports); 238 if (r != 0) 239 return r; 240 } 241 number_rgmii_ports++; 242 243 /* 244 * Only true RGMII ports need to be polled. In GMII mode, port 245 * 0 is really a RGMII port. 246 */ 247 if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII) 248 && (priv->port == 0)) 249 || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) { 250 251 if (!octeon_is_simulation()) { 252 253 union cvmx_gmxx_rxx_int_en gmx_rx_int_en; 254 int interface = INTERFACE(priv->port); 255 int index = INDEX(priv->port); 256 257 /* 258 * Enable interrupts on inband status changes 259 * for this port. 260 */ 261 gmx_rx_int_en.u64 = 0; 262 gmx_rx_int_en.s.phy_dupx = 1; 263 gmx_rx_int_en.s.phy_link = 1; 264 gmx_rx_int_en.s.phy_spd = 1; 265 cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface), 266 gmx_rx_int_en.u64); 267 } 268 } 269 270 return 0; 271} 272 273void cvm_oct_rgmii_uninit(struct net_device *dev) 274{ 275 struct octeon_ethernet *priv = netdev_priv(dev); 276 277 cvm_oct_common_uninit(dev); 278 279 /* 280 * Only true RGMII ports need to be polled. In GMII mode, port 281 * 0 is really a RGMII port. 282 */ 283 if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII) 284 && (priv->port == 0)) 285 || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) { 286 287 if (!octeon_is_simulation()) { 288 289 union cvmx_gmxx_rxx_int_en gmx_rx_int_en; 290 int interface = INTERFACE(priv->port); 291 int index = INDEX(priv->port); 292 293 /* 294 * Disable interrupts on inband status changes 295 * for this port. 296 */ 297 gmx_rx_int_en.u64 = 298 cvmx_read_csr(CVMX_GMXX_RXX_INT_EN 299 (index, interface)); 300 gmx_rx_int_en.s.phy_dupx = 0; 301 gmx_rx_int_en.s.phy_link = 0; 302 gmx_rx_int_en.s.phy_spd = 0; 303 cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface), 304 gmx_rx_int_en.u64); 305 } 306 } 307 308 /* Remove the interrupt handler when the last port is removed. */ 309 number_rgmii_ports--; 310 if (number_rgmii_ports == 0) 311 free_irq(OCTEON_IRQ_RML, &number_rgmii_ports); 312 cancel_work_sync(&priv->port_work); 313} 314