summaryrefslogtreecommitdiffstats
path: root/target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2013-02-04 15:23:10 +0000
committerGabor Juhos <juhosg@openwrt.org>2013-02-04 15:23:10 +0000
commitb97aee1ee851c6ce0f48e9c231a8152c1151dbe4 (patch)
tree3f5f5e1f2c6c8577ee1388dcec0bf4ba7d7565bd /target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch
parentc41002971aeecd78e93ce553028f7cc01c4de777 (diff)
downloadmaster-31e0f0ae-b97aee1ee851c6ce0f48e9c231a8152c1151dbe4.tar.gz
master-31e0f0ae-b97aee1ee851c6ce0f48e9c231a8152c1151dbe4.tar.bz2
master-31e0f0ae-b97aee1ee851c6ce0f48e9c231a8152c1151dbe4.zip
coldfire: R.I.P.
The target still uses 2.6.38. The support of that kernel version has been removed ~9 months ago. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> SVN-Revision: 35489
Diffstat (limited to 'target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch')
-rw-r--r--target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch6152
1 files changed, 0 insertions, 6152 deletions
diff --git a/target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch b/target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch
deleted file mode 100644
index e5bbc69738..0000000000
--- a/target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch
+++ /dev/null
@@ -1,6152 +0,0 @@
-From 51e66f289f280a33bb17047717d2e6539a2917e1 Mon Sep 17 00:00:00 2001
-From: Alison Wang <b18965@freescale.com>
-Date: Thu, 4 Aug 2011 09:59:44 +0800
-Subject: [PATCH 21/52] Add ethernet switch driver for MCF54418
-
-Add ethernet switch driver support for MCF54418.
-
-Signed-off-by: Alison Wang <b18965@freescale.com>
----
- arch/m68k/coldfire/m5441x/l2switch.c | 284 +++
- arch/m68k/include/asm/mcfswitch.h | 324 +++
- drivers/net/Kconfig | 8 +
- drivers/net/Makefile | 1 +
- drivers/net/modelo_switch.c | 4293 ++++++++++++++++++++++++++++++++++
- drivers/net/modelo_switch.h | 1141 +++++++++
- include/linux/fsl_devices.h | 17 +
- net/core/dev.c | 8 +
- 8 files changed, 6076 insertions(+), 0 deletions(-)
- create mode 100644 arch/m68k/coldfire/m5441x/l2switch.c
- create mode 100644 arch/m68k/include/asm/mcfswitch.h
- create mode 100644 drivers/net/modelo_switch.c
- create mode 100644 drivers/net/modelo_switch.h
-
---- /dev/null
-+++ b/arch/m68k/coldfire/m5441x/l2switch.c
-@@ -0,0 +1,284 @@
-+/*
-+ * l2switch.c
-+ *
-+ * Sub-architcture dependant initialization code for the Freescale
-+ * 5441X L2 Switch module.
-+ *
-+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
-+ * ShrekWu B16972@freescale.com
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/param.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/fsl_devices.h>
-+
-+#include <asm/traps.h>
-+#include <asm/machdep.h>
-+#include <asm/coldfire.h>
-+#include <asm/mcfswitch.h>
-+#include <asm/mcfsim.h>
-+
-+static unsigned char switch_mac_default[] = {
-+ 0x00, 0x04, 0x9F, 0x00, 0xB3, 0x49,
-+};
-+
-+static unsigned char switch_mac_addr[6];
-+
-+static void switch_request_intrs(struct net_device *dev,
-+ irqreturn_t switch_net_irq_handler(int irq, void *private),
-+ void *irq_privatedata)
-+{
-+ struct switch_enet_private *fep;
-+ int b;
-+ static const struct idesc {
-+ char *name;
-+ unsigned short irq;
-+ } *idp, id[] = {
-+ /*{ "esw_isr(EBERR)", 38 },*/
-+ { "esw_isr(RxBuffer)", 39 },
-+ { "esw_isr(RxFrame)", 40 },
-+ { "esw_isr(TxBuffer)", 41 },
-+ { "esw_isr(TxFrame)", 42 },
-+ { "esw_isr(QM)", 43 },
-+ { "esw_isr(P0OutputDiscard)", 44 },
-+ { "esw_isr(P1OutputDiscard)", 45 },
-+ { "esw_isr(P2OutputDiscard)", 46 },
-+ { "esw_isr(LearningRecord)", 47 },
-+ { NULL },
-+ };
-+
-+ fep = netdev_priv(dev);
-+ /*intrruption L2 ethernet SWITCH */
-+ b = 64 + 64 + 64;
-+
-+ /* Setup interrupt handlers. */
-+ for (idp = id; idp->name; idp++) {
-+ if (request_irq(b+idp->irq,
-+ switch_net_irq_handler, IRQF_DISABLED,
-+ idp->name, irq_privatedata) != 0)
-+ printk(KERN_ERR "FEC: Could not alloc %s IRQ(%d)!\n",
-+ idp->name, b+idp->irq);
-+ }
-+
-+ /* Configure RMII */
-+ MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
-+ MCF_GPIO_PAR_FEC_FEC_MASK) |
-+ MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL;
-+
-+ MCF_GPIO_PAR_FEC =
-+ (MCF_GPIO_PAR_FEC &
-+ MCF_GPIO_PAR_FEC_FEC_MASK) |
-+ MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL;
-+
-+ MCF_GPIO_SRCR_FEC = 0x0F;
-+
-+ MCF_GPIO_PAR_SIMP0H =
-+ (MCF_GPIO_PAR_SIMP0H &
-+ MCF_GPIO_PAR_SIMP0H_DAT_MASK) |
-+ MCF_GPIO_PAR_SIMP0H_DAT_GPIO;
-+
-+ MCF_GPIO_PDDR_G =
-+ (MCF_GPIO_PDDR_G &
-+ MCF_GPIO_PDDR_G4_MASK) |
-+ MCF_GPIO_PDDR_G4_OUTPUT;
-+
-+ MCF_GPIO_PODR_G =
-+ (MCF_GPIO_PODR_G &
-+ MCF_GPIO_PODR_G4_MASK);
-+}
-+
-+static void switch_set_mii(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ MCF_FEC_RCR0 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
-+ MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
-+ MCF_FEC_RCR1 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
-+ MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
-+ /* TCR */
-+ MCF_FEC_TCR0 = MCF_FEC_TCR_FDEN;
-+ MCF_FEC_TCR1 = MCF_FEC_TCR_FDEN;
-+ /* ECR */
-+#ifdef MODELO_ENHANCE_BUFFER
-+ MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
-+ MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
-+#else /*legac buffer*/
-+ MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN;
-+ MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN;
-+#endif
-+ /*
-+ * Set MII speed to 2.5 MHz
-+ */
-+ MCF_FEC_MSCR0 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
-+ MCF_FEC_MSCR1 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
-+
-+}
-+
-+static void switch_get_mac(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+ volatile switch_t *fecp;
-+ unsigned char *iap;
-+
-+ fecp = fep->hwp;
-+
-+ if (FEC_FLASHMAC) {
-+ /*
-+ * Get MAC address from FLASH.
-+ * If it is all 1's or 0's, use the default.
-+ */
-+ iap = FEC_FLASHMAC;
-+ if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-+ (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-+ iap = switch_mac_default;
-+ if ((iap[0] == 0xff) && (iap[1] == 0xff) &&
-+ (iap[2] == 0xff) && (iap[3] == 0xff) &&
-+ (iap[4] == 0xff) && (iap[5] == 0xff))
-+ iap = switch_mac_default;
-+
-+ } else {
-+ iap = &switch_mac_addr[0];
-+
-+ if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-+ (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-+ iap = switch_mac_default;
-+ if ((iap[0] == 0xff) && (iap[1] == 0xff) &&
-+ (iap[2] == 0xff) && (iap[3] == 0xff) &&
-+ (iap[4] == 0xff) && (iap[5] == 0xff))
-+ iap = switch_mac_default;
-+ }
-+
-+ memcpy(dev->dev_addr, iap, ETH_ALEN);
-+ /* Adjust MAC if using default MAC address */
-+ if (iap == switch_mac_default)
-+ dev->dev_addr[ETH_ALEN-1] = switch_mac_default[ETH_ALEN-1] +
-+ fep->index;
-+}
-+
-+static void switch_enable_phy_intr(void)
-+{
-+}
-+
-+static void switch_disable_phy_intr(void)
-+{
-+}
-+
-+static void switch_phy_ack_intr(void)
-+{
-+}
-+
-+static void switch_localhw_setup(void)
-+{
-+}
-+
-+static void switch_uncache(unsigned long addr)
-+{
-+}
-+
-+static void switch_platform_flush_cache(void)
-+{
-+}
-+
-+/*
-+ * Define the fixed address of the FEC hardware.
-+ */
-+static unsigned int switch_platform_hw[] = {
-+ (0xfc0dc000),
-+ (0xfc0e000),
-+};
-+
-+static struct coldfire_switch_platform_data mcf5441x_switch_data = {
-+ .hash_table = 0,
-+ .switch_hw = switch_platform_hw,
-+ .request_intrs = switch_request_intrs,
-+ .set_mii = switch_set_mii,
-+ .get_mac = switch_get_mac,
-+ .enable_phy_intr = switch_enable_phy_intr,
-+ .disable_phy_intr = switch_disable_phy_intr,
-+ .phy_ack_intr = switch_phy_ack_intr,
-+ .localhw_setup = switch_localhw_setup,
-+ .uncache = switch_uncache,
-+ .platform_flush_cache = switch_platform_flush_cache,
-+};
-+
-+static struct resource l2switch_coldfire_resources[] = {
-+ [0] = {
-+ .start = 0xFC0DC000,
-+ .end = 0xFC0DC508,
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .start = (64 + 64 + 64 + 38),
-+ .end = (64 + 64 + 64 + 48),
-+ .flags = IORESOURCE_IRQ,
-+ },
-+ [2] = {
-+ .start = 0xFC0E0000,
-+ .end = 0xFC0E3FFC,
-+ .flags = IORESOURCE_MEM,
-+ },
-+};
-+
-+static struct platform_device l2switch_coldfire_device = {
-+ .name = "coldfire-switch",
-+ .id = 0,
-+ .resource = l2switch_coldfire_resources,
-+ .num_resources = ARRAY_SIZE(l2switch_coldfire_resources),
-+ .dev = {
-+ .platform_data = &mcf5441x_switch_data,
-+ .coherent_dma_mask = ~0, /* $$$ REVISIT */
-+ }
-+};
-+
-+
-+static int __init mcf5441x_switch_dev_init(void)
-+{
-+ int retval = 0;
-+
-+ retval = platform_device_register(&l2switch_coldfire_device);
-+
-+ if (retval < 0) {
-+ printk(KERN_ERR "MCF5441x L2Switch: platform_device_register"
-+ " failed with code=%d\n", retval);
-+ }
-+
-+ return retval;
-+}
-+
-+static int __init param_switch_addr_setup(char *str)
-+{
-+ char *end;
-+ int i;
-+
-+ for (i = 0; i < 6; i++) {
-+ switch_mac_addr[i] = str ? simple_strtoul(str, &end, 16) : 0;
-+ if (str)
-+ str = (*end) ? end + 1 : end;
-+ }
-+ return 0;
-+}
-+__setup("switchaddr=", param_switch_addr_setup);
-+
-+arch_initcall(mcf5441x_switch_dev_init);
---- /dev/null
-+++ b/arch/m68k/include/asm/mcfswitch.h
-@@ -0,0 +1,324 @@
-+/****************************************************************************/
-+
-+/*
-+ * mcfswitch -- L2 SWITCH Controller for Motorola ColdFire SoC
-+ * processors.
-+ *
-+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+/****************************************************************************/
-+#ifndef SWITCH_H
-+#define SWITCH_H
-+/****************************************************************************/
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <linux/platform_device.h>
-+#include <asm/pgtable.h>
-+
-+#define FEC_FLASHMAC 0
-+#define SWITCH_EPORT_NUMBER 2
-+
-+#ifdef CONFIG_SWITCH_DMA_USE_SRAM
-+#define TX_RING_SIZE 8 /* Must be power of two */
-+#define TX_RING_MOD_MASK 7 /* for this to work */
-+#else
-+#define TX_RING_SIZE 16 /* Must be power of two */
-+#define TX_RING_MOD_MASK 15 /* for this to work */
-+#endif
-+
-+typedef struct l2switch_port_statistics_status {
-+ /*outgoing frames discarded due to transmit queue congestion*/
-+ unsigned long MCF_ESW_POQC;
-+ /*incoming frames discarded due to VLAN domain mismatch*/
-+ unsigned long MCF_ESW_PMVID;
-+ /*incoming frames discarded due to untagged discard*/
-+ unsigned long MCF_ESW_PMVTAG;
-+ /*incoming frames discarded due port is in blocking state*/
-+ unsigned long MCF_ESW_PBL;
-+} esw_port_statistics_status;
-+
-+typedef struct l2switch {
-+ unsigned long ESW_REVISION;
-+ unsigned long ESW_SCRATCH;
-+ unsigned long ESW_PER;
-+ unsigned long reserved0[1];
-+ unsigned long ESW_VLANV;
-+ unsigned long ESW_DBCR;
-+ unsigned long ESW_DMCR;
-+ unsigned long ESW_BKLR;
-+ unsigned long ESW_BMPC;
-+ unsigned long ESW_MODE;
-+ unsigned long ESW_VIMSEL;
-+ unsigned long ESW_VOMSEL;
-+ unsigned long ESW_VIMEN;
-+ unsigned long ESW_VID;/*0x34*/
-+ /*from 0x38 0x3C*/
-+ unsigned long esw_reserved0[2];
-+ unsigned long ESW_MCR;/*0x40*/
-+ unsigned long ESW_EGMAP;
-+ unsigned long ESW_INGMAP;
-+ unsigned long ESW_INGSAL;
-+ unsigned long ESW_INGSAH;
-+ unsigned long ESW_INGDAL;
-+ unsigned long ESW_INGDAH;
-+ unsigned long ESW_ENGSAL;
-+ unsigned long ESW_ENGSAH;
-+ unsigned long ESW_ENGDAL;
-+ unsigned long ESW_ENGDAH;
-+ unsigned long ESW_MCVAL;/*0x6C*/
-+ /*from 0x70--0x7C*/
-+ unsigned long esw_reserved1[4];
-+ unsigned long ESW_MMSR;/*0x80*/
-+ unsigned long ESW_LMT;
-+ unsigned long ESW_LFC;
-+ unsigned long ESW_PCSR;
-+ unsigned long ESW_IOSR;
-+ unsigned long ESW_QWT;/*0x94*/
-+ unsigned long esw_reserved2[1];/*0x98*/
-+ unsigned long ESW_P0BCT;/*0x9C*/
-+ /*from 0xA0-0xB8*/
-+ unsigned long esw_reserved3[7];
-+ unsigned long ESW_P0FFEN;/*0xBC*/
-+ unsigned long ESW_PSNP[8];
-+ unsigned long ESW_IPSNP[8];
-+ unsigned long ESW_PVRES[3];
-+ /*from 0x10C-0x13C*/
-+ unsigned long esw_reserved4[13];
-+ unsigned long ESW_IPRES;/*0x140*/
-+ /*from 0x144-0x17C*/
-+ unsigned long esw_reserved5[15];
-+
-+ /*port0-port2 Priority Configuration 0xFC0D_C180-C188*/
-+ unsigned long ESW_PRES[3];
-+ /*from 0x18C-0x1FC*/
-+ unsigned long esw_reserved6[29];
-+
-+ /*port0-port2 VLAN ID 0xFC0D_C200-C208*/
-+ unsigned long ESW_PID[3];
-+ /*from 0x20C-0x27C*/
-+ unsigned long esw_reserved7[29];
-+
-+ /*port0-port2 VLAN domain resolution entry 0xFC0D_C280-C2FC*/
-+ unsigned long ESW_VRES[32];
-+
-+ unsigned long ESW_DISCN;/*0x300*/
-+ unsigned long ESW_DISCB;
-+ unsigned long ESW_NDISCN;
-+ unsigned long ESW_NDISCB;/*0xFC0DC30C*/
-+ /*per port statistics 0xFC0DC310_C33C*/
-+ esw_port_statistics_status port_statistics_status[3];
-+ /*from 0x340-0x400*/
-+ unsigned long esw_reserved8[48];
-+
-+ /*0xFC0DC400---0xFC0DC418*/
-+ /*unsigned long MCF_ESW_ISR;*/
-+ unsigned long switch_ievent; /* Interrupt event reg */
-+ /*unsigned long MCF_ESW_IMR;*/
-+ unsigned long switch_imask; /* Interrupt mask reg */
-+ /*unsigned long MCF_ESW_RDSR;*/
-+ unsigned long fec_r_des_start; /* Receive descriptor ring */
-+ /*unsigned long MCF_ESW_TDSR;*/
-+ unsigned long fec_x_des_start; /* Transmit descriptor ring */
-+ /*unsigned long MCF_ESW_MRBR;*/
-+ unsigned long fec_r_buff_size; /* Maximum receive buff size */
-+ /*unsigned long MCF_ESW_RDAR;*/
-+ unsigned long fec_r_des_active; /* Receive descriptor reg */
-+ /*unsigned long MCF_ESW_TDAR;*/
-+ unsigned long fec_x_des_active; /* Transmit descriptor reg */
-+ /*from 0x420-0x4FC*/
-+ unsigned long esw_reserved9[57];
-+
-+ /*0xFC0DC500---0xFC0DC508*/
-+ unsigned long ESW_LREC0;
-+ unsigned long ESW_LREC1;
-+ unsigned long ESW_LSR;
-+} switch_t;
-+
-+typedef struct _64bTableEntry {
-+ unsigned int lo; /* lower 32 bits */
-+ unsigned int hi; /* upper 32 bits */
-+} AddrTable64bEntry;
-+
-+typedef struct l2switchaddrtable {
-+ AddrTable64bEntry eswTable64bEntry[2048];
-+} eswAddrTable_t;
-+
-+#define MCF_FEC_MSCR0 (*(volatile unsigned long *)(0xFC0D4044))
-+#define MCF_FEC_MSCR1 (*(volatile unsigned long *)(0xFC0D8044))
-+#define MCF_FEC_RCR0 (*(volatile unsigned long *)(0xFC0D4084))
-+#define MCF_FEC_RCR1 (*(volatile unsigned long *)(0xFC0D8084))
-+#define MCF_FEC_TCR0 (*(volatile unsigned long *)(0xFC0D40C4))
-+#define MCF_FEC_TCR1 (*(volatile unsigned long *)(0xFC0D80C4))
-+#define MCF_FEC_ECR0 (*(volatile unsigned long *)(0xFC0D4024))
-+#define MCF_FEC_ECR1 (*(volatile unsigned long *)(0xFC0D8024))
-+
-+#define MCF_FEC_RCR_PROM (0x00000008)
-+#define MCF_FEC_RCR_RMII_MODE (0x00000100)
-+#define MCF_FEC_RCR_MAX_FL(x) (((x)&0x00003FFF)<<16)
-+#define MCF_FEC_RCR_CRC_FWD (0x00004000)
-+
-+#define MCF_FEC_TCR_FDEN (0x00000004)
-+
-+#define MCF_FEC_ECR_ETHER_EN (0x00000002)
-+#define MCF_FEC_ECR_ENA_1588 (0x00000010)
-+
-+
-+typedef struct bufdesc {
-+ unsigned short cbd_sc; /* Control and status info */
-+ unsigned short cbd_datlen; /* Data length */
-+ unsigned long cbd_bufaddr; /* Buffer address */
-+#ifdef MODELO_BUFFER
-+ unsigned long ebd_status;
-+ unsigned short length_proto_type;
-+ unsigned short payload_checksum;
-+ unsigned long bdu;
-+ unsigned long timestamp;
-+ unsigned long reserverd_word1;
-+ unsigned long reserverd_word2;
-+#endif
-+} cbd_t;
-+
-+/* Forward declarations of some structures to support different PHYs
-+ */
-+typedef struct {
-+ uint mii_data;
-+ void (*funct)(uint mii_reg, struct net_device *dev);
-+} phy_cmd_t;
-+
-+typedef struct {
-+ uint id;
-+ char *name;
-+
-+ const phy_cmd_t *config;
-+ const phy_cmd_t *startup;
-+ const phy_cmd_t *ack_int;
-+ const phy_cmd_t *shutdown;
-+} phy_info_t;
-+
-+/* The switch buffer descriptors track the ring buffers. The rx_bd_base and
-+ * tx_bd_base always point to the base of the buffer descriptors. The
-+ * cur_rx and cur_tx point to the currently available buffer.
-+ * The dirty_tx tracks the current buffer that is being sent by the
-+ * controller. The cur_tx and dirty_tx are equal under both completely
-+ * empty and completely full conditions. The empty/ready indicator in
-+ * the buffer descriptor determines the actual condition.
-+ */
-+struct switch_enet_private {
-+ /* Hardware registers of the switch device */
-+ volatile switch_t *hwp;
-+ volatile eswAddrTable_t *hwentry;
-+
-+ struct net_device *netdev;
-+ struct platform_device *pdev;
-+ /* The saved address of a sent-in-place packet/buffer, for skfree(). */
-+ unsigned char *tx_bounce[TX_RING_SIZE];
-+ struct sk_buff *tx_skbuff[TX_RING_SIZE];
-+ ushort skb_cur;
-+ ushort skb_dirty;
-+
-+ /* CPM dual port RAM relative addresses.
-+ */
-+ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
-+ cbd_t *tx_bd_base;
-+ cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
-+ cbd_t *dirty_tx; /* The ring entries to be free()ed. */
-+ uint tx_full;
-+ /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
-+ spinlock_t hw_lock;
-+
-+ /* hold while accessing the mii_list_t() elements */
-+ spinlock_t mii_lock;
-+ struct mii_bus *mdio_bus;
-+ struct phy_device *phydev[SWITCH_EPORT_NUMBER];
-+
-+ uint phy_id;
-+ uint phy_id_done;
-+ uint phy_status;
-+ uint phy_speed;
-+ phy_info_t const *phy;
-+ struct work_struct phy_task;
-+ volatile switch_t *phy_hwp;
-+
-+ uint sequence_done;
-+ uint mii_phy_task_queued;
-+
-+ uint phy_addr;
-+
-+ int index;
-+ int opened;
-+ int full_duplex;
-+ int msg_enable;
-+ int phy1_link;
-+ int phy1_old_link;
-+ int phy1_duplex;
-+ int phy1_speed;
-+
-+ int phy2_link;
-+ int phy2_old_link;
-+ int phy2_duplex;
-+ int phy2_speed;
-+ /* --------------Statistics--------------------------- */
-+ /* when a new element deleted a element with in
-+ * a block due to lack of space */
-+ int atBlockOverflows;
-+ /* Peak number of valid entries in the address table */
-+ int atMaxEntries;
-+ /* current number of valid entries in the address table */
-+ int atCurrEntries;
-+ /* maximum entries within a block found
-+ * (updated within ageing)*/
-+ int atMaxEntriesPerBlock;
-+
-+ /* -------------------ageing function------------------ */
-+ /* maximum age allowed for an entry */
-+ int ageMax;
-+ /* last LUT entry to block that was
-+ * inspected by the Ageing task*/
-+ int ageLutIdx;
-+ /* last element within block inspected by the Ageing task */
-+ int ageBlockElemIdx;
-+ /* complete table has been processed by ageing process */
-+ int ageCompleted;
-+ /* delay setting */
-+ int ageDelay;
-+ /* current delay Counter */
-+ int ageDelayCnt;
-+
-+ /* ----------------timer related---------------------------- */
-+ /* current time (for timestamping) */
-+ int currTime;
-+ /* flag set by timer when currTime changed
-+ * and cleared by serving function*/
-+ int timeChanged;
-+
-+ /* Timer for Aging */
-+ struct timer_list timer_aging;
-+ int learning_irqhandle_enable;
-+};
-+
-+struct switch_platform_private {
-+ struct platform_device *pdev;
-+
-+ unsigned long quirks;
-+ int num_slots; /* Slots on controller */
-+ struct switch_enet_private *fep_host[0]; /* Pointers to hosts */
-+};
-+#endif
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -1950,6 +1950,14 @@ config FEC
- Say Y here if you want to use the built-in 10/100 Fast ethernet
- controller on some Motorola ColdFire and Freescale i.MX processors.
-
-+config MODELO_SWITCH
-+ bool "ethernet switch controller (of ColdFire CPUs)"
-+ depends on !FEC && M5441X
-+ help
-+ Say Y here if you want to use the built-in ethernet switch
-+ controller on some ColdFire processors.
-+ The Integrated Ethernet switch engine is compatible with
-+ 10/100 MAC-NET core.
-
- config FEC2
- bool "Second FEC ethernet controller (on some ColdFire CPUs)"
---- a/drivers/net/Makefile
-+++ b/drivers/net/Makefile
-@@ -127,6 +127,7 @@ ifeq ($(CONFIG_FEC_1588), y)
- obj-$(CONFIG_FEC) += fec_1588.o
- endif
- obj-$(CONFIG_FEC_548x) += fec_m547x.o
-+obj-$(CONFIG_MODELO_SWITCH) += modelo_switch.o
- obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
- ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
- obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
---- /dev/null
-+++ b/drivers/net/modelo_switch.c
-@@ -0,0 +1,4293 @@
-+/*
-+ * L2 switch Controller (Etheren switch) driver for MCF5441x.
-+ *
-+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
-+ * Shrek Wu (B16972@freescale.com)
-+ * Alison Wang (b18965@freescale.com)
-+ * Jason Jin (Jason.jin@freescale.com)
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/ptrace.h>
-+#include <linux/errno.h>
-+#include <linux/ioport.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <linux/bitops.h>
-+#include <linux/platform_device.h>
-+#include <linux/fsl_devices.h>
-+#include <linux/phy.h>
-+#include <linux/kthread.h>
-+#include <linux/syscalls.h>
-+#include <linux/uaccess.h>
-+#include <linux/io.h>
-+#include <linux/signal.h>
-+
-+#include <asm/irq.h>
-+#include <asm/pgtable.h>
-+#include <asm/cacheflush.h>
-+#include <asm/coldfire.h>
-+#include <asm/mcfsim.h>
-+#include "modelo_switch.h"
-+
-+#define SWITCH_MAX_PORTS 1
-+#define CONFIG_FEC_SHARED_PHY
-+
-+/* Interrupt events/masks.
-+*/
-+#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
-+#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
-+#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
-+#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
-+#define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */
-+#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
-+#define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */
-+#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
-+#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
-+#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
-+
-+static int switch_enet_open(struct net_device *dev);
-+static int switch_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
-+static irqreturn_t switch_enet_interrupt(int irq, void *dev_id);
-+static void switch_enet_tx(struct net_device *dev);
-+static void switch_enet_rx(struct net_device *dev);
-+static int switch_enet_close(struct net_device *dev);
-+static void set_multicast_list(struct net_device *dev);
-+static void switch_restart(struct net_device *dev, int duplex);
-+static void switch_stop(struct net_device *dev);
-+static void switch_set_mac_address(struct net_device *dev);
-+
-+#define NMII 20
-+
-+/* Make MII read/write commands for the FEC.
-+*/
-+#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
-+#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
-+ (VAL & 0xffff))
-+
-+/* Transmitter timeout.
-+*/
-+#define TX_TIMEOUT (2*HZ)
-+
-+/*last read entry from learning interface*/
-+eswPortInfo g_info;
-+/* switch ports status */
-+struct port_status ports_link_status;
-+
-+/* the user space pid, used to send the link change to user space */
-+long user_pid = 1;
-+
-+/* ----------------------------------------------------------------*/
-+/*
-+ * Calculate Galois Field Arithmetic CRC for Polynom x^8+x^2+x+1.
-+ * It omits the final shift in of 8 zeroes a "normal" CRC would do
-+ * (getting the remainder).
-+ *
-+ * Examples (hexadecimal values):<br>
-+ * 10-11-12-13-14-15 => CRC=0xc2
-+ * 10-11-cc-dd-ee-00 => CRC=0xe6
-+ *
-+ * param: pmacaddress
-+ * A 6-byte array with the MAC address.
-+ * The first byte is the first byte transmitted
-+ * return The 8-bit CRC in bits 7:0
-+ */
-+int crc8_calc(unsigned char *pmacaddress)
-+{
-+ /* byte index */
-+ int byt;
-+ /* bit index */
-+ int bit;
-+ int inval;
-+ int crc;
-+ /* preset */
-+ crc = 0x12;
-+ for (byt = 0; byt < 6; byt++) {
-+ inval = (((int)pmacaddress[byt]) & 0xff);
-+ /*
-+ * shift bit 0 to bit 8 so all our bits
-+ * travel through bit 8
-+ * (simplifies below calc)
-+ */
-+ inval <<= 8;
-+
-+ for (bit = 0; bit < 8; bit++) {
-+ /* next input bit comes into d7 after shift */
-+ crc |= inval & 0x100;
-+ if (crc & 0x01)
-+ /* before shift */
-+ crc ^= 0x1c0;
-+
-+ crc >>= 1;
-+ inval >>= 1;
-+ }
-+
-+ }
-+ /* upper bits are clean as we shifted in zeroes! */
-+ return crc;
-+}
-+
-+void read_atable(struct switch_enet_private *fep,
-+ int index, unsigned long *read_lo, unsigned long *read_hi)
-+{
-+ unsigned long atable_base = 0xFC0E0000;
-+
-+ *read_lo = *((volatile unsigned long *)(atable_base + (index<<3)));
-+ *read_hi = *((volatile unsigned long *)(atable_base + (index<<3) + 4));
-+}
-+
-+void write_atable(struct switch_enet_private *fep,
-+ int index, unsigned long write_lo, unsigned long write_hi)
-+{
-+ unsigned long atable_base = 0xFC0E0000;
-+
-+ *((volatile unsigned long *)(atable_base + (index<<3))) = write_lo;
-+ *((volatile unsigned long *)(atable_base + (index<<3) + 4)) = write_hi;
-+}
-+
-+/* Check if the Port Info FIFO has data available
-+ * for reading. 1 valid, 0 invalid*/
-+int esw_portinfofifo_status(struct switch_enet_private *fep)
-+{
-+ volatile switch_t *fecp;
-+ fecp = fep->hwp;
-+ return fecp->ESW_LSR;
-+}
-+
-+/* Initialize the Port Info FIFO. */
-+void esw_portinfofifo_initialize(struct switch_enet_private *fep)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp;
-+ fecp = fep->hwp;
-+
-+ /*disable all learn*/
-+ fecp->switch_imask &= (~MCF_ESW_IMR_LRN);
-+ /* remove all entries from FIFO */
-+ while (esw_portinfofifo_status(fep)) {
-+ /* read one data word */
-+ tmp = fecp->ESW_LREC0;
-+ tmp = fecp->ESW_LREC1;
-+ }
-+
-+}
-+
-+/* Read one element from the HW receive FIFO (Queue)
-+ * if available and return it.
-+ * return ms_HwPortInfo or null if no data is available
-+ */
-+eswPortInfo *esw_portinfofifo_read(struct switch_enet_private *fep)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp;
-+
-+ fecp = fep->hwp;
-+ /* check learning record valid */
-+ if (fecp->ESW_LSR == 0)
-+ return NULL;
-+
-+ /*read word from FIFO*/
-+ g_info.maclo = fecp->ESW_LREC0;
-+
-+ /*but verify that we actually did so
-+ * (0=no data available)*/
-+ if (g_info.maclo == 0)
-+ return NULL;
-+
-+ /* read 2nd word from FIFO */
-+ tmp = fecp->ESW_LREC1;
-+ g_info.machi = tmp & 0xffff;
-+ g_info.hash = (tmp >> 16) & 0xff;
-+ g_info.port = (tmp >> 24) & 0xf;
-+
-+ return &g_info;
-+}
-+
-+/*
-+ * Clear complete MAC Look Up Table
-+ */
-+void esw_clear_atable(struct switch_enet_private *fep)
-+{
-+ int index;
-+ for (index = 0; index < 2048; index++)
-+ write_atable(fep, index, 0, 0);
-+}
-+
-+void esw_dump_atable(struct switch_enet_private *fep)
-+{
-+ int index;
-+ unsigned long read_lo, read_hi;
-+ for (index = 0; index < 2048; index++)
-+ read_atable(fep, index, &read_lo, &read_hi);
-+}
-+
-+/*
-+ * pdates MAC address lookup table with a static entry
-+ * Searches if the MAC address is already there in the block and replaces
-+ * the older entry with new one. If MAC address is not there then puts a
-+ * new entry in the first empty slot available in the block
-+ *
-+ * mac_addr Pointer to the array containing MAC address to
-+ * be put as static entry
-+ * port Port bitmask numbers to be added in static entry,
-+ * valid values are 1-7
-+ * priority Priority for the static entry in table
-+ *
-+ * return 0 for a successful update else -1 when no slot available
-+ */
-+int esw_update_atable_static(unsigned char *mac_addr,
-+ unsigned int port, unsigned int priority,
-+ struct switch_enet_private *fep)
-+{
-+ unsigned long block_index, entry, index_end;
-+ unsigned long read_lo, read_hi;
-+ unsigned long write_lo, write_hi;
-+
-+ write_lo = (unsigned long)((mac_addr[3] << 24) |
-+ (mac_addr[2] << 16) |
-+ (mac_addr[1] << 8) |
-+ mac_addr[0]);
-+ write_hi = (unsigned long)(0 |
-+ (port << AT_SENTRY_PORTMASK_shift) |
-+ (priority << AT_SENTRY_PRIO_shift) |
-+ (AT_ENTRY_TYPE_STATIC << AT_ENTRY_TYPE_shift) |
-+ (AT_ENTRY_RECORD_VALID << AT_ENTRY_VALID_shift) |
-+ (mac_addr[5] << 8) | (mac_addr[4]));
-+
-+ block_index = GET_BLOCK_PTR(crc8_calc(mac_addr));
-+ index_end = block_index + ATABLE_ENTRY_PER_SLOT;
-+ /* Now search all the entries in the selected block */
-+ for (entry = block_index; entry < index_end; entry++) {
-+ read_atable(fep, entry, &read_lo, &read_hi);
-+ /*
-+ * MAC address matched, so update the
-+ * existing entry
-+ * even if its a dynamic one
-+ */
-+ if ((read_lo == write_lo) && ((read_hi & 0x0000ffff) ==
-+ (write_hi & 0x0000ffff))) {
-+ write_atable(fep, entry, write_lo, write_hi);
-+ return 0;
-+ } else if (!(read_hi & (1 << 16))) {
-+ /*
-+ * Fill this empty slot (valid bit zero),
-+ * assuming no holes in the block
-+ */
-+ write_atable(fep, entry, write_lo, write_hi);
-+ fep->atCurrEntries++;
-+ return 0;
-+ }
-+ }
-+
-+ /* No space available for this static entry */
-+ return -1;
-+}
-+
-+/* lookup entry in given Address Table slot and
-+ * insert (learn) it if it is not found.
-+ * return 0 if entry was found and updated.
-+ * 1 if entry was not found and has been inserted (learned).
-+ */
-+int esw_update_atable_dynamic(unsigned char *mac_addr, unsigned int port,
-+ unsigned int currTime, struct switch_enet_private *fep)
-+{
-+ unsigned long block_index, entry, index_end;
-+ unsigned long read_lo, read_hi;
-+ unsigned long write_lo, write_hi;
-+ unsigned long tmp;
-+ int time, timeold, indexold;
-+
-+ /* prepare update port and timestamp */
-+ write_hi = (mac_addr[5] << 8) | (mac_addr[4]);
-+ write_lo = (unsigned long)((mac_addr[3] << 24) |
-+ (mac_addr[2] << 16) |
-+ (mac_addr[1] << 8) |
-+ mac_addr[0]);
-+ tmp = AT_ENTRY_RECORD_VALID << AT_ENTRY_VALID_shift;
-+ tmp |= AT_ENTRY_TYPE_DYNAMIC << AT_ENTRY_TYPE_shift;
-+ tmp |= currTime << AT_DENTRY_TIME_shift;
-+ tmp |= port << AT_DENTRY_PORT_shift;
-+ tmp |= write_hi;
-+
-+ /*
-+ * linear search through all slot
-+ * entries and update if found
-+ */
-+ block_index = GET_BLOCK_PTR(crc8_calc(mac_addr));
-+ index_end = block_index + ATABLE_ENTRY_PER_SLOT;
-+ /* Now search all the entries in the selected block */
-+ for (entry = block_index; entry < index_end; entry++) {
-+ read_atable(fep, entry, &read_lo, &read_hi);
-+
-+ if ((read_lo == write_lo) &&
-+ ((read_hi & 0x0000ffff) ==
-+ (write_hi & 0x0000ffff))) {
-+ /* found correct address,
-+ * update timestamp. */
-+ write_atable(fep, entry, write_lo, tmp);
-+ return 0;
-+ } else if (!(read_hi & (1 << 16))) {
-+ /* slot is empty, then use it
-+ * for new entry
-+ * Note: There are no holes,
-+ * therefore cannot be any
-+ * more that need to be compared.
-+ */
-+ write_atable(fep, entry, write_lo, tmp);
-+ /* statistics (we do it between writing
-+ * .hi an .lo due to
-+ * hardware limitation...
-+ */
-+ fep->atCurrEntries++;
-+ /* newly inserted */
-+ return 1;
-+ }
-+ }
-+
-+ /*
-+ * no more entry available in blockk ...
-+ * overwrite oldest
-+ */
-+ timeold = 0;
-+ indexold = 0;
-+ for (entry = block_index; entry < index_end; entry++) {
-+ read_atable(fep, entry, &read_lo, &read_hi);
-+ time = AT_EXTRACT_TIMESTAMP(read_hi);
-+ time = TIMEDELTA(currTime, time);
-+ if (time > timeold) {
-+ /* is it older ?*/
-+ timeold = time;
-+ indexold = entry;
-+ }
-+ }
-+
-+ write_atable(fep, indexold, write_lo, tmp);
-+ /* Statistics (do it inbetween
-+ * writing to .lo and .hi*/
-+ fep->atBlockOverflows++;
-+ /* newly inserted */
-+ return 1;
-+}
-+
-+int esw_update_atable_dynamic1(unsigned long write_lo, unsigned long write_hi,
-+ int block_index, unsigned int port, unsigned int currTime,
-+ struct switch_enet_private *fep)
-+{
-+ unsigned long entry, index_end;
-+ unsigned long read_lo, read_hi;
-+ unsigned long tmp;
-+ int time, timeold, indexold;
-+
-+ /* prepare update port and timestamp */
-+ tmp = AT_ENTRY_RECORD_VALID << AT_ENTRY_VALID_shift;
-+ tmp |= AT_ENTRY_TYPE_DYNAMIC << AT_ENTRY_TYPE_shift;
-+ tmp |= currTime << AT_DENTRY_TIME_shift;
-+ tmp |= port << AT_DENTRY_PORT_shift;
-+ tmp |= write_hi;
-+
-+ /*
-+ * linear search through all slot
-+ * entries and update if found
-+ */
-+ index_end = block_index + ATABLE_ENTRY_PER_SLOT;
-+ /* Now search all the entries in the selected block */
-+ for (entry = block_index; entry < index_end; entry++) {
-+ read_atable(fep, entry, &read_lo, &read_hi);
-+ if ((read_lo == write_lo) &&
-+ ((read_hi & 0x0000ffff) ==
-+ (write_hi & 0x0000ffff))) {
-+ /* found correct address,
-+ * update timestamp. */
-+ write_atable(fep, entry, write_lo, tmp);
-+ return 0;
-+ } else if (!(read_hi & (1 << 16))) {
-+ /* slot is empty, then use it
-+ * for new entry
-+ * Note: There are no holes,
-+ * therefore cannot be any
-+ * more that need to be compared.
-+ */
-+ write_atable(fep, entry, write_lo, tmp);
-+ /* statistics (we do it between writing
-+ * .hi an .lo due to
-+ * hardware limitation...
-+ */
-+ fep->atCurrEntries++;
-+ /* newly inserted */
-+ return 1;
-+ }
-+ }
-+
-+ /*
-+ * no more entry available in block ...
-+ * overwrite oldest
-+ */
-+ timeold = 0;
-+ indexold = 0;
-+ for (entry = block_index; entry < index_end; entry++) {
-+ read_atable(fep, entry, &read_lo, &read_hi);
-+ time = AT_EXTRACT_TIMESTAMP(read_hi);
-+ time = TIMEDELTA(currTime, time);
-+ if (time > timeold) {
-+ /* is it older ?*/
-+ timeold = time;
-+ indexold = entry;
-+ }
-+ }
-+
-+ write_atable(fep, indexold, write_lo, tmp);
-+ /* Statistics (do it inbetween
-+ * writing to .lo and .hi*/
-+ fep->atBlockOverflows++;
-+ /* newly inserted */
-+ return 1;
-+}
-+
-+/*
-+ * Delete one dynamic entry within the given block
-+ * of 64-bit entries.
-+ * return number of valid entries in the block after deletion.
-+ */
-+int esw_del_atable_dynamic(struct switch_enet_private *fep,
-+ int blockidx, int entryidx)
-+{
-+ unsigned long index_start, index_end;
-+ int i;
-+ unsigned long read_lo, read_hi;
-+
-+ /* the entry to delete */
-+ index_start = blockidx + entryidx;
-+ /* one after last */
-+ index_end = blockidx + ATABLE_ENTRY_PER_SLOT;
-+ /* Statistics */
-+ fep->atCurrEntries--;
-+
-+ if (entryidx == (ATABLE_ENTRY_PER_SLOT - 1)) {
-+ /* if it is the very last entry,
-+ * just delete it without further efford*/
-+ write_atable(fep, index_start, 0, 0);
-+ /*number of entries left*/
-+ i = ATABLE_ENTRY_PER_SLOT - 1;
-+ return i;
-+ } else {
-+ /*not the last in the block, then
-+ * shift all that follow the one
-+ * that is deleted to avoid "holes".
-+ */
-+ for (i = index_start; i < (index_end - 1); i++) {
-+ read_atable(fep, i + 1, &read_lo, &read_hi);
-+ /* move it down */
-+ write_atable(fep, i, read_lo, read_hi);
-+ if (!(read_hi & (1 << 16))) {
-+ /* stop if we just copied the last */
-+ return i - blockidx;
-+ }
-+ }
-+
-+ /*moved all entries up to the last.
-+ * then set invalid flag in the last*/
-+ write_atable(fep, index_end - 1, 0, 0);
-+ /* number of valid entries left */
-+ return i - blockidx;
-+ }
-+}
-+
-+void esw_atable_dynamicms_del_entries_for_port(
-+ struct switch_enet_private *fep, int port_index)
-+{
-+ unsigned long read_lo, read_hi;
-+ unsigned int port_idx;
-+ int i;
-+
-+ for (i = 0; i < ESW_ATABLE_MEM_NUM_ENTRIES; i++) {
-+ read_atable(fep, i, &read_lo, &read_hi);
-+ if (read_hi & (1 << 16)) {
-+ port_idx = AT_EXTRACT_PORT(read_hi);
-+
-+ if (port_idx == port_index)
-+ write_atable(fep, i, 0, 0);
-+ }
-+ }
-+}
-+
-+void esw_atable_dynamicms_del_entries_for_other_port(
-+ struct switch_enet_private *fep,
-+ int port_index)
-+{
-+ unsigned long read_lo, read_hi;
-+ unsigned int port_idx;
-+ int i;
-+
-+ for (i = 0; i < ESW_ATABLE_MEM_NUM_ENTRIES; i++) {
-+ read_atable(fep, i, &read_lo, &read_hi);
-+ if (read_hi & (1 << 16)) {
-+ port_idx = AT_EXTRACT_PORT(read_hi);
-+
-+ if (port_idx != port_index)
-+ write_atable(fep, i, 0, 0);
-+ }
-+ }
-+}
-+
-+/*
-+ * Scan one complete block (Slot) for outdated entries and delete them.
-+ * blockidx index of block of entries that should be analyzed.
-+ * return number of deleted entries, 0 if nothing was modified.
-+ */
-+int esw_atable_dynamicms_check_block_age(
-+ struct switch_enet_private *fep, int blockidx) {
-+
-+ int i, tm, tdelta;
-+ int deleted = 0, entries = 0;
-+ unsigned long read_lo, read_hi;
-+ /* Scan all entries from last down to
-+ * have faster deletion speed if necessary*/
-+ for (i = (blockidx + ATABLE_ENTRY_PER_SLOT - 1);
-+ i >= blockidx; i--) {
-+ read_atable(fep, i, &read_lo, &read_hi);
-+
-+ if (read_hi & (1 << 16)) {
-+ /* the entry is valide*/
-+ tm = AT_EXTRACT_TIMESTAMP(read_hi);
-+ tdelta = TIMEDELTA(fep->currTime, tm);
-+ if (tdelta > fep->ageMax) {
-+ esw_del_atable_dynamic(fep,
-+ blockidx, i-blockidx);
-+ deleted++;
-+ } else {
-+ /* statistics */
-+ entries++;
-+ }
-+ }
-+ }
-+
-+ /*update statistics*/
-+ if (fep->atMaxEntriesPerBlock < entries)
-+ fep->atMaxEntriesPerBlock = entries;
-+
-+ return deleted;
-+}
-+
-+/* scan the complete address table and find the most current entry.
-+ * The time of the most current entry then is used as current time
-+ * for the context structure.
-+ * In addition the atCurrEntries value is updated as well.
-+ * return time that has been set in the context.
-+ */
-+int esw_atable_dynamicms_find_set_latesttime(
-+ struct switch_enet_private *fep) {
-+
-+ int tm_min, tm_max, tm;
-+ int delta, current, i;
-+ unsigned long read_lo, read_hi;
-+
-+ tm_min = (1 << AT_DENTRY_TIMESTAMP_WIDTH) - 1;
-+ tm_max = 0;
-+ current = 0;
-+
-+ for (i = 0; i < ESW_ATABLE_MEM_NUM_ENTRIES; i++) {
-+ read_atable(fep, i, &read_lo, &read_hi);
-+ if (read_hi & (1 << 16)) {
-+ /*the entry is valid*/
-+ tm = AT_EXTRACT_TIMESTAMP(read_hi);
-+ if (tm > tm_max)
-+ tm_max = tm;
-+ if (tm < tm_min)
-+ tm_min = tm;
-+ current++;
-+ }
-+ }
-+
-+ delta = TIMEDELTA(tm_max, tm_min);
-+ if (delta < fep->ageMax) {
-+ /*Difference must be in range*/
-+ fep->currTime = tm_max;
-+ } else {
-+ fep->currTime = tm_min;
-+ }
-+
-+ fep->atCurrEntries = current;
-+ return fep->currTime;
-+}
-+
-+int esw_atable_dynamicms_get_port(
-+ struct switch_enet_private *fep,
-+ unsigned long write_lo,
-+ unsigned long write_hi,
-+ int block_index)
-+{
-+ int i, index_end;
-+ unsigned long read_lo, read_hi, port;
-+
-+ index_end = block_index + ATABLE_ENTRY_PER_SLOT;
-+ /* Now search all the entries in the selected block */
-+ for (i = block_index; i < index_end; i++) {
-+ read_atable(fep, i, &read_lo, &read_hi);
-+
-+ if ((read_lo == write_lo) &&
-+ ((read_hi & 0x0000ffff) ==
-+ (write_hi & 0x0000ffff))) {
-+ /* found correct address,*/
-+ if (read_hi & (1 << 16)) {
-+ /*extract the port index from the valid entry*/
-+ port = AT_EXTRACT_PORT(read_hi);
-+ return port;
-+ }
-+ }
-+ }
-+
-+ return -1;
-+}
-+
-+/* Get the port index from the source MAC address
-+ * of the received frame
-+ * @return port index
-+ */
-+int esw_atable_dynamicms_get_portindex_from_mac(
-+ struct switch_enet_private *fep,
-+ unsigned char *mac_addr,
-+ unsigned long write_lo,
-+ unsigned long write_hi)
-+{
-+ int blockIdx;
-+ int rc;
-+ /*compute the block index*/
-+ blockIdx = GET_BLOCK_PTR(crc8_calc(mac_addr));
-+ /* Get the ingress port index of the received BPDU */
-+ rc = esw_atable_dynamicms_get_port(fep,
-+ write_lo, write_hi, blockIdx);
-+
-+ return rc;
-+}
-+
-+/* dynamicms MAC address table learn and migration*/
-+int esw_atable_dynamicms_learn_migration(
-+ struct switch_enet_private *fep,
-+ int currTime)
-+{
-+ eswPortInfo *pESWPortInfo;
-+ int index;
-+ int inserted = 0;
-+
-+ pESWPortInfo = esw_portinfofifo_read(fep);
-+ /* Anything to learn */
-+ if (pESWPortInfo != 0) {
-+ /*get block index from lookup table*/
-+ index = GET_BLOCK_PTR(pESWPortInfo->hash);
-+ inserted = esw_update_atable_dynamic1(
-+ pESWPortInfo->maclo,
-+ pESWPortInfo->machi, index,
-+ pESWPortInfo->port, currTime, fep);
-+ }
-+
-+ return 0;
-+}
-+/* -----------------------------------------------------------------*/
-+/*
-+ * esw_forced_forward
-+ * The frame is forwared to the forced destination ports.
-+ * It only replace the MAC lookup function,
-+ * all other filtering(eg.VLAN verification) act as normal
-+ */
-+int esw_forced_forward(struct switch_enet_private *fep,
-+ int port1, int port2, int enable)
-+{
-+ unsigned long tmp = 0;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ /* Enable Forced forwarding for port num */
-+ if ((port1 == 1) && (port2 == 1))
-+ tmp |= MCF_ESW_P0FFEN_FD(3);
-+ else if (port1 == 1)
-+ /*Enable Forced forwarding for port 1 only*/
-+ tmp |= MCF_ESW_P0FFEN_FD(1);
-+ else if (port2 == 1)
-+ /*Enable Forced forwarding for port 2 only*/
-+ tmp |= MCF_ESW_P0FFEN_FD(2);
-+ else {
-+ printk(KERN_ERR "%s:do not support "
-+ "the forced forward mode"
-+ "port1 %x port2 %x\n",
-+ __func__, port1, port2);
-+ return -1;
-+ }
-+
-+ if (enable == 1)
-+ tmp |= MCF_ESW_P0FFEN_FEN;
-+ else if (enable == 0)
-+ tmp &= ~MCF_ESW_P0FFEN_FEN;
-+ else {
-+ printk(KERN_ERR "%s: the enable %x is error\n",
-+ __func__, enable);
-+ return -2;
-+ }
-+
-+ fecp->ESW_P0FFEN = tmp;
-+ return 0;
-+}
-+
-+void esw_get_forced_forward(
-+ struct switch_enet_private *fep,
-+ unsigned long *ulForceForward)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulForceForward = fecp->ESW_P0FFEN;
-+}
-+
-+void esw_get_port_enable(
-+ struct switch_enet_private *fep,
-+ unsigned long *ulPortEnable)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulPortEnable = fecp->ESW_PER;
-+}
-+/*
-+ * enable or disable port n tx or rx
-+ * tx_en 0 disable port n tx
-+ * tx_en 1 enable port n tx
-+ * rx_en 0 disbale port n rx
-+ * rx_en 1 enable port n rx
-+ */
-+int esw_port_enable_config(struct switch_enet_private *fep,
-+ int port, int tx_en, int rx_en)
-+{
-+ unsigned long tmp = 0;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ tmp = fecp->ESW_PER;
-+ if (tx_en == 1) {
-+ if (port == 0)
-+ tmp |= MCF_ESW_PER_TE0;
-+ else if (port == 1)
-+ tmp |= MCF_ESW_PER_TE1;
-+ else if (port == 2)
-+ tmp |= MCF_ESW_PER_TE2;
-+ else {
-+ printk(KERN_ERR "%s:do not support the"
-+ " port %x tx enable\n",
-+ __func__, port);
-+ return -1;
-+ }
-+ } else if (tx_en == 0) {
-+ if (port == 0)
-+ tmp &= (~MCF_ESW_PER_TE0);
-+ else if (port == 1)
-+ tmp &= (~MCF_ESW_PER_TE1);
-+ else if (port == 2)
-+ tmp &= (~MCF_ESW_PER_TE2);
-+ else {
-+ printk(KERN_ERR "%s:do not support "
-+ "the port %x tx disable\n",
-+ __func__, port);
-+ return -2;
-+ }
-+ } else {
-+ printk(KERN_ERR "%s:do not support the port %x"
-+ " tx op value %x\n",
-+ __func__, port, tx_en);
-+ return -3;
-+ }
-+
-+ if (rx_en == 1) {
-+ if (port == 0)
-+ tmp |= MCF_ESW_PER_RE0;
-+ else if (port == 1)
-+ tmp |= MCF_ESW_PER_RE1;
-+ else if (port == 2)
-+ tmp |= MCF_ESW_PER_RE2;
-+ else {
-+ printk(KERN_ERR "%s:do not support the "
-+ "port %x rx enable\n",
-+ __func__, port);
-+ return -4;
-+ }
-+ } else if (rx_en == 0) {
-+ if (port == 0)
-+ tmp &= (~MCF_ESW_PER_RE0);
-+ else if (port == 1)
-+ tmp &= (~MCF_ESW_PER_RE1);
-+ else if (port == 2)
-+ tmp &= (~MCF_ESW_PER_RE2);
-+ else {
-+ printk(KERN_ERR "%s:do not support the "
-+ "port %x rx disable\n",
-+ __func__, port);
-+ return -5;
-+ }
-+ } else {
-+ printk(KERN_ERR "%s:do not support the port %x"
-+ " rx op value %x\n",
-+ __func__, port, tx_en);
-+ return -6;
-+ }
-+
-+ fecp->ESW_PER = tmp;
-+ return 0;
-+}
-+
-+
-+void esw_get_port_broadcast(struct switch_enet_private *fep,
-+ unsigned long *ulPortBroadcast)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulPortBroadcast = fecp->ESW_DBCR;
-+}
-+
-+int esw_port_broadcast_config(struct switch_enet_private *fep,
-+ int port, int enable)
-+{
-+ unsigned long tmp = 0;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port > 2) || (port < 0)) {
-+ printk(KERN_ERR "%s:do not support the port %x"
-+ " default broadcast\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ tmp = fecp->ESW_DBCR;
-+ if (enable == 1) {
-+ if (port == 0)
-+ tmp |= MCF_ESW_DBCR_P0;
-+ else if (port == 1)
-+ tmp |= MCF_ESW_DBCR_P1;
-+ else if (port == 2)
-+ tmp |= MCF_ESW_DBCR_P2;
-+ } else if (enable == 0) {
-+ if (port == 0)
-+ tmp &= ~MCF_ESW_DBCR_P0;
-+ else if (port == 1)
-+ tmp &= ~MCF_ESW_DBCR_P1;
-+ else if (port == 2)
-+ tmp &= ~MCF_ESW_DBCR_P2;
-+ }
-+
-+ fecp->ESW_DBCR = tmp;
-+ return 0;
-+}
-+
-+
-+void esw_get_port_multicast(struct switch_enet_private *fep,
-+ unsigned long *ulPortMulticast)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulPortMulticast = fecp->ESW_DMCR;
-+}
-+
-+int esw_port_multicast_config(struct switch_enet_private *fep,
-+ int port, int enable)
-+{
-+ unsigned long tmp = 0;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port > 2) || (port < 0)) {
-+ printk(KERN_ERR "%s:do not support the port %x"
-+ " default broadcast\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ tmp = fecp->ESW_DMCR;
-+ if (enable == 1) {
-+ if (port == 0)
-+ tmp |= MCF_ESW_DMCR_P0;
-+ else if (port == 1)
-+ tmp |= MCF_ESW_DMCR_P1;
-+ else if (port == 2)
-+ tmp |= MCF_ESW_DMCR_P2;
-+ } else if (enable == 0) {
-+ if (port == 0)
-+ tmp &= ~MCF_ESW_DMCR_P0;
-+ else if (port == 1)
-+ tmp &= ~MCF_ESW_DMCR_P1;
-+ else if (port == 2)
-+ tmp &= ~MCF_ESW_DMCR_P2;
-+ }
-+
-+ fecp->ESW_DMCR = tmp;
-+ return 0;
-+}
-+
-+
-+void esw_get_port_blocking(struct switch_enet_private *fep,
-+ unsigned long *ulPortBlocking)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulPortBlocking = (fecp->ESW_BKLR & 0x0000000f);
-+}
-+
-+int esw_port_blocking_config(struct switch_enet_private *fep,
-+ int port, int enable)
-+{
-+ unsigned long tmp = 0;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port > 2) || (port < 0)) {
-+ printk(KERN_ERR "%s:do not support the port %x"
-+ " default broadcast\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ tmp = fecp->ESW_BKLR;
-+ if (enable == 1) {
-+ if (port == 0)
-+ tmp |= MCF_ESW_BKLR_BE0;
-+ else if (port == 1)
-+ tmp |= MCF_ESW_BKLR_BE1;
-+ else if (port == 2)
-+ tmp |= MCF_ESW_BKLR_BE2;
-+ } else if (enable == 0) {
-+ if (port == 0)
-+ tmp &= ~MCF_ESW_BKLR_BE0;
-+ else if (port == 1)
-+ tmp &= ~MCF_ESW_BKLR_BE1;
-+ else if (port == 2)
-+ tmp &= ~MCF_ESW_BKLR_BE2;
-+ }
-+
-+ fecp->ESW_BKLR = tmp;
-+ return 0;
-+}
-+
-+
-+void esw_get_port_learning(struct switch_enet_private *fep,
-+ unsigned long *ulPortLearning)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulPortLearning = (fecp->ESW_BKLR & 0x000f0000) >> 16;
-+}
-+
-+int esw_port_learning_config(struct switch_enet_private *fep,
-+ int port, int disable)
-+{
-+ unsigned long tmp = 0;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port > 2) || (port < 0)) {
-+ printk(KERN_ERR "%s:do not support the port %x"
-+ " default broadcast\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ tmp = fecp->ESW_BKLR;
-+ if (disable == 0) {
-+ fep->learning_irqhandle_enable = 0;
-+ if (port == 0)
-+ tmp |= MCF_ESW_BKLR_LD0;
-+ else if (port == 1)
-+ tmp |= MCF_ESW_BKLR_LD1;
-+ else if (port == 2)
-+ tmp |= MCF_ESW_BKLR_LD2;
-+ } else if (disable == 1) {
-+ if (port == 0)
-+ tmp &= ~MCF_ESW_BKLR_LD0;
-+ else if (port == 1)
-+ tmp &= ~MCF_ESW_BKLR_LD1;
-+ else if (port == 2)
-+ tmp &= ~MCF_ESW_BKLR_LD2;
-+ }
-+
-+ fecp->ESW_BKLR = tmp;
-+ return 0;
-+}
-+/*********************************************************************/
-+void esw_mac_lookup_table_range(struct switch_enet_private *fep)
-+{
-+ int index;
-+ unsigned long read_lo, read_hi;
-+ /* Pointer to switch address look up memory*/
-+ for (index = 0; index < 2048; index++)
-+ write_atable(fep, index, index, (~index));
-+
-+ /* Pointer to switch address look up memory*/
-+ for (index = 0; index < 2048; index++) {
-+ read_atable(fep, index, &read_lo, &read_hi);
-+ if (read_lo != index) {
-+ printk(KERN_ERR "%s:Mismatch at low %d\n",
-+ __func__, index);
-+ return;
-+ }
-+
-+ if (read_hi != (~index)) {
-+ printk(KERN_ERR "%s:Mismatch at high %d\n",
-+ __func__, index);
-+ return;
-+ }
-+ }
-+}
-+
-+/*
-+ * Checks IP Snoop options of handling the snooped frame.
-+ * mode 0 : The snooped frame is forward only to management port
-+ * mode 1 : The snooped frame is copy to management port and
-+ * normal forwarding is checked.
-+ * mode 2 : The snooped frame is discarded.
-+ * mode 3 : Disable the ip snoop function
-+ * ip_header_protocol : the IP header protocol field
-+ */
-+int esw_ip_snoop_config(struct switch_enet_private *fep,
-+ int mode, unsigned long ip_header_protocol)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp = 0, protocol_type = 0;
-+ int num = 0;
-+
-+ fecp = fep->hwp;
-+ /* Config IP Snooping */
-+ if (mode == 0) {
-+ /* Enable IP Snooping */
-+ tmp = MCF_ESW_IPSNP_EN;
-+ tmp |= MCF_ESW_IPSNP_MODE(0);/*For Forward*/
-+ } else if (mode == 1) {
-+ /* Enable IP Snooping */
-+ tmp = MCF_ESW_IPSNP_EN;
-+ /*For Forward and copy_to_mangmnt_port*/
-+ tmp |= MCF_ESW_IPSNP_MODE(1);
-+ } else if (mode == 2) {
-+ /* Enable IP Snooping */
-+ tmp = MCF_ESW_IPSNP_EN;
-+ tmp |= MCF_ESW_IPSNP_MODE(2);/*discard*/
-+ } else if (mode == 3) {
-+ /* disable IP Snooping */
-+ tmp = MCF_ESW_IPSNP_EN;
-+ tmp &= ~MCF_ESW_IPSNP_EN;
-+ } else {
-+ printk(KERN_ERR "%s: the mode %x "
-+ "we do not support\n", __func__, mode);
-+ return -1;
-+ }
-+
-+ protocol_type = ip_header_protocol;
-+ for (num = 0; num < 8; num++) {
-+ if (protocol_type ==
-+ AT_EXTRACT_IP_PROTOCOL(fecp->ESW_IPSNP[num])) {
-+ fecp->ESW_IPSNP[num] =
-+ tmp | MCF_ESW_IPSNP_PROTOCOL(protocol_type);
-+ break;
-+ } else if (!(fecp->ESW_IPSNP[num])) {
-+ fecp->ESW_IPSNP[num] =
-+ tmp | MCF_ESW_IPSNP_PROTOCOL(protocol_type);
-+ break;
-+ }
-+ }
-+ if (num == 8) {
-+ printk(KERN_INFO "IP snooping table is full\n");
-+ return 0;
-+ }
-+
-+ return 0;
-+}
-+
-+void esw_get_ip_snoop_config(struct switch_enet_private *fep,
-+ unsigned long *ulpESW_IPSNP)
-+{
-+ int i;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ for (i = 0; i < 8; i++)
-+ *(ulpESW_IPSNP + i) = fecp->ESW_IPSNP[i];
-+}
-+/*
-+ * Checks TCP/UDP Port Snoop options of handling the snooped frame.
-+ * mode 0 : The snooped frame is forward only to management port
-+ * mode 1 : The snooped frame is copy to management port and
-+ * normal forwarding is checked.
-+ * mode 2 : The snooped frame is discarded.
-+ * mode 3 : Disable the TCP/UDP port snoop function
-+ * compare_port : port number in the TCP/UDP header
-+ * compare_num 1: TCP/UDP source port number is compared
-+ * compare_num 2: TCP/UDP destination port number is compared
-+ * compare_num 3: TCP/UDP source and destination port number is compared
-+ */
-+int esw_tcpudp_port_snoop_config(struct switch_enet_private *fep,
-+ int mode, int compare_port, int compare_num)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp;
-+ int num;
-+
-+ fecp = fep->hwp;
-+
-+ /* Enable TCP/UDP port Snooping */
-+ tmp = MCF_ESW_PSNP_EN;
-+ if (mode == 0)
-+ tmp |= MCF_ESW_PSNP_MODE(0);/*For Forward*/
-+ else if (mode == 1)/*For Forward and copy_to_mangmnt_port*/
-+ tmp |= MCF_ESW_PSNP_MODE(1);
-+ else if (mode == 2)
-+ tmp |= MCF_ESW_PSNP_MODE(2);/*discard*/
-+ else if (mode == 3) /*disable the port function*/
-+ tmp &= (~MCF_ESW_PSNP_EN);
-+ else {
-+ printk(KERN_ERR "%s: the mode %x we do not support\n",
-+ __func__, mode);
-+ return -1;
-+ }
-+
-+ if (compare_num == 1)
-+ tmp |= MCF_ESW_PSNP_CS;
-+ else if (compare_num == 2)
-+ tmp |= MCF_ESW_PSNP_CD;
-+ else if (compare_num == 3)
-+ tmp |= MCF_ESW_PSNP_CD | MCF_ESW_PSNP_CS;
-+ else {
-+ printk(KERN_ERR "%s: the compare port address %x"
-+ " we do not support\n",
-+ __func__, compare_num);
-+ return -1;
-+ }
-+
-+ for (num = 0; num < 8; num++) {
-+ if (compare_port ==
-+ AT_EXTRACT_TCP_UDP_PORT(fecp->ESW_PSNP[num])) {
-+ fecp->ESW_PSNP[num] =
-+ tmp | MCF_ESW_PSNP_PORT_COMPARE(compare_port);
-+ break;
-+ } else if (!(fecp->ESW_PSNP[num])) {
-+ fecp->ESW_PSNP[num] =
-+ tmp | MCF_ESW_PSNP_PORT_COMPARE(compare_port);
-+ break;
-+ }
-+ }
-+ if (num == 8) {
-+ printk(KERN_INFO "TCP/UDP port snooping table is full\n");
-+ return 0;
-+ }
-+
-+ return 0;
-+}
-+
-+void esw_get_tcpudp_port_snoop_config(
-+ struct switch_enet_private *fep,
-+ unsigned long *ulpESW_PSNP)
-+{
-+ int i;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ for (i = 0; i < 8; i++)
-+ *(ulpESW_PSNP + i) = fecp->ESW_PSNP[i];
-+}
-+/*-----------------mirror----------------------------------------*/
-+void esw_get_port_mirroring(struct switch_enet_private *fep)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ printk(KERN_INFO "Mirror Port: %1ld Egress Port Match:%s "
-+ "Ingress Port Match:%s\n", fecp->ESW_MCR & 0xf,
-+ (fecp->ESW_MCR >> 6) & 1 ? "Y" : "N",
-+ (fecp->ESW_MCR >> 5) & 1 ? "Y" : "N");
-+
-+ if ((fecp->ESW_MCR >> 6) & 1)
-+ printk(KERN_INFO "Egress Port to be mirrored: Port %ld\n",
-+ fecp->ESW_EGMAP >> 1);
-+ if ((fecp->ESW_MCR >> 5) & 1)
-+ printk(KERN_INFO "Ingress Port to be mirrored: Port %ld\n",
-+ fecp->ESW_INGMAP >> 1);
-+
-+ printk(KERN_INFO "Egress Des Address Match:%s "
-+ "Egress Src Address Match:%s\n",
-+ (fecp->ESW_MCR >> 10) & 1 ? "Y" : "N",
-+ (fecp->ESW_MCR >> 9) & 1 ? "Y" : "N");
-+ printk(KERN_INFO "Ingress Des Address Match:%s "
-+ "Ingress Src Address Match:%s\n",
-+ (fecp->ESW_MCR >> 8) & 1 ? "Y" : "N",
-+ (fecp->ESW_MCR >> 7) & 1 ? "Y" : "N");
-+
-+ if ((fecp->ESW_MCR >> 10) & 1)
-+ printk(KERN_INFO "Egress Des Address to be mirrored: "
-+ "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
-+ fecp->ESW_ENGDAL & 0xff, (fecp->ESW_ENGDAL >> 8) & 0xff,
-+ (fecp->ESW_ENGDAL >> 16) & 0xff,
-+ (fecp->ESW_ENGDAL >> 24) & 0xff,
-+ fecp->ESW_ENGDAH & 0xff,
-+ (fecp->ESW_ENGDAH >> 8) & 0xff);
-+ if ((fecp->ESW_MCR >> 9) & 1)
-+ printk("Egress Src Address to be mirrored: "
-+ "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
-+ fecp->ESW_ENGSAL & 0xff, (fecp->ESW_ENGSAL >> 8) & 0xff,
-+ (fecp->ESW_ENGSAL >> 16) & 0xff,
-+ (fecp->ESW_ENGSAL >> 24) & 0xff,
-+ fecp->ESW_ENGSAH & 0xff,
-+ (fecp->ESW_ENGSAH >> 8) & 0xff);
-+ if ((fecp->ESW_MCR >> 8) & 1)
-+ printk("Ingress Des Address to be mirrored: "
-+ "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
-+ fecp->ESW_INGDAL & 0xff, (fecp->ESW_INGDAL >> 8) & 0xff,
-+ (fecp->ESW_INGDAL >> 16) & 0xff,
-+ (fecp->ESW_INGDAL >> 24) & 0xff,
-+ fecp->ESW_INGDAH & 0xff,
-+ (fecp->ESW_INGDAH >> 8) & 0xff);
-+ if ((fecp->ESW_MCR >> 7) & 1)
-+ printk("Ingress Src Address to be mirrored: "
-+ "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
-+ fecp->ESW_INGSAL & 0xff, (fecp->ESW_INGSAL >> 8) & 0xff,
-+ (fecp->ESW_INGSAL >> 16) & 0xff,
-+ (fecp->ESW_INGSAL >> 24) & 0xff,
-+ fecp->ESW_INGSAH & 0xff,
-+ (fecp->ESW_INGSAH >> 8) & 0xff);
-+}
-+
-+int esw_port_mirroring_config_port_match(struct switch_enet_private *fep,
-+ int mirror_port, int port_match_en, int port)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp = 0;
-+
-+ fecp = fep->hwp;
-+
-+ tmp = fecp->ESW_MCR;
-+ if (mirror_port != (tmp & 0xf))
-+ tmp = 0;
-+
-+ switch (port_match_en) {
-+ case MIRROR_EGRESS_PORT_MATCH:
-+ tmp |= MCF_ESW_MCR_EGMAP;
-+ if (port == 0)
-+ fecp->ESW_EGMAP = MCF_ESW_EGMAP_EG0;
-+ else if (port == 1)
-+ fecp->ESW_EGMAP = MCF_ESW_EGMAP_EG1;
-+ else if (port == 2)
-+ fecp->ESW_EGMAP = MCF_ESW_EGMAP_EG2;
-+ break;
-+ case MIRROR_INGRESS_PORT_MATCH:
-+ tmp |= MCF_ESW_MCR_INGMAP;
-+ if (port == 0)
-+ fecp->ESW_INGMAP = MCF_ESW_INGMAP_ING0;
-+ else if (port == 1)
-+ fecp->ESW_INGMAP = MCF_ESW_INGMAP_ING1;
-+ else if (port == 2)
-+ fecp->ESW_INGMAP = MCF_ESW_INGMAP_ING2;
-+ break;
-+ default:
-+ tmp = 0;
-+ break;
-+ }
-+
-+ tmp = tmp & 0x07e0;
-+ if (port_match_en)
-+ tmp |= MCF_ESW_MCR_MEN | MCF_ESW_MCR_PORT(mirror_port);
-+
-+ fecp->ESW_MCR = tmp;
-+ return 0;
-+}
-+
-+int esw_port_mirroring_config(struct switch_enet_private *fep,
-+ int mirror_port, int port, int mirror_enable,
-+ unsigned char *src_mac, unsigned char *des_mac,
-+ int egress_en, int ingress_en,
-+ int egress_mac_src_en, int egress_mac_des_en,
-+ int ingress_mac_src_en, int ingress_mac_des_en)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp;
-+
-+ fecp = fep->hwp;
-+
-+ /*mirroring config*/
-+ tmp = 0;
-+ if (egress_en == 1) {
-+ tmp |= MCF_ESW_MCR_EGMAP;
-+ if (port == 0)
-+ fecp->ESW_EGMAP = MCF_ESW_EGMAP_EG0;
-+ else if (port == 1)
-+ fecp->ESW_EGMAP = MCF_ESW_EGMAP_EG1;
-+ else if (port == 2)
-+ fecp->ESW_EGMAP = MCF_ESW_EGMAP_EG2;
-+ else {
-+ printk(KERN_ERR "%s: the port %x we do not support\n",
-+ __func__, port);
-+ return -1;
-+ }
-+ } else if (egress_en == 0) {
-+ tmp &= (~MCF_ESW_MCR_EGMAP);
-+ } else {
-+ printk(KERN_ERR "%s: egress_en %x we do not support\n",
-+ __func__, egress_en);
-+ return -1;
-+ }
-+
-+ if (ingress_en == 1) {
-+ tmp |= MCF_ESW_MCR_INGMAP;
-+ if (port == 0)
-+ fecp->ESW_INGMAP = MCF_ESW_INGMAP_ING0;
-+ else if (port == 1)
-+ fecp->ESW_INGMAP = MCF_ESW_INGMAP_ING1;
-+ else if (port == 2)
-+ fecp->ESW_INGMAP = MCF_ESW_INGMAP_ING2;
-+ else {
-+ printk(KERN_ERR "%s: the port %x we do not support\n",
-+ __func__, port);
-+ return -1;
-+ }
-+ } else if (ingress_en == 0) {
-+ tmp &= ~MCF_ESW_MCR_INGMAP;
-+ } else{
-+ printk(KERN_ERR "%s: ingress_en %x we do not support\n",
-+ __func__, ingress_en);
-+ return -1;
-+ }
-+
-+ if (egress_mac_src_en == 1) {
-+ tmp |= MCF_ESW_MCR_EGSA;
-+ fecp->ESW_ENGSAH = (src_mac[5] << 8) | (src_mac[4]);
-+ fecp->ESW_ENGSAL = (unsigned long)((src_mac[3] << 24) |
-+ (src_mac[2] << 16) |
-+ (src_mac[1] << 8) |
-+ src_mac[0]);
-+ } else if (egress_mac_src_en == 0) {
-+ tmp &= ~MCF_ESW_MCR_EGSA;
-+ } else {
-+ printk(KERN_ERR "%s: egress_mac_src_en %x we do not support\n",
-+ __func__, egress_mac_src_en);
-+ return -1;
-+ }
-+
-+ if (egress_mac_des_en == 1) {
-+ tmp |= MCF_ESW_MCR_EGDA;
-+ fecp->ESW_ENGDAH = (des_mac[5] << 8) | (des_mac[4]);
-+ fecp->ESW_ENGDAL = (unsigned long)((des_mac[3] << 24) |
-+ (des_mac[2] << 16) |
-+ (des_mac[1] << 8) |
-+ des_mac[0]);
-+ } else if (egress_mac_des_en == 0) {
-+ tmp &= ~MCF_ESW_MCR_EGDA;
-+ } else {
-+ printk(KERN_ERR "%s: egress_mac_des_en %x we do not support\n",
-+ __func__, egress_mac_des_en);
-+ return -1;
-+ }
-+
-+ if (ingress_mac_src_en == 1) {
-+ tmp |= MCF_ESW_MCR_INGSA;
-+ fecp->ESW_INGSAH = (src_mac[5] << 8) | (src_mac[4]);
-+ fecp->ESW_INGSAL = (unsigned long)((src_mac[3] << 24) |
-+ (src_mac[2] << 16) |
-+ (src_mac[1] << 8) |
-+ src_mac[0]);
-+ } else if (ingress_mac_src_en == 0) {
-+ tmp &= ~MCF_ESW_MCR_INGSA;
-+ } else {
-+ printk(KERN_ERR "%s: ingress_mac_src_en %x we do not support\n",
-+ __func__, ingress_mac_src_en);
-+ return -1;
-+ }
-+
-+ if (ingress_mac_des_en == 1) {
-+ tmp |= MCF_ESW_MCR_INGDA;
-+ fecp->ESW_INGDAH = (des_mac[5] << 8) | (des_mac[4]);
-+ fecp->ESW_INGDAL = (unsigned long)((des_mac[3] << 24) |
-+ (des_mac[2] << 16) |
-+ (des_mac[1] << 8) |
-+ des_mac[0]);
-+ } else if (ingress_mac_des_en == 0) {
-+ tmp &= ~MCF_ESW_MCR_INGDA;
-+ } else {
-+ printk(KERN_ERR "%s: ingress_mac_des_en %x we do not support\n",
-+ __func__, ingress_mac_des_en);
-+ return -1;
-+ }
-+
-+ if (mirror_enable == 1)
-+ tmp |= MCF_ESW_MCR_MEN | MCF_ESW_MCR_PORT(mirror_port);
-+ else if (mirror_enable == 0)
-+ tmp &= ~MCF_ESW_MCR_MEN;
-+ else
-+ printk(KERN_ERR "%s: the mirror enable %x is error\n",
-+ __func__, mirror_enable);
-+
-+
-+ fecp->ESW_MCR = tmp;
-+ return 0;
-+}
-+
-+int esw_port_mirroring_config_addr_match(struct switch_enet_private *fep,
-+ int mirror_port, int addr_match_enable, unsigned char *mac_addr)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp = 0;
-+
-+ fecp = fep->hwp;
-+
-+ tmp = fecp->ESW_MCR;
-+ if (mirror_port != (tmp & 0xf))
-+ tmp = 0;
-+
-+ switch (addr_match_enable) {
-+ case MIRROR_EGRESS_SOURCE_MATCH:
-+ tmp |= MCF_ESW_MCR_EGSA;
-+ fecp->ESW_ENGSAH = (mac_addr[5] << 8) | (mac_addr[4]);
-+ fecp->ESW_ENGSAL = (unsigned long)((mac_addr[3] << 24) |
-+ (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]);
-+ break;
-+ case MIRROR_INGRESS_SOURCE_MATCH:
-+ tmp |= MCF_ESW_MCR_INGSA;
-+ fecp->ESW_INGSAH = (mac_addr[5] << 8) | (mac_addr[4]);
-+ fecp->ESW_INGSAL = (unsigned long)((mac_addr[3] << 24) |
-+ (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]);
-+ break;
-+ case MIRROR_EGRESS_DESTINATION_MATCH:
-+ tmp |= MCF_ESW_MCR_EGDA;
-+ fecp->ESW_ENGDAH = (mac_addr[5] << 8) | (mac_addr[4]);
-+ fecp->ESW_ENGDAL = (unsigned long)((mac_addr[3] << 24) |
-+ (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]);
-+ break;
-+ case MIRROR_INGRESS_DESTINATION_MATCH:
-+ tmp |= MCF_ESW_MCR_INGDA;
-+ fecp->ESW_INGDAH = (mac_addr[5] << 8) | (mac_addr[4]);
-+ fecp->ESW_INGDAL = (unsigned long)((mac_addr[3] << 24) |
-+ (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]);
-+ break;
-+ default:
-+ tmp = 0;
-+ break;
-+ }
-+
-+ tmp = tmp & 0x07e0;
-+ if (addr_match_enable)
-+ tmp |= MCF_ESW_MCR_MEN | MCF_ESW_MCR_PORT(mirror_port);
-+
-+ fecp->ESW_MCR = tmp;
-+ return 0;
-+}
-+
-+void esw_get_vlan_verification(struct switch_enet_private *fep,
-+ unsigned long *ulValue)
-+{
-+ volatile switch_t *fecp;
-+ fecp = fep->hwp;
-+ *ulValue = fecp->ESW_VLANV;
-+}
-+
-+int esw_set_vlan_verification(struct switch_enet_private *fep, int port,
-+ int vlan_domain_verify_en, int vlan_discard_unknown_en)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ if ((port < 0) || (port > 2)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ if (vlan_domain_verify_en == 1) {
-+ if (port == 0)
-+ fecp->ESW_VLANV |= MCF_ESW_VLANV_VV0;
-+ else if (port == 1)
-+ fecp->ESW_VLANV |= MCF_ESW_VLANV_VV1;
-+ else if (port == 2)
-+ fecp->ESW_VLANV |= MCF_ESW_VLANV_VV2;
-+ } else if (vlan_domain_verify_en == 0) {
-+ if (port == 0)
-+ fecp->ESW_VLANV &= ~MCF_ESW_VLANV_VV0;
-+ else if (port == 1)
-+ fecp->ESW_VLANV &= ~MCF_ESW_VLANV_VV1;
-+ else if (port == 2)
-+ fecp->ESW_VLANV &= ~MCF_ESW_VLANV_VV2;
-+ } else {
-+ printk(KERN_INFO "%s: donot support "
-+ "vlan_domain_verify %x\n",
-+ __func__, vlan_domain_verify_en);
-+ return -2;
-+ }
-+
-+ if (vlan_discard_unknown_en == 1) {
-+ if (port == 0)
-+ fecp->ESW_VLANV |= MCF_ESW_VLANV_DU0;
-+ else if (port == 1)
-+ fecp->ESW_VLANV |= MCF_ESW_VLANV_DU1;
-+ else if (port == 2)
-+ fecp->ESW_VLANV |= MCF_ESW_VLANV_DU2;
-+ } else if (vlan_discard_unknown_en == 0) {
-+ if (port == 0)
-+ fecp->ESW_VLANV &= ~MCF_ESW_VLANV_DU0;
-+ else if (port == 1)
-+ fecp->ESW_VLANV &= ~MCF_ESW_VLANV_DU1;
-+ else if (port == 2)
-+ fecp->ESW_VLANV &= ~MCF_ESW_VLANV_DU2;
-+ } else {
-+ printk(KERN_INFO "%s: donot support "
-+ "vlan_discard_unknown %x\n",
-+ __func__, vlan_discard_unknown_en);
-+ return -3;
-+ }
-+
-+ return 0;
-+}
-+
-+void esw_get_vlan_resolution_table(struct switch_enet_private *fep,
-+ struct eswVlanTableItem *tableaddr)
-+{
-+ volatile switch_t *fecp;
-+ int vnum = 0;
-+ int i;
-+
-+ fecp = fep->hwp;
-+ for (i = 0; i < 32; i++) {
-+ if (fecp->ESW_VRES[i]) {
-+ tableaddr->table[i].port_vlanid =
-+ fecp->ESW_VRES[i] >> 3;
-+ tableaddr->table[i].vlan_domain_port =
-+ fecp->ESW_VRES[i] & 7;
-+ vnum++;
-+ }
-+ }
-+ tableaddr->valid_num = vnum;
-+}
-+
-+int esw_set_vlan_id(struct switch_enet_private *fep, unsigned long configData)
-+{
-+ volatile switch_t *fecp;
-+ int i;
-+
-+ fecp = fep->hwp;
-+
-+ for (i = 0; i < 32; i++) {
-+ if (fecp->ESW_VRES[i] == 0) {
-+ fecp->ESW_VRES[i] = MCF_ESW_VRES_VLANID(configData);
-+ return 0;
-+ } else if (((fecp->ESW_VRES[i] >> 3) & 0xfff) == configData) {
-+ printk(KERN_INFO "The VLAN already exists\n");
-+ return 0;
-+ }
-+ }
-+
-+ printk(KERN_INFO "The VLAN can't create, because VLAN table is full\n");
-+ return 0;
-+}
-+
-+int esw_set_vlan_id_cleared(struct switch_enet_private *fep,
-+ unsigned long configData)
-+{
-+ volatile switch_t *fecp;
-+ int i;
-+
-+ fecp = fep->hwp;
-+
-+ for (i = 0; i < 32; i++) {
-+ if (((fecp->ESW_VRES[i] >> 3) & 0xfff) == configData) {
-+ fecp->ESW_VRES[i] = 0;
-+ break;
-+ }
-+ }
-+ return 0;
-+}
-+
-+int esw_set_port_in_vlan_id(struct switch_enet_private *fep,
-+ eswIoctlVlanResoultionTable configData)
-+{
-+ volatile switch_t *fecp;
-+ int i;
-+ int lastnum = 0;
-+
-+ fecp = fep->hwp;
-+
-+ for (i = 0; i < 32; i++) {
-+ if (fecp->ESW_VRES[i] == 0) {
-+ lastnum = i;
-+ break;
-+ } else if (((fecp->ESW_VRES[i] >> 3) & 0xfff) ==
-+ configData.port_vlanid) {
-+ /* update the port members of this vlan */
-+ fecp->ESW_VRES[i] |= 1 << configData.vlan_domain_port;
-+ return 0;
-+ }
-+ }
-+ /* creat a new vlan in vlan table */
-+ fecp->ESW_VRES[lastnum] = MCF_ESW_VRES_VLANID(configData.port_vlanid) |
-+ (1 << configData.vlan_domain_port);
-+ return 0;
-+}
-+
-+int esw_set_vlan_resolution_table(struct switch_enet_private *fep,
-+ unsigned short port_vlanid, int vlan_domain_num,
-+ int vlan_domain_port)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ if ((vlan_domain_num < 0)
-+ || (vlan_domain_num > 31)) {
-+ printk(KERN_ERR "%s: do not support the "
-+ "vlan_domain_num %d\n",
-+ __func__, vlan_domain_num);
-+ return -1;
-+ }
-+
-+ if ((vlan_domain_port < 0)
-+ || (vlan_domain_port > 7)) {
-+ printk(KERN_ERR "%s: do not support the "
-+ "vlan_domain_port %d\n",
-+ __func__, vlan_domain_port);
-+ return -2;
-+ }
-+
-+ fecp->ESW_VRES[vlan_domain_num] =
-+ MCF_ESW_VRES_VLANID(port_vlanid)
-+ | vlan_domain_port;
-+
-+ return 0;
-+}
-+
-+void esw_get_vlan_input_config(struct switch_enet_private *fep,
-+ eswIoctlVlanInputStatus *pVlanInputConfig)
-+{
-+ volatile switch_t *fecp;
-+ int i;
-+
-+ fecp = fep->hwp;
-+ for (i = 0; i < 3; i++)
-+ pVlanInputConfig->ESW_PID[i] = fecp->ESW_PID[i];
-+
-+ pVlanInputConfig->ESW_VLANV = fecp->ESW_VLANV;
-+ pVlanInputConfig->ESW_VIMSEL = fecp->ESW_VIMSEL;
-+ pVlanInputConfig->ESW_VIMEN = fecp->ESW_VIMEN;
-+
-+ for (i = 0; i < 32; i++)
-+ pVlanInputConfig->ESW_VRES[i] = fecp->ESW_VRES[i];
-+}
-+
-+
-+int esw_vlan_input_process(struct switch_enet_private *fep,
-+ int port, int mode, unsigned short port_vlanid)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((mode < 0) || (mode > 5)) {
-+ printk(KERN_ERR "%s: do not support the"
-+ " VLAN input processing mode %d\n",
-+ __func__, mode);
-+ return -1;
-+ }
-+
-+ if ((port < 0) || (port > 3)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, mode);
-+ return -2;
-+ }
-+
-+ fecp->ESW_PID[port] = MCF_ESW_PID_VLANID(port_vlanid);
-+ if (port == 0) {
-+ if (mode == 4)
-+ fecp->ESW_VIMEN &= ~MCF_ESW_VIMEN_EN0;
-+ else
-+ fecp->ESW_VIMEN |= MCF_ESW_VIMEN_EN0;
-+
-+ fecp->ESW_VIMSEL &= ~MCF_ESW_VIMSEL_IM0(3);
-+ fecp->ESW_VIMSEL |= MCF_ESW_VIMSEL_IM0(mode);
-+ } else if (port == 1) {
-+ if (mode == 4)
-+ fecp->ESW_VIMEN &= ~MCF_ESW_VIMEN_EN1;
-+ else
-+ fecp->ESW_VIMEN |= MCF_ESW_VIMEN_EN1;
-+
-+ fecp->ESW_VIMSEL &= ~MCF_ESW_VIMSEL_IM1(3);
-+ fecp->ESW_VIMSEL |= MCF_ESW_VIMSEL_IM1(mode);
-+ } else if (port == 2) {
-+ if (mode == 4)
-+ fecp->ESW_VIMEN &= ~MCF_ESW_VIMEN_EN2;
-+ else
-+ fecp->ESW_VIMEN |= MCF_ESW_VIMEN_EN2;
-+
-+ fecp->ESW_VIMSEL &= ~MCF_ESW_VIMSEL_IM2(3);
-+ fecp->ESW_VIMSEL |= MCF_ESW_VIMSEL_IM2(mode);
-+ } else {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -2;
-+ }
-+
-+ return 0;
-+}
-+
-+void esw_get_vlan_output_config(struct switch_enet_private *fep,
-+ unsigned long *ulVlanOutputConfig)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulVlanOutputConfig = fecp->ESW_VOMSEL;
-+}
-+
-+int esw_vlan_output_process(struct switch_enet_private *fep,
-+ int port, int mode)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port < 0) || (port > 2)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, mode);
-+ return -1;
-+ }
-+
-+ if (port == 0) {
-+ fecp->ESW_VOMSEL &= ~MCF_ESW_VOMSEL_OM0(3);
-+ fecp->ESW_VOMSEL |= MCF_ESW_VOMSEL_OM0(mode);
-+ } else if (port == 1) {
-+ fecp->ESW_VOMSEL &= ~MCF_ESW_VOMSEL_OM1(3);
-+ fecp->ESW_VOMSEL |= MCF_ESW_VOMSEL_OM1(mode);
-+ } else if (port == 2) {
-+ fecp->ESW_VOMSEL &= ~MCF_ESW_VOMSEL_OM2(3);
-+ fecp->ESW_VOMSEL |= MCF_ESW_VOMSEL_OM2(mode);
-+ } else {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+/*------------frame calssify and priority resolution------------*/
-+/*vlan priority lookup*/
-+int esw_framecalssify_vlan_priority_lookup(struct switch_enet_private *fep,
-+ int port, int func_enable, int vlan_pri_table_num,
-+ int vlan_pri_table_value)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port < 0) || (port > 3)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ if (func_enable == 0) {
-+ fecp->ESW_PRES[port] &= ~MCF_ESW_PRES_VLAN;
-+ printk(KERN_ERR "%s: disable port %d VLAN priority "
-+ "lookup function\n", __func__, port);
-+ return 0;
-+ }
-+
-+ if ((vlan_pri_table_num < 0) || (vlan_pri_table_num > 7)) {
-+ printk(KERN_ERR "%s: do not support the priority %d\n",
-+ __func__, vlan_pri_table_num);
-+ return -1;
-+ }
-+
-+ fecp->ESW_PVRES[port] |= ((vlan_pri_table_value & 0x3)
-+ << (vlan_pri_table_num*3));
-+ /* enable port VLAN priority lookup function*/
-+ fecp->ESW_PRES[port] |= MCF_ESW_PRES_VLAN;
-+ return 0;
-+}
-+
-+int esw_framecalssify_ip_priority_lookup(struct switch_enet_private *fep,
-+ int port, int func_enable, int ipv4_en, int ip_priority_num,
-+ int ip_priority_value)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long tmp = 0, tmp_prio = 0;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port < 0) || (port > 3)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ if (func_enable == 0) {
-+ fecp->ESW_PRES[port] &= ~MCF_ESW_PRES_IP;
-+ printk(KERN_ERR "%s: disable port %d ip priority "
-+ "lookup function\n", __func__, port);
-+ return 0;
-+ }
-+
-+ /* IPV4 priority 64 entry table lookup*/
-+ /* IPv4 head 6 bit TOS field*/
-+ if (ipv4_en == 1) {
-+ if ((ip_priority_num < 0) || (ip_priority_num > 63)) {
-+ printk(KERN_ERR "%s: do not support the table entry %d\n",
-+ __func__, ip_priority_num);
-+ return -2;
-+ }
-+ } else { /* IPV6 priority 256 entry table lookup*/
-+ /* IPv6 head 8 bit COS field*/
-+ if ((ip_priority_num < 0) || (ip_priority_num > 255)) {
-+ printk(KERN_ERR "%s: do not support the table entry %d\n",
-+ __func__, ip_priority_num);
-+ return -3;
-+ }
-+ }
-+
-+ /* IP priority table lookup : address*/
-+ tmp = MCF_ESW_IPRES_ADDRESS(ip_priority_num);
-+ /* IP priority table lookup : ipv4sel*/
-+ if (ipv4_en == 1)
-+ tmp = tmp | MCF_ESW_IPRES_IPV4SEL;
-+ /* IP priority table lookup : priority*/
-+ if (port == 0)
-+ tmp |= MCF_ESW_IPRES_PRI0(ip_priority_value);
-+ else if (port == 1)
-+ tmp |= MCF_ESW_IPRES_PRI1(ip_priority_value);
-+ else if (port == 2)
-+ tmp |= MCF_ESW_IPRES_PRI2(ip_priority_value);
-+
-+ /* configure*/
-+ fecp->ESW_IPRES = MCF_ESW_IPRES_READ |
-+ MCF_ESW_IPRES_ADDRESS(ip_priority_num);
-+ tmp_prio = fecp->ESW_IPRES;
-+
-+ fecp->ESW_IPRES = tmp | tmp_prio;
-+
-+ fecp->ESW_IPRES = MCF_ESW_IPRES_READ |
-+ MCF_ESW_IPRES_ADDRESS(ip_priority_num);
-+ tmp_prio = fecp->ESW_IPRES;
-+
-+ /* enable port IP priority lookup function*/
-+ fecp->ESW_PRES[port] |= MCF_ESW_PRES_IP;
-+ return 0;
-+}
-+
-+int esw_framecalssify_mac_priority_lookup(
-+ struct switch_enet_private *fep, int port)
-+{
-+ volatile switch_t *fecp;
-+
-+ if ((port < 0) || (port > 3)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ fecp = fep->hwp;
-+ fecp->ESW_PRES[port] |= MCF_ESW_PRES_MAC;
-+
-+ return 0;
-+}
-+
-+int esw_frame_calssify_priority_init(struct switch_enet_private *fep,
-+ int port, unsigned char priority_value)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if ((port < 0) || (port > 3)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -1;
-+ }
-+ /*disable all priority lookup function*/
-+ fecp->ESW_PRES[port] = 0;
-+ fecp->ESW_PRES[port] = MCF_ESW_PRES_DFLT_PRI(priority_value & 0x7);
-+
-+ return 0;
-+}
-+
-+/*---------------------------------------------------------------------------*/
-+int esw_get_statistics_status(struct switch_enet_private *fep,
-+ esw_statistics_status *pStatistics)
-+{
-+ volatile switch_t *fecp;
-+ fecp = fep->hwp;
-+
-+ pStatistics->ESW_DISCN = fecp->ESW_DISCN;
-+ pStatistics->ESW_DISCB = fecp->ESW_DISCB;
-+ pStatistics->ESW_NDISCN = fecp->ESW_NDISCN;
-+ pStatistics->ESW_NDISCB = fecp->ESW_NDISCB;
-+ return 0;
-+}
-+
-+int esw_get_port_statistics_status(struct switch_enet_private *fep,
-+ int port, esw_port_statistics_status *pPortStatistics)
-+{
-+ volatile switch_t *fecp;
-+
-+ if ((port < 0) || (port > 3)) {
-+ printk(KERN_ERR "%s: do not support the port %d\n",
-+ __func__, port);
-+ return -1;
-+ }
-+
-+ fecp = fep->hwp;
-+
-+ pPortStatistics->MCF_ESW_POQC =
-+ fecp->port_statistics_status[port].MCF_ESW_POQC;
-+ pPortStatistics->MCF_ESW_PMVID =
-+ fecp->port_statistics_status[port].MCF_ESW_PMVID;
-+ pPortStatistics->MCF_ESW_PMVTAG =
-+ fecp->port_statistics_status[port].MCF_ESW_PMVTAG;
-+ pPortStatistics->MCF_ESW_PBL =
-+ fecp->port_statistics_status[port].MCF_ESW_PBL;
-+ return 0;
-+}
-+/*----------------------------------------------------------------------*/
-+int esw_get_output_queue_status(struct switch_enet_private *fep,
-+ esw_output_queue_status *pOutputQueue)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ pOutputQueue->ESW_MMSR = fecp->ESW_MMSR;
-+ pOutputQueue->ESW_LMT = fecp->ESW_LMT;
-+ pOutputQueue->ESW_LFC = fecp->ESW_LFC;
-+ pOutputQueue->ESW_IOSR = fecp->ESW_IOSR;
-+ pOutputQueue->ESW_PCSR = fecp->ESW_PCSR;
-+ pOutputQueue->ESW_QWT = fecp->ESW_QWT;
-+ pOutputQueue->ESW_P0BCT = fecp->ESW_P0BCT;
-+ return 0;
-+}
-+
-+/* set output queue memory status and configure*/
-+int esw_set_output_queue_memory(struct switch_enet_private *fep,
-+ int fun_num, esw_output_queue_status *pOutputQueue)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if (fun_num == 1) {
-+ /* memory manager status*/
-+ fecp->ESW_MMSR = pOutputQueue->ESW_MMSR;
-+ } else if (fun_num == 2) {
-+ /*low memory threshold*/
-+ fecp->ESW_LMT = pOutputQueue->ESW_LMT;
-+ } else if (fun_num == 3) {
-+ /*lowest number of free cells*/
-+ fecp->ESW_LFC = pOutputQueue->ESW_LFC;
-+ } else if (fun_num == 4) {
-+ /*queue weights*/
-+ fecp->ESW_QWT = pOutputQueue->ESW_QWT;
-+ } else if (fun_num == 5) {
-+ /*port 0 backpressure congenstion thresled*/
-+ fecp->ESW_P0BCT = pOutputQueue->ESW_P0BCT;
-+ } else {
-+ printk(KERN_ERR "%s: do not support the cmd %x\n",
-+ __func__, fun_num);
-+ return -1;
-+ }
-+ return 0;
-+}
-+/*--------------------------------------------------------------------*/
-+int esw_get_irq_status(struct switch_enet_private *fep,
-+ eswIoctlIrqStatus *pIrqStatus)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ pIrqStatus->isr = fecp->switch_ievent;
-+ pIrqStatus->imr = fecp->switch_imask;
-+ pIrqStatus->rx_buf_pointer = fecp->fec_r_des_start;
-+ pIrqStatus->tx_buf_pointer = fecp->fec_x_des_start;
-+ pIrqStatus->rx_max_size = fecp->fec_r_buff_size;
-+ pIrqStatus->rx_buf_active = fecp->fec_r_des_active;
-+ pIrqStatus->tx_buf_active = fecp->fec_x_des_active;
-+ return 0;
-+}
-+
-+int esw_set_irq_mask(struct switch_enet_private *fep,
-+ unsigned long mask, int enable)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+
-+ if (enable == 1)
-+ fecp->switch_imask |= mask;
-+ else if (enable == 1)
-+ fecp->switch_imask &= (~mask);
-+ else {
-+ printk(KERN_INFO "%s: enable %lx is error value\n",
-+ __func__, mask);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+void esw_clear_irq_event(struct switch_enet_private *fep,
-+ unsigned long mask)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ fecp->switch_ievent |= mask;
-+}
-+
-+void esw_get_switch_mode(struct switch_enet_private *fep,
-+ unsigned long *ulModeConfig)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulModeConfig = fecp->ESW_MODE;
-+}
-+
-+void esw_switch_mode_configure(struct switch_enet_private *fep,
-+ unsigned long configure)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ fecp->ESW_MODE |= configure;
-+}
-+
-+void esw_get_bridge_port(struct switch_enet_private *fep,
-+ unsigned long *ulBMPConfig)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ *ulBMPConfig = fecp->ESW_BMPC;
-+}
-+
-+void esw_bridge_port_configure(struct switch_enet_private *fep,
-+ unsigned long configure)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ fecp->ESW_BMPC = configure;
-+}
-+
-+int esw_get_port_all_status(struct switch_enet_private *fep,
-+ unsigned char portnum, struct port_all_status *port_alstatus)
-+{
-+ volatile switch_t *fecp;
-+ unsigned long PortBlocking;
-+ unsigned long PortLearning;
-+ unsigned long VlanVerify;
-+ unsigned long DiscardUnknown;
-+ unsigned long MultiReso;
-+ unsigned long BroadReso;
-+ unsigned long FTransmit;
-+ unsigned long FReceive;
-+
-+ fecp = fep->hwp;
-+ PortBlocking = fecp->ESW_BKLR & 0x0000000f;
-+ PortLearning = (fecp->ESW_BKLR & 0x000f0000) >> 16;
-+ VlanVerify = fecp->ESW_VLANV & 0x0000000f;
-+ DiscardUnknown = (fecp->ESW_VLANV & 0x000f0000) >> 16;
-+ MultiReso = fecp->ESW_DMCR & 0x0000000f;
-+ BroadReso = fecp->ESW_DBCR & 0x0000000f;
-+ FTransmit = fecp->ESW_PER & 0x0000000f;
-+ FReceive = (fecp->ESW_PER & 0x000f0000) >> 16;
-+
-+ switch (portnum) {
-+ case 0:
-+ port_alstatus->link_status = 1;
-+ port_alstatus->block_status = PortBlocking & 1;
-+ port_alstatus->learn_status = PortLearning & 1;
-+ port_alstatus->vlan_verify = VlanVerify & 1;
-+ port_alstatus->discard_unknown = DiscardUnknown & 1;
-+ port_alstatus->multi_reso = MultiReso & 1;
-+ port_alstatus->broad_reso = BroadReso & 1;
-+ port_alstatus->ftransmit = FTransmit & 1;
-+ port_alstatus->freceive = FReceive & 1;
-+ break;
-+ case 1:
-+ port_alstatus->link_status =
-+ ports_link_status.port1_link_status;
-+ port_alstatus->block_status = (PortBlocking >> 1) & 1;
-+ port_alstatus->learn_status = (PortLearning >> 1) & 1;
-+ port_alstatus->vlan_verify = (VlanVerify >> 1) & 1;
-+ port_alstatus->discard_unknown = (DiscardUnknown >> 1) & 1;
-+ port_alstatus->multi_reso = (MultiReso >> 1) & 1;
-+ port_alstatus->broad_reso = (BroadReso >> 1) & 1;
-+ port_alstatus->ftransmit = (FTransmit >> 1) & 1;
-+ port_alstatus->freceive = (FReceive >> 1) & 1;
-+ break;
-+ case 2:
-+ port_alstatus->link_status =
-+ ports_link_status.port2_link_status;
-+ port_alstatus->block_status = (PortBlocking >> 2) & 1;
-+ port_alstatus->learn_status = (PortLearning >> 2) & 1;
-+ port_alstatus->vlan_verify = (VlanVerify >> 2) & 1;
-+ port_alstatus->discard_unknown = (DiscardUnknown >> 2) & 1;
-+ port_alstatus->multi_reso = (MultiReso >> 2) & 1;
-+ port_alstatus->broad_reso = (BroadReso >> 2) & 1;
-+ port_alstatus->ftransmit = (FTransmit >> 2) & 1;
-+ port_alstatus->freceive = (FReceive >> 2) & 1;
-+ break;
-+ default:
-+ printk(KERN_ERR "%s:do not support the port %d",
-+ __func__, portnum);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+int esw_atable_get_entry_port_number(struct switch_enet_private *fep,
-+ unsigned char *mac_addr, unsigned char *port)
-+{
-+ int block_index, block_index_end, entry;
-+ unsigned long read_lo, read_hi;
-+ unsigned long mac_addr_lo, mac_addr_hi;
-+
-+ mac_addr_lo = (unsigned long)((mac_addr[3]<<24) | (mac_addr[2]<<16) |
-+ (mac_addr[1]<<8) | mac_addr[0]);
-+ mac_addr_hi = (unsigned long)((mac_addr[5]<<8) | (mac_addr[4]));
-+
-+ block_index = GET_BLOCK_PTR(crc8_calc(mac_addr));
-+ block_index_end = block_index + ATABLE_ENTRY_PER_SLOT;
-+
-+ /* now search all the entries in the selected block */
-+ for (entry = block_index; entry < block_index_end; entry++) {
-+ read_atable(fep, entry, &read_lo, &read_hi);
-+ if ((read_lo == mac_addr_lo) &&
-+ ((read_hi & 0x0000ffff) ==
-+ (mac_addr_hi & 0x0000ffff))) {
-+ /* found the correct address */
-+ if ((read_hi & (1 << 16)) && (!(read_hi & (1 << 17))))
-+ *port = AT_EXTRACT_PORT(read_hi);
-+ break;
-+ } else
-+ *port = -1;
-+ }
-+
-+ return 0;
-+}
-+
-+int esw_get_mac_address_lookup_table(struct switch_enet_private *fep,
-+ unsigned long *tableaddr, unsigned long *dnum, unsigned long *snum)
-+{
-+ unsigned long read_lo, read_hi;
-+ unsigned long entry;
-+ unsigned long dennum = 0;
-+ unsigned long sennum = 0;
-+
-+ for (entry = 0; entry < ESW_ATABLE_MEM_NUM_ENTRIES; entry++) {
-+ read_atable(fep, entry, &read_lo, &read_hi);
-+ if ((read_hi & (1 << 17)) && (read_hi & (1 << 16))) {
-+ /* static entry */
-+ *(tableaddr + (2047 - sennum) * 11) = entry;
-+ *(tableaddr + (2047 - sennum) * 11 + 2) =
-+ read_lo & 0x000000ff;
-+ *(tableaddr + (2047 - sennum) * 11 + 3) =
-+ (read_lo & 0x0000ff00) >> 8;
-+ *(tableaddr + (2047 - sennum) * 11 + 4) =
-+ (read_lo & 0x00ff0000) >> 16;
-+ *(tableaddr + (2047 - sennum) * 11 + 5) =
-+ (read_lo & 0xff000000) >> 24;
-+ *(tableaddr + (2047 - sennum) * 11 + 6) =
-+ read_hi & 0x000000ff;
-+ *(tableaddr + (2047 - sennum) * 11 + 7) =
-+ (read_hi & 0x0000ff00) >> 8;
-+ *(tableaddr + (2047 - sennum) * 11 + 8) =
-+ AT_EXTRACT_PORTMASK(read_hi);
-+ *(tableaddr + (2047 - sennum) * 11 + 9) =
-+ AT_EXTRACT_PRIO(read_hi);
-+ sennum++;
-+ } else if ((read_hi & (1 << 16)) && (!(read_hi & (1 << 17)))) {
-+ /* dynamic entry */
-+ *(tableaddr + dennum * 11) = entry;
-+ *(tableaddr + dennum * 11 + 2) = read_lo & 0xff;
-+ *(tableaddr + dennum * 11 + 3) =
-+ (read_lo & 0x0000ff00) >> 8;
-+ *(tableaddr + dennum * 11 + 4) =
-+ (read_lo & 0x00ff0000) >> 16;
-+ *(tableaddr + dennum * 11 + 5) =
-+ (read_lo & 0xff000000) >> 24;
-+ *(tableaddr + dennum * 11 + 6) = read_hi & 0xff;
-+ *(tableaddr + dennum * 11 + 7) =
-+ (read_hi & 0x0000ff00) >> 8;
-+ *(tableaddr + dennum * 11 + 8) =
-+ AT_EXTRACT_PORT(read_hi);
-+ *(tableaddr + dennum * 11 + 9) =
-+ AT_EXTRACT_TIMESTAMP(read_hi);
-+ dennum++;
-+ }
-+ }
-+
-+ *dnum = dennum;
-+ *snum = sennum;
-+ return 0;
-+}
-+
-+/*----------------------------------------------------------------------------*/
-+/* The timer should create an interrupt every 4 seconds*/
-+static void l2switch_aging_timer(unsigned long data)
-+{
-+ struct switch_enet_private *fep;
-+
-+ fep = (struct switch_enet_private *)data;
-+
-+ if (fep) {
-+ TIMEINCREMENT(fep->currTime);
-+ fep->timeChanged++;
-+ }
-+
-+ mod_timer(&fep->timer_aging, jiffies + LEARNING_AGING_TIMER);
-+}
-+
-+/* ----------------------------------------------------------------------- */
-+void esw_check_rxb_txb_interrupt(struct switch_enet_private *fep)
-+{
-+ volatile switch_t *fecp;
-+ fecp = fep->hwp;
-+
-+ /*Enable Forced forwarding for port 1*/
-+ fecp->ESW_P0FFEN = MCF_ESW_P0FFEN_FEN |
-+ MCF_ESW_P0FFEN_FD(1);
-+ /*Disable learning for all ports*/
-+ MCF_ESW_IMR = MCF_ESW_IMR_TXB | MCF_ESW_IMR_TXF |
-+ MCF_ESW_IMR_RXB | MCF_ESW_IMR_RXF;
-+}
-+
-+/*----------------------------------------------------------------*/
-+static int switch_enet_learning(void *arg)
-+{
-+ struct switch_enet_private *fep = arg;
-+ volatile switch_t *fecp;
-+
-+ fecp = fep->hwp;
-+ while (!kthread_should_stop()) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ /* check learning record valid */
-+ if (fecp->ESW_LSR)
-+ esw_atable_dynamicms_learn_migration(fep,
-+ fep->currTime);
-+ else
-+ schedule_timeout(HZ/100);
-+ }
-+
-+ return 0;
-+}
-+
-+static int switch_enet_ioctl(struct net_device *dev,
-+ struct ifreq *ifr, int cmd)
-+{
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+ volatile switch_t *fecp;
-+ int ret = 0;
-+
-+ fecp = (volatile switch_t *)dev->base_addr;
-+
-+ switch (cmd) {
-+ /*------------------------------------------------------------*/
-+ case ESW_SET_PORTENABLE_CONF:
-+ {
-+ eswIoctlPortEnableConfig configData;
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data,
-+ sizeof(eswIoctlPortEnableConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_port_enable_config(fep,
-+ configData.port,
-+ configData.tx_enable,
-+ configData.rx_enable);
-+ }
-+ break;
-+ case ESW_SET_BROADCAST_CONF:
-+ {
-+ eswIoctlPortConfig configData;
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPortConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_port_broadcast_config(fep,
-+ configData.port, configData.enable);
-+ }
-+ break;
-+
-+ case ESW_SET_MULTICAST_CONF:
-+ {
-+ eswIoctlPortConfig configData;
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPortConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_port_multicast_config(fep,
-+ configData.port, configData.enable);
-+ }
-+ break;
-+
-+ case ESW_SET_BLOCKING_CONF:
-+ {
-+ eswIoctlPortConfig configData;
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPortConfig));
-+
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_port_blocking_config(fep,
-+ configData.port, configData.enable);
-+ }
-+ break;
-+
-+ case ESW_SET_LEARNING_CONF:
-+ {
-+ eswIoctlPortConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPortConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_port_learning_config(fep,
-+ configData.port, configData.enable);
-+ }
-+ break;
-+
-+ case ESW_SET_PORT_ENTRY_EMPTY:
-+ {
-+ unsigned long portnum;
-+
-+ ret = copy_from_user(&portnum,
-+ ifr->ifr_data, sizeof(portnum));
-+ if (ret)
-+ return -EFAULT;
-+ esw_atable_dynamicms_del_entries_for_port(fep, portnum);
-+ }
-+ break;
-+
-+ case ESW_SET_OTHER_PORT_ENTRY_EMPTY:
-+ {
-+ unsigned long portnum;
-+
-+ ret = copy_from_user(&portnum,
-+ ifr->ifr_data, sizeof(portnum));
-+ if (ret)
-+ return -EFAULT;
-+
-+ esw_atable_dynamicms_del_entries_for_other_port(fep, portnum);
-+ }
-+ break;
-+
-+ case ESW_SET_IP_SNOOP_CONF:
-+ {
-+ eswIoctlIpsnoopConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlIpsnoopConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_ip_snoop_config(fep, configData.mode,
-+ configData.ip_header_protocol);
-+ }
-+ break;
-+
-+ case ESW_SET_PORT_SNOOP_CONF:
-+ {
-+ eswIoctlPortsnoopConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPortsnoopConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_tcpudp_port_snoop_config(fep, configData.mode,
-+ configData.compare_port,
-+ configData.compare_num);
-+ }
-+ break;
-+
-+ case ESW_SET_PORT_MIRROR_CONF_PORT_MATCH:
-+ {
-+ struct eswIoctlMirrorCfgPortMatch configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(configData));
-+ if (ret)
-+ return -EFAULT;
-+ ret = esw_port_mirroring_config_port_match(fep,
-+ configData.mirror_port, configData.port_match_en,
-+ configData.port);
-+ }
-+ break;
-+
-+ case ESW_SET_PORT_MIRROR_CONF:
-+ {
-+ eswIoctlPortMirrorConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPortMirrorConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_port_mirroring_config(fep,
-+ configData.mirror_port, configData.port,
-+ configData.mirror_enable,
-+ configData.src_mac, configData.des_mac,
-+ configData.egress_en, configData.ingress_en,
-+ configData.egress_mac_src_en,
-+ configData.egress_mac_des_en,
-+ configData.ingress_mac_src_en,
-+ configData.ingress_mac_des_en);
-+ }
-+ break;
-+
-+ case ESW_SET_PORT_MIRROR_CONF_ADDR_MATCH:
-+ {
-+ struct eswIoctlMirrorCfgAddrMatch configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(configData));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_port_mirroring_config_addr_match(fep,
-+ configData.mirror_port, configData.addr_match_en,
-+ configData.mac_addr);
-+ }
-+ break;
-+
-+ case ESW_SET_PIRORITY_VLAN:
-+ {
-+ eswIoctlPriorityVlanConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPriorityVlanConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_framecalssify_vlan_priority_lookup(fep,
-+ configData.port, configData.func_enable,
-+ configData.vlan_pri_table_num,
-+ configData.vlan_pri_table_value);
-+ }
-+ break;
-+
-+ case ESW_SET_PIRORITY_IP:
-+ {
-+ eswIoctlPriorityIPConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPriorityIPConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_framecalssify_ip_priority_lookup(fep,
-+ configData.port, configData.func_enable,
-+ configData.ipv4_en, configData.ip_priority_num,
-+ configData.ip_priority_value);
-+ }
-+ break;
-+
-+ case ESW_SET_PIRORITY_MAC:
-+ {
-+ eswIoctlPriorityMacConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPriorityMacConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_framecalssify_mac_priority_lookup(fep,
-+ configData.port);
-+ }
-+ break;
-+
-+ case ESW_SET_PIRORITY_DEFAULT:
-+ {
-+ eswIoctlPriorityDefaultConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlPriorityDefaultConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_frame_calssify_priority_init(fep,
-+ configData.port, configData.priority_value);
-+ }
-+ break;
-+
-+ case ESW_SET_P0_FORCED_FORWARD:
-+ {
-+ eswIoctlP0ForcedForwardConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlP0ForcedForwardConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_forced_forward(fep, configData.port1,
-+ configData.port2, configData.enable);
-+ }
-+ break;
-+
-+ case ESW_SET_BRIDGE_CONFIG:
-+ {
-+ unsigned long configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+
-+ esw_bridge_port_configure(fep, configData);
-+ }
-+ break;
-+
-+ case ESW_SET_SWITCH_MODE:
-+ {
-+ unsigned long configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+
-+ esw_switch_mode_configure(fep, configData);
-+ }
-+ break;
-+
-+ case ESW_SET_OUTPUT_QUEUE_MEMORY:
-+ {
-+ eswIoctlOutputQueue configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlOutputQueue));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_set_output_queue_memory(fep,
-+ configData.fun_num, &configData.sOutputQueue);
-+ }
-+ break;
-+
-+ case ESW_SET_VLAN_OUTPUT_PROCESS:
-+ {
-+ eswIoctlVlanOutputConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlVlanOutputConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_vlan_output_process(fep,
-+ configData.port, configData.mode);
-+ }
-+ break;
-+
-+ case ESW_SET_VLAN_INPUT_PROCESS:
-+ {
-+ eswIoctlVlanInputConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data,
-+ sizeof(eswIoctlVlanInputConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_vlan_input_process(fep, configData.port,
-+ configData.mode, configData.port_vlanid);
-+ }
-+ break;
-+
-+ case ESW_SET_VLAN_DOMAIN_VERIFICATION:
-+ {
-+ eswIoctlVlanVerificationConfig configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data,
-+ sizeof(eswIoctlVlanVerificationConfig));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_set_vlan_verification(
-+ fep, configData.port,
-+ configData.vlan_domain_verify_en,
-+ configData.vlan_discard_unknown_en);
-+ }
-+ break;
-+
-+ case ESW_SET_VLAN_RESOLUTION_TABLE:
-+ {
-+ eswIoctlVlanResoultionTable configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data,
-+ sizeof(eswIoctlVlanResoultionTable));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_set_vlan_resolution_table(
-+ fep, configData.port_vlanid,
-+ configData.vlan_domain_num,
-+ configData.vlan_domain_port);
-+
-+ }
-+ break;
-+
-+ case ESW_SET_VLAN_ID:
-+ {
-+ unsigned long configData;
-+ ret = copy_from_user(&configData, ifr->ifr_data,
-+ sizeof(configData));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_set_vlan_id(fep, configData);
-+ }
-+ break;
-+
-+ case ESW_SET_VLAN_ID_CLEARED:
-+ {
-+ unsigned long configData;
-+ ret = copy_from_user(&configData, ifr->ifr_data,
-+ sizeof(configData));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_set_vlan_id_cleared(fep, configData);
-+ }
-+ break;
-+
-+ case ESW_SET_PORT_IN_VLAN_ID:
-+ {
-+ eswIoctlVlanResoultionTable configData;
-+
-+ ret = copy_from_user(&configData, ifr->ifr_data,
-+ sizeof(configData));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_set_port_in_vlan_id(fep, configData);
-+ }
-+ break;
-+
-+ /*--------------------------------------------------------------------*/
-+ case ESW_UPDATE_STATIC_MACTABLE:
-+ {
-+ eswIoctlUpdateStaticMACtable configData;
-+
-+ ret = copy_from_user(&configData,
-+ ifr->ifr_data, sizeof(eswIoctlUpdateStaticMACtable));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_update_atable_static(configData.mac_addr,
-+ configData.port, configData.priority, fep);
-+ }
-+ break;
-+
-+ case ESW_CLEAR_ALL_MACTABLE:
-+ {
-+ esw_clear_atable(fep);
-+ }
-+ break;
-+
-+ /*-------------------get----------------------------------------------*/
-+ case ESW_GET_STATISTICS_STATUS:
-+ {
-+ esw_statistics_status Statistics;
-+ esw_port_statistics_status PortSta;
-+ int i;
-+
-+ ret = esw_get_statistics_status(fep, &Statistics);
-+ if (ret != 0) {
-+ printk(KERN_ERR "%s: cmd %x fail\n", __func__, cmd);
-+ return -1;
-+ }
-+ printk(KERN_INFO "DISCN : %10ld DISCB : %10ld\n",
-+ Statistics.ESW_DISCN, Statistics.ESW_DISCB);
-+ printk(KERN_INFO "NDISCN: %10ld NDISCB: %10ld\n",
-+ Statistics.ESW_NDISCN, Statistics.ESW_NDISCB);
-+
-+ for (i = 0; i < 3; i++) {
-+ ret = esw_get_port_statistics_status(fep, i,
-+ &PortSta);
-+ if (ret != 0) {
-+ printk(KERN_ERR "%s: cmd %x fail\n",
-+ __func__, cmd);
-+ return -1;
-+ }
-+ printk(KERN_INFO "port %d: POQC : %ld\n",
-+ i, PortSta.MCF_ESW_POQC);
-+ printk(KERN_INFO " PMVID : %ld\n",
-+ PortSta.MCF_ESW_PMVID);
-+ printk(KERN_INFO " PMVTAG: %ld\n",
-+ PortSta.MCF_ESW_PMVTAG);
-+ printk(KERN_INFO " PBL : %ld\n",
-+ PortSta.MCF_ESW_PBL);
-+ }
-+ }
-+ break;
-+
-+ case ESW_GET_LEARNING_CONF:
-+ {
-+ unsigned long PortLearning;
-+
-+ esw_get_port_learning(fep, &PortLearning);
-+ ret = copy_to_user(ifr->ifr_data, &PortLearning,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_BLOCKING_CONF:
-+ {
-+ unsigned long PortBlocking;
-+
-+ esw_get_port_blocking(fep, &PortBlocking);
-+ ret = copy_to_user(ifr->ifr_data, &PortBlocking,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_MULTICAST_CONF:
-+ {
-+ unsigned long PortMulticast;
-+
-+ esw_get_port_multicast(fep, &PortMulticast);
-+ ret = copy_to_user(ifr->ifr_data, &PortMulticast,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_BROADCAST_CONF:
-+ {
-+ unsigned long PortBroadcast;
-+
-+ esw_get_port_broadcast(fep, &PortBroadcast);
-+ ret = copy_to_user(ifr->ifr_data, &PortBroadcast,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_PORTENABLE_CONF:
-+ {
-+ unsigned long PortEnable;
-+
-+ esw_get_port_enable(fep, &PortEnable);
-+ ret = copy_to_user(ifr->ifr_data, &PortEnable,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_IP_SNOOP_CONF:
-+ {
-+ unsigned long ESW_IPSNP[8];
-+ int i;
-+
-+ esw_get_ip_snoop_config(fep, (unsigned long *)ESW_IPSNP);
-+ printk(KERN_INFO "IP Protocol Mode Type\n");
-+ for (i = 0; i < 8; i++) {
-+ if (ESW_IPSNP[i] != 0)
-+ printk(KERN_INFO "%3ld "
-+ "%1ld %s\n",
-+ (ESW_IPSNP[i] >> 8) & 0xff,
-+ (ESW_IPSNP[i] >> 1) & 3,
-+ ESW_IPSNP[i] & 1 ? "Active" :
-+ "Inactive");
-+ }
-+ }
-+ break;
-+
-+ case ESW_GET_PORT_SNOOP_CONF:
-+ {
-+ unsigned long ESW_PSNP[8];
-+ int i;
-+
-+ esw_get_tcpudp_port_snoop_config(fep,
-+ (unsigned long *)ESW_PSNP);
-+ printk(KERN_INFO "TCP/UDP Port SrcCompare DesCompare "
-+ "Mode Type\n");
-+ for (i = 0; i < 8; i++) {
-+ if (ESW_PSNP[i] != 0)
-+ printk(KERN_INFO "%5ld %s "
-+ "%s %1ld %s\n",
-+ (ESW_PSNP[i] >> 16) & 0xffff,
-+ (ESW_PSNP[i] >> 4) & 1 ? "Y" : "N",
-+ (ESW_PSNP[i] >> 3) & 1 ? "Y" : "N",
-+ (ESW_PSNP[i] >> 1) & 3,
-+ ESW_PSNP[i] & 1 ? "Active" :
-+ "Inactive");
-+ }
-+ }
-+ break;
-+
-+ case ESW_GET_PORT_MIRROR_CONF:
-+ esw_get_port_mirroring(fep);
-+ break;
-+
-+ case ESW_GET_P0_FORCED_FORWARD:
-+ {
-+ unsigned long ForceForward;
-+
-+ esw_get_forced_forward(fep, &ForceForward);
-+ ret = copy_to_user(ifr->ifr_data, &ForceForward,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_SWITCH_MODE:
-+ {
-+ unsigned long Config;
-+
-+ esw_get_switch_mode(fep, &Config);
-+ ret = copy_to_user(ifr->ifr_data, &Config,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_BRIDGE_CONFIG:
-+ {
-+ unsigned long Config;
-+
-+ esw_get_bridge_port(fep, &Config);
-+ ret = copy_to_user(ifr->ifr_data, &Config,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+ case ESW_GET_OUTPUT_QUEUE_STATUS:
-+ {
-+ esw_output_queue_status Config;
-+ esw_get_output_queue_status(fep,
-+ &Config);
-+ ret = copy_to_user(ifr->ifr_data, &Config,
-+ sizeof(esw_output_queue_status));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_VLAN_OUTPUT_PROCESS:
-+ {
-+ unsigned long Config;
-+ int tmp;
-+ int i;
-+
-+ esw_get_vlan_output_config(fep, &Config);
-+
-+ for (i = 0; i < 3; i++) {
-+ tmp = (Config >> (i << 1)) & 3;
-+
-+ if (tmp != 0)
-+ printk(KERN_INFO "port %d: vlan output "
-+ "manipulation enable (mode %d)\n",
-+ i, tmp);
-+ else
-+ printk(KERN_INFO "port %d: vlan output "
-+ "manipulation disable\n", i);
-+ }
-+ }
-+ break;
-+
-+ case ESW_GET_VLAN_INPUT_PROCESS:
-+ {
-+ eswIoctlVlanInputStatus Config;
-+ int i;
-+
-+ esw_get_vlan_input_config(fep, &Config);
-+
-+ for (i = 0; i < 3; i++) {
-+ if (((Config.ESW_VIMEN >> i) & 1) == 0)
-+ printk(KERN_INFO "port %d: vlan input "
-+ "manipulation disable\n", i);
-+ else
-+ printk("port %d: vlan input manipulation enable"
-+ " (mode %ld, vlan id %ld)\n", i,
-+ (((Config.ESW_VIMSEL >> (i << 1)) & 3)
-+ + 1), Config.ESW_PID[i]);
-+ }
-+ }
-+ break;
-+
-+ case ESW_GET_VLAN_RESOLUTION_TABLE:
-+ {
-+ struct eswVlanTableItem vtableitem;
-+ unsigned char tmp0, tmp1, tmp2;
-+ int i;
-+
-+ esw_get_vlan_resolution_table(fep, &vtableitem);
-+
-+ printk(KERN_INFO "VLAN Name VLAN Id Ports\n");
-+ for (i = 0; i < vtableitem.valid_num; i++) {
-+ tmp0 = vtableitem.table[i].vlan_domain_port & 1;
-+ tmp1 = (vtableitem.table[i].vlan_domain_port >> 1) & 1;
-+ tmp2 = (vtableitem.table[i].vlan_domain_port >> 2) & 1;
-+ printk(KERN_INFO "%2d %4d %s%s%s\n",
-+ i, vtableitem.table[i].port_vlanid,
-+ tmp0 ? "0 " : "", tmp1 ? "1 " : "",
-+ tmp2 ? "2" : "");
-+ }
-+ }
-+ break;
-+
-+ case ESW_GET_VLAN_DOMAIN_VERIFICATION:
-+ {
-+ unsigned long Config;
-+
-+ esw_get_vlan_verification(fep, &Config);
-+ ret = copy_to_user(ifr->ifr_data, &Config,
-+ sizeof(unsigned long));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_ENTRY_PORT_NUMBER:
-+ {
-+ unsigned char mac_addr[6];
-+ unsigned char portnum;
-+
-+ ret = copy_from_user(mac_addr,
-+ ifr->ifr_data, sizeof(mac_addr));
-+ if (ret)
-+ return -EFAULT;
-+
-+ ret = esw_atable_get_entry_port_number(fep, mac_addr,
-+ &portnum);
-+
-+ ret = copy_to_user(ifr->ifr_data, &portnum,
-+ sizeof(unsigned char));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_LOOKUP_TABLE:
-+ {
-+ unsigned long *ConfigData;
-+ unsigned long dennum, sennum;
-+ int i;
-+ int tmp;
-+
-+ ConfigData = kmalloc(sizeof(struct eswAddrTableEntryExample) *
-+ ESW_ATABLE_MEM_NUM_ENTRIES, GFP_KERNEL);
-+ ret = esw_get_mac_address_lookup_table(fep, ConfigData,
-+ &dennum, &sennum);
-+ printk(KERN_INFO "Dynamic entries number: %ld\n", dennum);
-+ printk(KERN_INFO "Static entries number: %ld\n", sennum);
-+ printk(KERN_INFO "Type MAC address Port Timestamp\n");
-+ for (i = 0; i < dennum; i++) {
-+ printk(KERN_INFO "dynamic "
-+ "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx "
-+ "%01lx %4ld\n", *(ConfigData + i * 11 + 2),
-+ *(ConfigData + i * 11 + 3),
-+ *(ConfigData + i * 11 + 4),
-+ *(ConfigData + i * 11 + 5),
-+ *(ConfigData + i * 11 + 6),
-+ *(ConfigData + i * 11 + 7),
-+ *(ConfigData + i * 11 + 8),
-+ *(ConfigData + i * 11 + 9));
-+ }
-+
-+ if (sennum != 0)
-+ printk(KERN_INFO "Type MAC address"
-+ " Port Priority\n");
-+
-+ for (i = 0; i < sennum; i++) {
-+ printk(KERN_INFO "static %02lx-%02lx-%02lx-%02lx"
-+ "-%02lx-%02lx ",
-+ *(ConfigData + (2047 - i) * 11 + 2),
-+ *(ConfigData + (2047 - i) * 11 + 3),
-+ *(ConfigData + (2047 - i) * 11 + 4),
-+ *(ConfigData + (2047 - i) * 11 + 5),
-+ *(ConfigData + (2047 - i) * 11 + 6),
-+ *(ConfigData + (2047 - i) * 11 + 7));
-+
-+ tmp = *(ConfigData + (2047 - i) * 11 + 8);
-+ if ((tmp == 0) || (tmp == 2) || (tmp == 4))
-+ printk("%01x ", tmp >> 1);
-+ else if (tmp == 3)
-+ printk("0,1 ");
-+ else if (tmp == 5)
-+ printk("0,2 ");
-+ else if (tmp == 6)
-+ printk("1,2 ");
-+
-+ printk("%4ld\n", *(ConfigData + (2047 - i) * 11 + 9));
-+ }
-+ kfree(ConfigData);
-+ }
-+ break;
-+
-+ case ESW_GET_PORT_STATUS:
-+ {
-+ unsigned long PortBlocking;
-+
-+ esw_get_port_blocking(fep, &PortBlocking);
-+
-+ ports_link_status.port0_block_status = PortBlocking & 1;
-+ ports_link_status.port1_block_status = (PortBlocking >> 1) & 1;
-+ ports_link_status.port2_block_status = PortBlocking >> 2;
-+
-+ ret = copy_to_user(ifr->ifr_data, &ports_link_status,
-+ sizeof(ports_link_status));
-+ if (ret)
-+ return -EFAULT;
-+ }
-+ break;
-+
-+ case ESW_GET_PORT_ALL_STATUS:
-+ {
-+ unsigned char portnum;
-+ struct port_all_status port_astatus;
-+
-+ ret = copy_from_user(&portnum,
-+ ifr->ifr_data, sizeof(portnum));
-+ if (ret)
-+ return -EFAULT;
-+
-+ esw_get_port_all_status(fep, portnum, &port_astatus);
-+ printk(KERN_INFO "Port %d status:\n", portnum);
-+ printk(KERN_INFO "Link:%-4s Blocking:%1s "
-+ "Learning:%1s\n",
-+ port_astatus.link_status ? "Up" : "Down",
-+ port_astatus.block_status ? "Y" : "N",
-+ port_astatus.learn_status ? "N" : "Y");
-+ printk(KERN_INFO "VLAN Verify:%1s Discard Unknown:%1s "
-+ "Multicast Res:%1s\n",
-+ port_astatus.vlan_verify ? "Y" : "N",
-+ port_astatus.discard_unknown ? "Y" : "N",
-+ port_astatus.multi_reso ? "Y" : "N");
-+ printk(KERN_INFO "Broadcast Res:%1s Transmit:%-7s "
-+ "Receive:%7s\n",
-+ port_astatus.broad_reso ? "Y" : "N",
-+ port_astatus.ftransmit ? "Enable" : "Disable",
-+ port_astatus.freceive ? "Enable" : "Disable");
-+
-+ }
-+ break;
-+
-+ case ESW_GET_USER_PID:
-+ {
-+ long get_pid = 0;
-+ ret = copy_from_user(&get_pid,
-+ ifr->ifr_data, sizeof(get_pid));
-+
-+ if (ret)
-+ return -EFAULT;
-+ user_pid = get_pid;
-+ }
-+ break;
-+ /*------------------------------------------------------------------*/
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return ret;
-+}
-+
-+static netdev_tx_t switch_enet_start_xmit(struct sk_buff *skb,
-+ struct net_device *dev)
-+{
-+ struct switch_enet_private *fep;
-+ volatile switch_t *fecp;
-+ cbd_t *bdp;
-+ unsigned short status;
-+ unsigned long flags;
-+
-+ fep = netdev_priv(dev);
-+ fecp = (switch_t *)fep->hwp;
-+
-+ spin_lock_irqsave(&fep->hw_lock, flags);
-+ /* Fill in a Tx ring entry */
-+ bdp = fep->cur_tx;
-+
-+ status = bdp->cbd_sc;
-+
-+ /* Clear all of the status flags.
-+ */
-+ status &= ~BD_ENET_TX_STATS;
-+
-+ /* Set buffer length and buffer pointer.
-+ */
-+ bdp->cbd_bufaddr = __pa(skb->data);
-+ bdp->cbd_datlen = skb->len;
-+
-+ /*
-+ * On some FEC implementations data must be aligned on
-+ * 4-byte boundaries. Use bounce buffers to copy data
-+ * and get it aligned. Ugh.
-+ */
-+ if (bdp->cbd_bufaddr & 0x3) {
-+ unsigned int index1;
-+ index1 = bdp - fep->tx_bd_base;
-+
-+ memcpy(fep->tx_bounce[index1],
-+ (void *)skb->data, bdp->cbd_datlen);
-+ bdp->cbd_bufaddr = __pa(fep->tx_bounce[index1]);
-+ }
-+
-+ /* Save skb pointer. */
-+ fep->tx_skbuff[fep->skb_cur] = skb;
-+
-+ dev->stats.tx_bytes += skb->len;
-+ fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
-+
-+ /* Push the data cache so the CPM does not get stale memory
-+ * data.
-+ */
-+ flush_dcache_range((unsigned long)skb->data,
-+ (unsigned long)skb->data + skb->len);
-+
-+ /* Send it on its way. Tell FEC it's ready, interrupt when done,
-+ * it's the last BD of the frame, and to put the CRC on the end.
-+ */
-+
-+ status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
-+ | BD_ENET_TX_LAST | BD_ENET_TX_TC);
-+ bdp->cbd_sc = status;
-+ dev->trans_start = jiffies;
-+
-+ /* Trigger transmission start */
-+ fecp->fec_x_des_active = MCF_ESW_TDAR_X_DES_ACTIVE;
-+
-+ /* If this was the last BD in the ring,
-+ * start at the beginning again.*/
-+ if (status & BD_ENET_TX_WRAP)
-+ bdp = fep->tx_bd_base;
-+ else
-+ bdp++;
-+
-+ if (bdp == fep->dirty_tx) {
-+ fep->tx_full = 1;
-+ netif_stop_queue(dev);
-+ printk(KERN_ERR "%s: net stop\n", __func__);
-+ }
-+
-+ fep->cur_tx = (cbd_t *)bdp;
-+
-+ spin_unlock_irqrestore(&fep->hw_lock, flags);
-+
-+ return NETDEV_TX_OK;
-+}
-+
-+static void switch_timeout(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+
-+ printk(KERN_ERR "%s: transmit timed out.\n", dev->name);
-+ dev->stats.tx_errors++;
-+ switch_restart(dev, fep->full_duplex);
-+ netif_wake_queue(dev);
-+}
-+
-+/* The interrupt handler.
-+ * This is called from the MPC core interrupt.
-+ */
-+static irqreturn_t switch_enet_interrupt(int irq, void *dev_id)
-+{
-+ struct net_device *dev = dev_id;
-+ volatile switch_t *fecp;
-+ uint int_events;
-+ irqreturn_t ret = IRQ_NONE;
-+
-+ fecp = (switch_t *)dev->base_addr;
-+
-+ /* Get the interrupt events that caused us to be here.
-+ */
-+ do {
-+ int_events = fecp->switch_ievent;
-+ fecp->switch_ievent = int_events;
-+ /* Handle receive event in its own function. */
-+
-+ /* Transmit OK, or non-fatal error. Update the buffer
-+ descriptors. Switch handles all errors, we just discover
-+ them as part of the transmit process.
-+ */
-+ if (int_events & MCF_ESW_ISR_OD0)
-+ ret = IRQ_HANDLED;
-+
-+ if (int_events & MCF_ESW_ISR_OD1)
-+ ret = IRQ_HANDLED;
-+
-+ if (int_events & MCF_ESW_ISR_OD2)
-+ ret = IRQ_HANDLED;
-+
-+ if (int_events & MCF_ESW_ISR_RXB)
-+ ret = IRQ_HANDLED;
-+
-+ if (int_events & MCF_ESW_ISR_RXF) {
-+ ret = IRQ_HANDLED;
-+ switch_enet_rx(dev);
-+ }
-+
-+ if (int_events & MCF_ESW_ISR_TXB)
-+ ret = IRQ_HANDLED;
-+
-+ if (int_events & MCF_ESW_ISR_TXF) {
-+ ret = IRQ_HANDLED;
-+ switch_enet_tx(dev);
-+ }
-+
-+ } while (int_events);
-+
-+ return ret;
-+}
-+
-+static void switch_enet_tx(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep;
-+ cbd_t *bdp;
-+ unsigned short status;
-+ struct sk_buff *skb;
-+
-+ fep = netdev_priv(dev);
-+ spin_lock_irq(&fep->hw_lock);
-+ bdp = fep->dirty_tx;
-+
-+ while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
-+ if (bdp == fep->cur_tx && fep->tx_full == 0)
-+ break;
-+
-+ skb = fep->tx_skbuff[fep->skb_dirty];
-+ /* Check for errors. */
-+ if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
-+ BD_ENET_TX_RL | BD_ENET_TX_UN |
-+ BD_ENET_TX_CSL)) {
-+ dev->stats.tx_errors++;
-+ if (status & BD_ENET_TX_HB) /* No heartbeat */
-+ dev->stats.tx_heartbeat_errors++;
-+ if (status & BD_ENET_TX_LC) /* Late collision */
-+ dev->stats.tx_window_errors++;
-+ if (status & BD_ENET_TX_RL) /* Retrans limit */
-+ dev->stats.tx_aborted_errors++;
-+ if (status & BD_ENET_TX_UN) /* Underrun */
-+ dev->stats.tx_fifo_errors++;
-+ if (status & BD_ENET_TX_CSL) /* Carrier lost */
-+ dev->stats.tx_carrier_errors++;
-+ } else {
-+ dev->stats.tx_packets++;
-+ }
-+
-+ /* Deferred means some collisions occurred during transmit,
-+ * but we eventually sent the packet OK.
-+ */
-+ if (status & BD_ENET_TX_DEF)
-+ dev->stats.collisions++;
-+
-+ /* Free the sk buffer associated with this last transmit.
-+ */
-+ dev_kfree_skb_any(skb);
-+ fep->tx_skbuff[fep->skb_dirty] = NULL;
-+ fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
-+
-+ /* Update pointer to next buffer descriptor to be transmitted.
-+ */
-+ if (status & BD_ENET_TX_WRAP)
-+ bdp = fep->tx_bd_base;
-+ else
-+ bdp++;
-+
-+ /* Since we have freed up a buffer, the ring is no longer
-+ * full.
-+ */
-+ if (fep->tx_full) {
-+ fep->tx_full = 0;
-+ printk(KERN_ERR "%s: tx full is zero\n", __func__);
-+ if (netif_queue_stopped(dev))
-+ netif_wake_queue(dev);
-+ }
-+ }
-+ fep->dirty_tx = (cbd_t *)bdp;
-+ spin_unlock_irq(&fep->hw_lock);
-+}
-+
-+
-+/* During a receive, the cur_rx points to the current incoming buffer.
-+ * When we update through the ring, if the next incoming buffer has
-+ * not been given to the system, we just set the empty indicator,
-+ * effectively tossing the packet.
-+ */
-+static void switch_enet_rx(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep;
-+ volatile switch_t *fecp;
-+ cbd_t *bdp;
-+ unsigned short status;
-+ struct sk_buff *skb;
-+ ushort pkt_len;
-+ __u8 *data;
-+
-+ fep = netdev_priv(dev);
-+ /*fecp = (volatile switch_t *)dev->base_addr;*/
-+ fecp = (volatile switch_t *)fep->hwp;
-+
-+ spin_lock_irq(&fep->hw_lock);
-+ /* First, grab all of the stats for the incoming packet.
-+ * These get messed up if we get called due to a busy condition.
-+ */
-+ bdp = fep->cur_rx;
-+
-+ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
-+
-+ /* Since we have allocated space to hold a complete frame,
-+ * the last indicator should be set.
-+ * */
-+ if ((status & BD_ENET_RX_LAST) == 0)
-+ printk(KERN_ERR "SWITCH ENET: rcv is not +last\n");
-+
-+ if (!fep->opened)
-+ goto rx_processing_done;
-+
-+ /* Check for errors. */
-+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
-+ BD_ENET_RX_CR | BD_ENET_RX_OV)) {
-+ dev->stats.rx_errors++;
-+ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
-+ /* Frame too long or too short. */
-+ dev->stats.rx_length_errors++;
-+ }
-+ if (status & BD_ENET_RX_NO) /* Frame alignment */
-+ dev->stats.rx_frame_errors++;
-+ if (status & BD_ENET_RX_CR) /* CRC Error */
-+ dev->stats.rx_crc_errors++;
-+ if (status & BD_ENET_RX_OV) /* FIFO overrun */
-+ dev->stats.rx_fifo_errors++;
-+ }
-+ /* Report late collisions as a frame error.
-+ * On this error, the BD is closed, but we don't know what we
-+ * have in the buffer. So, just drop this frame on the floor.
-+ * */
-+ if (status & BD_ENET_RX_CL) {
-+ dev->stats.rx_errors++;
-+ dev->stats.rx_frame_errors++;
-+ goto rx_processing_done;
-+ }
-+ /* Process the incoming frame */
-+ dev->stats.rx_packets++;
-+ pkt_len = bdp->cbd_datlen;
-+ dev->stats.rx_bytes += pkt_len;
-+ data = (__u8 *)__va(bdp->cbd_bufaddr);
-+
-+ /* This does 16 byte alignment, exactly what we need.
-+ * The packet length includes FCS, but we don't want to
-+ * include that when passing upstream as it messes up
-+ * bridging applications.
-+ * */
-+ skb = dev_alloc_skb(pkt_len);
-+
-+ if (skb == NULL)
-+ dev->stats.rx_dropped++;
-+ else {
-+ skb_put(skb, pkt_len); /* Make room */
-+ skb_copy_to_linear_data(skb, data, pkt_len);
-+ skb->protocol = eth_type_trans(skb, dev);
-+ netif_rx(skb);
-+ }
-+rx_processing_done:
-+
-+ /* Clear the status flags for this buffer */
-+ status &= ~BD_ENET_RX_STATS;
-+
-+ /* Mark the buffer empty */
-+ status |= BD_ENET_RX_EMPTY;
-+ bdp->cbd_sc = status;
-+
-+ /* Update BD pointer to next entry */
-+ if (status & BD_ENET_RX_WRAP)
-+ bdp = fep->rx_bd_base;
-+ else
-+ bdp++;
-+
-+ /* Doing this here will keep the FEC running while we process
-+ * incoming frames. On a heavily loaded network, we should be
-+ * able to keep up at the expense of system resources.
-+ * */
-+ fecp->fec_r_des_active = MCF_ESW_RDAR_R_DES_ACTIVE;
-+ }
-+ fep->cur_rx = (cbd_t *)bdp;
-+
-+ spin_unlock_irq(&fep->hw_lock);
-+}
-+
-+static int fec_mdio_transfer(struct mii_bus *bus, int phy_id,
-+ int reg, int regval)
-+{
-+ struct net_device *dev = bus->priv;
-+ unsigned long flags;
-+ struct switch_enet_private *fep;
-+ int tries = 100;
-+ int retval = 0;
-+
-+ fep = netdev_priv(dev);
-+ spin_lock_irqsave(&fep->mii_lock, flags);
-+
-+ regval |= phy_id << 23;
-+ MCF_FEC_MMFR0 = regval;
-+
-+ /* wait for it to finish, this takes about 23 us on lite5200b */
-+ while (!(MCF_FEC_EIR0 & FEC_ENET_MII) && --tries)
-+ udelay(5);
-+
-+ if (!tries) {
-+ printk(KERN_ERR "%s timeout\n", __func__);
-+ return -ETIMEDOUT;
-+ }
-+
-+ MCF_FEC_EIR0 = FEC_ENET_MII;
-+ retval = MCF_FEC_MMFR0;
-+ spin_unlock_irqrestore(&fep->mii_lock, flags);
-+
-+ return retval;
-+}
-+
-+
-+static int coldfire_fec_mdio_read(struct mii_bus *bus,
-+ int phy_id, int reg)
-+{
-+ int ret;
-+ ret = fec_mdio_transfer(bus, phy_id, reg,
-+ mk_mii_read(reg));
-+ return ret;
-+}
-+
-+static int coldfire_fec_mdio_write(struct mii_bus *bus,
-+ int phy_id, int reg, u16 data)
-+{
-+ return fec_mdio_transfer(bus, phy_id, reg,
-+ mk_mii_write(reg, data));
-+}
-+
-+static void switch_adjust_link1(struct net_device *dev)
-+{
-+ struct switch_enet_private *priv = netdev_priv(dev);
-+ struct phy_device *phydev1 = priv->phydev[0];
-+ int new_state = 0;
-+
-+ if (phydev1->link != PHY_DOWN) {
-+ if (phydev1->duplex != priv->phy1_duplex) {
-+ new_state = 1;
-+ priv->phy1_duplex = phydev1->duplex;
-+ }
-+
-+ if (phydev1->speed != priv->phy1_speed) {
-+ new_state = 1;
-+ priv->phy1_speed = phydev1->speed;
-+ }
-+
-+ if (priv->phy1_old_link == PHY_DOWN) {
-+ new_state = 1;
-+ priv->phy1_old_link = phydev1->link;
-+ }
-+ } else if (priv->phy1_old_link) {
-+ new_state = 1;
-+ priv->phy1_old_link = PHY_DOWN;
-+ priv->phy1_speed = 0;
-+ priv->phy1_duplex = -1;
-+ }
-+
-+ if (new_state) {
-+ ports_link_status.port1_link_status = phydev1->link;
-+ if (phydev1->link == PHY_DOWN)
-+ esw_atable_dynamicms_del_entries_for_port(priv, 1);
-+
-+ /*Send the new status to user space*/
-+ if (user_pid != 1)
-+ sys_tkill(user_pid, SIGUSR1);
-+ }
-+}
-+
-+static void switch_adjust_link2(struct net_device *dev)
-+{
-+ struct switch_enet_private *priv = netdev_priv(dev);
-+ struct phy_device *phydev2 = priv->phydev[1];
-+ int new_state = 0;
-+
-+ if (phydev2->link != PHY_DOWN) {
-+ if (phydev2->duplex != priv->phy2_duplex) {
-+ new_state = 1;
-+ priv->phy2_duplex = phydev2->duplex;
-+ }
-+
-+ if (phydev2->speed != priv->phy2_speed) {
-+ new_state = 1;
-+ priv->phy2_speed = phydev2->speed;
-+ }
-+
-+ if (priv->phy2_old_link == PHY_DOWN) {
-+ new_state = 1;
-+ priv->phy2_old_link = phydev2->link;
-+ }
-+ } else if (priv->phy2_old_link) {
-+ new_state = 1;
-+ priv->phy2_old_link = PHY_DOWN;
-+ priv->phy2_speed = 0;
-+ priv->phy2_duplex = -1;
-+ }
-+
-+ if (new_state) {
-+ ports_link_status.port2_link_status = phydev2->link;
-+ if (phydev2->link == PHY_DOWN)
-+ esw_atable_dynamicms_del_entries_for_port(priv, 2);
-+
-+ /*Send the new status to user space*/
-+ if (user_pid != 1)
-+ sys_tkill(user_pid, SIGUSR1);
-+ }
-+}
-+
-+static int coldfire_switch_init_phy(struct net_device *dev)
-+{
-+ struct switch_enet_private *priv = netdev_priv(dev);
-+ struct phy_device *phydev[SWITCH_EPORT_NUMBER] = {NULL, NULL};
-+ int i, startnode = 0;
-+
-+ /* search for connect PHY device */
-+ for (i = 0; i < PHY_MAX_ADDR; i++) {
-+ struct phy_device *const tmp_phydev =
-+ priv->mdio_bus->phy_map[i];
-+
-+ if (!tmp_phydev)
-+ continue;
-+
-+#ifdef CONFIG_FEC_SHARED_PHY
-+ if (priv->index == 0)
-+ phydev[i] = tmp_phydev;
-+ else if (priv->index == 1) {
-+ if (startnode == 1) {
-+ phydev[i] = tmp_phydev;
-+ startnode = 0;
-+ } else {
-+ startnode++;
-+ continue;
-+ }
-+ } else
-+ printk(KERN_INFO "%s now we do not"
-+ "support (%d) more than"
-+ "2 phys shared "
-+ "one mdio bus\n",
-+ __func__, startnode);
-+#else
-+ phydev[i] = tmp_phydev;
-+#endif
-+ }
-+
-+ /* now we are supposed to have a proper phydev, to attach to... */
-+ if ((!phydev[0]) && (!phydev[1])) {
-+ printk(KERN_INFO "%s: Don't found any phy device at all\n",
-+ dev->name);
-+ return -ENODEV;
-+ }
-+
-+ priv->phy1_link = PHY_DOWN;
-+ priv->phy1_old_link = PHY_DOWN;
-+ priv->phy1_speed = 0;
-+ priv->phy1_duplex = -1;
-+
-+ priv->phy2_link = PHY_DOWN;
-+ priv->phy2_old_link = PHY_DOWN;
-+ priv->phy2_speed = 0;
-+ priv->phy2_duplex = -1;
-+
-+ phydev[0] = phy_connect(dev, dev_name(&phydev[0]->dev),
-+ &switch_adjust_link1, 0, PHY_INTERFACE_MODE_MII);
-+ if (IS_ERR(phydev[0])) {
-+ printk(KERN_ERR " %s phy_connect failed\n", __func__);
-+ return PTR_ERR(phydev[0]);
-+ }
-+
-+ phydev[1] = phy_connect(dev, dev_name(&phydev[1]->dev),
-+ &switch_adjust_link2, 0, PHY_INTERFACE_MODE_MII);
-+ if (IS_ERR(phydev[1])) {
-+ printk(KERN_ERR " %s phy_connect failed\n", __func__);
-+ return PTR_ERR(phydev[1]);
-+ }
-+
-+ for (i = 0; i < SWITCH_EPORT_NUMBER; i++) {
-+ printk(KERN_INFO "attached phy %i to driver %s\n",
-+ phydev[i]->addr, phydev[i]->drv->name);
-+ priv->phydev[i] = phydev[i];
-+ }
-+
-+ return 0;
-+}
-+/* -----------------------------------------------------------------------*/
-+static int switch_enet_open(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+ volatile switch_t *fecp;
-+ int i;
-+
-+ fecp = (volatile switch_t *)fep->hwp;
-+ /* I should reset the ring buffers here, but I don't yet know
-+ * a simple way to do that.
-+ */
-+ switch_set_mac_address(dev);
-+
-+ fep->phy1_link = 0;
-+ fep->phy2_link = 0;
-+
-+ coldfire_switch_init_phy(dev);
-+ for (i = 0; i < SWITCH_EPORT_NUMBER; i++) {
-+ phy_write(fep->phydev[i], MII_BMCR, BMCR_RESET);
-+ phy_start(fep->phydev[i]);
-+ }
-+
-+ fep->phy1_old_link = 0;
-+ fep->phy2_old_link = 0;
-+ fep->phy1_link = 1;
-+ fep->phy2_link = 1;
-+
-+ /* no phy, go full duplex, it's most likely a hub chip */
-+ switch_restart(dev, 1);
-+
-+ /* if the fec is the fist open, we need to do nothing*/
-+ /* if the fec is not the fist open, we need to restart the FEC*/
-+ if (fep->sequence_done == 0)
-+ switch_restart(dev, 1);
-+ else
-+ fep->sequence_done = 0;
-+
-+ fep->currTime = 0;
-+ fep->learning_irqhandle_enable = 0;
-+
-+ MCF_ESW_PER = 0x70007;
-+ fecp->ESW_DBCR = MCF_ESW_DBCR_P0 | MCF_ESW_DBCR_P1 | MCF_ESW_DBCR_P2;
-+ fecp->ESW_DMCR = MCF_ESW_DMCR_P0 | MCF_ESW_DMCR_P1 | MCF_ESW_DMCR_P2;
-+
-+ netif_start_queue(dev);
-+ fep->opened = 1;
-+
-+ return 0;
-+}
-+
-+static int switch_enet_close(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+ int i;
-+
-+ /* Don't know what to do yet.*/
-+ fep->opened = 0;
-+ netif_stop_queue(dev);
-+ switch_stop(dev);
-+
-+ for (i = 0; i < SWITCH_EPORT_NUMBER; i++) {
-+ phy_disconnect(fep->phydev[i]);
-+ phy_stop(fep->phydev[i]);
-+ phy_write(fep->phydev[i], MII_BMCR, BMCR_PDOWN);
-+ }
-+
-+ return 0;
-+}
-+
-+/* Set or clear the multicast filter for this adaptor.
-+ * Skeleton taken from sunlance driver.
-+ * The CPM Ethernet implementation allows Multicast as well as individual
-+ * MAC address filtering. Some of the drivers check to make sure it is
-+ * a group multicast address, and discard those that are not. I guess I
-+ * will do the same for now, but just remove the test if you want
-+ * individual filtering as well (do the upper net layers want or support
-+ * this kind of feature?).
-+ */
-+
-+#define HASH_BITS 6 /* #bits in hash */
-+#define CRC32_POLY 0xEDB88320
-+
-+static void set_multicast_list(struct net_device *dev)
-+{
-+ struct switch_enet_private *fep;
-+ volatile switch_t *ep;
-+ unsigned int i, bit, data, crc;
-+ struct netdev_hw_addr *ha;
-+
-+ fep = netdev_priv(dev);
-+ ep = fep->hwp;
-+
-+ if (dev->flags & IFF_PROMISC) {
-+ printk(KERN_INFO "%s IFF_PROMISC\n", __func__);
-+ } else {
-+ if (dev->flags & IFF_ALLMULTI)
-+ /* Catch all multicast addresses, so set the
-+ * filter to all 1's.
-+ */
-+ printk(KERN_INFO "%s IFF_ALLMULTI\n", __func__);
-+ else {
-+ netdev_for_each_mc_addr(ha, dev) {
-+ if (!(ha->addr[0] & 1))
-+ continue;
-+
-+ /* calculate crc32 value of mac address
-+ */
-+ crc = 0xffffffff;
-+
-+ for (i = 0; i < dev->addr_len; i++) {
-+ data = ha->addr[i];
-+ for (bit = 0; bit < 8; bit++,
-+ data >>= 1) {
-+ crc = (crc >> 1) ^
-+ (((crc ^ data) & 1) ?
-+ CRC32_POLY : 0);
-+ }
-+ }
-+
-+ }
-+ }
-+ }
-+}
-+
-+/* Set a MAC change in hardware.*/
-+static void switch_set_mac_address(struct net_device *dev)
-+{
-+ volatile switch_t *fecp;
-+
-+ fecp = ((struct switch_enet_private *)netdev_priv(dev))->hwp;
-+}
-+
-+static void switch_hw_init(void)
-+{
-+ /* GPIO config - RMII mode for both MACs */
-+ MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
-+ MCF_GPIO_PAR_FEC_FEC_MASK) |
-+ MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL;
-+
-+ /* Initialize MAC 0/1 */
-+ /* RCR */
-+ MCF_FEC_RCR0 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
-+ MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
-+ MCF_FEC_RCR1 = (MCF_FEC_RCR_PROM | MCF_FEC_RCR_RMII_MODE |
-+ MCF_FEC_RCR_MAX_FL(1522) | MCF_FEC_RCR_CRC_FWD);
-+ /* TCR */
-+ MCF_FEC_TCR0 = MCF_FEC_TCR_FDEN;
-+ MCF_FEC_TCR1 = MCF_FEC_TCR_FDEN;
-+ /* ECR */
-+#ifdef MODELO_BUFFER
-+ MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
-+ MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN | MCF_FEC_ECR_ENA_1588;
-+#else
-+ MCF_FEC_ECR0 = MCF_FEC_ECR_ETHER_EN;
-+ MCF_FEC_ECR1 = MCF_FEC_ECR_ETHER_EN;
-+#endif
-+ MCF_FEC_MSCR0 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
-+ MCF_FEC_MSCR1 = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
-+
-+ MCF_FEC_EIMR0 = FEC_ENET_TXF | FEC_ENET_RXF;
-+ MCF_FEC_EIMR1 = FEC_ENET_TXF | FEC_ENET_RXF;
-+ /*MCF_PPMHR0*/
-+ MCF_PPMCR0 = 0;
-+}
-+
-+static const struct net_device_ops switch_netdev_ops = {
-+ .ndo_open = switch_enet_open,
-+ .ndo_stop = switch_enet_close,
-+ .ndo_start_xmit = switch_enet_start_xmit,
-+ .ndo_set_multicast_list = set_multicast_list,
-+ .ndo_do_ioctl = switch_enet_ioctl,
-+ .ndo_tx_timeout = switch_timeout,
-+};
-+
-+/* Initialize the FEC Ethernet.
-+ */
-+ /*
-+ * XXX: We need to clean up on failure exits here.
-+ */
-+static int switch_enet_init(struct platform_device *pdev)
-+{
-+ struct net_device *dev = platform_get_drvdata(pdev);
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+ unsigned long mem_addr;
-+ cbd_t *bdp;
-+ cbd_t *cbd_base;
-+ volatile switch_t *fecp;
-+ int i, j;
-+ struct coldfire_switch_platform_data *plat =
-+ pdev->dev.platform_data;
-+
-+ /* Allocate memory for buffer descriptors.
-+ */
-+ mem_addr = __get_free_page(GFP_DMA);
-+ if (mem_addr == 0) {
-+ printk(KERN_ERR "Switch: allocate descriptor memory failed?\n");
-+ return -ENOMEM;
-+ }
-+
-+ spin_lock_init(&fep->hw_lock);
-+ spin_lock_init(&fep->mii_lock);
-+
-+ /* Create an Ethernet device instance.
-+ */
-+ fecp = (volatile switch_t *)plat->switch_hw[0];
-+ fep->hwp = fecp;
-+ fep->netdev = dev;
-+
-+ /*
-+ * SWITCH CONFIGURATION
-+ */
-+ fecp->ESW_MODE = MCF_ESW_MODE_SW_RST;
-+ udelay(10);
-+ /* enable switch*/
-+ fecp->ESW_MODE = MCF_ESW_MODE_STATRST;
-+ fecp->ESW_MODE = MCF_ESW_MODE_SW_EN;
-+
-+ /* Enable transmit/receive on all ports */
-+ fecp->ESW_PER = 0xffffffff;
-+
-+ /* Management port configuration,
-+ * make port 0 as management port */
-+ fecp->ESW_BMPC = 0;
-+
-+ /* clear all switch irq*/
-+ fecp->switch_ievent = 0xffffffff;
-+ fecp->switch_imask = 0;
-+
-+ udelay(10);
-+
-+ /* Set the Ethernet address. If using multiple Enets on the 8xx,
-+ * this needs some work to get unique addresses.
-+ *
-+ * This is our default MAC address unless the user changes
-+ * it via eth_mac_addr (our dev->set_mac_addr handler).
-+ */
-+ if (plat && plat->get_mac)
-+ plat->get_mac(dev);
-+
-+ cbd_base = (cbd_t *)mem_addr;
-+ /* XXX: missing check for allocation failure */
-+ if (plat && plat->uncache)
-+ plat->uncache(mem_addr);
-+
-+ /* Set receive and transmit descriptor base.
-+ */
-+ fep->rx_bd_base = cbd_base;
-+ fep->tx_bd_base = cbd_base + RX_RING_SIZE;
-+
-+ dev->base_addr = (unsigned long)fecp;
-+
-+ /* The FEC Ethernet specific entries in the device structure. */
-+ dev->watchdog_timeo = TX_TIMEOUT;
-+ dev->netdev_ops = &switch_netdev_ops;
-+
-+ fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
-+ fep->cur_rx = fep->rx_bd_base;
-+
-+ fep->skb_cur = fep->skb_dirty = 0;
-+
-+ /* Initialize the receive buffer descriptors. */
-+ bdp = fep->rx_bd_base;
-+
-+ for (i = 0; i < SWITCH_ENET_RX_PAGES; i++) {
-+
-+ /* Allocate a page.
-+ */
-+ mem_addr = __get_free_page(GFP_DMA);
-+ /* XXX: missing check for allocation failure */
-+ if (plat && plat->uncache)
-+ plat->uncache(mem_addr);
-+
-+ /* Initialize the BD for every fragment in the page.
-+ */
-+ for (j = 0; j < SWITCH_ENET_RX_FRPPG; j++) {
-+ bdp->cbd_sc = BD_ENET_RX_EMPTY;
-+ bdp->cbd_bufaddr = __pa(mem_addr);
-+#ifdef MODELO_BUFFER
-+ bdp->bdu = 0x00000000;
-+ bdp->ebd_status = RX_BD_INT;
-+#endif
-+ mem_addr += SWITCH_ENET_RX_FRSIZE;
-+ bdp++;
-+ }
-+ }
-+
-+ /* Set the last buffer to wrap.
-+ */
-+ bdp--;
-+ bdp->cbd_sc |= BD_SC_WRAP;
-+
-+ /* ...and the same for transmmit.
-+ */
-+ bdp = fep->tx_bd_base;
-+ for (i = 0, j = SWITCH_ENET_TX_FRPPG; i < TX_RING_SIZE; i++) {
-+ if (j >= SWITCH_ENET_TX_FRPPG) {
-+ mem_addr = __get_free_page(GFP_DMA);
-+ j = 1;
-+ } else {
-+ mem_addr += SWITCH_ENET_TX_FRSIZE;
-+ j++;
-+ }
-+ fep->tx_bounce[i] = (unsigned char *) mem_addr;
-+
-+ /* Initialize the BD for every fragment in the page.
-+ */
-+ bdp->cbd_sc = 0;
-+ bdp->cbd_bufaddr = 0;
-+ bdp++;
-+ }
-+
-+ /* Set the last buffer to wrap.
-+ */
-+ bdp--;
-+ bdp->cbd_sc |= BD_SC_WRAP;
-+
-+ /* Set receive and transmit descriptor base.
-+ */
-+ fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
-+ fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
-+
-+ /* Install our interrupt handlers. This varies depending on
-+ * the architecture.
-+ */
-+ if (plat && plat->request_intrs)
-+ plat->request_intrs(dev, switch_enet_interrupt, dev);
-+
-+ fecp->fec_r_buff_size = RX_BUFFER_SIZE;
-+ fecp->fec_r_des_active = MCF_ESW_RDAR_R_DES_ACTIVE;
-+
-+ /* setup MII interface */
-+ if (plat && plat->set_mii)
-+ plat->set_mii(dev);
-+
-+ /* Clear and enable interrupts */
-+ fecp->switch_ievent = 0xffffffff;
-+ fecp->switch_imask = MCF_ESW_IMR_RXB | MCF_ESW_IMR_TXB |
-+ MCF_ESW_IMR_RXF | MCF_ESW_IMR_TXF;
-+ esw_clear_atable(fep);
-+ /* Queue up command to detect the PHY and initialize the
-+ * remainder of the interface.
-+ */
-+#ifndef CONFIG_FEC_SHARED_PHY
-+ fep->phy_addr = 0;
-+#else
-+ fep->phy_addr = fep->index;
-+#endif
-+
-+ fep->sequence_done = 1;
-+ return 0;
-+}
-+
-+/* This function is called to start or restart the FEC during a link
-+ * change. This only happens when switching between half and full
-+ * duplex.
-+ */
-+static void switch_restart(struct net_device *dev, int duplex)
-+{
-+ struct switch_enet_private *fep;
-+ cbd_t *bdp;
-+ volatile switch_t *fecp;
-+ int i;
-+ struct coldfire_switch_platform_data *plat;
-+
-+ fep = netdev_priv(dev);
-+ fecp = fep->hwp;
-+ plat = fep->pdev->dev.platform_data;
-+ /* Whack a reset. We should wait for this.*/
-+ MCF_FEC_ECR0 = 1;
-+ MCF_FEC_ECR1 = 1;
-+ udelay(10);
-+
-+ fecp->ESW_MODE = MCF_ESW_MODE_SW_RST;
-+ udelay(10);
-+ fecp->ESW_MODE = MCF_ESW_MODE_STATRST;
-+ fecp->ESW_MODE = MCF_ESW_MODE_SW_EN;
-+
-+ /* Enable transmit/receive on all ports */
-+ fecp->ESW_PER = 0xffffffff;
-+
-+ /* Management port configuration,
-+ * make port 0 as management port */
-+ fecp->ESW_BMPC = 0;
-+
-+ /* Clear any outstanding interrupt.
-+ */
-+ fecp->switch_ievent = 0xffffffff;
-+
-+ /* Set station address.*/
-+ switch_set_mac_address(dev);
-+
-+ switch_hw_init();
-+
-+ /* Reset all multicast.*/
-+
-+ /* Set maximum receive buffer size.
-+ */
-+ fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-+
-+ if (plat && plat->localhw_setup)
-+ plat->localhw_setup();
-+ /* Set receive and transmit descriptor base.
-+ */
-+ fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
-+ fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
-+
-+ fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
-+ fep->cur_rx = fep->rx_bd_base;
-+
-+ /* Reset SKB transmit buffers.
-+ */
-+ fep->skb_cur = fep->skb_dirty = 0;
-+ for (i = 0; i <= TX_RING_MOD_MASK; i++) {
-+ if (fep->tx_skbuff[i] != NULL) {
-+ dev_kfree_skb_any(fep->tx_skbuff[i]);
-+ fep->tx_skbuff[i] = NULL;
-+ }
-+ }
-+
-+ /* Initialize the receive buffer descriptors.
-+ */
-+ bdp = fep->rx_bd_base;
-+ for (i = 0; i < RX_RING_SIZE; i++) {
-+
-+ /* Initialize the BD for every fragment in the page.
-+ */
-+ bdp->cbd_sc = BD_ENET_RX_EMPTY;
-+#ifdef MODELO_BUFFER
-+ bdp->bdu = 0x00000000;
-+ bdp->ebd_status = RX_BD_INT;
-+#endif
-+ bdp++;
-+ }
-+
-+ /* Set the last buffer to wrap.
-+ */
-+ bdp--;
-+ bdp->cbd_sc |= BD_SC_WRAP;
-+
-+ /* ...and the same for transmmit.
-+ */
-+ bdp = fep->tx_bd_base;
-+ for (i = 0; i < TX_RING_SIZE; i++) {
-+
-+ /* Initialize the BD for every fragment in the page.*/
-+ bdp->cbd_sc = 0;
-+ bdp->cbd_bufaddr = 0;
-+ bdp++;
-+ }
-+
-+ /* Set the last buffer to wrap.*/
-+ bdp--;
-+ bdp->cbd_sc |= BD_SC_WRAP;
-+
-+ fep->full_duplex = duplex;
-+
-+ /* And last, enable the transmit and receive processing.*/
-+ fecp->fec_r_buff_size = RX_BUFFER_SIZE;
-+ fecp->fec_r_des_active = MCF_ESW_RDAR_R_DES_ACTIVE;
-+
-+ /* Enable interrupts we wish to service.
-+ */
-+ fecp->switch_ievent = 0xffffffff;
-+ fecp->switch_imask = MCF_ESW_IMR_RXF | MCF_ESW_IMR_TXF |
-+ MCF_ESW_IMR_RXB | MCF_ESW_IMR_TXB;
-+}
-+
-+static void switch_stop(struct net_device *dev)
-+{
-+ volatile switch_t *fecp;
-+ struct switch_enet_private *fep;
-+ struct coldfire_switch_platform_data *plat;
-+
-+ fep = netdev_priv(dev);
-+ fecp = fep->hwp;
-+ plat = fep->pdev->dev.platform_data;
-+ /*
-+ ** We cannot expect a graceful transmit stop without link !!!
-+ */
-+ if (fep->phy1_link)
-+ udelay(10);
-+ if (fep->phy2_link)
-+ udelay(10);
-+
-+ /* Whack a reset. We should wait for this.
-+ */
-+ udelay(10);
-+}
-+
-+static int fec_mdio_register(struct net_device *dev)
-+{
-+ int err = 0;
-+ struct switch_enet_private *fep = netdev_priv(dev);
-+
-+ fep->mdio_bus = mdiobus_alloc();
-+ if (!fep->mdio_bus) {
-+ printk(KERN_ERR "ethernet switch mdiobus_alloc fail\n");
-+ return -ENOMEM;
-+ }
-+
-+ fep->mdio_bus->name = "Coldfire switch MII 0 Bus";
-+ strcpy(fep->mdio_bus->id, "0");
-+
-+ fep->mdio_bus->read = &coldfire_fec_mdio_read;
-+ fep->mdio_bus->write = &coldfire_fec_mdio_write;
-+ fep->mdio_bus->priv = dev;
-+ err = mdiobus_register(fep->mdio_bus);
-+ if (err) {
-+ mdiobus_free(fep->mdio_bus);
-+ printk(KERN_ERR "%s: ethernet mdiobus_register fail\n",
-+ dev->name);
-+ return -EIO;
-+ }
-+
-+ printk(KERN_INFO "mdiobus_register %s ok\n",
-+ fep->mdio_bus->name);
-+ return err;
-+}
-+
-+static int __devinit eth_switch_probe(struct platform_device *pdev)
-+{
-+ struct net_device *dev;
-+ int err;
-+ struct switch_enet_private *fep;
-+ struct task_struct *task;
-+
-+ printk(KERN_INFO "Ethernet Switch Version 1.0\n");
-+
-+ dev = alloc_etherdev(sizeof(struct switch_enet_private));
-+ if (!dev) {
-+ printk(KERN_ERR "%s: ethernet switch alloc_etherdev fail\n",
-+ dev->name);
-+ return -ENOMEM;
-+ }
-+
-+ SET_NETDEV_DEV(dev, &pdev->dev);
-+
-+ fep = netdev_priv(dev);
-+ memset(fep, 0, sizeof(*fep));
-+
-+ fep->pdev = pdev;
-+ platform_set_drvdata(pdev, dev);
-+ printk(KERN_ERR "%s: ethernet switch port 0 init\n",
-+ __func__);
-+ err = switch_enet_init(pdev);
-+ if (err) {
-+ free_netdev(dev);
-+ platform_set_drvdata(pdev, NULL);
-+ }
-+
-+ err = fec_mdio_register(dev);
-+ if (err) {
-+ printk(KERN_ERR "%s: ethernet switch fec_mdio_register\n",
-+ dev->name);
-+ free_netdev(dev);
-+ platform_set_drvdata(pdev, NULL);
-+ return -ENOMEM;
-+ }
-+
-+ /* setup timer for Learning Aging function */
-+ init_timer(&fep->timer_aging);
-+ fep->timer_aging.function = l2switch_aging_timer;
-+ fep->timer_aging.data = (unsigned long) fep;
-+ fep->timer_aging.expires = jiffies + LEARNING_AGING_TIMER;
-+ add_timer(&fep->timer_aging);
-+
-+ /* register network device*/
-+ if (register_netdev(dev) != 0) {
-+ /* XXX: missing cleanup here */
-+ free_netdev(dev);
-+ platform_set_drvdata(pdev, NULL);
-+ printk(KERN_ERR "%s: ethernet switch register_netdev fail\n",
-+ dev->name);
-+ return -EIO;
-+ }
-+
-+ task = kthread_run(switch_enet_learning, fep,
-+ "modelo l2switch");
-+ if (IS_ERR(task)) {
-+ err = PTR_ERR(task);
-+ return err;
-+ }
-+
-+ printk(KERN_INFO "%s: ethernet switch %pM\n",
-+ dev->name, dev->dev_addr);
-+ return 0;
-+}
-+
-+static int __devexit eth_switch_remove(struct platform_device *pdev)
-+{
-+ int i;
-+ struct net_device *dev;
-+ struct switch_enet_private *fep;
-+ struct switch_platform_private *chip;
-+
-+ chip = platform_get_drvdata(pdev);
-+ if (chip) {
-+ for (i = 0; i < chip->num_slots; i++) {
-+ fep = chip->fep_host[i];
-+ dev = fep->netdev;
-+ fep->sequence_done = 1;
-+ unregister_netdev(dev);
-+ free_netdev(dev);
-+
-+ del_timer_sync(&fep->timer_aging);
-+ }
-+
-+ platform_set_drvdata(pdev, NULL);
-+ kfree(chip);
-+
-+ } else
-+ printk(KERN_ERR "%s: can not get the "
-+ "switch_platform_private %x\n", __func__,
-+ (unsigned int)chip);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver eth_switch_driver = {
-+ .probe = eth_switch_probe,
-+ .remove = __devexit_p(eth_switch_remove),
-+ .driver = {
-+ .name = "coldfire-switch",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __init coldfire_switch_init(void)
-+{
-+ return platform_driver_register(&eth_switch_driver);
-+}
-+
-+static void __exit coldfire_switch_exit(void)
-+{
-+ platform_driver_unregister(&eth_switch_driver);
-+}
-+
-+module_init(coldfire_switch_init);
-+module_exit(coldfire_switch_exit);
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/net/modelo_switch.h
-@@ -0,0 +1,1141 @@
-+/****************************************************************************/
-+
-+/*
-+ * mcfswitch -- L2 Switch Controller for Modelo ColdFire SoC
-+ * processors.
-+ *
-+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at
-+ * your option) any later version.
-+ *
-+ */
-+
-+/****************************************************************************/
-+#ifndef SWITCH_H
-+#define SWITCH_H
-+/****************************************************************************/
-+/* The Switch stores dest/src/type, data, and checksum for receive packets.
-+ */
-+#define PKT_MAXBUF_SIZE 1518
-+#define PKT_MINBUF_SIZE 64
-+#define PKT_MAXBLR_SIZE 1520
-+
-+/*
-+ * The 5441x RX control register also contains maximum frame
-+ * size bits.
-+ */
-+#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
-+
-+/*
-+ * Some hardware gets it MAC address out of local flash memory.
-+ * if this is non-zero then assume it is the address to get MAC from.
-+ */
-+#define FEC_FLASHMAC 0
-+
-+/* The number of Tx and Rx buffers. These are allocated from the page
-+ * pool. The code may assume these are power of two, so it it best
-+ * to keep them that size.
-+ * We don't need to allocate pages for the transmitter. We just use
-+ * the skbuffer directly.
-+ */
-+#ifdef CONFIG_SWITCH_DMA_USE_SRAM
-+#define SWITCH_ENET_RX_PAGES 6
-+#else
-+#define SWITCH_ENET_RX_PAGES 8
-+#endif
-+
-+#define SWITCH_ENET_RX_FRSIZE 2048
-+#define SWITCH_ENET_RX_FRPPG (PAGE_SIZE / SWITCH_ENET_RX_FRSIZE)
-+#define RX_RING_SIZE (SWITCH_ENET_RX_FRPPG * SWITCH_ENET_RX_PAGES)
-+#define SWITCH_ENET_TX_FRSIZE 2048
-+#define SWITCH_ENET_TX_FRPPG (PAGE_SIZE / SWITCH_ENET_TX_FRSIZE)
-+
-+#ifdef CONFIG_SWITCH_DMA_USE_SRAM
-+#define TX_RING_SIZE 8 /* Must be power of two */
-+#define TX_RING_MOD_MASK 7 /* for this to work */
-+#else
-+#define TX_RING_SIZE 16 /* Must be power of two */
-+#define TX_RING_MOD_MASK 15 /* for this to work */
-+#endif
-+
-+#define SWITCH_EPORT_NUMBER 2
-+
-+#if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
-+#error "L2SWITCH: descriptor ring size constants too large"
-+#endif
-+/*-----------------------------------------------------------------------*/
-+typedef struct l2switch_output_queue_status {
-+ unsigned long ESW_MMSR;
-+ unsigned long ESW_LMT;
-+ unsigned long ESW_LFC;
-+ unsigned long ESW_PCSR;
-+ unsigned long ESW_IOSR;
-+ unsigned long ESW_QWT;
-+ unsigned long esw_reserved;
-+ unsigned long ESW_P0BCT;
-+} esw_output_queue_status;
-+
-+typedef struct l2switch_statistics_status {
-+ /*
-+ * Total number of incoming frames processed
-+ * but discarded in switch
-+ */
-+ unsigned long ESW_DISCN;
-+ /*Sum of bytes of frames counted in ESW_DISCN*/
-+ unsigned long ESW_DISCB;
-+ /*
-+ * Total number of incoming frames processed
-+ * but not discarded in switch
-+ */
-+ unsigned long ESW_NDISCN;
-+ /*Sum of bytes of frames counted in ESW_NDISCN*/
-+ unsigned long ESW_NDISCB;
-+} esw_statistics_status;
-+
-+typedef struct l2switch_port_statistics_status {
-+ /*outgoing frames discarded due to transmit queue congestion*/
-+ unsigned long MCF_ESW_POQC;
-+ /*incoming frames discarded due to VLAN domain mismatch*/
-+ unsigned long MCF_ESW_PMVID;
-+ /*incoming frames discarded due to untagged discard*/
-+ unsigned long MCF_ESW_PMVTAG;
-+ /*incoming frames discarded due port is in blocking state*/
-+ unsigned long MCF_ESW_PBL;
-+} esw_port_statistics_status;
-+
-+typedef struct l2switch {
-+ unsigned long ESW_REVISION;
-+ unsigned long ESW_SCRATCH;
-+ unsigned long ESW_PER;
-+ unsigned long reserved0[1];
-+ unsigned long ESW_VLANV;
-+ unsigned long ESW_DBCR;
-+ unsigned long ESW_DMCR;
-+ unsigned long ESW_BKLR;
-+ unsigned long ESW_BMPC;
-+ unsigned long ESW_MODE;
-+ unsigned long ESW_VIMSEL;
-+ unsigned long ESW_VOMSEL;
-+ unsigned long ESW_VIMEN;
-+ unsigned long ESW_VID;/*0x34*/
-+ /*from 0x38 0x3C*/
-+ unsigned long esw_reserved0[2];
-+ unsigned long ESW_MCR;/*0x40*/
-+ unsigned long ESW_EGMAP;
-+ unsigned long ESW_INGMAP;
-+ unsigned long ESW_INGSAL;
-+ unsigned long ESW_INGSAH;
-+ unsigned long ESW_INGDAL;
-+ unsigned long ESW_INGDAH;
-+ unsigned long ESW_ENGSAL;
-+ unsigned long ESW_ENGSAH;
-+ unsigned long ESW_ENGDAL;
-+ unsigned long ESW_ENGDAH;
-+ unsigned long ESW_MCVAL;/*0x6C*/
-+ /*from 0x70--0x7C*/
-+ unsigned long esw_reserved1[4];
-+ unsigned long ESW_MMSR;/*0x80*/
-+ unsigned long ESW_LMT;
-+ unsigned long ESW_LFC;
-+ unsigned long ESW_PCSR;
-+ unsigned long ESW_IOSR;
-+ unsigned long ESW_QWT;/*0x94*/
-+ unsigned long esw_reserved2[1];/*0x98*/
-+ unsigned long ESW_P0BCT;/*0x9C*/
-+ /*from 0xA0-0xB8*/
-+ unsigned long esw_reserved3[7];
-+ unsigned long ESW_P0FFEN;/*0xBC*/
-+ unsigned long ESW_PSNP[8];
-+ unsigned long ESW_IPSNP[8];
-+ /*port0-port2 VLAN Priority resolution map 0xFC0D_C100-C108*/
-+ unsigned long ESW_PVRES[3];
-+ /*from 0x10C-0x13C*/
-+ unsigned long esw_reserved4[13];
-+ unsigned long ESW_IPRES;/*0x140*/
-+ /*from 0x144-0x17C*/
-+ unsigned long esw_reserved5[15];
-+
-+ /*port0-port2 Priority Configuration 0xFC0D_C180-C188*/
-+ unsigned long ESW_PRES[3];
-+ /*from 0x18C-0x1FC*/
-+ unsigned long esw_reserved6[29];
-+
-+ /*port0-port2 VLAN ID 0xFC0D_C200-C208*/
-+ unsigned long ESW_PID[3];
-+ /*from 0x20C-0x27C*/
-+ unsigned long esw_reserved7[29];
-+
-+ /*port0-port2 VLAN domain resolution entry 0xFC0D_C280-C2FC*/
-+ unsigned long ESW_VRES[32];
-+
-+ unsigned long ESW_DISCN;/*0x300*/
-+ unsigned long ESW_DISCB;
-+ unsigned long ESW_NDISCN;
-+ unsigned long ESW_NDISCB;/*0xFC0DC30C*/
-+ /*per port statistics 0xFC0DC310_C33C*/
-+ esw_port_statistics_status port_statistics_status[3];
-+ /*from 0x340-0x400*/
-+ unsigned long esw_reserved8[48];
-+
-+ /*0xFC0DC400---0xFC0DC418*/
-+ /*unsigned long MCF_ESW_ISR;*/
-+ unsigned long switch_ievent; /* Interrupt event reg */
-+ /*unsigned long MCF_ESW_IMR;*/
-+ unsigned long switch_imask; /* Interrupt mask reg */
-+ /*unsigned long MCF_ESW_RDSR;*/
-+ unsigned long fec_r_des_start; /* Receive descriptor ring */
-+ /*unsigned long MCF_ESW_TDSR;*/
-+ unsigned long fec_x_des_start; /* Transmit descriptor ring */
-+ /*unsigned long MCF_ESW_MRBR;*/
-+ unsigned long fec_r_buff_size; /* Maximum receive buff size */
-+ /*unsigned long MCF_ESW_RDAR;*/
-+ unsigned long fec_r_des_active; /* Receive descriptor reg */
-+ /*unsigned long MCF_ESW_TDAR;*/
-+ unsigned long fec_x_des_active; /* Transmit descriptor reg */
-+ /*from 0x420-0x4FC*/
-+ unsigned long esw_reserved9[57];
-+
-+ /*0xFC0DC500---0xFC0DC508*/
-+ unsigned long ESW_LREC0;
-+ unsigned long ESW_LREC1;
-+ unsigned long ESW_LSR;
-+} switch_t;
-+
-+typedef struct _64bTableEntry {
-+ unsigned int lo; /* lower 32 bits */
-+ unsigned int hi; /* upper 32 bits */
-+} AddrTable64bEntry;
-+
-+typedef struct l2switchaddrtable {
-+ AddrTable64bEntry eswTable64bEntry[2048];
-+} eswAddrTable_t;
-+
-+/*unsigned long MCF_ESW_LOOKUP_MEM;*/
-+#define MCF_ESW_REVISION (*(volatile unsigned long *)(0xFC0DC000))
-+#define MCF_ESW_PER (*(volatile unsigned long *)(0xFC0DC008))
-+#define MCF_ESW_VLANV (*(volatile unsigned long *)(0xFC0DC010))
-+#define MCF_ESW_DBCR (*(volatile unsigned long *)(0xFC0DC014))
-+#define MCF_ESW_DMCR (*(volatile unsigned long *)(0xFC0DC018))
-+#define MCF_ESW_BKLR (*(volatile unsigned long *)(0xFC0DC01C))
-+#define MCF_ESW_BMPC (*(volatile unsigned long *)(0xFC0DC020))
-+#define MCF_ESW_MODE (*(volatile unsigned long *)(0xFC0DC024))
-+
-+#define MCF_ESW_ISR (*(volatile unsigned long *)(0xFC0DC400))
-+#define MCF_ESW_IMR (*(volatile unsigned long *)(0xFC0DC404))
-+#define MCF_ESW_TDAR (*(volatile unsigned long *)(0xFC0DC418))
-+#define MCF_ESW_LOOKUP_MEM (*(volatile unsigned long *)(0xFC0E0000))
-+
-+#define MCF_PPMCR0 (*(volatile unsigned short *)(0xFC04002D))
-+#define MCF_PPMHR0 (*(volatile unsigned long *)(0xFC040030))
-+
-+#define MCF_FEC_EIR0 (*(volatile unsigned long *)(0xFC0D4004))
-+#define MCF_FEC_EIR1 (*(volatile unsigned long *)(0xFC0D8004))
-+#define MCF_FEC_EIMR0 (*(volatile unsigned long *)(0xFC0D4008))
-+#define MCF_FEC_EIMR1 (*(volatile unsigned long *)(0xFC0D8008))
-+#define MCF_FEC_MMFR0 (*(volatile unsigned long *)(0xFC0D4040))
-+#define MCF_FEC_MMFR1 (*(volatile unsigned long *)(0xFC0D8040))
-+#define MCF_FEC_MSCR0 (*(volatile unsigned long *)(0xFC0D4044))
-+#define MCF_FEC_MSCR1 (*(volatile unsigned long *)(0xFC0D8044))
-+#define MCF_FEC_RCR0 (*(volatile unsigned long *)(0xFC0D4084))
-+#define MCF_FEC_RCR1 (*(volatile unsigned long *)(0xFC0D8084))
-+#define MCF_FEC_TCR0 (*(volatile unsigned long *)(0xFC0D40C4))
-+#define MCF_FEC_TCR1 (*(volatile unsigned long *)(0xFC0D80C4))
-+#define MCF_FEC_ECR0 (*(volatile unsigned long *)(0xFC0D4024))
-+#define MCF_FEC_ECR1 (*(volatile unsigned long *)(0xFC0D8024))
-+
-+
-+#define MCF_FEC_RCR_PROM (0x00000008)
-+#define MCF_FEC_RCR_RMII_MODE (0x00000100)
-+#define MCF_FEC_RCR_MAX_FL(x) (((x)&0x00003FFF)<<16)
-+#define MCF_FEC_RCR_CRC_FWD (0x00004000)
-+
-+#define MCF_FEC_TCR_FDEN (0x00000004)
-+
-+#define MCF_FEC_ECR_ETHER_EN (0x00000002)
-+#define MCF_FEC_ECR_ENA_1588 (0x00000010)
-+
-+/*-------------ioctl command ---------------------------------------*/
-+#define ESW_SET_LEARNING_CONF 0x9101
-+#define ESW_GET_LEARNING_CONF 0x9201
-+#define ESW_SET_BLOCKING_CONF 0x9102
-+#define ESW_GET_BLOCKING_CONF 0x9202
-+#define ESW_SET_MULTICAST_CONF 0x9103
-+#define ESW_GET_MULTICAST_CONF 0x9203
-+#define ESW_SET_BROADCAST_CONF 0x9104
-+#define ESW_GET_BROADCAST_CONF 0x9204
-+#define ESW_SET_PORTENABLE_CONF 0x9105
-+#define ESW_GET_PORTENABLE_CONF 0x9205
-+#define ESW_SET_IP_SNOOP_CONF 0x9106
-+#define ESW_GET_IP_SNOOP_CONF 0x9206
-+#define ESW_SET_PORT_SNOOP_CONF 0x9107
-+#define ESW_GET_PORT_SNOOP_CONF 0x9207
-+#define ESW_SET_PORT_MIRROR_CONF 0x9108
-+#define ESW_GET_PORT_MIRROR_CONF 0x9208
-+#define ESW_SET_PIRORITY_VLAN 0x9109
-+#define ESW_GET_PIRORITY_VLAN 0x9209
-+#define ESW_SET_PIRORITY_IP 0x910A
-+#define ESW_GET_PIRORITY_IP 0x920A
-+#define ESW_SET_PIRORITY_MAC 0x910B
-+#define ESW_GET_PIRORITY_MAC 0x920B
-+#define ESW_SET_PIRORITY_DEFAULT 0x910C
-+#define ESW_GET_PIRORITY_DEFAULT 0x920C
-+#define ESW_SET_P0_FORCED_FORWARD 0x910D
-+#define ESW_GET_P0_FORCED_FORWARD 0x920D
-+#define ESW_SET_SWITCH_MODE 0x910E
-+#define ESW_GET_SWITCH_MODE 0x920E
-+#define ESW_SET_BRIDGE_CONFIG 0x910F
-+#define ESW_GET_BRIDGE_CONFIG 0x920F
-+#define ESW_SET_VLAN_OUTPUT_PROCESS 0x9110
-+#define ESW_GET_VLAN_OUTPUT_PROCESS 0x9210
-+#define ESW_SET_VLAN_INPUT_PROCESS 0x9111
-+#define ESW_GET_VLAN_INPUT_PROCESS 0x9211
-+#define ESW_SET_VLAN_DOMAIN_VERIFICATION 0x9112
-+#define ESW_GET_VLAN_DOMAIN_VERIFICATION 0x9212
-+#define ESW_SET_VLAN_RESOLUTION_TABLE 0x9113
-+#define ESW_GET_VLAN_RESOLUTION_TABLE 0x9213
-+#define ESW_GET_ENTRY_PORT_NUMBER 0x9214
-+#define ESW_GET_LOOKUP_TABLE 0x9215
-+#define ESW_GET_PORT_STATUS 0x9216
-+#define ESW_SET_VLAN_ID 0x9114
-+#define ESW_SET_VLAN_ID_CLEARED 0x9115
-+#define ESW_SET_PORT_IN_VLAN_ID 0x9116
-+#define ESW_SET_PORT_ENTRY_EMPTY 0x9117
-+#define ESW_SET_OTHER_PORT_ENTRY_EMPTY 0x9118
-+#define ESW_GET_PORT_ALL_STATUS 0x9217
-+#define ESW_SET_PORT_MIRROR_CONF_PORT_MATCH 0x9119
-+#define ESW_SET_PORT_MIRROR_CONF_ADDR_MATCH 0x911A
-+
-+#define ESW_GET_STATISTICS_STATUS 0x9221
-+#define ESW_SET_OUTPUT_QUEUE_MEMORY 0x9125
-+#define ESW_GET_OUTPUT_QUEUE_STATUS 0x9225
-+#define ESW_UPDATE_STATIC_MACTABLE 0x9226
-+#define ESW_CLEAR_ALL_MACTABLE 0x9227
-+#define ESW_GET_USER_PID 0x9228
-+
-+typedef struct _eswIOCTL_PORT_CONF {
-+ int port;
-+ int enable;
-+} eswIoctlPortConfig;
-+
-+typedef struct _eswIOCTL_PORT_EN_CONF {
-+ int port;
-+ int tx_enable;
-+ int rx_enable;
-+} eswIoctlPortEnableConfig;
-+
-+typedef struct _eswIOCTL_IP_SNOOP_CONF {
-+ int mode;
-+ unsigned long ip_header_protocol;
-+} eswIoctlIpsnoopConfig;
-+
-+typedef struct _eswIOCTL_P0_FORCED_FORWARD_CONF {
-+ int port1;
-+ int port2;
-+ int enable;
-+} eswIoctlP0ForcedForwardConfig;
-+
-+typedef struct _eswIOCTL_PORT_SNOOP_CONF {
-+ int mode;
-+ unsigned short compare_port;
-+ int compare_num;
-+} eswIoctlPortsnoopConfig;
-+
-+typedef struct _eswIOCTL_PORT_Mirror_CONF {
-+ int mirror_port;
-+ int port;
-+ int egress_en;
-+ int ingress_en;
-+ int egress_mac_src_en;
-+ int egress_mac_des_en;
-+ int ingress_mac_src_en;
-+ int ingress_mac_des_en;
-+ unsigned char *src_mac;
-+ unsigned char *des_mac;
-+ int mirror_enable;
-+} eswIoctlPortMirrorConfig;
-+
-+struct eswIoctlMirrorCfgPortMatch {
-+ int mirror_port;
-+ int port_match_en;
-+ int port;
-+};
-+
-+struct eswIoctlMirrorCfgAddrMatch {
-+ int mirror_port;
-+ int addr_match_en;
-+ unsigned char *mac_addr;
-+};
-+
-+typedef struct _eswIOCTL_PRIORITY_VLAN_CONF {
-+ int port;
-+ int func_enable;
-+ int vlan_pri_table_num;
-+ int vlan_pri_table_value;
-+} eswIoctlPriorityVlanConfig;
-+
-+typedef struct _eswIOCTL_PRIORITY_IP_CONF {
-+ int port;
-+ int func_enable;
-+ int ipv4_en;
-+ int ip_priority_num;
-+ int ip_priority_value;
-+} eswIoctlPriorityIPConfig;
-+
-+typedef struct _eswIOCTL_PRIORITY_MAC_CONF {
-+ int port;
-+} eswIoctlPriorityMacConfig;
-+
-+typedef struct _eswIOCTL_PRIORITY_DEFAULT_CONF {
-+ int port;
-+ unsigned char priority_value;
-+} eswIoctlPriorityDefaultConfig;
-+
-+typedef struct _eswIOCTL_IRQ_STATUS {
-+ unsigned long isr;
-+ unsigned long imr;
-+ unsigned long rx_buf_pointer;
-+ unsigned long tx_buf_pointer;
-+ unsigned long rx_max_size;
-+ unsigned long rx_buf_active;
-+ unsigned long tx_buf_active;
-+} eswIoctlIrqStatus;
-+
-+typedef struct _eswIOCTL_PORT_Mirror_STATUS {
-+ unsigned long ESW_MCR;
-+ unsigned long ESW_EGMAP;
-+ unsigned long ESW_INGMAP;
-+ unsigned long ESW_INGSAL;
-+ unsigned long ESW_INGSAH;
-+ unsigned long ESW_INGDAL;
-+ unsigned long ESW_INGDAH;
-+ unsigned long ESW_ENGSAL;
-+ unsigned long ESW_ENGSAH;
-+ unsigned long ESW_ENGDAL;
-+ unsigned long ESW_ENGDAH;
-+ unsigned long ESW_MCVAL;
-+} eswIoctlPortMirrorStatus;
-+
-+typedef struct _eswIOCTL_VLAN_OUTPUT_CONF {
-+ int port;
-+ int mode;
-+} eswIoctlVlanOutputConfig;
-+
-+typedef struct _eswIOCTL_VLAN_INPUT_CONF {
-+ int port;
-+ int mode;
-+ unsigned short port_vlanid;
-+} eswIoctlVlanInputConfig;
-+
-+typedef struct _eswIOCTL_VLAN_DOMAIN_VERIFY_CONF {
-+ int port;
-+ int vlan_domain_verify_en;
-+ int vlan_discard_unknown_en;
-+} eswIoctlVlanVerificationConfig;
-+
-+typedef struct _eswIOCTL_VLAN_RESOULATION_TABLE {
-+ unsigned short port_vlanid;
-+ unsigned char vlan_domain_port;
-+ unsigned char vlan_domain_num;
-+} eswIoctlVlanResoultionTable;
-+
-+struct eswVlanTableItem {
-+ eswIoctlVlanResoultionTable table[32];
-+ unsigned char valid_num;
-+};
-+
-+typedef struct _eswIOCTL_VLAN_INPUT_STATUS {
-+ unsigned long ESW_VLANV;
-+ unsigned long ESW_PID[3];
-+ unsigned long ESW_VIMSEL;
-+ unsigned long ESW_VIMEN;
-+ unsigned long ESW_VRES[32];
-+} eswIoctlVlanInputStatus;
-+
-+typedef struct _eswIOCTL_Static_MACTable {
-+ unsigned char *mac_addr;
-+ int port;
-+ int priority;
-+} eswIoctlUpdateStaticMACtable;
-+
-+typedef struct _eswIOCTL_OUTPUT_QUEUE {
-+ int fun_num;
-+ esw_output_queue_status sOutputQueue;
-+} eswIoctlOutputQueue;
-+
-+/*=============================================================*/
-+#define LEARNING_AGING_TIMER (10 * HZ)
-+/*
-+ * Info received from Hardware Learning FIFO,
-+ * holding MAC address and corresponding Hash Value and
-+ * port number where the frame was received (disassembled).
-+ */
-+typedef struct _eswPortInfo {
-+ /* MAC lower 32 bits (first byte is 7:0). */
-+ unsigned int maclo;
-+ /* MAC upper 16 bits (47:32). */
-+ unsigned int machi;
-+ /* the hash value for this MAC address. */
-+ unsigned int hash;
-+ /* the port number this MAC address is associated with. */
-+ unsigned int port;
-+} eswPortInfo;
-+
-+/*
-+ * Hardware Look up Address Table 64-bit element.
-+ */
-+typedef volatile struct _64bitTableEntry {
-+ unsigned int lo; /* lower 32 bits */
-+ unsigned int hi; /* upper 32 bits */
-+} eswTable64bitEntry;
-+
-+struct eswAddrTableEntryExample {
-+ /* the entry number */
-+ unsigned short entrynum;
-+ /* mac address array */
-+ unsigned char mac_addr[6];
-+ unsigned char item1;
-+ unsigned short item2;
-+};
-+
-+/*
-+ * Define the buffer descriptor structure.
-+ */
-+typedef struct bufdesc {
-+ unsigned short cbd_sc; /* Control and status info */
-+ unsigned short cbd_datlen; /* Data length */
-+ unsigned long cbd_bufaddr; /* Buffer address */
-+#ifdef MODELO_BUFFER
-+ unsigned long ebd_status;
-+ unsigned short length_proto_type;
-+ unsigned short payload_checksum;
-+ unsigned long bdu;
-+ unsigned long timestamp;
-+ unsigned long reserverd_word1;
-+ unsigned long reserverd_word2;
-+#endif
-+} cbd_t;
-+
-+/* Forward declarations of some structures to support different PHYs
-+ */
-+typedef struct {
-+ uint mii_data;
-+ void (*funct)(uint mii_reg, struct net_device *dev);
-+} phy_cmd_t;
-+
-+typedef struct {
-+ uint id;
-+ char *name;
-+
-+ const phy_cmd_t *config;
-+ const phy_cmd_t *startup;
-+ const phy_cmd_t *ack_int;
-+ const phy_cmd_t *shutdown;
-+} phy_info_t;
-+
-+struct port_status {
-+ /* 1: link is up, 0: link is down */
-+ int port1_link_status;
-+ int port2_link_status;
-+ /* 1: blocking, 0: unblocking */
-+ int port0_block_status;
-+ int port1_block_status;
-+ int port2_block_status;
-+};
-+
-+struct port_all_status {
-+ /* 1: link is up, 0: link is down */
-+ int link_status;
-+ /* 1: blocking, 0: unblocking */
-+ int block_status;
-+ /* 1: unlearning, 0: learning */
-+ int learn_status;
-+ /* vlan domain verify 1: enable 0: disable */
-+ int vlan_verify;
-+ /* discard unknow 1: enable 0: disable */
-+ int discard_unknown;
-+ /* multicast resolution 1: enable 0: disable */
-+ int multi_reso;
-+ /* broadcast resolution 1: enable 0: disalbe */
-+ int broad_reso;
-+ /* transmit 1: enable 0: disable */
-+ int ftransmit;
-+ /* receive 1: enable 0: disable */
-+ int freceive;
-+};
-+
-+/* The switch buffer descriptors track the ring buffers. The rx_bd_base and
-+ * tx_bd_base always point to the base of the buffer descriptors. The
-+ * cur_rx and cur_tx point to the currently available buffer.
-+ * The dirty_tx tracks the current buffer that is being sent by the
-+ * controller. The cur_tx and dirty_tx are equal under both completely
-+ * empty and completely full conditions. The empty/ready indicator in
-+ * the buffer descriptor determines the actual condition.
-+ */
-+struct switch_enet_private {
-+ /* Hardware registers of the switch device */
-+ volatile switch_t *hwp;
-+ volatile eswAddrTable_t *hwentry;
-+
-+ struct net_device *netdev;
-+ struct platform_device *pdev;
-+ /* The saved address of a sent-in-place packet/buffer, for skfree(). */
-+ unsigned char *tx_bounce[TX_RING_SIZE];
-+ struct sk_buff *tx_skbuff[TX_RING_SIZE];
-+ ushort skb_cur;
-+ ushort skb_dirty;
-+
-+ /* CPM dual port RAM relative addresses.
-+ */
-+ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
-+ cbd_t *tx_bd_base;
-+ cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
-+ cbd_t *dirty_tx; /* The ring entries to be free()ed. */
-+ uint tx_full;
-+ /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
-+ spinlock_t hw_lock;
-+
-+ /* hold while accessing the mii_list_t() elements */
-+ spinlock_t mii_lock;
-+ struct mii_bus *mdio_bus;
-+ struct phy_device *phydev[SWITCH_EPORT_NUMBER];
-+
-+ uint phy_id;
-+ uint phy_id_done;
-+ uint phy_status;
-+ uint phy_speed;
-+ phy_info_t const *phy;
-+ struct work_struct phy_task;
-+ volatile switch_t *phy_hwp;
-+
-+ uint sequence_done;
-+ uint mii_phy_task_queued;
-+
-+ uint phy_addr;
-+
-+ int index;
-+ int opened;
-+ int full_duplex;
-+ int msg_enable;
-+ int phy1_link;
-+ int phy1_old_link;
-+ int phy1_duplex;
-+ int phy1_speed;
-+
-+ int phy2_link;
-+ int phy2_old_link;
-+ int phy2_duplex;
-+ int phy2_speed;
-+ /* --------------Statistics--------------------------- */
-+ /* when a new element deleted a element with in
-+ * a block due to lack of space */
-+ int atBlockOverflows;
-+ /* Peak number of valid entries in the address table */
-+ int atMaxEntries;
-+ /* current number of valid entries in the address table */
-+ int atCurrEntries;
-+ /* maximum entries within a block found
-+ * (updated within ageing)*/
-+ int atMaxEntriesPerBlock;
-+
-+ /* -------------------ageing function------------------ */
-+ /* maximum age allowed for an entry */
-+ int ageMax;
-+ /* last LUT entry to block that was
-+ * inspected by the Ageing task*/
-+ int ageLutIdx;
-+ /* last element within block inspected by the Ageing task */
-+ int ageBlockElemIdx;
-+ /* complete table has been processed by ageing process */
-+ int ageCompleted;
-+ /* delay setting */
-+ int ageDelay;
-+ /* current delay Counter */
-+ int ageDelayCnt;
-+
-+ /* ----------------timer related---------------------------- */
-+ /* current time (for timestamping) */
-+ int currTime;
-+ /* flag set by timer when currTime changed
-+ * and cleared by serving function*/
-+ int timeChanged;
-+
-+ /**/
-+ /* Timer for Aging */
-+ struct timer_list timer_aging;
-+ int learning_irqhandle_enable;
-+};
-+
-+struct switch_platform_private {
-+ unsigned long quirks;
-+ int num_slots; /* Slots on controller */
-+ struct switch_enet_private *fep_host[0]; /* Pointers to hosts */
-+};
-+
-+/******************************************************************************/
-+/* Recieve is empty */
-+#define BD_SC_EMPTY ((unsigned short)0x8000)
-+/* Transmit is ready */
-+#define BD_SC_READY ((unsigned short)0x8000)
-+/* Last buffer descriptor */
-+#define BD_SC_WRAP ((unsigned short)0x2000)
-+/* Interrupt on change */
-+#define BD_SC_INTRPT ((unsigned short)0x1000)
-+/* Continous mode */
-+#define BD_SC_CM ((unsigned short)0x0200)
-+/* Rec'd too many idles */
-+#define BD_SC_ID ((unsigned short)0x0100)
-+/* xmt preamble */
-+#define BD_SC_P ((unsigned short)0x0100)
-+/* Break received */
-+#define BD_SC_BR ((unsigned short)0x0020)
-+/* Framing error */
-+#define BD_SC_FR ((unsigned short)0x0010)
-+/* Parity error */
-+#define BD_SC_PR ((unsigned short)0x0008)
-+/* Overrun */
-+#define BD_SC_OV ((unsigned short)0x0002)
-+#define BD_SC_CD ((unsigned short)0x0001)
-+
-+/* Buffer descriptor control/status used by Ethernet receive.
-+*/
-+#define BD_ENET_RX_EMPTY ((unsigned short)0x8000)
-+#define BD_ENET_RX_WRAP ((unsigned short)0x2000)
-+#define BD_ENET_RX_INTR ((unsigned short)0x1000)
-+#define BD_ENET_RX_LAST ((unsigned short)0x0800)
-+#define BD_ENET_RX_FIRST ((unsigned short)0x0400)
-+#define BD_ENET_RX_MISS ((unsigned short)0x0100)
-+#define BD_ENET_RX_LG ((unsigned short)0x0020)
-+#define BD_ENET_RX_NO ((unsigned short)0x0010)
-+#define BD_ENET_RX_SH ((unsigned short)0x0008)
-+#define BD_ENET_RX_CR ((unsigned short)0x0004)
-+#define BD_ENET_RX_OV ((unsigned short)0x0002)
-+#define BD_ENET_RX_CL ((unsigned short)0x0001)
-+/* All status bits */
-+#define BD_ENET_RX_STATS ((unsigned short)0x013f)
-+
-+/* Buffer descriptor control/status used by Ethernet transmit.
-+*/
-+#define BD_ENET_TX_READY ((unsigned short)0x8000)
-+#define BD_ENET_TX_PAD ((unsigned short)0x4000)
-+#define BD_ENET_TX_WRAP ((unsigned short)0x2000)
-+#define BD_ENET_TX_INTR ((unsigned short)0x1000)
-+#define BD_ENET_TX_LAST ((unsigned short)0x0800)
-+#define BD_ENET_TX_TC ((unsigned short)0x0400)
-+#define BD_ENET_TX_DEF ((unsigned short)0x0200)
-+#define BD_ENET_TX_HB ((unsigned short)0x0100)
-+#define BD_ENET_TX_LC ((unsigned short)0x0080)
-+#define BD_ENET_TX_RL ((unsigned short)0x0040)
-+#define BD_ENET_TX_RCMASK ((unsigned short)0x003c)
-+#define BD_ENET_TX_UN ((unsigned short)0x0002)
-+#define BD_ENET_TX_CSL ((unsigned short)0x0001)
-+/* All status bits */
-+#define BD_ENET_TX_STATS ((unsigned short)0x03ff)
-+
-+/*Copy from validation code */
-+#define RX_BUFFER_SIZE 1520
-+#define TX_BUFFER_SIZE 1520
-+#define NUM_RXBDS 20
-+#define NUM_TXBDS 20
-+
-+#define TX_BD_R 0x8000
-+#define TX_BD_TO1 0x4000
-+#define TX_BD_W 0x2000
-+#define TX_BD_TO2 0x1000
-+#define TX_BD_L 0x0800
-+#define TX_BD_TC 0x0400
-+
-+#define TX_BD_INT 0x40000000
-+#define TX_BD_TS 0x20000000
-+#define TX_BD_PINS 0x10000000
-+#define TX_BD_IINS 0x08000000
-+#define TX_BD_TXE 0x00008000
-+#define TX_BD_UE 0x00002000
-+#define TX_BD_EE 0x00001000
-+#define TX_BD_FE 0x00000800
-+#define TX_BD_LCE 0x00000400
-+#define TX_BD_OE 0x00000200
-+#define TX_BD_TSE 0x00000100
-+#define TX_BD_BDU 0x80000000
-+
-+#define RX_BD_E 0x8000
-+#define RX_BD_R01 0x4000
-+#define RX_BD_W 0x2000
-+#define RX_BD_R02 0x1000
-+#define RX_BD_L 0x0800
-+#define RX_BD_M 0x0100
-+#define RX_BD_BC 0x0080
-+#define RX_BD_MC 0x0040
-+#define RX_BD_LG 0x0020
-+#define RX_BD_NO 0x0010
-+#define RX_BD_CR 0x0004
-+#define RX_BD_OV 0x0002
-+#define RX_BD_TR 0x0001
-+
-+#define RX_BD_ME 0x80000000
-+#define RX_BD_PE 0x04000000
-+#define RX_BD_CE 0x02000000
-+#define RX_BD_UC 0x01000000
-+#define RX_BD_INT 0x00800000
-+#define RX_BD_ICE 0x00000020
-+#define RX_BD_PCR 0x00000010
-+#define RX_BD_VLAN 0x00000004
-+#define RX_BD_IPV6 0x00000002
-+#define RX_BD_FRAG 0x00000001
-+#define RX_BD_BDU 0x80000000
-+/****************************************************************************/
-+
-+/* Address Table size in bytes(2048 64bit entry ) */
-+#define ESW_ATABLE_MEM_SIZE (2048*8)
-+/* How many 64-bit elements fit in the address table */
-+#define ESW_ATABLE_MEM_NUM_ENTRIES (2048)
-+/* Address Table Maximum number of entries in each Slot */
-+#define ATABLE_ENTRY_PER_SLOT 8
-+/* log2(ATABLE_ENTRY_PER_SLOT)*/
-+#define ATABLE_ENTRY_PER_SLOT_bits 3
-+/* entry size in byte */
-+#define ATABLE_ENTRY_SIZE 8
-+/* slot size in byte */
-+#define ATABLE_SLOT_SIZE (ATABLE_ENTRY_PER_SLOT * ATABLE_ENTRY_SIZE)
-+/* width of timestamp variable (bits) within address table entry */
-+#define AT_DENTRY_TIMESTAMP_WIDTH 10
-+/* number of bits for port number storage */
-+#define AT_DENTRY_PORT_WIDTH 4
-+/* number of bits for port bitmask number storage */
-+#define AT_SENTRY_PORT_WIDTH 7
-+/* address table static entry port bitmask start address bit */
-+#define AT_SENTRY_PORTMASK_shift 21
-+/* number of bits for port priority storage */
-+#define AT_SENTRY_PRIO_WIDTH 7
-+/* address table static entry priority start address bit */
-+#define AT_SENTRY_PRIO_shift 18
-+/* address table dynamic entry port start address bit */
-+#define AT_DENTRY_PORT_shift 28
-+/* address table dynamic entry timestamp start address bit */
-+#define AT_DENTRY_TIME_shift 18
-+/* address table entry record type start address bit */
-+#define AT_ENTRY_TYPE_shift 17
-+/* address table entry record type bit: 1 static, 0 dynamic */
-+#define AT_ENTRY_TYPE_STATIC 1
-+#define AT_ENTRY_TYPE_DYNAMIC 0
-+/* address table entry record valid start address bit */
-+#define AT_ENTRY_VALID_shift 16
-+#define AT_ENTRY_RECORD_VALID 1
-+
-+#define AT_EXTRACT_VALID(x) \
-+ ((x >> AT_ENTRY_VALID_shift) & AT_ENTRY_RECORD_VALID)
-+
-+#define AT_EXTRACT_PORTMASK(x) \
-+ ((x >> AT_SENTRY_PORTMASK_shift) & AT_SENTRY_PORT_WIDTH)
-+
-+#define AT_EXTRACT_PRIO(x) \
-+ ((x >> AT_SENTRY_PRIO_shift) & AT_SENTRY_PRIO_WIDTH)
-+
-+/* return block corresponding to the 8 bit hash value calculated */
-+#define GET_BLOCK_PTR(hash) (hash << 3)
-+#define AT_EXTRACT_TIMESTAMP(x) \
-+ ((x >> AT_DENTRY_TIME_shift) & ((1 << AT_DENTRY_TIMESTAMP_WIDTH)-1))
-+#define AT_EXTRACT_PORT(x) \
-+ ((x >> AT_DENTRY_PORT_shift) & ((1 << AT_DENTRY_PORT_WIDTH)-1))
-+#define AT_SEXTRACT_PORT(x) \
-+ ((~((x >> AT_SENTRY_PORTMASK_shift) & \
-+ ((1 << AT_DENTRY_PORT_WIDTH)-1))) >> 1)
-+#define TIMEDELTA(newtime, oldtime) \
-+ ((newtime - oldtime) & \
-+ ((1 << AT_DENTRY_TIMESTAMP_WIDTH)-1))
-+
-+#define AT_EXTRACT_IP_PROTOCOL(x) ((x >> 8) & 0xff)
-+#define AT_EXTRACT_TCP_UDP_PORT(x) ((x >> 16) & 0xffff)
-+
-+/* increment time value respecting modulo. */
-+#define TIMEINCREMENT(time) \
-+ ((time) = ((time)+1) & ((1 << AT_DENTRY_TIMESTAMP_WIDTH)-1))
-+/* ------------------------------------------------------------------------- */
-+/* Bit definitions and macros for MCF_ESW_REVISION */
-+#define MCF_ESW_REVISION_CORE_REVISION(x) (((x)&0x0000FFFF)<<0)
-+#define MCF_ESW_REVISION_CUSTOMER_REVISION(x) (((x)&0x0000FFFF)<<16)
-+
-+/* Bit definitions and macros for MCF_ESW_PER */
-+#define MCF_ESW_PER_TE0 (0x00000001)
-+#define MCF_ESW_PER_TE1 (0x00000002)
-+#define MCF_ESW_PER_TE2 (0x00000004)
-+#define MCF_ESW_PER_RE0 (0x00010000)
-+#define MCF_ESW_PER_RE1 (0x00020000)
-+#define MCF_ESW_PER_RE2 (0x00040000)
-+
-+/* Bit definitions and macros for MCF_ESW_VLANV */
-+#define MCF_ESW_VLANV_VV0 (0x00000001)
-+#define MCF_ESW_VLANV_VV1 (0x00000002)
-+#define MCF_ESW_VLANV_VV2 (0x00000004)
-+#define MCF_ESW_VLANV_DU0 (0x00010000)
-+#define MCF_ESW_VLANV_DU1 (0x00020000)
-+#define MCF_ESW_VLANV_DU2 (0x00040000)
-+
-+/* Bit definitions and macros for MCF_ESW_DBCR */
-+#define MCF_ESW_DBCR_P0 (0x00000001)
-+#define MCF_ESW_DBCR_P1 (0x00000002)
-+#define MCF_ESW_DBCR_P2 (0x00000004)
-+
-+/* Bit definitions and macros for MCF_ESW_DMCR */
-+#define MCF_ESW_DMCR_P0 (0x00000001)
-+#define MCF_ESW_DMCR_P1 (0x00000002)
-+#define MCF_ESW_DMCR_P2 (0x00000004)
-+
-+/* Bit definitions and macros for MCF_ESW_BKLR */
-+#define MCF_ESW_BKLR_BE0 (0x00000001)
-+#define MCF_ESW_BKLR_BE1 (0x00000002)
-+#define MCF_ESW_BKLR_BE2 (0x00000004)
-+#define MCF_ESW_BKLR_LD0 (0x00010000)
-+#define MCF_ESW_BKLR_LD1 (0x00020000)
-+#define MCF_ESW_BKLR_LD2 (0x00040000)
-+
-+/* Bit definitions and macros for MCF_ESW_BMPC */
-+#define MCF_ESW_BMPC_PORT(x) (((x)&0x0000000F)<<0)
-+#define MCF_ESW_BMPC_MSG_TX (0x00000020)
-+#define MCF_ESW_BMPC_EN (0x00000040)
-+#define MCF_ESW_BMPC_DIS (0x00000080)
-+#define MCF_ESW_BMPC_PRIORITY(x) (((x)&0x00000007)<<13)
-+#define MCF_ESW_BMPC_PORTMASK(x) (((x)&0x00000007)<<16)
-+
-+/* Bit definitions and macros for MCF_ESW_MODE */
-+#define MCF_ESW_MODE_SW_RST (0x00000001)
-+#define MCF_ESW_MODE_SW_EN (0x00000002)
-+#define MCF_ESW_MODE_STOP (0x00000080)
-+#define MCF_ESW_MODE_CRC_TRAN (0x00000100)
-+#define MCF_ESW_MODE_P0CT (0x00000200)
-+#define MCF_ESW_MODE_STATRST (0x80000000)
-+
-+/* Bit definitions and macros for MCF_ESW_VIMSEL */
-+#define MCF_ESW_VIMSEL_IM0(x) (((x)&0x00000003)<<0)
-+#define MCF_ESW_VIMSEL_IM1(x) (((x)&0x00000003)<<2)
-+#define MCF_ESW_VIMSEL_IM2(x) (((x)&0x00000003)<<4)
-+
-+/* Bit definitions and macros for MCF_ESW_VOMSEL */
-+#define MCF_ESW_VOMSEL_OM0(x) (((x)&0x00000003)<<0)
-+#define MCF_ESW_VOMSEL_OM1(x) (((x)&0x00000003)<<2)
-+#define MCF_ESW_VOMSEL_OM2(x) (((x)&0x00000003)<<4)
-+
-+/* Bit definitions and macros for MCF_ESW_VIMEN */
-+#define MCF_ESW_VIMEN_EN0 (0x00000001)
-+#define MCF_ESW_VIMEN_EN1 (0x00000002)
-+#define MCF_ESW_VIMEN_EN2 (0x00000004)
-+
-+/* Bit definitions and macros for MCF_ESW_VID */
-+#define MCF_ESW_VID_TAG(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_MCR */
-+#define MCF_ESW_MCR_PORT(x) (((x)&0x0000000F)<<0)
-+#define MCF_ESW_MCR_MEN (0x00000010)
-+#define MCF_ESW_MCR_INGMAP (0x00000020)
-+#define MCF_ESW_MCR_EGMAP (0x00000040)
-+#define MCF_ESW_MCR_INGSA (0x00000080)
-+#define MCF_ESW_MCR_INGDA (0x00000100)
-+#define MCF_ESW_MCR_EGSA (0x00000200)
-+#define MCF_ESW_MCR_EGDA (0x00000400)
-+
-+/* Bit definitions and macros for MCF_ESW_EGMAP */
-+#define MCF_ESW_EGMAP_EG0 (0x00000001)
-+#define MCF_ESW_EGMAP_EG1 (0x00000002)
-+#define MCF_ESW_EGMAP_EG2 (0x00000004)
-+
-+/* Bit definitions and macros for MCF_ESW_INGMAP */
-+#define MCF_ESW_INGMAP_ING0 (0x00000001)
-+#define MCF_ESW_INGMAP_ING1 (0x00000002)
-+#define MCF_ESW_INGMAP_ING2 (0x00000004)
-+
-+/* Bit definitions and macros for MCF_ESW_INGSAL */
-+#define MCF_ESW_INGSAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_INGSAH */
-+#define MCF_ESW_INGSAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_INGDAL */
-+#define MCF_ESW_INGDAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_INGDAH */
-+#define MCF_ESW_INGDAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_ENGSAL */
-+#define MCF_ESW_ENGSAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_ENGSAH */
-+#define MCF_ESW_ENGSAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_ENGDAL */
-+#define MCF_ESW_ENGDAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_ENGDAH */
-+#define MCF_ESW_ENGDAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_MCVAL */
-+#define MCF_ESW_MCVAL_COUNT(x) (((x)&0x000000FF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_MMSR */
-+#define MCF_ESW_MMSR_BUSY (0x00000001)
-+#define MCF_ESW_MMSR_NOCELL (0x00000002)
-+#define MCF_ESW_MMSR_MEMFULL (0x00000004)
-+#define MCF_ESW_MMSR_MFLATCH (0x00000008)
-+#define MCF_ESW_MMSR_DQ_GRNT (0x00000040)
-+#define MCF_ESW_MMSR_CELLS_AVAIL(x) (((x)&0x000000FF)<<16)
-+
-+/* Bit definitions and macros for MCF_ESW_LMT */
-+#define MCF_ESW_LMT_THRESH(x) (((x)&0x000000FF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_LFC */
-+#define MCF_ESW_LFC_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_PCSR */
-+#define MCF_ESW_PCSR_PC0 (0x00000001)
-+#define MCF_ESW_PCSR_PC1 (0x00000002)
-+#define MCF_ESW_PCSR_PC2 (0x00000004)
-+
-+/* Bit definitions and macros for MCF_ESW_IOSR */
-+#define MCF_ESW_IOSR_OR0 (0x00000001)
-+#define MCF_ESW_IOSR_OR1 (0x00000002)
-+#define MCF_ESW_IOSR_OR2 (0x00000004)
-+
-+/* Bit definitions and macros for MCF_ESW_QWT */
-+#define MCF_ESW_QWT_Q0WT(x) (((x)&0x0000001F)<<0)
-+#define MCF_ESW_QWT_Q1WT(x) (((x)&0x0000001F)<<8)
-+#define MCF_ESW_QWT_Q2WT(x) (((x)&0x0000001F)<<16)
-+#define MCF_ESW_QWT_Q3WT(x) (((x)&0x0000001F)<<24)
-+
-+/* Bit definitions and macros for MCF_ESW_P0BCT */
-+#define MCF_ESW_P0BCT_THRESH(x) (((x)&0x000000FF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_P0FFEN */
-+#define MCF_ESW_P0FFEN_FEN (0x00000001)
-+#define MCF_ESW_P0FFEN_FD(x) (((x)&0x00000003)<<2)
-+
-+/* Bit definitions and macros for MCF_ESW_PSNP */
-+#define MCF_ESW_PSNP_EN (0x00000001)
-+#define MCF_ESW_PSNP_MODE(x) (((x)&0x00000003)<<1)
-+#define MCF_ESW_PSNP_CD (0x00000008)
-+#define MCF_ESW_PSNP_CS (0x00000010)
-+#define MCF_ESW_PSNP_PORT_COMPARE(x) (((x)&0x0000FFFF)<<16)
-+
-+/* Bit definitions and macros for MCF_ESW_IPSNP */
-+#define MCF_ESW_IPSNP_EN (0x00000001)
-+#define MCF_ESW_IPSNP_MODE(x) (((x)&0x00000003)<<1)
-+#define MCF_ESW_IPSNP_PROTOCOL(x) (((x)&0x000000FF)<<8)
-+
-+/* Bit definitions and macros for MCF_ESW_PVRES */
-+#define MCF_ESW_PVRES_PRI0(x) (((x)&0x00000007)<<0)
-+#define MCF_ESW_PVRES_PRI1(x) (((x)&0x00000007)<<3)
-+#define MCF_ESW_PVRES_PRI2(x) (((x)&0x00000007)<<6)
-+#define MCF_ESW_PVRES_PRI3(x) (((x)&0x00000007)<<9)
-+#define MCF_ESW_PVRES_PRI4(x) (((x)&0x00000007)<<12)
-+#define MCF_ESW_PVRES_PRI5(x) (((x)&0x00000007)<<15)
-+#define MCF_ESW_PVRES_PRI6(x) (((x)&0x00000007)<<18)
-+#define MCF_ESW_PVRES_PRI7(x) (((x)&0x00000007)<<21)
-+
-+/* Bit definitions and macros for MCF_ESW_IPRES */
-+#define MCF_ESW_IPRES_ADDRESS(x) (((x)&0x000000FF)<<0)
-+#define MCF_ESW_IPRES_IPV4SEL (0x00000100)
-+#define MCF_ESW_IPRES_PRI0(x) (((x)&0x00000003)<<9)
-+#define MCF_ESW_IPRES_PRI1(x) (((x)&0x00000003)<<11)
-+#define MCF_ESW_IPRES_PRI2(x) (((x)&0x00000003)<<13)
-+#define MCF_ESW_IPRES_READ (0x80000000)
-+
-+/* Bit definitions and macros for MCF_ESW_PRES */
-+#define MCF_ESW_PRES_VLAN (0x00000001)
-+#define MCF_ESW_PRES_IP (0x00000002)
-+#define MCF_ESW_PRES_MAC (0x00000004)
-+#define MCF_ESW_PRES_DFLT_PRI(x) (((x)&0x00000007)<<4)
-+
-+/* Bit definitions and macros for MCF_ESW_PID */
-+#define MCF_ESW_PID_VLANID(x) (((x)&0x0000FFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_VRES */
-+#define MCF_ESW_VRES_P0 (0x00000001)
-+#define MCF_ESW_VRES_P1 (0x00000002)
-+#define MCF_ESW_VRES_P2 (0x00000004)
-+#define MCF_ESW_VRES_VLANID(x) (((x)&0x00000FFF)<<3)
-+
-+/* Bit definitions and macros for MCF_ESW_DISCN */
-+#define MCF_ESW_DISCN_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_DISCB */
-+#define MCF_ESW_DISCB_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_NDISCN */
-+#define MCF_ESW_NDISCN_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_NDISCB */
-+#define MCF_ESW_NDISCB_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_POQC */
-+#define MCF_ESW_POQC_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_PMVID */
-+#define MCF_ESW_PMVID_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_PMVTAG */
-+#define MCF_ESW_PMVTAG_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_PBL */
-+#define MCF_ESW_PBL_COUNT(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_ISR */
-+#define MCF_ESW_ISR_EBERR (0x00000001)
-+#define MCF_ESW_ISR_RXB (0x00000002)
-+#define MCF_ESW_ISR_RXF (0x00000004)
-+#define MCF_ESW_ISR_TXB (0x00000008)
-+#define MCF_ESW_ISR_TXF (0x00000010)
-+#define MCF_ESW_ISR_QM (0x00000020)
-+#define MCF_ESW_ISR_OD0 (0x00000040)
-+#define MCF_ESW_ISR_OD1 (0x00000080)
-+#define MCF_ESW_ISR_OD2 (0x00000100)
-+#define MCF_ESW_ISR_LRN (0x00000200)
-+
-+/* Bit definitions and macros for MCF_ESW_IMR */
-+#define MCF_ESW_IMR_EBERR (0x00000001)
-+#define MCF_ESW_IMR_RXB (0x00000002)
-+#define MCF_ESW_IMR_RXF (0x00000004)
-+#define MCF_ESW_IMR_TXB (0x00000008)
-+#define MCF_ESW_IMR_TXF (0x00000010)
-+#define MCF_ESW_IMR_QM (0x00000020)
-+#define MCF_ESW_IMR_OD0 (0x00000040)
-+#define MCF_ESW_IMR_OD1 (0x00000080)
-+#define MCF_ESW_IMR_OD2 (0x00000100)
-+#define MCF_ESW_IMR_LRN (0x00000200)
-+
-+/* Bit definitions and macros for MCF_ESW_RDSR */
-+#define MCF_ESW_RDSR_ADDRESS(x) (((x)&0x3FFFFFFF)<<2)
-+
-+/* Bit definitions and macros for MCF_ESW_TDSR */
-+#define MCF_ESW_TDSR_ADDRESS(x) (((x)&0x3FFFFFFF)<<2)
-+
-+/* Bit definitions and macros for MCF_ESW_MRBR */
-+#define MCF_ESW_MRBR_SIZE(x) (((x)&0x000003FF)<<4)
-+
-+/* Bit definitions and macros for MCF_ESW_RDAR */
-+#define MCF_ESW_RDAR_R_DES_ACTIVE (0x01000000)
-+
-+/* Bit definitions and macros for MCF_ESW_TDAR */
-+#define MCF_ESW_TDAR_X_DES_ACTIVE (0x01000000)
-+
-+/* Bit definitions and macros for MCF_ESW_LREC0 */
-+#define MCF_ESW_LREC0_MACADDR0(x) (((x)&0xFFFFFFFF)<<0)
-+
-+/* Bit definitions and macros for MCF_ESW_LREC1 */
-+#define MCF_ESW_LREC1_MACADDR1(x) (((x)&0x0000FFFF)<<0)
-+#define MCF_ESW_LREC1_HASH(x) (((x)&0x000000FF)<<16)
-+#define MCF_ESW_LREC1_SWPORT(x) (((x)&0x00000003)<<24)
-+
-+/* Bit definitions and macros for MCF_ESW_LSR */
-+#define MCF_ESW_LSR_DA (0x00000001)
-+
-+/* port mirroring port number match */
-+#define MIRROR_EGRESS_PORT_MATCH 1
-+#define MIRROR_INGRESS_PORT_MATCH 2
-+
-+/* port mirroring mac address match */
-+#define MIRROR_EGRESS_SOURCE_MATCH 1
-+#define MIRROR_INGRESS_SOURCE_MATCH 2
-+#define MIRROR_EGRESS_DESTINATION_MATCH 3
-+#define MIRROR_INGRESS_DESTINATION_MATCH 4
-+
-+#endif /* SWITCH_H */
---- a/include/linux/fsl_devices.h
-+++ b/include/linux/fsl_devices.h
-@@ -129,4 +129,21 @@ struct fsl_ata_platform_data {
- void (*exit)(void);
- int (*get_clk_rate)(void);
- };
-+
-+struct net_device;
-+struct coldfire_switch_platform_data {
-+ int hash_table;
-+ unsigned int *switch_hw;
-+ void (*request_intrs)(struct net_device *dev,
-+ irqreturn_t (*)(int, void *),
-+ void *irq_privatedata);
-+ void (*set_mii)(struct net_device *dev);
-+ void (*get_mac)(struct net_device *dev);
-+ void (*enable_phy_intr)(void);
-+ void (*disable_phy_intr)(void);
-+ void (*phy_ack_intr)(void);
-+ void (*localhw_setup)(void);
-+ void (*uncache)(unsigned long addr);
-+ void (*platform_flush_cache)(void);
-+};
- #endif /* _FSL_DEVICE_H_ */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -4756,6 +4756,10 @@ static int dev_ifsioc(struct net *net, s
- default:
- if ((cmd >= SIOCDEVPRIVATE &&
- cmd <= SIOCDEVPRIVATE + 15) ||
-+#if defined(CONFIG_MODELO_SWITCH)
-+ (cmd >= 0x9101 &&
-+ cmd <= 0x92ff) ||
-+#endif
- cmd == SIOCBONDENSLAVE ||
- cmd == SIOCBONDRELEASE ||
- cmd == SIOCBONDSETHWADDR ||
-@@ -4948,6 +4952,10 @@ int dev_ioctl(struct net *net, unsigned
- */
- default:
- if (cmd == SIOCWANDEV ||
-+#if defined(CONFIG_MODELO_SWITCH)
-+ (cmd >= 0x9101 &&
-+ cmd <= 0x92ff) ||
-+#endif
- (cmd >= SIOCDEVPRIVATE &&
- cmd <= SIOCDEVPRIVATE + 15)) {
- dev_load(net, ifr.ifr_name);