Release 4.7 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 | 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 | david daney | 122 | 71.76% | 2 | 28.57% |
aaro koskinen | aaro koskinen | 45 | 26.47% | 2 | 28.57% |
andrew lunn | andrew lunn | 1 | 0.59% | 1 | 14.29% |
gulsah kose | gulsah kose | 1 | 0.59% | 1 | 14.29% |
christian dietrich | christian dietrich | 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_autoconf(priv->port);
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 |
david daney | david daney | 65 | 57.02% | 3 | 50.00% |
aaro koskinen | aaro koskinen | 48 | 42.11% | 2 | 33.33% |
andrew lunn | andrew lunn | 1 | 0.88% | 1 | 16.67% |
| Total | 114 | 100.00% | 6 | 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 (priv->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 | david daney | 54 | 61.36% | 1 | 33.33% |
aaro koskinen | aaro koskinen | 34 | 38.64% | 2 | 66.67% |
| Total | 88 | 100.00% | 3 | 100.00% |
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aaro koskinen | aaro koskinen | 293 | 49.83% | 6 | 40.00% |
david daney | david daney | 288 | 48.98% | 6 | 40.00% |
christian dietrich | christian dietrich | 4 | 0.68% | 1 | 6.67% |
andrew lunn | andrew lunn | 2 | 0.34% | 1 | 6.67% |
gulsah kose | gulsah kose | 1 | 0.17% | 1 | 6.67% |
| Total | 588 | 100.00% | 15 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.