diff options
Diffstat (limited to 'kernel/drivers/staging/octeon')
-rw-r--r-- | kernel/drivers/staging/octeon/Makefile | 2 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-defines.h | 67 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-mdio.c | 48 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-mdio.h | 26 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-mem.c | 30 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-mem.h | 23 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-rgmii.c | 313 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-rx.c | 181 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-rx.h | 24 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-sgmii.c | 112 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-spi.c | 237 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-tx.c | 65 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-tx.h | 23 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-util.h | 45 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet-xaui.c | 144 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/ethernet.c | 159 | ||||
-rw-r--r-- | kernel/drivers/staging/octeon/octeon-ethernet.h | 57 |
17 files changed, 502 insertions, 1054 deletions
diff --git a/kernel/drivers/staging/octeon/Makefile b/kernel/drivers/staging/octeon/Makefile index 9012dee0c..8ca17210d 100644 --- a/kernel/drivers/staging/octeon/Makefile +++ b/kernel/drivers/staging/octeon/Makefile @@ -19,5 +19,3 @@ octeon-ethernet-y += ethernet-rx.o octeon-ethernet-y += ethernet-sgmii.o octeon-ethernet-y += ethernet-spi.o octeon-ethernet-y += ethernet-tx.o -octeon-ethernet-y += ethernet-xaui.o - diff --git a/kernel/drivers/staging/octeon/ethernet-defines.h b/kernel/drivers/staging/octeon/ethernet-defines.h index 2a98a2153..13e4cee1f 100644 --- a/kernel/drivers/staging/octeon/ethernet-defines.h +++ b/kernel/drivers/staging/octeon/ethernet-defines.h @@ -1,46 +1,15 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ /* * A few defines are used to control the operation of this driver: - * CONFIG_CAVIUM_RESERVE32 - * This kernel config options controls the amount of memory configured - * in a wired TLB entry for all processes to share. If this is set, the - * driver will use this memory instead of kernel memory for pools. This - * allows 32bit userspace application to access the buffers, but also - * requires all received packets to be copied. - * USE_SKBUFFS_IN_HW - * Tells the driver to populate the packet buffers with kernel skbuffs. - * This allows the driver to receive packets without copying them. It also - * means that 32bit userspace can't access the packet buffers. - * USE_HW_TCPUDP_CHECKSUM - * Controls if the Octeon TCP/UDP checksum engine is used for packet - * output. If this is zero, the kernel will perform the checksum in - * software. * USE_ASYNC_IOBDMA * Use asynchronous IO access to hardware. This uses Octeon's asynchronous * IOBDMAs to issue IO accesses without stalling. Set this to zero @@ -57,46 +26,20 @@ #include <asm/octeon/cvmx-config.h> - -#define OCTEON_ETHERNET_VERSION "1.9" - -#ifndef CONFIG_CAVIUM_RESERVE32 -#define CONFIG_CAVIUM_RESERVE32 0 -#endif - -#define USE_SKBUFFS_IN_HW 1 #ifdef CONFIG_NETFILTER #define REUSE_SKBUFFS_WITHOUT_FREE 0 #else #define REUSE_SKBUFFS_WITHOUT_FREE 1 #endif -#define USE_HW_TCPUDP_CHECKSUM 1 - -/* Enable Random Early Dropping under load */ -#define USE_RED 1 #define USE_ASYNC_IOBDMA (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0) -/* - * Allow SW based preamble removal at 10Mbps to workaround PHYs giving - * us bad preambles. - */ -#define USE_10MBPS_PREAMBLE_WORKAROUND 1 -/* - * Use this to have all FPA frees also tell the L2 not to write data - * to memory. - */ -#define DONT_WRITEBACK(x) (x) -/* Use this to not have FPA frees control L2 */ -/*#define DONT_WRITEBACK(x) 0 */ - /* Maximum number of SKBs to try to free per xmit packet. */ #define MAX_OUT_QUEUE_DEPTH 1000 -#define FAU_TOTAL_TX_TO_CLEAN (CVMX_FAU_REG_END - sizeof(uint32_t)) -#define FAU_NUM_PACKET_BUFFERS_TO_FREE (FAU_TOTAL_TX_TO_CLEAN - sizeof(uint32_t)) +#define FAU_TOTAL_TX_TO_CLEAN (CVMX_FAU_REG_END - sizeof(u32)) +#define FAU_NUM_PACKET_BUFFERS_TO_FREE (FAU_TOTAL_TX_TO_CLEAN - sizeof(u32)) #define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS+1) - #endif /* __ETHERNET_DEFINES_H__ */ diff --git a/kernel/drivers/staging/octeon/ethernet-mdio.c b/kernel/drivers/staging/octeon/ethernet-mdio.c index 40dab11e5..fd9b3d899 100644 --- a/kernel/drivers/staging/octeon/ethernet-mdio.c +++ b/kernel/drivers/staging/octeon/ethernet-mdio.c @@ -1,35 +1,19 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ + #include <linux/kernel.h> #include <linux/ethtool.h> #include <linux/phy.h> #include <linux/ratelimit.h> #include <linux/of_mdio.h> - +#include <generated/utsrelease.h> #include <net/dst.h> #include <asm/octeon/octeon.h> @@ -39,15 +23,14 @@ #include "ethernet-mdio.h" #include "ethernet-util.h" -#include <asm/octeon/cvmx-helper-board.h> - +#include <asm/octeon/cvmx-gmxx-defs.h> #include <asm/octeon/cvmx-smix-defs.h> static void cvm_oct_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - strlcpy(info->driver, "cavium-ethernet", sizeof(info->driver)); - strlcpy(info->version, OCTEON_ETHERNET_VERSION, sizeof(info->version)); + strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); + strlcpy(info->version, UTS_RELEASE, sizeof(info->version)); strlcpy(info->bus_info, "Builtin", sizeof(info->bus_info)); } @@ -116,14 +99,14 @@ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return phy_mii_ioctl(priv->phydev, rq, cmd); } -static void cvm_oct_note_carrier(struct octeon_ethernet *priv, - cvmx_helper_link_info_t li) +void cvm_oct_note_carrier(struct octeon_ethernet *priv, + cvmx_helper_link_info_t li) { if (li.s.link_up) { - pr_notice_ratelimited("%s: %u Mbps %s duplex, port %d\n", + pr_notice_ratelimited("%s: %u Mbps %s duplex, port %d, queue %d\n", netdev_name(priv->netdev), li.s.speed, (li.s.full_duplex) ? "Full" : "Half", - priv->port); + priv->port, priv->queue); } else { pr_notice_ratelimited("%s: Link down\n", netdev_name(priv->netdev)); @@ -150,7 +133,14 @@ void cvm_oct_adjust_link(struct net_device *dev) int cvm_oct_common_stop(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); + int interface = INTERFACE(priv->port); cvmx_helper_link_info_t link_info; + union cvmx_gmxx_prtx_cfg gmx_cfg; + int index = INDEX(priv->port); + + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); + gmx_cfg.s.en = 0; + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); priv->poll = NULL; diff --git a/kernel/drivers/staging/octeon/ethernet-mdio.h b/kernel/drivers/staging/octeon/ethernet-mdio.h index 6191b0850..5ed8483fc 100644 --- a/kernel/drivers/staging/octeon/ethernet-mdio.h +++ b/kernel/drivers/staging/octeon/ethernet-mdio.h @@ -1,29 +1,13 @@ -/********************************************************************* - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -*********************************************************************/ + */ + #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> @@ -41,7 +25,7 @@ extern const struct ethtool_ops cvm_oct_ethtool_ops; -extern void octeon_mdiobus_force_mod_depencency(void); +void octeon_mdiobus_force_mod_depencency(void); int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int cvm_oct_phy_setup_device(struct net_device *dev); diff --git a/kernel/drivers/staging/octeon/ethernet-mem.c b/kernel/drivers/staging/octeon/ethernet-mem.c index 964da860f..5a5cdb3cd 100644 --- a/kernel/drivers/staging/octeon/ethernet-mem.c +++ b/kernel/drivers/staging/octeon/ethernet-mem.c @@ -1,29 +1,13 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ + #include <linux/kernel.h> #include <linux/netdevice.h> #include <linux/slab.h> @@ -54,7 +38,7 @@ static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements) break; skb_reserve(skb, 256 - (((unsigned long)skb->data) & 0x7f)); *(struct sk_buff **)(skb->data - sizeof(void *)) = skb; - cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128)); + cvmx_fpa_free(skb->data, pool, size / 128); freed--; } return elements - freed; @@ -160,7 +144,7 @@ int cvm_oct_mem_fill_fpa(int pool, int size, int elements) { int freed; - if (USE_SKBUFFS_IN_HW && pool == CVMX_FPA_PACKET_POOL) + if (pool == CVMX_FPA_PACKET_POOL) freed = cvm_oct_fill_hw_skbuff(pool, size, elements); else freed = cvm_oct_fill_hw_memory(pool, size, elements); @@ -169,7 +153,7 @@ int cvm_oct_mem_fill_fpa(int pool, int size, int elements) void cvm_oct_mem_empty_fpa(int pool, int size, int elements) { - if (USE_SKBUFFS_IN_HW && pool == CVMX_FPA_PACKET_POOL) + if (pool == CVMX_FPA_PACKET_POOL) cvm_oct_free_hw_skbuff(pool, size, elements); else cvm_oct_free_hw_memory(pool, size, elements); diff --git a/kernel/drivers/staging/octeon/ethernet-mem.h b/kernel/drivers/staging/octeon/ethernet-mem.h index 713f2edc8..62d07c426 100644 --- a/kernel/drivers/staging/octeon/ethernet-mem.h +++ b/kernel/drivers/staging/octeon/ethernet-mem.h @@ -1,29 +1,12 @@ -/********************************************************************* - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -********************************************************************/ + */ int cvm_oct_mem_fill_fpa(int pool, int size, int elements); void cvm_oct_mem_empty_fpa(int pool, int size, int elements); diff --git a/kernel/drivers/staging/octeon/ethernet-rgmii.c b/kernel/drivers/staging/octeon/ethernet-rgmii.c index e36f9bc69..613344b88 100644 --- a/kernel/drivers/staging/octeon/ethernet-rgmii.c +++ b/kernel/drivers/staging/octeon/ethernet-rgmii.c @@ -1,29 +1,13 @@ -/********************************************************************* - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ + #include <linux/kernel.h> #include <linux/netdevice.h> #include <linux/interrupt.h> @@ -48,6 +32,37 @@ static DEFINE_SPINLOCK(global_register_lock); static int number_rgmii_ports; +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_rgmii_poll(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); @@ -68,14 +83,7 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) link_info = cvmx_helper_link_get(priv->port); if (link_info.u64 == priv->link_info) { - - /* - * If the 10Mbps preamble workaround is supported and we're - * at 10Mbps we may need to do some special checking. - */ - if (USE_10MBPS_PREAMBLE_WORKAROUND && - (link_info.s.speed == 10)) { - + if (link_info.s.speed == 10) { /* * Read the GMXX_RXX_INT_REG[PCTERR] bit and * see if we are getting preamble errors. @@ -88,7 +96,6 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) 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 @@ -97,30 +104,7 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) * packets we need to disable preamble * checking and do it in software. */ - union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; - union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs; - - /* Disable preamble checking */ - gmxx_rxx_frm_ctl.u64 = - cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL - (index, interface)); - gmxx_rxx_frm_ctl.s.pre_chk = 0; - cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL - (index, interface), - gmxx_rxx_frm_ctl.u64); - - /* Disable FCS stripping */ - ipd_sub_port_fcs.u64 = - cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS); - 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 */ - cvmx_write_csr(CVMX_GMXX_RXX_INT_REG - (index, interface), - gmxx_rxx_int_reg.u64); + cvm_oct_set_hw_preamble(priv, false); printk_ratelimited("%s: Using 10Mbps with software preamble removal\n", dev->name); } @@ -133,34 +117,13 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) return; } - /* If the 10Mbps preamble workaround is allowed we need to on - 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 (USE_10MBPS_PREAMBLE_WORKAROUND) { - - 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); - - /* Enable preamble checking */ - gmxx_rxx_frm_ctl.u64 = - cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface)); - gmxx_rxx_frm_ctl.s.pre_chk = 1; - cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface), - gmxx_rxx_frm_ctl.u64); - /* Enable FCS stripping */ - ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS); - ipd_sub_port_fcs.s.port_bit |= 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); - } + /* 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 + */ + cvm_oct_set_hw_preamble(priv, true); + if (priv->phydev == NULL) { link_info = cvmx_helper_link_autoconf(priv->port); priv->link_info = link_info.u64; @@ -176,172 +139,75 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) if (link_info.s.link_up) { if (!netif_carrier_ok(dev)) netif_carrier_on(dev); - if (priv->queue != -1) - printk_ratelimited("%s: %u Mbps %s duplex, port %2d, queue %2d\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? - "Full" : "Half", - priv->port, priv->queue); - else - printk_ratelimited("%s: %u Mbps %s duplex, port %2d, POW\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? - "Full" : "Half", - priv->port); - } else { - if (netif_carrier_ok(dev)) - netif_carrier_off(dev); - printk_ratelimited("%s: Link down\n", dev->name); + } else if (netif_carrier_ok(dev)) { + netif_carrier_off(dev); } + cvm_oct_note_carrier(priv, link_info); } } -static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id) +static int cmv_oct_rgmii_gmx_interrupt(int interface) { - union cvmx_npi_rsl_int_blocks rsl_int_blocks; int index; - irqreturn_t return_status = IRQ_NONE; + int count = 0; - rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS); - - /* Check and see if this interrupt was caused by the GMX0 block */ - if (rsl_int_blocks.s.gmx0) { - - int interface = 0; - /* Loop through every port of this interface */ - for (index = 0; - index < cvmx_helper_ports_on_interface(interface); - index++) { + /* Loop through every port of this interface */ + for (index = 0; + index < cvmx_helper_ports_on_interface(interface); + index++) { + union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg; - /* Read the GMX interrupt status bits */ - union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg; - - gmx_rx_int_reg.u64 = - cvmx_read_csr(CVMX_GMXX_RXX_INT_REG + /* Read the GMX interrupt status bits */ + gmx_rx_int_reg.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_REG (index, interface)); - gmx_rx_int_reg.u64 &= - cvmx_read_csr(CVMX_GMXX_RXX_INT_EN + gmx_rx_int_reg.u64 &= cvmx_read_csr(CVMX_GMXX_RXX_INT_EN (index, interface)); - /* Poll the port if inband status changed */ - if (gmx_rx_int_reg.s.phy_dupx - || gmx_rx_int_reg.s.phy_link - || gmx_rx_int_reg.s.phy_spd) { - struct net_device *dev = + /* Poll the port if inband status changed */ + if (gmx_rx_int_reg.s.phy_dupx || gmx_rx_int_reg.s.phy_link || + gmx_rx_int_reg.s.phy_spd) { + struct net_device *dev = cvm_oct_device[cvmx_helper_get_ipd_port (interface, index)]; - struct octeon_ethernet *priv = netdev_priv(dev); - - if (dev && - !atomic_read(&cvm_oct_poll_queue_stopping)) - queue_work(cvm_oct_poll_queue, - &priv->port_work); - - gmx_rx_int_reg.u64 = 0; - gmx_rx_int_reg.s.phy_dupx = 1; - gmx_rx_int_reg.s.phy_link = 1; - gmx_rx_int_reg.s.phy_spd = 1; - cvmx_write_csr(CVMX_GMXX_RXX_INT_REG - (index, interface), - gmx_rx_int_reg.u64); - return_status = IRQ_HANDLED; - } + struct octeon_ethernet *priv = netdev_priv(dev); + + if (dev && !atomic_read(&cvm_oct_poll_queue_stopping)) + queue_work(cvm_oct_poll_queue, + &priv->port_work); + + gmx_rx_int_reg.u64 = 0; + gmx_rx_int_reg.s.phy_dupx = 1; + gmx_rx_int_reg.s.phy_link = 1; + gmx_rx_int_reg.s.phy_spd = 1; + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), + gmx_rx_int_reg.u64); + count++; } } + return count; +} - /* Check and see if this interrupt was caused by the GMX1 block */ - if (rsl_int_blocks.s.gmx1) { +static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id) +{ + union cvmx_npi_rsl_int_blocks rsl_int_blocks; + int count = 0; - int interface = 1; - /* Loop through every port of this interface */ - for (index = 0; - index < cvmx_helper_ports_on_interface(interface); - index++) { + rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS); - /* Read the GMX interrupt status bits */ - union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg; + /* Check and see if this interrupt was caused by the GMX0 block */ + if (rsl_int_blocks.s.gmx0) + count += cmv_oct_rgmii_gmx_interrupt(0); - gmx_rx_int_reg.u64 = - cvmx_read_csr(CVMX_GMXX_RXX_INT_REG - (index, interface)); - gmx_rx_int_reg.u64 &= - cvmx_read_csr(CVMX_GMXX_RXX_INT_EN - (index, interface)); - /* Poll the port if inband status changed */ - if (gmx_rx_int_reg.s.phy_dupx - || gmx_rx_int_reg.s.phy_link - || gmx_rx_int_reg.s.phy_spd) { + /* Check and see if this interrupt was caused by the GMX1 block */ + if (rsl_int_blocks.s.gmx1) + count += cmv_oct_rgmii_gmx_interrupt(1); - struct net_device *dev = - cvm_oct_device[cvmx_helper_get_ipd_port - (interface, index)]; - struct octeon_ethernet *priv = netdev_priv(dev); - - if (dev && - !atomic_read(&cvm_oct_poll_queue_stopping)) - queue_work(cvm_oct_poll_queue, - &priv->port_work); - - gmx_rx_int_reg.u64 = 0; - gmx_rx_int_reg.s.phy_dupx = 1; - gmx_rx_int_reg.s.phy_link = 1; - gmx_rx_int_reg.s.phy_spd = 1; - cvmx_write_csr(CVMX_GMXX_RXX_INT_REG - (index, interface), - gmx_rx_int_reg.u64); - return_status = IRQ_HANDLED; - } - } - } - return return_status; + return count ? IRQ_HANDLED : IRQ_NONE; } int cvm_oct_rgmii_open(struct net_device *dev) { - union cvmx_gmxx_prtx_cfg gmx_cfg; - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - cvmx_helper_link_info_t link_info; - int rv; - - rv = cvm_oct_phy_setup_device(dev); - if (rv) - return rv; - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 1; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - - if (!octeon_is_simulation()) { - if (priv->phydev) { - int r = phy_read_status(priv->phydev); - - if (r == 0 && priv->phydev->link == 0) - netif_carrier_off(dev); - cvm_oct_adjust_link(dev); - } else { - link_info = cvmx_helper_link_get(priv->port); - if (!link_info.s.link_up) - netif_carrier_off(dev); - priv->poll = cvm_oct_rgmii_poll; - } - } - - return 0; -} - -int cvm_oct_rgmii_stop(struct net_device *dev) -{ - union cvmx_gmxx_prtx_cfg gmx_cfg; - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 0; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - return cvm_oct_common_stop(dev); + return cvm_oct_common_open(dev, cvm_oct_rgmii_poll); } static void cvm_oct_rgmii_immediate_poll(struct work_struct *work) @@ -357,7 +223,6 @@ int cvm_oct_rgmii_init(struct net_device *dev) int r; cvm_oct_common_init(dev); - dev->netdev_ops->ndo_stop(dev); INIT_WORK(&priv->port_work, cvm_oct_rgmii_immediate_poll); /* * Due to GMX errata in CN3XXX series chips, it is necessary diff --git a/kernel/drivers/staging/octeon/ethernet-rx.c b/kernel/drivers/staging/octeon/ethernet-rx.c index 22667dbb1..6aed3cf6c 100644 --- a/kernel/drivers/staging/octeon/ethernet-rx.c +++ b/kernel/drivers/staging/octeon/ethernet-rx.c @@ -1,29 +1,13 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ + #include <linux/module.h> #include <linux/kernel.h> #include <linux/cache.h> @@ -65,6 +49,8 @@ static struct napi_struct cvm_oct_napi; /** * cvm_oct_do_interrupt - interrupt handler. + * @cpl: Interrupt number. Unused + * @dev_id: Cookie to identify the device. Unused * * The interrupt occurs whenever the POW has packets in our group. * @@ -86,18 +72,22 @@ static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id) */ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) { - if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) { + int port; + + if (octeon_has_feature(OCTEON_FEATURE_PKND)) + port = work->word0.pip.cn68xx.pknd; + else + port = work->word1.cn38xx.ipprt; + + if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) { /* * Ignore length errors on min size packets. Some * equipment incorrectly pads packets to 64+4FCS * instead of 60+4FCS. Note these packets still get * counted as frame errors. */ - } else - if (USE_10MBPS_PREAMBLE_WORKAROUND - && ((work->word2.snoip.err_code == 5) - || (work->word2.snoip.err_code == 7))) { - + } else if (work->word2.snoip.err_code == 5 || + work->word2.snoip.err_code == 7) { /* * We received a packet with either an alignment error * or a FCS error. This may be signalling that we are @@ -106,19 +96,19 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) * packet to determine if we can remove a non spec * preamble and generate a correct packet. */ - int interface = cvmx_helper_get_interface_num(work->ipprt); - int index = cvmx_helper_get_interface_index_num(work->ipprt); + int interface = cvmx_helper_get_interface_num(port); + int index = cvmx_helper_get_interface_index_num(port); union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; gmxx_rxx_frm_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface)); if (gmxx_rxx_frm_ctl.s.pre_chk == 0) { - uint8_t *ptr = + u8 *ptr = cvmx_phys_to_ptr(work->packet_ptr.s.addr); int i = 0; - while (i < work->len - 1) { + while (i < work->word1.len - 1) { if (*ptr != 0x55) break; ptr++; @@ -128,18 +118,18 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) if (*ptr == 0xd5) { /* printk_ratelimited("Port %d received 0xd5 preamble\n", - work->ipprt); + port); */ work->packet_ptr.s.addr += i + 1; - work->len -= i + 5; + work->word1.len -= i + 5; } else if ((*ptr & 0xf) == 0xd) { /* printk_ratelimited("Port %d received 0x?d preamble\n", - work->ipprt); + port); */ work->packet_ptr.s.addr += i; - work->len -= i + 4; - for (i = 0; i < work->len; i++) { + work->word1.len -= i + 4; + for (i = 0; i < work->word1.len; i++) { *ptr = ((*ptr & 0xf0) >> 4) | ((*(ptr + 1) & 0xf) << 4); @@ -147,7 +137,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) } } else { printk_ratelimited("Port %d unknown preamble, packet dropped\n", - work->ipprt); + port); /* cvmx_helper_dump_packet(work); */ @@ -157,7 +147,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) } } else { printk_ratelimited("Port %d receive error code %d, packet dropped\n", - work->ipprt, work->word2.snoip.err_code); + port, work->word2.snoip.err_code); cvm_oct_free_work(work); return 1; } @@ -175,8 +165,8 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) { const int coreid = cvmx_get_core_num(); - uint64_t old_group_mask; - uint64_t old_scratch; + u64 old_group_mask; + u64 old_scratch; int rx_count = 0; int did_work_request = 0; int packet_not_copied; @@ -191,9 +181,16 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) } /* Only allow work for our group (and preserve priorities) */ - old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid)); - cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), - (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group); + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { + old_group_mask = cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); + cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid), + 1ull << pow_receive_group); + cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */ + } else { + old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid)); + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), + (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group); + } if (USE_ASYNC_IOBDMA) { cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT); @@ -205,6 +202,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) struct sk_buff **pskb = NULL; int skb_in_hw; cvmx_wqe_t *work; + int port; if (USE_ASYNC_IOBDMA && did_work_request) work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH); @@ -214,12 +212,19 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) prefetch(work); did_work_request = 0; if (work == NULL) { - union cvmx_pow_wq_int wq_int; + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { + cvmx_write_csr(CVMX_SSO_WQ_IQ_DIS, + 1ull << pow_receive_group); + cvmx_write_csr(CVMX_SSO_WQ_INT, + 1ull << pow_receive_group); + } else { + union cvmx_pow_wq_int wq_int; - wq_int.u64 = 0; - wq_int.s.iq_dis = 1 << pow_receive_group; - wq_int.s.wq_int = 1 << pow_receive_group; - cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64); + wq_int.u64 = 0; + wq_int.s.iq_dis = 1 << pow_receive_group; + wq_int.s.wq_int = 1 << pow_receive_group; + cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64); + } break; } pskb = (struct sk_buff **)(cvm_oct_get_buffer_ptr(work->packet_ptr) - @@ -233,13 +238,19 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) } rx_count++; - skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1; + skb_in_hw = work->word2.s.bufs == 1; if (likely(skb_in_hw)) { skb = *pskb; prefetch(&skb->head); prefetch(&skb->len); } - prefetch(cvm_oct_device[work->ipprt]); + + if (octeon_has_feature(OCTEON_FEATURE_PKND)) + port = work->word0.pip.cn68xx.pknd; + else + port = work->word1.cn38xx.ipprt; + + prefetch(cvm_oct_device[port]); /* Immediately throw away all packets with receive errors */ if (unlikely(work->word2.snoip.rcv_error)) { @@ -256,7 +267,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) skb->data = skb->head + work->packet_ptr.s.addr - cvmx_ptr_to_phys(skb->head); prefetch(skb->data); - skb->len = work->len; + skb->len = work->word1.len; skb_set_tail_pointer(skb, skb->len); packet_not_copied = 1; } else { @@ -264,7 +275,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) * We have to copy the packet. First allocate * an skbuff for it. */ - skb = dev_alloc_skb(work->len); + skb = dev_alloc_skb(work->word1.len); if (!skb) { cvm_oct_free_work(work); continue; @@ -275,7 +286,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) * entirely stored in the work entry. */ if (unlikely(work->word2.s.bufs == 0)) { - uint8_t *ptr = work->packet_data; + u8 *ptr = work->packet_data; if (likely(!work->word2.s.not_IP)) { /* @@ -287,13 +298,14 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) else ptr += 6; } - memcpy(skb_put(skb, work->len), ptr, work->len); + memcpy(skb_put(skb, work->word1.len), ptr, + work->word1.len); /* No packet buffers to free */ } else { int segments = work->word2.s.bufs; union cvmx_buf_ptr segment_ptr = work->packet_ptr; - int len = work->len; + int len = work->word1.len; while (segments--) { union cvmx_buf_ptr next_ptr = @@ -329,10 +341,9 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) } packet_not_copied = 0; } - - if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) && - cvm_oct_device[work->ipprt])) { - struct net_device *dev = cvm_oct_device[work->ipprt]; + if (likely((port < TOTAL_NUMBER_OF_PORTS) && + cvm_oct_device[port])) { + struct net_device *dev = cvm_oct_device[port]; struct octeon_ethernet *priv = netdev_priv(dev); /* @@ -352,7 +363,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) skb->ip_summed = CHECKSUM_UNNECESSARY; /* Increment RX stats for virtual ports */ - if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) { + if (port >= CVMX_PIP_NUM_INPUT_PORTS) { #ifdef CONFIG_64BIT atomic64_add(1, (atomic64_t *)&priv->stats.rx_packets); @@ -387,14 +398,14 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) * doesn't exist. */ printk_ratelimited("Port %d not controlled by Linux, packet dropped\n", - work->ipprt); + port); dev_kfree_skb_irq(skb); } /* * Check to see if the skbuff and work share the same * packet buffer. */ - if (USE_SKBUFFS_IN_HW && likely(packet_not_copied)) { + if (likely(packet_not_copied)) { /* * This buffer needs to be replaced, increment * the number of buffers we need to free by @@ -403,14 +414,19 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 1); - cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, - DONT_WRITEBACK(1)); + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1); } else { cvm_oct_free_work(work); } } /* Restore the original POW group mask */ - cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask); + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { + cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid), old_group_mask); + cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */ + } else { + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask); + } + if (USE_ASYNC_IOBDMA) { /* Restore the scratch area */ cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch); @@ -442,8 +458,6 @@ void cvm_oct_rx_initialize(void) { int i; struct net_device *dev_for_napi = NULL; - union cvmx_pow_wq_int_thrx int_thr; - union cvmx_pow_wq_int_pc int_pc; for (i = 0; i < TOTAL_NUMBER_OF_PORTS; i++) { if (cvm_oct_device[i]) { @@ -469,15 +483,34 @@ void cvm_oct_rx_initialize(void) disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group); - int_thr.u64 = 0; - int_thr.s.tc_en = 1; - int_thr.s.tc_thr = 1; /* Enable POW interrupt when our port has at least one packet */ - cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), int_thr.u64); - - int_pc.u64 = 0; - int_pc.s.pc_thr = 5; - cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64); + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { + union cvmx_sso_wq_int_thrx int_thr; + union cvmx_pow_wq_int_pc int_pc; + + int_thr.u64 = 0; + int_thr.s.tc_en = 1; + int_thr.s.tc_thr = 1; + cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(pow_receive_group), + int_thr.u64); + + int_pc.u64 = 0; + int_pc.s.pc_thr = 5; + cvmx_write_csr(CVMX_SSO_WQ_INT_PC, int_pc.u64); + } else { + union cvmx_pow_wq_int_thrx int_thr; + union cvmx_pow_wq_int_pc int_pc; + + int_thr.u64 = 0; + int_thr.s.tc_en = 1; + int_thr.s.tc_thr = 1; + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), + int_thr.u64); + + int_pc.u64 = 0; + int_pc.s.pc_thr = 5; + cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64); + } /* Schedule NAPI now. This will indirectly enable the interrupt. */ napi_schedule(&cvm_oct_napi); diff --git a/kernel/drivers/staging/octeon/ethernet-rx.h b/kernel/drivers/staging/octeon/ethernet-rx.h index 9240c85ce..a5973fd01 100644 --- a/kernel/drivers/staging/octeon/ethernet-rx.h +++ b/kernel/drivers/staging/octeon/ethernet-rx.h @@ -1,29 +1,13 @@ -/********************************************************************* - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -*********************************************************************/ + */ + #include <asm/octeon/cvmx-fau.h> void cvm_oct_poll_controller(struct net_device *dev); diff --git a/kernel/drivers/staging/octeon/ethernet-sgmii.c b/kernel/drivers/staging/octeon/ethernet-sgmii.c index 21a7a17ac..7424dc45a 100644 --- a/kernel/drivers/staging/octeon/ethernet-sgmii.c +++ b/kernel/drivers/staging/octeon/ethernet-sgmii.c @@ -1,29 +1,13 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ + #include <linux/phy.h> #include <linux/kernel.h> #include <linux/netdevice.h> @@ -41,101 +25,15 @@ #include <asm/octeon/cvmx-gmxx-defs.h> -static void cvm_oct_sgmii_poll(struct net_device *dev) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - cvmx_helper_link_info_t link_info; - - link_info = cvmx_helper_link_get(priv->port); - if (link_info.u64 == priv->link_info) - return; - - link_info = cvmx_helper_link_autoconf(priv->port); - priv->link_info = link_info.u64; - - /* Tell Linux */ - if (link_info.s.link_up) { - - if (!netif_carrier_ok(dev)) - netif_carrier_on(dev); - if (priv->queue != -1) - printk_ratelimited - ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port, priv->queue); - else - printk_ratelimited - ("%s: %u Mbps %s duplex, port %2d, POW\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port); - } else { - if (netif_carrier_ok(dev)) - netif_carrier_off(dev); - printk_ratelimited("%s: Link down\n", dev->name); - } -} - int cvm_oct_sgmii_open(struct net_device *dev) { - union cvmx_gmxx_prtx_cfg gmx_cfg; - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - cvmx_helper_link_info_t link_info; - int rv; - - rv = cvm_oct_phy_setup_device(dev); - if (rv) - return rv; - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 1; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - - if (octeon_is_simulation()) - return 0; - - if (priv->phydev) { - int r = phy_read_status(priv->phydev); - - if (r == 0 && priv->phydev->link == 0) - netif_carrier_off(dev); - cvm_oct_adjust_link(dev); - } else { - link_info = cvmx_helper_link_get(priv->port); - if (!link_info.s.link_up) - netif_carrier_off(dev); - priv->poll = cvm_oct_sgmii_poll; - cvm_oct_sgmii_poll(dev); - } - return 0; -} - -int cvm_oct_sgmii_stop(struct net_device *dev) -{ - union cvmx_gmxx_prtx_cfg gmx_cfg; - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 0; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - return cvm_oct_common_stop(dev); + return cvm_oct_common_open(dev, cvm_oct_link_poll); } int cvm_oct_sgmii_init(struct net_device *dev) { cvm_oct_common_init(dev); - dev->netdev_ops->ndo_stop(dev); /* FIXME: Need autoneg logic */ return 0; } - -void cvm_oct_sgmii_uninit(struct net_device *dev) -{ - cvm_oct_common_uninit(dev); -} diff --git a/kernel/drivers/staging/octeon/ethernet-spi.c b/kernel/drivers/staging/octeon/ethernet-spi.c index 5108bc0bb..2ae1944b3 100644 --- a/kernel/drivers/staging/octeon/ethernet-spi.c +++ b/kernel/drivers/staging/octeon/ethernet-spi.c @@ -1,29 +1,13 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ + #include <linux/kernel.h> #include <linux/netdevice.h> #include <linux/interrupt.h> @@ -44,141 +28,104 @@ static int number_spi_ports; static int need_retrain[2] = { 0, 0 }; -static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id) +static void cvm_oct_spxx_int_pr(union cvmx_spxx_int_reg spx_int_reg, int index) { - irqreturn_t return_status = IRQ_NONE; - union cvmx_npi_rsl_int_blocks rsl_int_blocks; - - /* Check and see if this interrupt was caused by the GMX block */ - rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS); - if (rsl_int_blocks.s.spx1) { /* 19 - SPX1_INT_REG & STX1_INT_REG */ - - union cvmx_spxx_int_reg spx_int_reg; - union cvmx_stxx_int_reg stx_int_reg; - - spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(1)); - cvmx_write_csr(CVMX_SPXX_INT_REG(1), spx_int_reg.u64); - if (!need_retrain[1]) { - - spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(1)); - if (spx_int_reg.s.spf) - pr_err("SPI1: SRX Spi4 interface down\n"); - if (spx_int_reg.s.calerr) - pr_err("SPI1: SRX Spi4 Calendar table parity error\n"); - if (spx_int_reg.s.syncerr) - pr_err("SPI1: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n"); - if (spx_int_reg.s.diperr) - pr_err("SPI1: SRX Spi4 DIP4 error\n"); - if (spx_int_reg.s.tpaovr) - pr_err("SPI1: SRX Selected port has hit TPA overflow\n"); - if (spx_int_reg.s.rsverr) - pr_err("SPI1: SRX Spi4 reserved control word detected\n"); - if (spx_int_reg.s.drwnng) - pr_err("SPI1: SRX Spi4 receive FIFO drowning/overflow\n"); - if (spx_int_reg.s.clserr) - pr_err("SPI1: SRX Spi4 packet closed on non-16B alignment without EOP\n"); - if (spx_int_reg.s.spiovr) - pr_err("SPI1: SRX Spi4 async FIFO overflow\n"); - if (spx_int_reg.s.abnorm) - pr_err("SPI1: SRX Abnormal packet termination (ERR bit)\n"); - if (spx_int_reg.s.prtnxa) - pr_err("SPI1: SRX Port out of range\n"); - } - - stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(1)); - cvmx_write_csr(CVMX_STXX_INT_REG(1), stx_int_reg.u64); - if (!need_retrain[1]) { + if (spx_int_reg.s.spf) + pr_err("SPI%d: SRX Spi4 interface down\n", index); + if (spx_int_reg.s.calerr) + pr_err("SPI%d: SRX Spi4 Calendar table parity error\n", index); + if (spx_int_reg.s.syncerr) + pr_err("SPI%d: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n", + index); + if (spx_int_reg.s.diperr) + pr_err("SPI%d: SRX Spi4 DIP4 error\n", index); + if (spx_int_reg.s.tpaovr) + pr_err("SPI%d: SRX Selected port has hit TPA overflow\n", + index); + if (spx_int_reg.s.rsverr) + pr_err("SPI%d: SRX Spi4 reserved control word detected\n", + index); + if (spx_int_reg.s.drwnng) + pr_err("SPI%d: SRX Spi4 receive FIFO drowning/overflow\n", + index); + if (spx_int_reg.s.clserr) + pr_err("SPI%d: SRX Spi4 packet closed on non-16B alignment without EOP\n", + index); + if (spx_int_reg.s.spiovr) + pr_err("SPI%d: SRX Spi4 async FIFO overflow\n", index); + if (spx_int_reg.s.abnorm) + pr_err("SPI%d: SRX Abnormal packet termination (ERR bit)\n", + index); + if (spx_int_reg.s.prtnxa) + pr_err("SPI%d: SRX Port out of range\n", index); +} - stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1)); - if (stx_int_reg.s.syncerr) - pr_err("SPI1: STX Interface encountered a fatal error\n"); - if (stx_int_reg.s.frmerr) - pr_err("SPI1: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n"); - if (stx_int_reg.s.unxfrm) - pr_err("SPI1: STX Unexpected framing sequence\n"); - if (stx_int_reg.s.nosync) - pr_err("SPI1: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n"); - if (stx_int_reg.s.diperr) - pr_err("SPI1: STX DIP2 error on the Spi4 Status channel\n"); - if (stx_int_reg.s.datovr) - pr_err("SPI1: STX Spi4 FIFO overflow error\n"); - if (stx_int_reg.s.ovrbst) - pr_err("SPI1: STX Transmit packet burst too big\n"); - if (stx_int_reg.s.calpar1) - pr_err("SPI1: STX Calendar Table Parity Error Bank1\n"); - if (stx_int_reg.s.calpar0) - pr_err("SPI1: STX Calendar Table Parity Error Bank0\n"); - } +static void cvm_oct_stxx_int_pr(union cvmx_stxx_int_reg stx_int_reg, int index) +{ + if (stx_int_reg.s.syncerr) + pr_err("SPI%d: STX Interface encountered a fatal error\n", + index); + if (stx_int_reg.s.frmerr) + pr_err("SPI%d: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n", + index); + if (stx_int_reg.s.unxfrm) + pr_err("SPI%d: STX Unexpected framing sequence\n", index); + if (stx_int_reg.s.nosync) + pr_err("SPI%d: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n", + index); + if (stx_int_reg.s.diperr) + pr_err("SPI%d: STX DIP2 error on the Spi4 Status channel\n", + index); + if (stx_int_reg.s.datovr) + pr_err("SPI%d: STX Spi4 FIFO overflow error\n", index); + if (stx_int_reg.s.ovrbst) + pr_err("SPI%d: STX Transmit packet burst too big\n", index); + if (stx_int_reg.s.calpar1) + pr_err("SPI%d: STX Calendar Table Parity Error Bank%d\n", + index, 1); + if (stx_int_reg.s.calpar0) + pr_err("SPI%d: STX Calendar Table Parity Error Bank%d\n", + index, 0); +} - cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0); - cvmx_write_csr(CVMX_STXX_INT_MSK(1), 0); - need_retrain[1] = 1; - return_status = IRQ_HANDLED; +static irqreturn_t cvm_oct_spi_spx_int(int index) +{ + union cvmx_spxx_int_reg spx_int_reg; + union cvmx_stxx_int_reg stx_int_reg; + + spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(index)); + cvmx_write_csr(CVMX_SPXX_INT_REG(index), spx_int_reg.u64); + if (!need_retrain[index]) { + spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(index)); + cvm_oct_spxx_int_pr(spx_int_reg, index); } - if (rsl_int_blocks.s.spx0) { /* 18 - SPX0_INT_REG & STX0_INT_REG */ - union cvmx_spxx_int_reg spx_int_reg; - union cvmx_stxx_int_reg stx_int_reg; + stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(index)); + cvmx_write_csr(CVMX_STXX_INT_REG(index), stx_int_reg.u64); + if (!need_retrain[index]) { + stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(index)); + cvm_oct_stxx_int_pr(stx_int_reg, index); + } - spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(0)); - cvmx_write_csr(CVMX_SPXX_INT_REG(0), spx_int_reg.u64); - if (!need_retrain[0]) { + cvmx_write_csr(CVMX_SPXX_INT_MSK(index), 0); + cvmx_write_csr(CVMX_STXX_INT_MSK(index), 0); + need_retrain[index] = 1; - spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(0)); - if (spx_int_reg.s.spf) - pr_err("SPI0: SRX Spi4 interface down\n"); - if (spx_int_reg.s.calerr) - pr_err("SPI0: SRX Spi4 Calendar table parity error\n"); - if (spx_int_reg.s.syncerr) - pr_err("SPI0: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n"); - if (spx_int_reg.s.diperr) - pr_err("SPI0: SRX Spi4 DIP4 error\n"); - if (spx_int_reg.s.tpaovr) - pr_err("SPI0: SRX Selected port has hit TPA overflow\n"); - if (spx_int_reg.s.rsverr) - pr_err("SPI0: SRX Spi4 reserved control word detected\n"); - if (spx_int_reg.s.drwnng) - pr_err("SPI0: SRX Spi4 receive FIFO drowning/overflow\n"); - if (spx_int_reg.s.clserr) - pr_err("SPI0: SRX Spi4 packet closed on non-16B alignment without EOP\n"); - if (spx_int_reg.s.spiovr) - pr_err("SPI0: SRX Spi4 async FIFO overflow\n"); - if (spx_int_reg.s.abnorm) - pr_err("SPI0: SRX Abnormal packet termination (ERR bit)\n"); - if (spx_int_reg.s.prtnxa) - pr_err("SPI0: SRX Port out of range\n"); - } + return IRQ_HANDLED; +} - stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(0)); - cvmx_write_csr(CVMX_STXX_INT_REG(0), stx_int_reg.u64); - if (!need_retrain[0]) { +static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id) +{ + irqreturn_t return_status = IRQ_NONE; + union cvmx_npi_rsl_int_blocks rsl_int_blocks; - stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0)); - if (stx_int_reg.s.syncerr) - pr_err("SPI0: STX Interface encountered a fatal error\n"); - if (stx_int_reg.s.frmerr) - pr_err("SPI0: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n"); - if (stx_int_reg.s.unxfrm) - pr_err("SPI0: STX Unexpected framing sequence\n"); - if (stx_int_reg.s.nosync) - pr_err("SPI0: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n"); - if (stx_int_reg.s.diperr) - pr_err("SPI0: STX DIP2 error on the Spi4 Status channel\n"); - if (stx_int_reg.s.datovr) - pr_err("SPI0: STX Spi4 FIFO overflow error\n"); - if (stx_int_reg.s.ovrbst) - pr_err("SPI0: STX Transmit packet burst too big\n"); - if (stx_int_reg.s.calpar1) - pr_err("SPI0: STX Calendar Table Parity Error Bank1\n"); - if (stx_int_reg.s.calpar0) - pr_err("SPI0: STX Calendar Table Parity Error Bank0\n"); - } + /* Check and see if this interrupt was caused by the GMX block */ + rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS); + if (rsl_int_blocks.s.spx1) /* 19 - SPX1_INT_REG & STX1_INT_REG */ + return_status = cvm_oct_spi_spx_int(1); - cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0); - cvmx_write_csr(CVMX_STXX_INT_MSK(0), 0); - need_retrain[0] = 1; - return_status = IRQ_HANDLED; - } + if (rsl_int_blocks.s.spx0) /* 18 - SPX0_INT_REG & STX0_INT_REG */ + return_status = cvm_oct_spi_spx_int(0); return return_status; } diff --git a/kernel/drivers/staging/octeon/ethernet-tx.c b/kernel/drivers/staging/octeon/ethernet-tx.c index 5b9ac1f6d..c053c4a47 100644 --- a/kernel/drivers/staging/octeon/ethernet-tx.c +++ b/kernel/drivers/staging/octeon/ethernet-tx.c @@ -1,29 +1,13 @@ -/********************************************************************* - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -*********************************************************************/ + */ + #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> @@ -159,8 +143,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) { cvmx_pko_command_word0_t pko_command; union cvmx_buf_ptr hw_buffer; - uint64_t old_scratch; - uint64_t old_scratch2; + u64 old_scratch; + u64 old_scratch2; int qos; int i; enum {QUEUE_CORE, QUEUE_HW, QUEUE_DROP} queue_type; @@ -411,11 +395,13 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) dont_put_skbuff_in_hw: /* Check if we can use the hardware checksumming */ - if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) && - (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) && - ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == htons(1 << 14))) - && ((ip_hdr(skb)->protocol == IPPROTO_TCP) - || (ip_hdr(skb)->protocol == IPPROTO_UDP))) { + if ((skb->protocol == htons(ETH_P_IP)) && + (ip_hdr(skb)->version == 4) && + (ip_hdr(skb)->ihl == 5) && + ((ip_hdr(skb)->frag_off == 0) || + (ip_hdr(skb)->frag_off == htons(1 << 14))) && + ((ip_hdr(skb)->protocol == IPPROTO_TCP) || + (ip_hdr(skb)->protocol == IPPROTO_UDP))) { /* Use hardware checksum calc */ pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1; } @@ -563,7 +549,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) /* Get a work queue entry */ cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL); - if (unlikely(work == NULL)) { + if (unlikely(!work)) { printk_ratelimited("%s: Failed to allocate a work queue entry\n", dev->name); priv->stats.tx_dropped++; @@ -576,7 +562,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) if (unlikely(packet_buffer == NULL)) { printk_ratelimited("%s: Failed to allocate a packet buffer\n", dev->name); - cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1)); + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1); priv->stats.tx_dropped++; dev_kfree_skb_any(skb); return 0; @@ -590,7 +576,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) * calculation may add a little extra, but that doesn't * hurt. */ - copy_location = packet_buffer + sizeof(uint64_t); + copy_location = packet_buffer + sizeof(u64); copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6; /* @@ -605,13 +591,14 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) * Fill in some of the work queue fields. We may need to add * more if the software at the other end needs them. */ - work->hw_chksum = skb->csum; - work->len = skb->len; - work->ipprt = priv->port; - work->qos = priv->port & 0x7; - work->grp = pow_send_group; - work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE; - work->tag = pow_send_group; /* FIXME */ + if (!OCTEON_IS_MODEL(OCTEON_CN68XX)) + work->word0.pip.cn38xx.hw_chksum = skb->csum; + work->word1.len = skb->len; + cvmx_wqe_set_port(work, priv->port); + cvmx_wqe_set_qos(work, priv->port & 0x7); + cvmx_wqe_set_grp(work, pow_send_group); + work->word1.tag_type = CVMX_HELPER_INPUT_TAG_TYPE; + work->word1.tag = pow_send_group; /* FIXME */ /* Default to zero. Sets of zero later are commented out */ work->word2.u64 = 0; work->word2.s.bufs = 1; @@ -691,8 +678,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) } /* Submit the packet to the POW */ - cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos, - work->grp); + cvmx_pow_work_submit(work, work->word1.tag, work->word1.tag_type, + cvmx_wqe_get_qos(work), cvmx_wqe_get_grp(work)); priv->stats.tx_packets++; priv->stats.tx_bytes += skb->len; dev_consume_skb_any(skb); diff --git a/kernel/drivers/staging/octeon/ethernet-tx.h b/kernel/drivers/staging/octeon/ethernet-tx.h index 547680c6c..84848e4c1 100644 --- a/kernel/drivers/staging/octeon/ethernet-tx.h +++ b/kernel/drivers/staging/octeon/ethernet-tx.h @@ -1,29 +1,12 @@ -/********************************************************************* - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -*********************************************************************/ + */ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev); int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev); diff --git a/kernel/drivers/staging/octeon/ethernet-util.h b/kernel/drivers/staging/octeon/ethernet-util.h index 0f9b4a18f..45f024bc5 100644 --- a/kernel/drivers/staging/octeon/ethernet-util.h +++ b/kernel/drivers/staging/octeon/ethernet-util.h @@ -1,29 +1,16 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -*********************************************************************/ + */ + +#include <asm/octeon/cvmx-pip.h> +#include <asm/octeon/cvmx-helper.h> +#include <asm/octeon/cvmx-helper-util.h> /** * cvm_oct_get_buffer_ptr - convert packet data address to pointer @@ -45,14 +32,12 @@ static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr) */ static inline int INTERFACE(int ipd_port) { - if (ipd_port < 32) /* Interface 0 or 1 for RGMII,GMII,SPI, etc */ - return ipd_port >> 4; - else if (ipd_port < 36) /* Interface 2 for NPI */ - return 2; - else if (ipd_port < 40) /* Interface 3 for loopback */ - return 3; - else if (ipd_port == 40) /* Non existent interface for POW0 */ - return 4; + int interface = cvmx_helper_get_interface_num(ipd_port); + + if (interface >= 0) + return interface; + else if (ipd_port == CVMX_PIP_NUM_INPUT_PORTS) + return 10; panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port); } @@ -64,7 +49,5 @@ static inline int INTERFACE(int ipd_port) */ static inline int INDEX(int ipd_port) { - if (ipd_port < 32) - return ipd_port & 15; - return ipd_port & 3; + return cvmx_helper_get_interface_index_num(ipd_port); } diff --git a/kernel/drivers/staging/octeon/ethernet-xaui.c b/kernel/drivers/staging/octeon/ethernet-xaui.c deleted file mode 100644 index fd9d103d8..000000000 --- a/kernel/drivers/staging/octeon/ethernet-xaui.c +++ /dev/null @@ -1,144 +0,0 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK - * - * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ -#include <linux/phy.h> -#include <linux/kernel.h> -#include <linux/netdevice.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-gmxx-defs.h> - -static void cvm_oct_xaui_poll(struct net_device *dev) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - cvmx_helper_link_info_t link_info; - - link_info = cvmx_helper_link_get(priv->port); - if (link_info.u64 == priv->link_info) - return; - - link_info = cvmx_helper_link_autoconf(priv->port); - priv->link_info = link_info.u64; - - /* Tell Linux */ - if (link_info.s.link_up) { - - if (!netif_carrier_ok(dev)) - netif_carrier_on(dev); - if (priv->queue != -1) - printk_ratelimited - ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port, priv->queue); - else - printk_ratelimited - ("%s: %u Mbps %s duplex, port %2d, POW\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port); - } else { - if (netif_carrier_ok(dev)) - netif_carrier_off(dev); - printk_ratelimited("%s: Link down\n", dev->name); - } -} - -int cvm_oct_xaui_open(struct net_device *dev) -{ - union cvmx_gmxx_prtx_cfg gmx_cfg; - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - cvmx_helper_link_info_t link_info; - int rv; - - rv = cvm_oct_phy_setup_device(dev); - if (rv) - return rv; - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 1; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - - if (octeon_is_simulation()) - return 0; - - if (priv->phydev) { - int r = phy_read_status(priv->phydev); - - if (r == 0 && priv->phydev->link == 0) - netif_carrier_off(dev); - cvm_oct_adjust_link(dev); - } else { - link_info = cvmx_helper_link_get(priv->port); - if (!link_info.s.link_up) - netif_carrier_off(dev); - priv->poll = cvm_oct_xaui_poll; - cvm_oct_xaui_poll(dev); - } - return 0; -} - -int cvm_oct_xaui_stop(struct net_device *dev) -{ - union cvmx_gmxx_prtx_cfg gmx_cfg; - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 0; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - return cvm_oct_common_stop(dev); -} - -int cvm_oct_xaui_init(struct net_device *dev) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - - cvm_oct_common_init(dev); - dev->netdev_ops->ndo_stop(dev); - if (!octeon_is_simulation() && priv->phydev == NULL) - priv->poll = cvm_oct_xaui_poll; - - return 0; -} - -void cvm_oct_xaui_uninit(struct net_device *dev) -{ - cvm_oct_common_uninit(dev); -} diff --git a/kernel/drivers/staging/octeon/ethernet.c b/kernel/drivers/staging/octeon/ethernet.c index fbbe86648..f69fb5cc7 100644 --- a/kernel/drivers/staging/octeon/ethernet.c +++ b/kernel/drivers/staging/octeon/ethernet.c @@ -1,29 +1,13 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ + #include <linux/platform_device.h> #include <linux/kernel.h> #include <linux/module.h> @@ -102,19 +86,19 @@ int rx_napi_weight = 32; module_param(rx_napi_weight, int, 0444); MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter."); -/** +/* * cvm_oct_poll_queue - Workqueue for polling operations. */ struct workqueue_struct *cvm_oct_poll_queue; -/** +/* * cvm_oct_poll_queue_stopping - flag to indicate polling should stop. * * Set to one right before cvm_oct_poll_queue is destroyed. */ atomic_t cvm_oct_poll_queue_stopping = ATOMIC_INIT(0); -/** +/* * Array of every ethernet device owned by this driver indexed by * the ipd input port number. */ @@ -168,11 +152,12 @@ static void cvm_oct_configure_common_hw(void) num_packet_buffers); if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, - CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128); + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 1024); #ifdef __LITTLE_ENDIAN { union cvmx_ipd_ctl_status ipd_ctl_status; + ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); ipd_ctl_status.s.pkt_lend = 1; ipd_ctl_status.s.wqe_lend = 1; @@ -180,10 +165,7 @@ static void cvm_oct_configure_common_hw(void) } #endif - if (USE_RED) - cvmx_helper_setup_red(num_packet_buffers / 4, - num_packet_buffers / 8); - + cvmx_helper_setup_red(num_packet_buffers / 4, num_packet_buffers / 8); } /** @@ -206,11 +188,10 @@ int cvm_oct_free_work(void *work_queue_entry) if (unlikely(!segment_ptr.s.i)) cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr), segment_ptr.s.pool, - DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE / - 128)); + CVMX_FPA_PACKET_POOL_SIZE / 128); segment_ptr = next_ptr; } - cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1)); + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1); return 0; } @@ -383,13 +364,6 @@ static void cvm_oct_common_set_multicast_list(struct net_device *dev) } } -/** - * cvm_oct_common_set_mac_address - set the hardware MAC address for a device - * @dev: The device in question. - * @addr: Address structure to change it too. - - * Returns Zero on success - */ static int cvm_oct_set_mac_filter(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); @@ -401,11 +375,11 @@ static int cvm_oct_set_mac_filter(struct net_device *dev) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) { int i; - uint8_t *ptr = dev->dev_addr; - uint64_t mac = 0; + u8 *ptr = dev->dev_addr; + u64 mac = 0; for (i = 0; i < 6; i++) - mac = (mac << 8) | (uint64_t)ptr[i]; + mac = (mac << 8) | (u64)ptr[i]; gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); @@ -432,6 +406,13 @@ static int cvm_oct_set_mac_filter(struct net_device *dev) return 0; } +/** + * cvm_oct_common_set_mac_address - set the hardware MAC address for a device + * @dev: The device in question. + * @addr: Socket address. + * + * Returns Zero on success + */ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) { int r = eth_mac_addr(dev, addr); @@ -468,11 +449,8 @@ int cvm_oct_common_init(struct net_device *dev) && (always_use_pow || strstr(pow_send_list, dev->name))) priv->queue = -1; - if (priv->queue != -1) { - dev->features |= NETIF_F_SG; - if (USE_HW_TCPUDP_CHECKSUM) - dev->features |= NETIF_F_IP_CSUM; - } + if (priv->queue != -1) + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; /* We do our own locking, Linux doesn't need to */ dev->features |= NETIF_F_LLTX; @@ -488,6 +466,9 @@ int cvm_oct_common_init(struct net_device *dev) memset(dev->netdev_ops->ndo_get_stats(dev), 0, sizeof(struct net_device_stats)); + if (dev->netdev_ops->ndo_stop) + dev->netdev_ops->ndo_stop(dev); + return 0; } @@ -499,6 +480,70 @@ void cvm_oct_common_uninit(struct net_device *dev) phy_disconnect(priv->phydev); } +int cvm_oct_common_open(struct net_device *dev, + void (*link_poll)(struct net_device *)) +{ + union cvmx_gmxx_prtx_cfg gmx_cfg; + struct octeon_ethernet *priv = netdev_priv(dev); + int interface = INTERFACE(priv->port); + int index = INDEX(priv->port); + cvmx_helper_link_info_t link_info; + int rv; + + rv = cvm_oct_phy_setup_device(dev); + if (rv) + return rv; + + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); + gmx_cfg.s.en = 1; + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); + + if (octeon_is_simulation()) + return 0; + + if (priv->phydev) { + int r = phy_read_status(priv->phydev); + + if (r == 0 && priv->phydev->link == 0) + netif_carrier_off(dev); + cvm_oct_adjust_link(dev); + } else { + link_info = cvmx_helper_link_get(priv->port); + if (!link_info.s.link_up) + netif_carrier_off(dev); + priv->poll = link_poll; + link_poll(dev); + } + + return 0; +} + +void cvm_oct_link_poll(struct net_device *dev) +{ + struct octeon_ethernet *priv = netdev_priv(dev); + cvmx_helper_link_info_t link_info; + + link_info = cvmx_helper_link_get(priv->port); + if (link_info.u64 == priv->link_info) + return; + + link_info = cvmx_helper_link_autoconf(priv->port); + priv->link_info = link_info.u64; + + 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); +} + +static int cvm_oct_xaui_open(struct net_device *dev) +{ + return cvm_oct_common_open(dev, cvm_oct_link_poll); +} + static const struct net_device_ops cvm_oct_npi_netdev_ops = { .ndo_init = cvm_oct_common_init, .ndo_uninit = cvm_oct_common_uninit, @@ -513,10 +558,10 @@ static const struct net_device_ops cvm_oct_npi_netdev_ops = { #endif }; static const struct net_device_ops cvm_oct_xaui_netdev_ops = { - .ndo_init = cvm_oct_xaui_init, - .ndo_uninit = cvm_oct_xaui_uninit, + .ndo_init = cvm_oct_common_init, + .ndo_uninit = cvm_oct_common_uninit, .ndo_open = cvm_oct_xaui_open, - .ndo_stop = cvm_oct_xaui_stop, + .ndo_stop = cvm_oct_common_stop, .ndo_start_xmit = cvm_oct_xmit, .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, @@ -529,9 +574,9 @@ static const struct net_device_ops cvm_oct_xaui_netdev_ops = { }; static const struct net_device_ops cvm_oct_sgmii_netdev_ops = { .ndo_init = cvm_oct_sgmii_init, - .ndo_uninit = cvm_oct_sgmii_uninit, + .ndo_uninit = cvm_oct_common_uninit, .ndo_open = cvm_oct_sgmii_open, - .ndo_stop = cvm_oct_sgmii_stop, + .ndo_stop = cvm_oct_common_stop, .ndo_start_xmit = cvm_oct_xmit, .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, @@ -559,7 +604,7 @@ static const struct net_device_ops cvm_oct_rgmii_netdev_ops = { .ndo_init = cvm_oct_rgmii_init, .ndo_uninit = cvm_oct_rgmii_uninit, .ndo_open = cvm_oct_rgmii_open, - .ndo_stop = cvm_oct_rgmii_stop, + .ndo_stop = cvm_oct_common_stop, .ndo_start_xmit = cvm_oct_xmit, .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, @@ -625,7 +670,6 @@ static int cvm_oct_probe(struct platform_device *pdev) struct device_node *pip; octeon_mdiobus_force_mod_depencency(); - pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); pip = pdev->dev.of_node; if (!pip) { @@ -634,7 +678,7 @@ static int cvm_oct_probe(struct platform_device *pdev) } cvm_oct_poll_queue = create_singlethread_workqueue("octeon-ethernet"); - if (cvm_oct_poll_queue == NULL) { + if (!cvm_oct_poll_queue) { pr_err("octeon-ethernet: Cannot create workqueue"); return -ENOMEM; } @@ -795,7 +839,7 @@ static int cvm_oct_probe(struct platform_device *pdev) cvm_oct_device[priv->port] = dev; fau -= cvmx_pko_get_num_queues(priv->port) * - sizeof(uint32_t); + sizeof(u32); queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ); } @@ -820,7 +864,10 @@ static int cvm_oct_remove(struct platform_device *pdev) int port; /* Disable POW interrupt */ - cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0); + if (OCTEON_IS_MODEL(OCTEON_CN68XX)) + cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(pow_receive_group), 0); + else + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0); cvmx_ipd_disable(); diff --git a/kernel/drivers/staging/octeon/octeon-ethernet.h b/kernel/drivers/staging/octeon/octeon-ethernet.h index f48dc766f..fdf24d120 100644 --- a/kernel/drivers/staging/octeon/octeon-ethernet.h +++ b/kernel/drivers/staging/octeon/octeon-ethernet.h @@ -1,29 +1,12 @@ -/********************************************************************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK +/* + * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 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. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information -**********************************************************************/ + */ /* * External interface for the Cavium Octeon ethernet driver. @@ -33,6 +16,8 @@ #include <linux/of.h> +#include <asm/octeon/cvmx-helper-board.h> + /** * This is the definition of the Ethernet driver's private * driver state stored in netdev_priv(dev). @@ -58,7 +43,7 @@ struct octeon_ethernet { struct phy_device *phydev; unsigned int last_link; /* Last negotiated link state */ - uint64_t link_info; + u64 link_info; /* Called periodically to check link status */ void (*poll)(struct net_device *dev); struct delayed_work port_periodic_work; @@ -68,27 +53,25 @@ struct octeon_ethernet { int cvm_oct_free_work(void *work_queue_entry); -extern int cvm_oct_rgmii_init(struct net_device *dev); -extern void cvm_oct_rgmii_uninit(struct net_device *dev); -extern int cvm_oct_rgmii_open(struct net_device *dev); -extern int cvm_oct_rgmii_stop(struct net_device *dev); +int cvm_oct_rgmii_init(struct net_device *dev); +void cvm_oct_rgmii_uninit(struct net_device *dev); +int cvm_oct_rgmii_open(struct net_device *dev); -extern int cvm_oct_sgmii_init(struct net_device *dev); -extern void cvm_oct_sgmii_uninit(struct net_device *dev); -extern int cvm_oct_sgmii_open(struct net_device *dev); -extern int cvm_oct_sgmii_stop(struct net_device *dev); +int cvm_oct_sgmii_init(struct net_device *dev); +int cvm_oct_sgmii_open(struct net_device *dev); -extern int cvm_oct_spi_init(struct net_device *dev); -extern void cvm_oct_spi_uninit(struct net_device *dev); -extern int cvm_oct_xaui_init(struct net_device *dev); -extern void cvm_oct_xaui_uninit(struct net_device *dev); -extern int cvm_oct_xaui_open(struct net_device *dev); -extern int cvm_oct_xaui_stop(struct net_device *dev); +int cvm_oct_spi_init(struct net_device *dev); +void cvm_oct_spi_uninit(struct net_device *dev); -extern int cvm_oct_common_init(struct net_device *dev); -extern void cvm_oct_common_uninit(struct net_device *dev); +int cvm_oct_common_init(struct net_device *dev); +void cvm_oct_common_uninit(struct net_device *dev); void cvm_oct_adjust_link(struct net_device *dev); int cvm_oct_common_stop(struct net_device *dev); +int cvm_oct_common_open(struct net_device *dev, + void (*link_poll)(struct net_device *)); +void cvm_oct_note_carrier(struct octeon_ethernet *priv, + cvmx_helper_link_info_t li); +void cvm_oct_link_poll(struct net_device *dev); extern int always_use_pow; extern int pow_send_group; |