diff options
Diffstat (limited to 'drivers/staging/octeon/ethernet-rgmii.c')
-rw-r--r-- | drivers/staging/octeon/ethernet-rgmii.c | 158 |
1 files changed, 0 insertions, 158 deletions
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c deleted file mode 100644 index 0c4fac31540a..000000000000 --- a/drivers/staging/octeon/ethernet-rgmii.c +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * This file is based on code from OCTEON SDK by Cavium Networks. - * - * Copyright (c) 2003-2007 Cavium Networks - */ - -#include <linux/kernel.h> -#include <linux/netdevice.h> -#include <linux/interrupt.h> -#include <linux/phy.h> -#include <linux/ratelimit.h> -#include <net/dst.h> - -#include "octeon-ethernet.h" -#include "ethernet-defines.h" -#include "ethernet-util.h" -#include "ethernet-mdio.h" - -static DEFINE_SPINLOCK(global_register_lock); - -static void cvm_oct_set_hw_preamble(struct octeon_ethernet *priv, bool enable) -{ - union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; - union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs; - union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg; - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - - /* Set preamble checking. */ - gmxx_rxx_frm_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, - interface)); - gmxx_rxx_frm_ctl.s.pre_chk = enable; - cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface), - gmxx_rxx_frm_ctl.u64); - - /* Set FCS stripping. */ - ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS); - if (enable) - ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port; - else - ipd_sub_port_fcs.s.port_bit &= - 0xffffffffull ^ (1ull << priv->port); - cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64); - - /* Clear any error bits. */ - gmxx_rxx_int_reg.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, - interface)); - cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), - gmxx_rxx_int_reg.u64); -} - -static void cvm_oct_check_preamble_errors(struct net_device *dev) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - union cvmx_helper_link_info link_info; - unsigned long flags; - - link_info.u64 = priv->link_info; - - /* - * Take the global register lock since we are going to - * touch registers that affect more than one port. - */ - spin_lock_irqsave(&global_register_lock, flags); - - if (link_info.s.speed == 10 && priv->last_speed == 10) { - /* - * Read the GMXX_RXX_INT_REG[PCTERR] bit and see if we are - * getting preamble errors. - */ - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg; - - gmxx_rxx_int_reg.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_REG - (index, interface)); - if (gmxx_rxx_int_reg.s.pcterr) { - /* - * We are getting preamble errors at 10Mbps. Most - * likely the PHY is giving us packets with misaligned - * preambles. In order to get these packets we need to - * disable preamble checking and do it in software. - */ - cvm_oct_set_hw_preamble(priv, false); - printk_ratelimited("%s: Using 10Mbps with software preamble removal\n", - dev->name); - } - } else { - /* - * Since the 10Mbps preamble workaround is allowed we need to - * enable preamble checking, FCS stripping, and clear error - * bits on every speed change. If errors occur during 10Mbps - * operation the above code will change this stuff - */ - if (priv->last_speed != link_info.s.speed) - cvm_oct_set_hw_preamble(priv, true); - priv->last_speed = link_info.s.speed; - } - spin_unlock_irqrestore(&global_register_lock, flags); -} - -static void cvm_oct_rgmii_poll(struct net_device *dev) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - union cvmx_helper_link_info link_info; - bool status_change; - - link_info = cvmx_helper_link_get(priv->port); - if (priv->link_info != link_info.u64 && - cvmx_helper_link_set(priv->port, link_info)) - link_info.u64 = priv->link_info; - status_change = priv->link_info != link_info.u64; - priv->link_info = link_info.u64; - - cvm_oct_check_preamble_errors(dev); - - if (likely(!status_change)) - return; - - /* Tell core. */ - if (link_info.s.link_up) { - if (!netif_carrier_ok(dev)) - netif_carrier_on(dev); - } else if (netif_carrier_ok(dev)) { - netif_carrier_off(dev); - } - cvm_oct_note_carrier(priv, link_info); -} - -int cvm_oct_rgmii_open(struct net_device *dev) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - int ret; - - ret = cvm_oct_common_open(dev, cvm_oct_rgmii_poll); - if (ret) - return ret; - - if (dev->phydev) { - /* - * In phydev mode, we need still periodic polling for the - * preamble error checking, and we also need to call this - * function on every link state change. - * - * Only true RGMII ports need to be polled. In GMII mode, port - * 0 is really a RGMII port. - */ - if ((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII && - priv->port == 0) || - (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) { - priv->poll = cvm_oct_check_preamble_errors; - cvm_oct_check_preamble_errors(dev); - } - } - - return 0; -} |