Release 4.12 drivers/staging/octeon/ethernet-rgmii.c
  
  
  
/*
 * This file is based on code from OCTEON SDK by Cavium Networks.
 *
 * Copyright (c) 2003-2007 Cavium Networks
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, Version 2, as
 * published by the Free Software Foundation.
 */
#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 <asm/octeon/octeon.h>
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-ipd-defs.h>
#include <asm/octeon/cvmx-npi-defs.h>
#include <asm/octeon/cvmx-gmxx-defs.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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Aaro Koskinen | 164 | 100.00% | 1 | 100.00% | 
| Total | 164 | 100.00% | 1 | 100.00% | 
static void cvm_oct_check_preamble_errors(struct net_device *dev)
{
	struct octeon_ethernet *priv = netdev_priv(dev);
	cvmx_helper_link_info_t 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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| David Daney | 122 | 71.76% | 2 | 28.57% | 
| Aaro Koskinen | 45 | 26.47% | 2 | 28.57% | 
| Christian Dietrich | 1 | 0.59% | 1 | 14.29% | 
| Gulsah Kose | 1 | 0.59% | 1 | 14.29% | 
| Andrew Lunn | 1 | 0.59% | 1 | 14.29% | 
| Total | 170 | 100.00% | 7 | 100.00% | 
static void cvm_oct_rgmii_poll(struct net_device *dev)
{
	struct octeon_ethernet *priv = netdev_priv(dev);
	cvmx_helper_link_info_t 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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Aaro Koskinen | 76 | 53.90% | 3 | 42.86% | 
| David Daney | 64 | 45.39% | 3 | 42.86% | 
| Andrew Lunn | 1 | 0.71% | 1 | 14.29% | 
| Total | 141 | 100.00% | 7 | 100.00% | 
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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| David Daney | 54 | 61.36% | 1 | 25.00% | 
| Aaro Koskinen | 33 | 37.50% | 2 | 50.00% | 
| Philippe Reynes | 1 | 1.14% | 1 | 25.00% | 
| Total | 88 | 100.00% | 4 | 100.00% | 
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Aaro Koskinen | 320 | 52.03% | 7 | 41.18% | 
| David Daney | 287 | 46.67% | 6 | 35.29% | 
| Christian Dietrich | 4 | 0.65% | 1 | 5.88% | 
| Andrew Lunn | 2 | 0.33% | 1 | 5.88% | 
| Gulsah Kose | 1 | 0.16% | 1 | 5.88% | 
| Philippe Reynes | 1 | 0.16% | 1 | 5.88% | 
| Total | 615 | 100.00% | 17 | 100.00% | 
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.