summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhuvanchandra DV <bhuvanchandra.dv@toradex.com>2016-04-25 15:15:45 +0530
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2016-06-27 08:58:09 +0200
commit62ff23d64d1a504e5869643b442f806631b7c6e8 (patch)
treea465f58100bf3cb0287e89cd960fb4c3c012c1ff
parentaed3304118e4fe4ceceeb9aaff2874bbd9b27def (diff)
net: ethernet: freescale: vf610_l2_switch
Drop the ioctl configuration functionality and configure the switch in a default switching mode. Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com> Signed-off-by: Stefan Agner <stefan.agner@toradex.com> Acked-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
-rw-r--r--drivers/net/ethernet/freescale/Kconfig4
-rw-r--r--drivers/net/ethernet/freescale/fsl_l2_switch.c4245
-rw-r--r--drivers/net/ethernet/freescale/fsl_l2_switch.h (renamed from include/linux/fsl_l2_switch.h)616
3 files changed, 735 insertions, 4130 deletions
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index 1a239f458617..84e29f5da4ba 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -32,10 +32,10 @@ config FEC
config FSL_L2_SWITCH
bool "Ethernet switch controller(Freescale ColdFire and Vybrid platform)"
- depends on (SOC_MVFA5 || SOC_VF610)
+ depends on (SOC_VF610)
help
Say Y here if you want to use the built-in ethernet switch
- controller on some ColdFire processors.
+ controller on Vybrid processors.
The Integrated Ethernet switch engine is compatible with
10/100 MAC-NET core.
diff --git a/drivers/net/ethernet/freescale/fsl_l2_switch.c b/drivers/net/ethernet/freescale/fsl_l2_switch.c
index ecad59c2c151..4d961c0dab3b 100644
--- a/drivers/net/ethernet/freescale/fsl_l2_switch.c
+++ b/drivers/net/ethernet/freescale/fsl_l2_switch.c
@@ -14,13 +14,8 @@
#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>
@@ -29,3056 +24,507 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
-#include <linux/platform_device.h>
-#include <linux/of_platform.h>
-#include <linux/of_address.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 <linux/clk.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_net.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-#include <linux/version.h>
-#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) */
-#include <mach/hardware.h>
-#include <mach/fsl_l2_switch.h>
-#else
-#include <linux/fsl_l2_switch.h>
-#endif
+#include "fsl_l2_switch.h"
-#define SWITCH_MAX_PORTS 1
-#define CONFIG_FEC_SHARED_PHY
+/* switch ports status */
+struct port_status ports_link_status;
static unsigned char macaddr[ETH_ALEN];
module_param_array(macaddr, byte, NULL, 0);
MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
-/* 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);
-#ifdef UNUSED
-static void set_multicast_list(struct net_device *dev);
-#endif
-static void switch_restart(struct net_device *dev, int duplex);
-static void switch_stop(struct net_device *dev);
-static void switch_get_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))
-/* MII MMFR bits definition */
-#define ESW_MMFR_ST (1 << 30)
-#define ESW_MMFR_OP_READ (2 << 28)
-#define ESW_MMFR_OP_WRITE (1 << 28)
-#define ESW_MMFR_PA(v) ((v & 0x1f) << 23)
-#define ESW_MMFR_RA(v) ((v & 0x1f) << 18)
-#define ESW_MMFR_TA (2 << 16)
-#define ESW_MMFR_DATA(v) (v & 0xffff)
-
-#define ESW_MII_TIMEOUT 30 /* ms */
-
-/* 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 = (unsigned long)fep->macbase;
-
- *read_lo = readl((void *)(atable_base + (index << 3)));
- *read_hi = readl((void *)(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 = (unsigned long)fep->macbase;
-
- writel(write_lo, (void *)atable_base + (index << 3));
- writel(write_hi, (void *)atable_base + (index<<3) + 4);
-}
-
-/* Check if the Port Info FIFO has data available
- * for reading. 1 valid, 0 invalid*/
-int esw_portinfofifo_status(struct switch_enet_private *fep)
-{
- return readl(fep->membase + FEC_ESW_LSR);
-}
-
-/* Initialize the Port Info FIFO. */
-void esw_portinfofifo_initialize(struct switch_enet_private *fep)
-{
- unsigned long tmp;
-
- /* disable all learn */
- tmp = readl(fep->membase + FEC_ESW_IMR);
- tmp &= (~FSL_ESW_IMR_LRN);
- writel(tmp, fep->membase + FEC_ESW_IMR);
-
- /* remove all entries from FIFO */
- while (esw_portinfofifo_status(fep)) {
- /* read one data word */
- tmp = readl(fep->membase + FEC_ESW_LREC0);
- tmp = readl(fep->membase + FEC_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)
-{
- unsigned long tmp;
-
- /* check learning record valid */
- if (!(readl(fep->membase + FEC_ESW_LSR)))
- return NULL;
-
- /*read word from FIFO*/
- g_info.maclo = readl(fep->membase + FEC_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 = readl(fep->membase + FEC_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)
+static void switch_adjust_link1(struct net_device *dev)
{
- 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;
-}
+ struct switch_enet_private *priv = netdev_priv(dev);
+ struct phy_device *phydev1 = priv->phydev[0];
+ int new_state = 0;
-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;
+ if (phydev1->link != PHY_DOWN) {
+ if (phydev1->duplex != priv->phy1_duplex) {
+ new_state = 1;
+ priv->phy1_duplex = phydev1->duplex;
}
- }
- /*
- * 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;
+ if (phydev1->speed != priv->phy1_speed) {
+ new_state = 1;
+ priv->phy1_speed = phydev1->speed;
}
- }
-
- 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;
- }
+ if (priv->phy1_old_link == PHY_DOWN) {
+ new_state = 1;
+ priv->phy1_old_link = phydev1->link;
}
-
- /*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;
+ } else if (priv->phy1_old_link) {
+ new_state = 1;
+ priv->phy1_old_link = PHY_DOWN;
+ priv->phy1_speed = 0;
+ priv->phy1_duplex = -1;
}
-}
-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);
- }
+ if (new_state) {
+ ports_link_status.port1_link_status = phydev1->link;
+ phy_print_status(phydev1);
}
}
-void esw_atable_dynamicms_del_entries_for_other_port(
- struct switch_enet_private *fep,
- int port_index)
+static void switch_adjust_link2(struct net_device *dev)
{
- 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);
+ struct switch_enet_private *priv = netdev_priv(dev);
+ struct phy_device *phydev2 = priv->phydev[1];
+ int new_state = 0;
- if (port_idx != port_index)
- write_atable(fep, i, 0, 0);
+ if (phydev2->link != PHY_DOWN) {
+ if (phydev2->duplex != priv->phy2_duplex) {
+ new_state = 1;
+ priv->phy2_duplex = phydev2->duplex;
}
- }
-}
-/*
- * 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++;
- }
+ if (phydev2->speed != priv->phy2_speed) {
+ new_state = 1;
+ priv->phy2_speed = phydev2->speed;
}
- }
-
- /*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, cur, i;
- unsigned long read_lo, read_hi;
-
- tm_min = (1 << AT_DENTRY_TIMESTAMP_WIDTH) - 1;
- tm_max = 0;
- cur = 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;
- cur++;
+ 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;
}
- delta = TIMEDELTA(tm_max, tm_min);
- if (delta < fep->ageMax) {
- /*Difference must be in range*/
- fep->currTime = tm_max;
- } else {
- fep->currTime = tm_min;
+ if (new_state) {
+ ports_link_status.port2_link_status = phydev2->link;
+ phy_print_status(phydev2);
}
-
- fep->atCurrEntries = cur;
- 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)
+static void switch_hw_init(struct net_device *dev)
{
- 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;
-}
+ struct switch_enet_private *fep = netdev_priv(dev);
-/* 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;
-}
+ /* Initialize MAC 0/1 */
+ writel(FSL_FEC_RCR_MAX_FL(1522) | FSL_FEC_RCR_RMII_MODE
+ | FSL_FEC_RCR_PROM | FSL_FEC_RCR_MII_MODE
+ | FSL_FEC_RCR_MII_MODE, fep->enetbase + FSL_FEC_RCR0);
+ writel(FSL_FEC_RCR_MAX_FL(1522) | FSL_FEC_RCR_RMII_MODE
+ | FSL_FEC_RCR_PROM | FSL_FEC_RCR_MII_MODE
+ | FSL_FEC_RCR_MII_MODE, fep->enetbase + FSL_FEC_RCR1);
-/* 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);
- }
+ writel(FSL_FEC_TCR_FDEN, fep->enetbase + FSL_FEC_TCR0);
+ writel(FSL_FEC_TCR_FDEN, fep->enetbase + FSL_FEC_TCR1);
- 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;
+ writel(0x1a, fep->enetbase + FSL_FEC_MSCR0);
- /* Enable Forced forwarding for port num */
- if ((port1 == 1) && (port2 == 1))
- tmp |= FSL_ESW_P0FFEN_FD(3);
- else if (port1 == 1)
- /*Enable Forced forwarding for port 1 only*/
- tmp |= FSL_ESW_P0FFEN_FD(1);
- else if (port2 == 1)
- /*Enable Forced forwarding for port 2 only*/
- tmp |= FSL_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;
- }
+ /* Set the station address for the ENET Adapter */
+ writel(dev->dev_addr[3] |
+ dev->dev_addr[2] << 8 |
+ dev->dev_addr[1] << 16 |
+ dev->dev_addr[0] << 24, fep->enetbase + FSL_FEC_PALR0);
+ writel((dev->dev_addr[5] << 16) |
+ (dev->dev_addr[4] << 24),
+ fep->enetbase + FSL_FEC_PAUR0);
+ writel(dev->dev_addr[3] |
+ dev->dev_addr[2] << 8 |
+ dev->dev_addr[1] << 16 |
+ dev->dev_addr[0] << 24, fep->enetbase + FSL_FEC_PALR1);
+ writel((dev->dev_addr[5] << 16) |
+ (dev->dev_addr[4] << 24),
+ fep->enetbase + FSL_FEC_PAUR1);
- if (enable == 1)
- tmp |= FSL_ESW_P0FFEN_FEN;
- else if (enable == 0)
- tmp &= ~FSL_ESW_P0FFEN_FEN;
- else {
- printk(KERN_ERR "%s: the enable %x is error\n",
- __func__, enable);
- return -2;
- }
+ writel(FEC_ENET_TXF | FEC_ENET_RXF, fep->enetbase + FSL_FEC_EIMR0);
+ writel(FEC_ENET_TXF | FEC_ENET_RXF, fep->enetbase + FSL_FEC_EIMR1);
- writel(tmp, fep->membase + FEC_ESW_P0FFEN);
- return 0;
+ writel(FSL_FEC_ECR_ETHER_EN |
+ (0x1 << 8), fep->enetbase + FSL_FEC_ECR0);
+ writel(FSL_FEC_ECR_ETHER_EN |
+ (0x1 << 8), fep->enetbase + FSL_FEC_ECR1);
+ udelay(20);
}
-void esw_get_forced_forward(
- struct switch_enet_private *fep,
- unsigned long *ulForceForward)
+/* Set a MAC change in hardware.*/
+static void switch_get_mac_address(struct net_device *dev)
{
- *ulForceForward = readl(fep->membase + FEC_ESW_P0FFEN);
-}
+ struct switch_enet_private *fep = netdev_priv(dev);
+ unsigned char *iap, tmpaddr[ETH_ALEN];
-void esw_get_port_enable(
- struct switch_enet_private *fep,
- unsigned long *ulPortEnable)
-{
- *ulPortEnable = readl(fep->membase + FEC_ESW_PER);
-}
+ iap = macaddr;
-/*
- * 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;
+ if (!is_valid_ether_addr(iap)) {
+ struct device_node *np = fep->pdev->dev.of_node;
- tmp = readl(fep->membase + FEC_ESW_PER);
- if (tx_en == 1) {
- if (port == 0)
- tmp |= FSL_ESW_PER_TE0;
- else if (port == 1)
- tmp |= FSL_ESW_PER_TE1;
- else if (port == 2)
- tmp |= FSL_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 &= (~FSL_ESW_PER_TE0);
- else if (port == 1)
- tmp &= (~FSL_ESW_PER_TE1);
- else if (port == 2)
- tmp &= (~FSL_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 (np) {
+ const char *mac = of_get_mac_address(np);
- if (rx_en == 1) {
- if (port == 0)
- tmp |= FSL_ESW_PER_RE0;
- else if (port == 1)
- tmp |= FSL_ESW_PER_RE1;
- else if (port == 2)
- tmp |= FSL_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 &= (~FSL_ESW_PER_RE0);
- else if (port == 1)
- tmp &= (~FSL_ESW_PER_RE1);
- else if (port == 2)
- tmp &= (~FSL_ESW_PER_RE2);
- else {
- printk(KERN_ERR "%s:do not support the "
- "port %x rx disable\n",
- __func__, port);
- return -5;
+ if (mac)
+ iap = (unsigned char *) mac;
}
- } else {
- printk(KERN_ERR "%s:do not support the port %x"
- " rx op value %x\n",
- __func__, port, tx_en);
- return -6;
- }
-
- writel(tmp, fep->membase + FEC_ESW_PER);
- return 0;
-}
-
-
-void esw_get_port_broadcast(struct switch_enet_private *fep,
- unsigned long *ulPortBroadcast)
-{
- *ulPortBroadcast = readl(fep->membase + FEC_ESW_DBCR);
-}
-
-int esw_port_broadcast_config(struct switch_enet_private *fep,
- int port, int enable)
-{
- unsigned long tmp = 0;
-
- if ((port > 2) || (port < 0)) {
- printk(KERN_ERR "%s:do not support the port %x"
- " default broadcast\n",
- __func__, port);
- return -1;
}
- tmp = readl(fep->membase + FEC_ESW_DBCR);
- if (enable == 1) {
- if (port == 0)
- tmp |= FSL_ESW_DBCR_P0;
- else if (port == 1)
- tmp |= FSL_ESW_DBCR_P1;
- else if (port == 2)
- tmp |= FSL_ESW_DBCR_P2;
- } else if (enable == 0) {
- if (port == 0)
- tmp &= ~FSL_ESW_DBCR_P0;
- else if (port == 1)
- tmp &= ~FSL_ESW_DBCR_P1;
- else if (port == 2)
- tmp &= ~FSL_ESW_DBCR_P2;
- }
-
- writel(tmp, fep->membase + FEC_ESW_DBCR);
- return 0;
-}
-
-
-void esw_get_port_multicast(struct switch_enet_private *fep,
- unsigned long *ulPortMulticast)
-{
- *ulPortMulticast = readl(fep->membase + FEC_ESW_DMCR);
-}
-
-int esw_port_multicast_config(struct switch_enet_private *fep,
- int port, int enable)
-{
- unsigned long tmp = 0;
-
- if ((port > 2) || (port < 0)) {
- printk(KERN_ERR "%s:do not support the port %x"
- " default broadcast\n",
- __func__, port);
- return -1;
- }
-
- tmp = readl(fep->membase + FEC_ESW_DMCR);
- if (enable == 1) {
- if (port == 0)
- tmp |= FSL_ESW_DMCR_P0;
- else if (port == 1)
- tmp |= FSL_ESW_DMCR_P1;
- else if (port == 2)
- tmp |= FSL_ESW_DMCR_P2;
- } else if (enable == 0) {
- if (port == 0)
- tmp &= ~FSL_ESW_DMCR_P0;
- else if (port == 1)
- tmp &= ~FSL_ESW_DMCR_P1;
- else if (port == 2)
- tmp &= ~FSL_ESW_DMCR_P2;
- }
-
- writel(tmp, fep->membase + FEC_ESW_DMCR);
- return 0;
-}
-
-
-void esw_get_port_blocking(struct switch_enet_private *fep,
- unsigned long *ulPortBlocking)
-{
- *ulPortBlocking = readl(fep->membase + FEC_ESW_BKLR) & 0x0000000f;
-}
-
-int esw_port_blocking_config(struct switch_enet_private *fep,
- int port, int enable)
-{
- unsigned long tmp = 0;
-
- if ((port > 2) || (port < 0)) {
- printk(KERN_ERR "%s:do not support the port %x"
- " default broadcast\n",
- __func__, port);
- return -1;
- }
-
- tmp = readl(fep->membase + FEC_ESW_BKLR);
- if (enable == 1) {
- if (port == 0)
- tmp |= FSL_ESW_BKLR_BE0;
- else if (port == 1)
- tmp |= FSL_ESW_BKLR_BE1;
- else if (port == 2)
- tmp |= FSL_ESW_BKLR_BE2;
- } else if (enable == 0) {
- if (port == 0)
- tmp &= ~FSL_ESW_BKLR_BE0;
- else if (port == 1)
- tmp &= ~FSL_ESW_BKLR_BE1;
- else if (port == 2)
- tmp &= ~FSL_ESW_BKLR_BE2;
- }
-
- writel(tmp, fep->membase + FEC_ESW_BKLR);
- return 0;
-}
-
-
-void esw_get_port_learning(struct switch_enet_private *fep,
- unsigned long *ulPortLearning)
-{
- *ulPortLearning =
- (readl(fep->membase + FEC_ESW_BKLR) & 0x000f0000) >> 16;
-}
-
-int esw_port_learning_config(struct switch_enet_private *fep,
- int port, int disable)
-{
- unsigned long tmp = 0;
-
- if ((port > 2) || (port < 0)) {
- printk(KERN_ERR "%s:do not support the port %x"
- " default broadcast\n",
- __func__, port);
- return -1;
+ if (!is_valid_ether_addr(iap)) {
+ *((__be32 *)&tmpaddr[0]) =
+ cpu_to_be32(readl(fep->enetbase + FSL_FEC_PALR0));
+ *((__be16 *)&tmpaddr[4]) =
+ cpu_to_be16(readl(fep->enetbase + FSL_FEC_PAUR0) >> 16);
+ iap = &tmpaddr[0];
}
- tmp = readl(fep->membase + FEC_ESW_BKLR);
- if (disable == 0) {
- fep->learning_irqhandle_enable = 0;
- if (port == 0)
- tmp |= FSL_ESW_BKLR_LD0;
- else if (port == 1)
- tmp |= FSL_ESW_BKLR_LD1;
- else if (port == 2)
- tmp |= FSL_ESW_BKLR_LD2;
- } else if (disable == 1) {
- if (port == 0)
- tmp &= ~FSL_ESW_BKLR_LD0;
- else if (port == 1)
- tmp &= ~FSL_ESW_BKLR_LD1;
- else if (port == 2)
- tmp &= ~FSL_ESW_BKLR_LD2;
+ if (!is_valid_ether_addr(iap)) {
+ /* Report it and use a random ethernet address instead */
+ netdev_err(dev, "Invalid MAC address: %pM\n", iap);
+ eth_hw_addr_random(dev);
+ netdev_info(dev, "Using random MAC address: %pM\n",
+ dev->dev_addr);
+ return;
}
- writel(tmp, fep->membase + FEC_ESW_BKLR);
- 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;
- }
+ memcpy(dev->dev_addr, iap, ETH_ALEN);
- if (read_hi != (~index)) {
- printk(KERN_ERR "%s:Mismatch at high %d\n",
- __func__, index);
- return;
- }
- }
+ /* Adjust MAC if using macaddr */
+ if (iap == macaddr)
+ dev->dev_addr[ETH_ALEN - 1] =
+ macaddr[ETH_ALEN - 1] + fep->dev_id;
}
-/*
- * 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
+/* This function is called to start or restart the FEC during a link
+ * change. This only happens when switching between half and full
+ * duplex.
*/
-int esw_ip_snoop_config(struct switch_enet_private *fep,
- int mode, unsigned long ip_header_protocol)
-{
- unsigned long tmp = 0, protocol_type = 0;
- int num = 0;
-
- /* Config IP Snooping */
- if (mode == 0) {
- /* Enable IP Snooping */
- tmp = FSL_ESW_IPSNP_EN;
- tmp |= FSL_ESW_IPSNP_MODE(0);/*For Forward*/
- } else if (mode == 1) {
- /* Enable IP Snooping */
- tmp = FSL_ESW_IPSNP_EN;
- /*For Forward and copy_to_mangmnt_port*/
- tmp |= FSL_ESW_IPSNP_MODE(1);
- } else if (mode == 2) {
- /* Enable IP Snooping */
- tmp = FSL_ESW_IPSNP_EN;
- tmp |= FSL_ESW_IPSNP_MODE(2);/*discard*/
- } else if (mode == 3) {
- /* disable IP Snooping */
- tmp = FSL_ESW_IPSNP_EN;
- tmp &= ~FSL_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++) {
- unsigned long reg = readl(fep->membase + FEC_ESW_IPSNP(num));
- if (protocol_type ==
- AT_EXTRACT_IP_PROTOCOL(reg)) {
- writel(tmp | FSL_ESW_IPSNP_PROTOCOL(protocol_type),
- fep->membase + FEC_ESW_IPSNP(num));
- break;
- } else if (!reg) {
- writel(tmp | FSL_ESW_IPSNP_PROTOCOL(protocol_type),
- fep->membase + FEC_ESW_IPSNP(num));
- 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)
+static void switch_restart(struct net_device *dev, int duplex)
{
+ struct switch_enet_private *fep;
int i;
- for (i = 0; i < 8; i++)
- *(ulpESW_IPSNP + i) = readl(fep->membase + FEC_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)
-{
- unsigned long tmp;
- int num;
-
- /* Enable TCP/UDP port Snooping */
- tmp = FSL_ESW_PSNP_EN;
- if (mode == 0)
- tmp |= FSL_ESW_PSNP_MODE(0);/*For Forward*/
- else if (mode == 1)/*For Forward and copy_to_mangmnt_port*/
- tmp |= FSL_ESW_PSNP_MODE(1);
- else if (mode == 2)
- tmp |= FSL_ESW_PSNP_MODE(2);/*discard*/
- else if (mode == 3) /*disable the port function*/
- tmp &= (~FSL_ESW_PSNP_EN);
- else {
- printk(KERN_ERR "%s: the mode %x we do not support\n",
- __func__, mode);
- return -1;
- }
+ fep = netdev_priv(dev);
- if (compare_num == 1)
- tmp |= FSL_ESW_PSNP_CS;
- else if (compare_num == 2)
- tmp |= FSL_ESW_PSNP_CD;
- else if (compare_num == 3)
- tmp |= FSL_ESW_PSNP_CD | FSL_ESW_PSNP_CS;
- else {
- printk(KERN_ERR "%s: the compare port address %x"
- " we do not support\n",
- __func__, compare_num);
- return -1;
- }
+ /* Whack a reset. We should wait for this.*/
+ writel(1, fep->enetbase + FSL_FEC_ECR0);
+ writel(1, fep->enetbase + FSL_FEC_ECR1);
+ udelay(10);
- for (num = 0; num < 8; num++) {
- u32 reg = readl(fep->membase + FEC_ESW_PSNP(num));
- if (compare_port ==
- AT_EXTRACT_TCP_UDP_PORT(reg)) {
- writel(tmp | FSL_ESW_PSNP_PORT_COMPARE(compare_port),
- fep->membase + FEC_ESW_PSNP(num));
- break;
- } else if (!reg) {
- writel(tmp | FSL_ESW_PSNP_PORT_COMPARE(compare_port),
- fep->membase + FEC_ESW_PSNP(num));
- break;
- }
- }
- if (num == 8) {
- printk(KERN_INFO "TCP/UDP port snooping table is full\n");
- return 0;
- }
+ writel(FSL_ESW_MODE_SW_RST, fep->membase + FEC_ESW_MODE);
+ udelay(10);
+ writel(FSL_ESW_MODE_STATRST, fep->membase + FEC_ESW_MODE);
+ writel(FSL_ESW_MODE_SW_EN, fep->membase + FEC_ESW_MODE);
- return 0;
-}
+ /* Enable transmit/receive on all ports */
+ writel(0xffffffff, fep->membase + FEC_ESW_PER);
-void esw_get_tcpudp_port_snoop_config(
- struct switch_enet_private *fep,
- unsigned long *ulpESW_PSNP)
-{
- int i;
+ /* Management port configuration,
+ * make port 0 as management port
+ */
+ writel(0, fep->membase + FEC_ESW_BMPC);
- for (i = 0; i < 8; i++)
- *(ulpESW_PSNP + i) = readl(fep->membase + FEC_ESW_PSNP(i));
-}
+ /* Clear any outstanding interrupt.*/
+ writel(0xffffffff, fep->membase + FEC_ESW_ISR);
-/*mirror*/
-void esw_get_port_mirroring(struct switch_enet_private *fep)
-{
- unsigned long tmp, tmp1, tmp2;
-
- tmp = readl(fep->membase + FEC_ESW_MCR);
-
- printk(KERN_INFO "Mirror Port: %ld Egress Port Match:%s "
- "Ingress Port Match:%s\n", tmp & 0xf,
- tmp & 1 ? "Y" : "N",
- tmp & 1 ? "Y" : "N");
-
- if ((tmp >> 6) & 1)
- printk(KERN_INFO "Egress Port to be mirrored: Port %d\n",
- readl(fep->membase + FEC_ESW_EGMAP) >> 1);
- if ((tmp >> 5) & 1)
- printk(KERN_INFO "Ingress Port to be mirrored: Port %d\n",
- readl(fep->membase + FEC_ESW_INGMAP) >> 1);
-
- printk(KERN_INFO "Egress Des Address Match:%s "
- "Egress Src Address Match:%s\n",
- (tmp >> 10) & 1 ? "Y" : "N",
- (tmp >> 9) & 1 ? "Y" : "N");
- printk(KERN_INFO "Ingress Des Address Match:%s "
- "Ingress Src Address Match:%s\n",
- (tmp >> 8) & 1 ? "Y" : "N",
- (tmp >> 7) & 1 ? "Y" : "N");
-
- if ((tmp >> 10) & 1) {
- tmp1 = readl(fep->membase + FEC_ESW_ENGDAL);
- tmp2 = readl(fep->membase + FEC_ESW_ENGDAH);
- printk(KERN_INFO "Egress Des Address to be mirrored: "
- "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
- tmp1 & 0xff,
- (tmp1 >> 8) & 0xff,
- (tmp1 >> 16) & 0xff,
- (tmp1 >> 24) & 0xff,
- tmp2 & 0xff,
- (tmp2 >> 8) & 0xff);
- }
- if ((tmp >> 9) & 1) {
- tmp1 = readl(fep->membase + FEC_ESW_ENGSAL);
- tmp2 = readl(fep->membase + FEC_ESW_ENGSAH);
- printk("Egress Src Address to be mirrored: "
- "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
- tmp1 & 0xff,
- (tmp1 >> 8) & 0xff,
- (tmp1 >> 16) & 0xff,
- (tmp1 >> 24) & 0xff,
- tmp2 & 0xff,
- (tmp2 >> 8) & 0xff);
- }
- if ((tmp >> 8) & 1) {
- tmp1 = readl(fep->membase + FEC_ESW_INGDAL);
- tmp2 = readl(fep->membase + FEC_ESW_INGDAH);
- printk("Ingress Des Address to be mirrored: "
- "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
- tmp1 & 0xff,
- (tmp1 >> 8) & 0xff,
- (tmp1 >> 16) & 0xff,
- (tmp1 >> 24) & 0xff,
- tmp2 & 0xff,
- (tmp2 >> 8) & 0xff);
- }
- if ((tmp >> 7) & 1) {
- tmp1 = readl(fep->membase + FEC_ESW_INGSAL);
- tmp2 = readl(fep->membase + FEC_ESW_INGSAH);
- printk("Ingress Src Address to be mirrored: "
- "%02lx-%02lx-%02lx-%02lx-%02lx-%02lx\n",
- tmp1 & 0xff,
- (tmp1 >> 8) & 0xff,
- (tmp1 >> 16) & 0xff,
- (tmp1 >> 24) & 0xff,
- tmp2 & 0xff,
- (tmp2 >> 8) & 0xff);
- }
-}
+ switch_hw_init(dev);
-int esw_port_mirroring_config_port_match(struct switch_enet_private *fep,
- int mirror_port, int port_match_en, int port)
-{
- unsigned long tmp = 0;
+ /* Set station address.*/
+ switch_get_mac_address(dev);
- tmp = readl(fep->membase + FEC_ESW_MCR);
- if (mirror_port != (tmp & 0xf))
- tmp = 0;
-
- switch (port_match_en) {
- case MIRROR_EGRESS_PORT_MATCH:
- tmp |= FSL_ESW_MCR_EGMAP;
- if (port == 0)
- writel(FSL_ESW_EGMAP_EG0, fep->membase + FEC_ESW_EGMAP);
- else if (port == 1)
- writel(FSL_ESW_EGMAP_EG1, fep->membase + FEC_ESW_EGMAP);
- else if (port == 2)
- writel(FSL_ESW_EGMAP_EG2, fep->membase + FEC_ESW_EGMAP);
- break;
- case MIRROR_INGRESS_PORT_MATCH:
- tmp |= FSL_ESW_MCR_INGMAP;
- if (port == 0)
- writel(FSL_ESW_INGMAP_ING0,
- fep->membase + FEC_ESW_INGMAP);
- else if (port == 1)
- writel(FSL_ESW_INGMAP_ING1,
- fep->membase + FEC_ESW_INGMAP);
- else if (port == 2)
- writel(FSL_ESW_INGMAP_ING2,
- fep->membase + FEC_ESW_INGMAP);
- break;
- default:
- tmp = 0;
- break;
- }
+ writel(0, fep->membase + FEC_ESW_IMR);
+ udelay(10);
- tmp = tmp & 0x07e0;
- if (port_match_en)
- tmp |= FSL_ESW_MCR_MEN | FSL_ESW_MCR_PORT(mirror_port);
+ /* Set maximum receive buffer size. */
+ writel(PKT_MAXBLR_SIZE, fep->membase + FEC_ESW_MRBR);
- writel(tmp, fep->membase + FEC_ESW_MCR);
- return 0;
-}
+ /* Set receive and transmit descriptor base. */
+ writel(fep->bd_dma, fep->membase + FEC_ESW_RDSR);
+ writel((unsigned long)fep->bd_dma +
+ sizeof(struct bufdesc) * RX_RING_SIZE,
+ fep->membase + FEC_ESW_TDSR);
-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)
-{
- unsigned long tmp;
-
- /*mirroring config*/
- tmp = 0;
- if (egress_en == 1) {
- tmp |= FSL_ESW_MCR_EGMAP;
- if (port == 0)
- writel(FSL_ESW_EGMAP_EG0, fep->membase + FEC_ESW_EGMAP);
- else if (port == 1)
- writel(FSL_ESW_EGMAP_EG1, fep->membase + FEC_ESW_EGMAP);
- else if (port == 2)
- writel(FSL_ESW_EGMAP_EG2, fep->membase + FEC_ESW_EGMAP);
- else {
- printk(KERN_ERR "%s: the port %x we do not support\n",
- __func__, port);
- return -1;
- }
- } else if (egress_en == 0) {
- tmp &= (~FSL_ESW_MCR_EGMAP);
- } else {
- printk(KERN_ERR "%s: egress_en %x we do not support\n",
- __func__, egress_en);
- return -1;
- }
+ fep->cur_tx = fep->tx_bd_base;
+ fep->dirty_tx = fep->cur_tx;
+ fep->cur_rx = fep->rx_bd_base;
- if (ingress_en == 1) {
- tmp |= FSL_ESW_MCR_INGMAP;
- if (port == 0)
- writel(FSL_ESW_INGMAP_ING0,
- fep->membase + FEC_ESW_INGMAP);
- else if (port == 1)
- writel(FSL_ESW_INGMAP_ING1,
- fep->membase + FEC_ESW_INGMAP);
- else if (port == 2)
- writel(FSL_ESW_INGMAP_ING2,
- fep->membase + FEC_ESW_INGMAP);
- else {
- printk(KERN_ERR "%s: the port %x we do not support\n",
- __func__, port);
- return -1;
+ /* Reset SKB transmit buffers. */
+ fep->skb_cur = 0;
+ 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;
}
- } else if (ingress_en == 0) {
- tmp &= ~FSL_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 |= FSL_ESW_MCR_EGSA;
- writel((src_mac[5] << 8) | (src_mac[4]),
- fep->membase + FEC_ESW_ENGSAH);
- writel((unsigned long)((src_mac[3] << 24) | (src_mac[2] << 16) |
- (src_mac[1] << 8) | src_mac[0]),
- fep->membase + FEC_ESW_ENGSAL);
- } else if (egress_mac_src_en == 0) {
- tmp &= ~FSL_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 |= FSL_ESW_MCR_EGDA;
- writel((des_mac[5] << 8) | (des_mac[4]),
- fep->membase + FEC_ESW_ENGDAH);
- writel((unsigned long)((des_mac[3] << 24) | (des_mac[2] << 16) |
- (des_mac[1] << 8) | des_mac[0]),
- fep->membase + FEC_ESW_ENGDAL);
- } else if (egress_mac_des_en == 0) {
- tmp &= ~FSL_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 |= FSL_ESW_MCR_INGSA;
- writel((src_mac[5] << 8) | (src_mac[4]),
- fep->membase + FEC_ESW_INGSAH);
- writel((unsigned long)((src_mac[3] << 24) | (src_mac[2] << 16) |
- (src_mac[1] << 8) | src_mac[0]),
- fep->membase + FEC_ESW_INGSAL);
- } else if (ingress_mac_src_en == 0) {
- tmp &= ~FSL_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 |= FSL_ESW_MCR_INGDA;
- writel((des_mac[5] << 8) | (des_mac[4]),
- fep->membase + FEC_ESW_INGDAH);
- writel((unsigned long)((des_mac[3] << 24) | (des_mac[2] << 16) |
- (des_mac[1] << 8) | des_mac[0]),
- fep->membase + FEC_ESW_INGDAL);
- } else if (ingress_mac_des_en == 0) {
- tmp &= ~FSL_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 |= FSL_ESW_MCR_MEN | FSL_ESW_MCR_PORT(mirror_port);
- else if (mirror_enable == 0)
- tmp &= ~FSL_ESW_MCR_MEN;
- else
- printk(KERN_ERR "%s: the mirror enable %x is error\n",
- __func__, mirror_enable);
-
-
- writel(tmp, fep->membase + FEC_ESW_MCR);
- 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)
-{
- unsigned long tmp = 0;
-
- tmp = readl(fep->membase + FEC_ESW_MCR);
- if (mirror_port != (tmp & 0xf))
- tmp = 0;
-
- switch (addr_match_enable) {
- case MIRROR_EGRESS_SOURCE_MATCH:
- tmp |= FSL_ESW_MCR_EGSA;
- writel((mac_addr[5] << 8) | (mac_addr[4]),
- fep->membase + FEC_ESW_ENGSAH);
- writel((unsigned long)((mac_addr[3] << 24) |
- (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]),
- fep->membase + FEC_ESW_ENGSAL);
- break;
- case MIRROR_INGRESS_SOURCE_MATCH:
- tmp |= FSL_ESW_MCR_INGSA;
- writel((mac_addr[5] << 8) | (mac_addr[4]),
- fep->membase + FEC_ESW_INGSAH);
- writel((unsigned long)((mac_addr[3] << 24) |
- (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]),
- fep->membase + FEC_ESW_INGSAL);
- break;
- case MIRROR_EGRESS_DESTINATION_MATCH:
- tmp |= FSL_ESW_MCR_EGDA;
- writel((mac_addr[5] << 8) | (mac_addr[4]),
- fep->membase + FEC_ESW_ENGDAH);
- writel((unsigned long)((mac_addr[3] << 24) |
- (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]),
- fep->membase + FEC_ESW_ENGDAL);
- break;
- case MIRROR_INGRESS_DESTINATION_MATCH:
- tmp |= FSL_ESW_MCR_INGDA;
- writel((mac_addr[5] << 8) | (mac_addr[4]),
- fep->membase + FEC_ESW_INGDAH);
- writel((unsigned long)((mac_addr[3] << 24) |
- (mac_addr[2] << 16) | (mac_addr[1] << 8) | mac_addr[0]),
- fep->membase + FEC_ESW_INGDAL);
- break;
- default:
- tmp = 0;
- break;
- }
-
- tmp = tmp & 0x07e0;
- if (addr_match_enable)
- tmp |= FSL_ESW_MCR_MEN | FSL_ESW_MCR_PORT(mirror_port);
-
- writel(tmp, fep->membase + FEC_ESW_MCR);
- return 0;
-}
+ /* hardware has set in hw_init */
+ fep->full_duplex = duplex;
-void esw_get_vlan_verification(struct switch_enet_private *fep,
- unsigned long *ulValue)
-{
- *ulValue = readl(fep->membase + FEC_ESW_VLANV);
+ /* Clear any outstanding interrupt.*/
+ writel(0xffffffff, fep->membase + FEC_ESW_ISR);
+ writel(FSL_ESW_IMR_RXF | FSL_ESW_IMR_TXF, fep->membase + FEC_ESW_IMR);
}
-int esw_set_vlan_verification(struct switch_enet_private *fep, int port,
- int vlan_domain_verify_en, int vlan_discard_unknown_en)
+static int switch_init_phy(struct net_device *dev)
{
- u32 tmp;
-
- if ((port < 0) || (port > 2)) {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, port);
- return -1;
- }
- tmp = readl(fep->membase + FEC_ESW_VLANV);
- if (vlan_domain_verify_en == 1) {
- if (port == 0)
- tmp |= FSL_ESW_VLANV_VV0;
- else if (port == 1)
- tmp |= FSL_ESW_VLANV_VV1;
- else if (port == 2)
- tmp |= FSL_ESW_VLANV_VV2;
- } else if (vlan_domain_verify_en == 0) {
- if (port == 0)
- tmp &= ~FSL_ESW_VLANV_VV0;
- else if (port == 1)
- tmp &= ~FSL_ESW_VLANV_VV1;
- else if (port == 2)
- tmp &= ~FSL_ESW_VLANV_VV2;
- } else {
- printk(KERN_INFO "%s: donot support "
- "vlan_domain_verify %x\n",
- __func__, vlan_domain_verify_en);
- return -2;
- }
+ struct switch_enet_private *priv = netdev_priv(dev);
+ struct phy_device *phydev[SWITCH_EPORT_NUMBER] = {NULL, NULL};
+ int i, j = 0;
- if (vlan_discard_unknown_en == 1) {
- if (port == 0)
- tmp |= FSL_ESW_VLANV_DU0;
- else if (port == 1)
- tmp |= FSL_ESW_VLANV_DU1;
- else if (port == 2)
- tmp |= FSL_ESW_VLANV_DU2;
- } else if (vlan_discard_unknown_en == 0) {
- if (port == 0)
- tmp &= ~FSL_ESW_VLANV_DU0;
- else if (port == 1)
- tmp &= ~FSL_ESW_VLANV_DU1;
- else if (port == 2)
- tmp &= ~FSL_ESW_VLANV_DU2;
- } else {
- printk(KERN_INFO "%s: donot support "
- "vlan_discard_unknown %x\n",
- __func__, vlan_discard_unknown_en);
- return -3;
- }
+ /* 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];
- writel(tmp, fep->membase + FEC_ESW_VLANV);
- return 0;
-}
+ if (!tmp_phydev)
+ continue;
-void esw_get_vlan_resolution_table(struct switch_enet_private *fep,
- struct eswVlanTableItem *tableaddr)
-{
- int vnum = 0;
- int i;
- u32 tmp;
-
- for (i = 0; i < 32; i++) {
- tmp = readl(fep->membase + FEC_ESW_VRES(i));
- if (tmp) {
- tableaddr->table[i].port_vlanid =
- tmp >> 3;
- tableaddr->table[i].vlan_domain_port =
- tmp & 7;
- vnum++;
- }
+ phydev[j++] = tmp_phydev;
+ if (j >= SWITCH_EPORT_NUMBER)
+ break;
}
- tableaddr->valid_num = vnum;
-}
-int esw_set_vlan_id(struct switch_enet_private *fep, unsigned long configData)
-{
- int i;
- u32 tmp;
-
- for (i = 0; i < 32; i++) {
- tmp = readl(fep->membase + FEC_ESW_VRES(i));
- if (tmp == 0) {
- writel(FSL_ESW_VRES_VLANID(configData),
- fep->membase + FEC_ESW_VRES(i));
- return 0;
- } else if (((tmp >> 3) & 0xfff) == configData) {
- printk(KERN_INFO "The VLAN already exists\n");
- return 0;
- }
+ /* now we are supposed to have a proper phydev, to attach to... */
+ if ((!phydev[0]) && (!phydev[1])) {
+ netdev_info(dev, "%s: Didn't find any PHY device at all\n",
+ dev->name);
+ return -ENODEV;
}
- 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)
-{
- int i;
- u32 tmp;
-
- for (i = 0; i < 32; i++) {
- tmp = readl(fep->membase + FEC_ESW_VRES(i));
- if (((tmp >> 3) & 0xfff) == configData) {
- writel(0, fep->membase + FEC_ESW_VRES(i));
- break;
- }
- }
- return 0;
-}
+ priv->phy1_link = PHY_DOWN;
+ priv->phy1_old_link = PHY_DOWN;
+ priv->phy1_speed = 0;
+ priv->phy1_duplex = -1;
-int esw_set_port_in_vlan_id(struct switch_enet_private *fep,
- eswIoctlVlanResoultionTable configData)
-{
- int i;
- int lastnum = 0;
- u32 tmp;
+ priv->phy2_link = PHY_DOWN;
+ priv->phy2_old_link = PHY_DOWN;
+ priv->phy2_speed = 0;
+ priv->phy2_duplex = -1;
- for (i = 0; i < 32; i++) {
- tmp = readl(fep->membase + FEC_ESW_VRES(i));
- if (tmp == 0) {
- lastnum = i;
- break;
- } else if (((tmp >> 3) & 0xfff) ==
- configData.port_vlanid) {
- /* update the port members of this vlan */
- tmp |= 1 << configData.vlan_domain_port;
- writel(tmp, fep->membase + FEC_ESW_VRES(i));
- return 0;
- }
+ phydev[0] = phy_connect(dev, dev_name(&phydev[0]->dev),
+ &switch_adjust_link1, PHY_INTERFACE_MODE_RMII);
+ if (IS_ERR(phydev[0])) {
+ netdev_err(dev, " %s phy_connect failed\n", __func__);
+ return PTR_ERR(phydev[0]);
}
- /* creat a new vlan in vlan table */
- writel(FSL_ESW_VRES_VLANID(configData.port_vlanid) |
- (1 << configData.vlan_domain_port),
- fep->membase + FEC_ESW_VRES(lastnum));
- 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)
-{
- 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;
+ phydev[1] = phy_connect(dev, dev_name(&phydev[1]->dev),
+ &switch_adjust_link2, PHY_INTERFACE_MODE_RMII);
+ if (IS_ERR(phydev[1])) {
+ netdev_err(dev, " %s phy_connect failed\n", __func__);
+ return PTR_ERR(phydev[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;
+ for (i = 0; i < SWITCH_EPORT_NUMBER; i++) {
+ phydev[i]->supported &= PHY_BASIC_FEATURES;
+ phydev[i]->advertising = phydev[i]->supported;
+ priv->phydev[i] = phydev[i];
+ netdev_info(dev, "attached phy %i to driver %s "
+ "(mii_bus:phy_addr=%s, irq=%d)\n",
+ phydev[i]->addr, phydev[i]->drv->name,
+ dev_name(&priv->phydev[i]->dev),
+ priv->phydev[i]->irq);
}
- writel(
- FSL_ESW_VRES_VLANID(port_vlanid)
- | vlan_domain_port,
- fep->membase + FEC_ESW_VRES(vlan_domain_num));
-
return 0;
}
-void esw_get_vlan_input_config(struct switch_enet_private *fep,
- eswIoctlVlanInputStatus *pVlanInputConfig)
+static void switch_stop(struct net_device *dev)
{
- int i;
-
- for (i = 0; i < 3; i++)
- pVlanInputConfig->ESW_PID[i] =
- readl(fep->membase + FEC_ESW_PID(i));
+ struct switch_enet_private *fep = netdev_priv(dev);
- pVlanInputConfig->ESW_VLANV = readl(fep->membase + FEC_ESW_VLANV);
- pVlanInputConfig->ESW_VIMSEL = readl(fep->membase + FEC_ESW_VIMSEL);
- pVlanInputConfig->ESW_VIMEN = readl(fep->membase + FEC_ESW_VIMEN);
+ /* We cannot expect a graceful transmit
+ * stop without link
+ */
+ if (fep->phy1_link)
+ udelay(10);
+ if (fep->phy2_link)
+ udelay(10);
- for (i = 0; i < 32; i++)
- pVlanInputConfig->ESW_VRES[i] =
- readl(fep->membase + FEC_ESW_VRES(i));
+ /* Whack a reset. We should wait for this */
+ udelay(10);
}
-
-int esw_vlan_input_process(struct switch_enet_private *fep,
- int port, int mode, unsigned short port_vlanid)
+static int switch_enet_clk_enable(struct net_device *ndev, bool enable)
{
- u32 tmp;
-
- if ((mode < 0) || (mode > 5)) {
- printk(KERN_ERR "%s: do not support the"
- " VLAN input processing mode %d\n",
- __func__, mode);
- return -1;
- }
+ struct switch_enet_private *fep = netdev_priv(ndev);
+ int ret;
- if ((port < 0) || (port > 3)) {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, mode);
- return -2;
- }
+ if (enable) {
+ ret = clk_prepare_enable(fep->clk_esw);
+ if (ret)
+ goto failed_clk_esw;
- writel(FSL_ESW_PID_VLANID(port_vlanid),
- fep->membase + FEC_ESW_PID(port));
+ ret = clk_prepare_enable(fep->clk_enet);
+ if (ret)
+ goto failed_clk_enet;
- if (port == 0) {
- tmp = readl(fep->membase + FEC_ESW_VIMEN);
- if (mode == 4)
- tmp &= ~FSL_ESW_VIMEN_EN0;
- else
- tmp |= FSL_ESW_VIMEN_EN0;
- writel(tmp, fep->membase + FEC_ESW_VIMEN);
-
- tmp = readl(fep->membase + FEC_ESW_VIMSEL);
- tmp &= ~FSL_ESW_VIMSEL_IM0(3);
- tmp |= FSL_ESW_VIMSEL_IM0(mode);
- writel(tmp, fep->membase + FEC_ESW_VIMSEL);
- } else if (port == 1) {
- tmp = readl(fep->membase + FEC_ESW_VIMEN);
- if (mode == 4)
- tmp &= ~FSL_ESW_VIMEN_EN1;
- else
- tmp |= FSL_ESW_VIMEN_EN1;
- writel(tmp, fep->membase + FEC_ESW_VIMEN);
-
- tmp = readl(fep->membase + FEC_ESW_VIMSEL);
- tmp &= ~FSL_ESW_VIMSEL_IM1(3);
- tmp |= FSL_ESW_VIMSEL_IM1(mode);
- writel(tmp, fep->membase + FEC_ESW_VIMSEL);
- } else if (port == 2) {
- tmp = readl(fep->membase + FEC_ESW_VIMEN);
- if (mode == 4)
- tmp &= ~FSL_ESW_VIMEN_EN2;
- else
- tmp |= FSL_ESW_VIMEN_EN2;
- writel(tmp, fep->membase + FEC_ESW_VIMEN);
+ ret = clk_prepare_enable(fep->clk_enet0);
+ if (ret)
+ goto failed_clk_enet0;
- tmp = readl(fep->membase + FEC_ESW_VIMSEL);
- tmp &= ~FSL_ESW_VIMSEL_IM2(3);
- tmp |= FSL_ESW_VIMSEL_IM2(mode);
- writel(tmp, fep->membase + FEC_ESW_VIMSEL);
+ ret = clk_prepare_enable(fep->clk_enet1);
+ if (ret)
+ goto failed_clk_enet1;
} else {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, port);
- return -2;
+ clk_disable_unprepare(fep->clk_esw);
+ clk_disable_unprepare(fep->clk_enet);
+ clk_disable_unprepare(fep->clk_enet0);
+ clk_disable_unprepare(fep->clk_enet1);
}
return 0;
-}
-void esw_get_vlan_output_config(struct switch_enet_private *fep,
- unsigned long *ulVlanOutputConfig)
-{
- *ulVlanOutputConfig = readl(fep->membase + FEC_ESW_VOMSEL);
-}
-
-int esw_vlan_output_process(struct switch_enet_private *fep,
- int port, int mode)
-{
- u32 tmp;
+failed_clk_esw:
+ clk_disable_unprepare(fep->clk_esw);
+failed_clk_enet:
+ clk_disable_unprepare(fep->clk_enet);
+failed_clk_enet0:
+ clk_disable_unprepare(fep->clk_enet0);
+failed_clk_enet1:
+ clk_disable_unprepare(fep->clk_enet1);
- if ((port < 0) || (port > 2)) {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, mode);
- return -1;
- }
- tmp = readl(fep->membase + FEC_ESW_VOMSEL);
- if (port == 0) {
- tmp &= ~FSL_ESW_VOMSEL_OM0(3);
- tmp |= FSL_ESW_VOMSEL_OM0(mode);
- } else if (port == 1) {
- tmp &= ~FSL_ESW_VOMSEL_OM1(3);
- tmp |= FSL_ESW_VOMSEL_OM1(mode);
- } else if (port == 2) {
- tmp &= ~FSL_ESW_VOMSEL_OM2(3);
- tmp |= FSL_ESW_VOMSEL_OM2(mode);
- } else {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, port);
- return -1;
- }
- writel(tmp, fep->membase + FEC_ESW_VOMSEL);
- return 0;
+ return ret;
}
-/*
- * 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)
+static void switch_enet_free_buffers(struct net_device *ndev)
{
- u32 tmp;
-
- if ((port < 0) || (port > 3)) {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, port);
- return -1;
- }
+ struct switch_enet_private *fep = netdev_priv(ndev);
+ int i;
+ struct sk_buff *skb;
+ cbd_t *bdp;
- if (func_enable == 0) {
- tmp = readl(fep->membase + FEC_ESW_PRES(port));
- tmp &= ~FSL_ESW_PRES_VLAN;
- writel(tmp, fep->membase + FEC_ESW_PRES(port));
- printk(KERN_ERR "%s: disable port %d VLAN priority "
- "lookup function\n", __func__, port);
- return 0;
- }
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = fep->rx_skbuff[i];
- 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;
+ if (bdp->cbd_bufaddr)
+ dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
+ SWITCH_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ if (skb)
+ dev_kfree_skb(skb);
+ bdp++;
}
- tmp = readl(fep->membase + FEC_ESW_PVRES(port));
- tmp |= ((vlan_pri_table_value & 0x3)
- << (vlan_pri_table_num*3));
- writel(tmp, fep->membase + FEC_ESW_PVRES(port));
-
- /* enable port VLAN priority lookup function*/
- tmp = readl(fep->membase + FEC_ESW_PRES(port));
- tmp |= FSL_ESW_PRES_VLAN;
- writel(tmp, fep->membase + FEC_ESW_PRES(port));
- return 0;
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++)
+ kfree(fep->tx_bounce[i]);
}
-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)
+static int switch_alloc_buffers(struct net_device *ndev)
{
- unsigned long tmp = 0, tmp_prio = 0;
-
- if ((port < 0) || (port > 3)) {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, port);
- return -1;
- }
-
- if (func_enable == 0) {
- tmp = readl(fep->membase + FEC_ESW_PRES(port));
- tmp &= ~FSL_ESW_PRES_IP;
- writel(tmp, fep->membase + FEC_ESW_PRES(port));
- printk(KERN_ERR "%s: disable port %d ip priority "
- "lookup function\n", __func__, port);
- return 0;
- }
+ struct switch_enet_private *fep = netdev_priv(ndev);
+ int i;
+ struct sk_buff *skb;
+ cbd_t *bdp;
- /* 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;
+ bdp = fep->rx_bd_base;
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = dev_alloc_skb(SWITCH_ENET_RX_FRSIZE);
+ if (!skb) {
+ switch_enet_free_buffers(ndev);
+ return -ENOMEM;
}
- }
-
- /* IP priority table lookup : address*/
- tmp = FSL_ESW_IPRES_ADDRESS(ip_priority_num);
- /* IP priority table lookup : ipv4sel*/
- if (ipv4_en == 1)
- tmp = tmp | FSL_ESW_IPRES_IPV4SEL;
- /* IP priority table lookup : priority*/
- if (port == 0)
- tmp |= FSL_ESW_IPRES_PRI0(ip_priority_value);
- else if (port == 1)
- tmp |= FSL_ESW_IPRES_PRI1(ip_priority_value);
- else if (port == 2)
- tmp |= FSL_ESW_IPRES_PRI2(ip_priority_value);
-
- /* configure*/
- writel(FSL_ESW_IPRES_READ | FSL_ESW_IPRES_ADDRESS(ip_priority_num),
- fep->membase + FEC_ESW_IPRES);
- tmp_prio = readl(fep->membase + FEC_ESW_IPRES);
-
- writel(tmp | tmp_prio, fep->membase + FEC_ESW_IPRES);
-
- writel(FSL_ESW_IPRES_READ | FSL_ESW_IPRES_ADDRESS(ip_priority_num),
- fep->membase + FEC_ESW_IPRES);
- tmp_prio = readl(fep->membase + FEC_ESW_IPRES);
-
- /* enable port IP priority lookup function*/
- tmp = readl(fep->membase + FEC_ESW_PRES(port));
- tmp |= FSL_ESW_PRES_IP;
- writel(tmp, fep->membase + FEC_ESW_PRES(port));
- return 0;
-}
-
-int esw_framecalssify_mac_priority_lookup(
- struct switch_enet_private *fep, int port)
-{
- u32 tmp;
-
- if ((port < 0) || (port > 3)) {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, port);
- return -1;
- }
-
- tmp = readl(fep->membase + FEC_ESW_PRES(port));
- tmp |= FSL_ESW_PRES_MAC;
- writel(tmp, fep->membase + FEC_ESW_PRES(port));
-
- return 0;
-}
-
-int esw_frame_calssify_priority_init(struct switch_enet_private *fep,
- int port, unsigned char priority_value)
-{
- 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*/
- writel(0, fep->membase + FEC_ESW_PRES(port));
- writel(FSL_ESW_PRES_DFLT_PRI(priority_value & 0x7),
- fep->membase + FEC_ESW_PRES(port));
-
- return 0;
-}
+ fep->rx_skbuff[i] = skb;
-int esw_get_statistics_status(struct switch_enet_private *fep,
- esw_statistics_status *pStatistics)
-{
- pStatistics->ESW_DISCN = readl(fep->membase + FEC_ESW_DISCN);
- pStatistics->ESW_DISCB = readl(fep->membase + FEC_ESW_DISCB);
- pStatistics->ESW_NDISCN = readl(fep->membase + FEC_ESW_NDISCN);
- pStatistics->ESW_NDISCB = readl(fep->membase + FEC_ESW_NDISCB);
- return 0;
-}
+ bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
+ SWITCH_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ bdp->cbd_sc = BD_ENET_RX_EMPTY;
-int esw_get_port_statistics_status(struct switch_enet_private *fep,
- int port, esw_port_statistics_status *pPortStatistics)
-{
- if ((port < 0) || (port > 3)) {
- printk(KERN_ERR "%s: do not support the port %d\n",
- __func__, port);
- return -1;
+ bdp++;
}
- pPortStatistics->FSL_ESW_POQC =
- readl(fep->membase + FEC_ESW_POQC(port));
- pPortStatistics->FSL_ESW_PMVID =
- readl(fep->membase + FEC_ESW_PMVID(port));
- pPortStatistics->FSL_ESW_PMVTAG =
- readl(fep->membase + FEC_ESW_PMVTAG(port));
- pPortStatistics->FSL_ESW_PBL =
- readl(fep->membase + FEC_ESW_PBL(port));
- return 0;
-}
-
-int esw_get_output_queue_status(struct switch_enet_private *fep,
- esw_output_queue_status *pOutputQueue)
-{
- pOutputQueue->ESW_MMSR = readl(fep->membase + FEC_ESW_MMSR);
- pOutputQueue->ESW_LMT = readl(fep->membase + FEC_ESW_LMT);
- pOutputQueue->ESW_LFC = readl(fep->membase + FEC_ESW_LFC);
- pOutputQueue->ESW_IOSR = readl(fep->membase + FEC_ESW_IOSR);
- pOutputQueue->ESW_PCSR = readl(fep->membase + FEC_ESW_PCSR);
- pOutputQueue->ESW_QWT = readl(fep->membase + FEC_ESW_QWT);
- pOutputQueue->ESW_P0BCT = readl(fep->membase + FEC_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)
-{
- if (fun_num == 1) {
- /* memory manager status*/
- writel(pOutputQueue->ESW_MMSR, fep->membase + FEC_ESW_MMSR);
- } else if (fun_num == 2) {
- /*low memory threshold*/
- writel(pOutputQueue->ESW_LMT, fep->membase + FEC_ESW_LMT);
- } else if (fun_num == 3) {
- /*lowest number of free cells*/
- writel(pOutputQueue->ESW_LFC, fep->membase + FEC_ESW_LFC);
- } else if (fun_num == 4) {
- /*queue weights*/
- writel(pOutputQueue->ESW_QWT, fep->membase + FEC_ESW_QWT);
- } else if (fun_num == 5) {
- /*port 0 backpressure congenstion thresled*/
- writel(pOutputQueue->ESW_P0BCT, fep->membase + FEC_ESW_P0BCT);
- } else {
- printk(KERN_ERR "%s: do not support the cmd %x\n",
- __func__, fun_num);
- return -1;
- }
- return 0;
-}
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
-int esw_get_irq_status(struct switch_enet_private *fep,
- eswIoctlIrqStatus *pIrqStatus)
-{
- pIrqStatus->isr = readl(fep->membase + FEC_ESW_ISR);
- pIrqStatus->imr = readl(fep->membase + FEC_ESW_IMR);
- pIrqStatus->rx_buf_pointer = readl(fep->membase + FEC_ESW_RDSR);
- pIrqStatus->tx_buf_pointer = readl(fep->membase + FEC_ESW_TDSR);
- pIrqStatus->rx_max_size = readl(fep->membase + FEC_ESW_MRBR);
- pIrqStatus->rx_buf_active = readl(fep->membase + FEC_ESW_RDAR);
- pIrqStatus->tx_buf_active = readl(fep->membase + FEC_ESW_TDAR);
- return 0;
-}
+ bdp = fep->tx_bd_base;
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ fep->tx_bounce[i] = kmalloc(SWITCH_ENET_TX_FRSIZE, GFP_KERNEL);
-int esw_set_irq_mask(struct switch_enet_private *fep,
- unsigned long mask, int enable)
-{
- u32 tmp = readl(fep->membase + FEC_ESW_IMR);
-
- if (enable == 1)
- tmp |= mask;
- else if (enable == 1)
- tmp &= (~mask);
- else {
- printk(KERN_INFO "%s: enable %lx is error value\n",
- __func__, mask);
- return -1;
+ bdp->cbd_sc = 0;
+ bdp->cbd_bufaddr = 0;
+ bdp++;
}
- writel(tmp, fep->membase + FEC_ESW_IMR);
- return 0;
-}
-void esw_clear_irq_event(struct switch_enet_private *fep,
- unsigned long mask)
-{
- u32 tmp = readl(fep->membase + FEC_ESW_ISR);
- tmp |= mask;
- writel(tmp, fep->membase + FEC_ESW_ISR);
-}
-
-void esw_get_switch_mode(struct switch_enet_private *fep,
- unsigned long *ulModeConfig)
-{
- *ulModeConfig = readl(fep->membase + FEC_ESW_MODE);
-}
-
-void esw_switch_mode_configure(struct switch_enet_private *fep,
- unsigned long configure)
-{
- u32 tmp = readl(fep->membase + FEC_ESW_MODE);
- tmp |= configure;
- writel(tmp, fep->membase + FEC_ESW_MODE);
-}
-
-void esw_get_bridge_port(struct switch_enet_private *fep,
- unsigned long *ulBMPConfig)
-{
- *ulBMPConfig = readl(fep->membase + FEC_ESW_BMPC);
-}
-
-void esw_bridge_port_configure(struct switch_enet_private *fep,
- unsigned long configure)
-{
- writel(configure, fep->membase + FEC_ESW_BMPC);
-}
+ /* Set the last buffer to wrap. */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
-int esw_get_port_all_status(struct switch_enet_private *fep,
- unsigned char portnum, struct port_all_status *port_alstatus)
-{
- unsigned long PortBlocking;
- unsigned long PortLearning;
- unsigned long VlanVerify;
- unsigned long DiscardUnknown;
- unsigned long MultiReso;
- unsigned long BroadReso;
- unsigned long FTransmit;
- unsigned long FReceive;
-
- PortBlocking = readl(fep->membase + FEC_ESW_BKLR) & 0x0000000f;
- PortLearning = (readl(fep->membase + FEC_ESW_BKLR) & 0x000f0000) >> 16;
- VlanVerify = readl(fep->membase + FEC_ESW_VLANV) & 0x0000000f;
- DiscardUnknown = (readl(fep->membase + FEC_ESW_VLANV) & 0x000f0000)
- >> 16;
- MultiReso = readl(fep->membase + FEC_ESW_DMCR) & 0x0000000f;
- BroadReso = readl(fep->membase + FEC_ESW_DBCR) & 0x0000000f;
- FTransmit = readl(fep->membase + FEC_ESW_PER) & 0x0000000f;
- FReceive = (readl(fep->membase + FEC_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)
+static int switch_enet_open(struct net_device *dev)
{
- 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;
- }
+ struct switch_enet_private *fep = netdev_priv(dev);
+ int port = 0;
+ unsigned long tmp = 0;
- return 0;
-}
+ fep->phy1_link = 0;
+ fep->phy2_link = 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++;
- }
+ switch_init_phy(dev);
+ for (port = 0; port < SWITCH_EPORT_NUMBER; port++) {
+ phy_write(fep->phydev[port], MII_BMCR, BMCR_RESET);
+ udelay(10);
+ phy_start(fep->phydev[port]);
}
- *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->phy1_old_link = 0;
+ fep->phy2_old_link = 0;
+ fep->phy1_link = 1;
+ fep->phy2_link = 1;
- fep = (struct switch_enet_private *)data;
+ /* no phy, go full duplex, it's most likely a hub chip */
+ switch_restart(dev, 1);
- if (fep) {
- TIMEINCREMENT(fep->currTime);
- fep->timeChanged++;
- }
+ /* if the fec open firstly, we need to do nothing
+ * otherwise, we need to restart the FEC
+ */
+ if (fep->sequence_done == 0)
+ switch_restart(dev, 1);
+ else
+ fep->sequence_done = 0;
- mod_timer(&fep->timer_aging, jiffies + LEARNING_AGING_TIMER);
-}
+ writel(0x70007, fep->membase + FEC_ESW_PER);
+ writel(FSL_ESW_DBCR_P0 | FSL_ESW_DBCR_P1 | FSL_ESW_DBCR_P2,
+ fep->membase + FEC_ESW_DBCR);
+ writel(FSL_ESW_DMCR_P0 | FSL_ESW_DMCR_P1 | FSL_ESW_DMCR_P2,
+ fep->membase + FEC_ESW_DMCR);
-static int switch_enet_learning(void *arg)
-{
- struct switch_enet_private *fep = arg;
+ /* Disable port learning */
+ tmp = readl(fep->membase + FEC_ESW_BKLR);
+ tmp &= ~FSL_ESW_BKLR_LDX;
+ writel(tmp, fep->membase + FEC_ESW_BKLR);
- while (!kthread_should_stop()) {
+ netif_start_queue(dev);
- set_current_state(TASK_INTERRUPTIBLE);
+ /* And last, enable the receive processing. */
+ writel(FSL_ESW_RDAR_R_DES_ACTIVE, fep->membase + FEC_ESW_RDAR);
- /* check learning record valid */
- if (readl(fep->membase + FEC_ESW_LSR))
- esw_atable_dynamicms_learn_migration(fep,
- fep->currTime);
- else
- schedule_timeout(HZ/100);
- }
+ fep->opened = 1;
return 0;
}
-static int switch_enet_ioctl(struct net_device *dev,
- struct ifreq *ifr, int cmd)
+static int switch_enet_close(struct net_device *dev)
{
struct switch_enet_private *fep = netdev_priv(dev);
- int ret = 0;
-
- 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.FSL_ESW_POQC);
- printk(KERN_INFO " PMVID : %ld\n",
- PortSta.FSL_ESW_PMVID);
- printk(KERN_INFO " PMVTAG: %ld\n",
- PortSta.FSL_ESW_PMVTAG);
- printk(KERN_INFO " PBL : %ld\n",
- PortSta.FSL_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));
+ int i;
- if (ret)
- return -EFAULT;
- user_pid = get_pid;
- }
- break;
+ /* Don't know what to do yet. */
+ fep->opened = 0;
+ netif_stop_queue(dev);
+ switch_stop(dev);
- default:
- return -EOPNOTSUPP;
+ 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 ret;
+ return 0;
}
static netdev_tx_t switch_enet_start_xmit(struct sk_buff *skb,
@@ -3101,19 +547,18 @@ static netdev_tx_t switch_enet_start_xmit(struct sk_buff *skb,
/* Clear all of the status flags */
status &= ~BD_ENET_TX_STATS;
- /* Set buffer length and buffer pointer.
- */
+ /* Set buffer length and buffer pointer. */
bufaddr = skb->data;
bdp->cbd_datlen = skb->len;
- /*
- * On some FEC implementations data must be aligned on
+ /* On some FEC implementations data must be aligned on
* 4-byte boundaries. Use bounce buffers to copy data
* and get it aligned. Ugh.
*/
if (((unsigned long)bufaddr) & 0xf) {
unsigned int index;
index = bdp - fep->tx_bd_base;
+
memcpy(fep->tx_bounce[index],
(void *)skb->data, bdp->cbd_datlen);
bufaddr = fep->tx_bounce[index];
@@ -3123,7 +568,7 @@ static netdev_tx_t switch_enet_start_xmit(struct sk_buff *skb,
fep->tx_skbuff[fep->skb_cur] = skb;
dev->stats.tx_bytes += skb->len;
- fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
+ fep->skb_cur = (fep->skb_cur + 1) & TX_RING_MOD_MASK;
/* Push the data cache so the CPM does not get stale memory
* data.
@@ -3144,7 +589,8 @@ static netdev_tx_t switch_enet_start_xmit(struct sk_buff *skb,
writel(FSL_ESW_TDAR_X_DES_ACTIVE, fep->membase + FEC_ESW_TDAR);
/* If this was the last BD in the ring,
- * start at the beginning again.*/
+ * start at the beginning again.
+ */
if (status & BD_ENET_TX_WRAP)
bdp = fep->tx_bd_base;
else
@@ -3153,7 +599,7 @@ static netdev_tx_t switch_enet_start_xmit(struct sk_buff *skb,
if (bdp == fep->dirty_tx) {
fep->tx_full = 1;
netif_stop_queue(dev);
- printk(KERN_ERR "%s: net stop\n", __func__);
+ netdev_err(dev, "%s: net stop\n", __func__);
}
fep->cur_tx = (cbd_t *)bdp;
@@ -3167,41 +613,101 @@ 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);
+ netdev_err(dev, "%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)
+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_tx_timeout = switch_timeout,
+};
+
+/* Initialize the FEC Ethernet. */
+static int switch_enet_init(struct net_device *dev)
{
- struct net_device *dev = dev_id;
struct switch_enet_private *fep = netdev_priv(dev);
- uint int_events;
- irqreturn_t ret = IRQ_NONE;
+ cbd_t *cbd_base = NULL;
+ int ret = 0;
- /* Get the interrupt events that caused us to be here.
- */
- do {
- int_events = readl(fep->membase + FEC_ESW_ISR);
- writel(int_events, fep->membase + FEC_ESW_ISR);
+ /* Allocate memory for buffer descriptors. */
+ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
+ GFP_KERNEL);
+ if (!cbd_base) {
+ return -ENOMEM;
+ }
- /* Handle receive event in its own function. */
+ spin_lock_init(&fep->hw_lock);
+ spin_lock_init(&fep->mii_lock);
- if (int_events & FSL_ESW_ISR_RXF) {
- ret = IRQ_HANDLED;
- switch_enet_rx(dev);
- }
+ writel(FSL_ESW_MODE_SW_RST, fep->membase + FEC_ESW_MODE);
+ udelay(10);
+ writel(FSL_ESW_MODE_STATRST, fep->membase + FEC_ESW_MODE);
+ writel(FSL_ESW_MODE_SW_EN, fep->membase + FEC_ESW_MODE);
- if (int_events & FSL_ESW_ISR_TXF) {
- ret = IRQ_HANDLED;
- switch_enet_tx(dev);
- }
+ /* Enable transmit/receive on all ports */
+ writel(0xffffffff, fep->membase + FEC_ESW_PER);
- } while (int_events);
+ /* Management port configuration,
+ * make port 0 as management port
+ */
+ writel(0, fep->membase + FEC_ESW_BMPC);
+
+ /* Clear any outstanding interrupt.*/
+ writel(0xffffffff, fep->membase + FEC_ESW_ISR);
+ writel(0, fep->membase + FEC_ESW_IMR);
+ udelay(100);
+
+ /* Get the Ethernet address */
+ switch_get_mac_address(dev);
+
+ /* 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)fep->membase;
+
+ /* The FEC Ethernet specific entries in the device structure. */
+ dev->watchdog_timeo = TX_TIMEOUT;
+ dev->netdev_ops = &switch_netdev_ops;
+
+ fep->skb_cur = fep->skb_dirty = 0;
+
+ ret = switch_alloc_buffers(dev);
+ if (ret)
+ goto err_enet_alloc;
+
+ /* Set receive and transmit descriptor base */
+ writel(fep->bd_dma, fep->membase + FEC_ESW_RDSR);
+ writel((unsigned long)fep->bd_dma +
+ sizeof(struct bufdesc) * RX_RING_SIZE,
+ fep->membase + FEC_ESW_TDSR);
+
+ /* set mii */
+ switch_hw_init(dev);
+
+ /* Clear any outstanding interrupt. */
+ writel(0xffffffff, fep->membase + FEC_ESW_ISR);
+ writel(FSL_ESW_IMR_RXF | FSL_ESW_IMR_TXF, fep->membase + FEC_ESW_IMR);
+
+ /* 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 ret;
+
+err_enet_alloc:
+ switch_enet_clk_enable(dev, false);
return ret;
}
@@ -3271,7 +777,7 @@ static void switch_enet_tx(struct net_device *dev)
*/
if (fep->tx_full) {
fep->tx_full = 0;
- printk(KERN_ERR "%s: tx full is zero\n", __func__);
+ netdev_err(dev, "%s: tx full is zero\n", __func__);
if (netif_queue_stopped(dev))
netif_wake_queue(dev);
}
@@ -3280,7 +786,6 @@ static void switch_enet_tx(struct net_device *dev)
spin_unlock_irqrestore(&fep->hw_lock, flags);
}
-
/* 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,
@@ -3305,12 +810,11 @@ static void switch_enet_rx(struct net_device *dev)
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");
+ netdev_err(dev, "SWITCH ENET: rcv is not +last\n");
if (!fep->opened)
goto rx_processing_done;
@@ -3333,7 +837,7 @@ static void switch_enet_rx(struct net_device *dev)
/* 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++;
@@ -3353,15 +857,16 @@ static void switch_enet_rx(struct net_device *dev)
* 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 - 4 + NET_IP_ALIGN);
- if (skb == NULL)
+ if (!skb)
dev->stats.rx_dropped++;
if (unlikely(!skb)) {
- printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n",
- dev->name);
+ netdev_err(dev,
+ "%s:Memory squeeze, dropping packet.\n",
+ dev->name);
dev->stats.rx_dropped++;
} else {
skb_reserve(skb, NET_IP_ALIGN);
@@ -3391,7 +896,7 @@ rx_processing_done:
/* 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.
- * */
+ */
writel(FSL_ESW_RDAR_R_DES_ACTIVE, fep->membase + FEC_ESW_RDAR);
}
fep->cur_rx = (cbd_t *)bdp;
@@ -3402,10 +907,10 @@ rx_processing_done:
static int fec_mdio_transfer(struct mii_bus *bus, int phy_id,
int reg, int regval)
{
- unsigned long flags;
+
struct switch_enet_private *fep = bus->priv;
- int retval = 0;
- int tries = 100;
+ unsigned long flags;
+ int retval = 0, tries = 100;
spin_lock_irqsave(&fep->mii_lock, flags);
@@ -3416,7 +921,8 @@ static int fec_mdio_transfer(struct mii_bus *bus, int phy_id,
writel(regval, fep->enetbase + FSL_FEC_MMFR0);
/* wait for it to finish, this takes about 23 us on lite5200b */
- while (!(readl(fep->enetbase + FSL_FEC_EIR0) & FEC_ENET_MII) && --tries)
+ while (!(readl(fep->enetbase + FSL_FEC_EIR0)
+ & FEC_ENET_MII) && --tries)
udelay(5);
if (!tries) {
printk(KERN_ERR "%s timeout\n", __func__);
@@ -3433,7 +939,8 @@ static int fec_mdio_transfer(struct mii_bus *bus, int phy_id,
static int fec_enet_mdio_read(struct mii_bus *bus,
int phy_id, int reg)
{
- int ret;
+ int ret = 0;
+
ret = fec_mdio_transfer(bus, phy_id, reg,
mk_mii_read(reg));
return ret;
@@ -3446,586 +953,48 @@ static int fec_enet_mdio_write(struct mii_bus *bus,
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);
- phy_print_status(phydev1);
- }
-}
-
-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);
- phy_print_status(phydev2);
- }
-}
-
-static int 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, j = 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;
-
- phydev[j++] = tmp_phydev;
- if (j >= SWITCH_EPORT_NUMBER)
- break;
- }
-
- /* 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, PHY_INTERFACE_MODE_RMII);
- 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, PHY_INTERFACE_MODE_RMII);
- 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++) {
- phydev[i]->supported &= PHY_BASIC_FEATURES;
- phydev[i]->advertising = phydev[i]->supported;
- priv->phydev[i] = phydev[i];
- printk(KERN_INFO "attached phy %i to driver %s "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- phydev[i]->addr, phydev[i]->drv->name,
- dev_name(&priv->phydev[i]->dev),
- priv->phydev[i]->irq);
- }
-
- return 0;
-}
-
-static void switch_enet_free_buffers(struct net_device *ndev)
-{
- struct switch_enet_private *fep = netdev_priv(ndev);
- int i;
- struct sk_buff *skb;
- cbd_t *bdp;
-
- bdp = fep->rx_bd_base;
- for (i = 0; i < RX_RING_SIZE; i++) {
- skb = fep->rx_skbuff[i];
-
- if (bdp->cbd_bufaddr)
- dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
- SWITCH_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
- if (skb)
- dev_kfree_skb(skb);
- bdp++;
- }
-
- bdp = fep->tx_bd_base;
- for (i = 0; i < TX_RING_SIZE; i++)
- kfree(fep->tx_bounce[i]);
-}
-
-static int switch_alloc_buffers(struct net_device *ndev)
-{
- struct switch_enet_private *fep = netdev_priv(ndev);
- int i;
- struct sk_buff *skb;
- cbd_t *bdp;
-
- bdp = fep->rx_bd_base;
- for (i = 0; i < RX_RING_SIZE; i++) {
- skb = dev_alloc_skb(SWITCH_ENET_RX_FRSIZE);
- if (!skb) {
- switch_enet_free_buffers(ndev);
- return -ENOMEM;
- }
- fep->rx_skbuff[i] = skb;
-
- bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
- SWITCH_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
- bdp->cbd_sc = BD_ENET_RX_EMPTY;
-
- bdp++;
- }
-
- /* Set the last buffer to wrap. */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
- bdp = fep->tx_bd_base;
- for (i = 0; i < TX_RING_SIZE; i++) {
- fep->tx_bounce[i] = kmalloc(SWITCH_ENET_TX_FRSIZE, GFP_KERNEL);
-
- bdp->cbd_sc = 0;
- bdp->cbd_bufaddr = 0;
- bdp++;
- }
-
- /* Set the last buffer to wrap. */
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-
- return 0;
-}
-
-static int switch_enet_open(struct net_device *dev)
-{
- struct switch_enet_private *fep = netdev_priv(dev);
- int i;
-
- fep->phy1_link = 0;
- fep->phy2_link = 0;
-
- switch_init_phy(dev);
- for (i = 0; i < SWITCH_EPORT_NUMBER; i++) {
- phy_write(fep->phydev[i], MII_BMCR, BMCR_RESET);
- udelay(10);
- 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 open firstly, we need to do nothing*/
- /* otherwise, 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;
-
- writel(0x70007, fep->membase + FEC_ESW_PER);
- writel(FSL_ESW_DBCR_P0 | FSL_ESW_DBCR_P1 | FSL_ESW_DBCR_P2,
- fep->membase + FEC_ESW_DBCR);
- writel(FSL_ESW_DMCR_P0 | FSL_ESW_DMCR_P1 | FSL_ESW_DMCR_P2,
- fep->membase + FEC_ESW_DMCR);
-
- writel(0,fep->membase + FEC_ESW_BKLR);
-
- netif_start_queue(dev);
-
- /* And last, enable the receive processing.*/
- writel(FSL_ESW_RDAR_R_DES_ACTIVE, fep->membase + FEC_ESW_RDAR);
-
- fep->opened = 1;
-
- return 0;
-}
-
-static int switch_enet_close(struct net_device *dev)
+/* The interrupt handler */
+static irqreturn_t switch_enet_interrupt(int irq, void *dev_id)
{
+ struct net_device *dev = dev_id;
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;
-}
-
-#define HASH_BITS 6 /* #bits in hash */
-#define CRC32_POLY 0xEDB88320
-#ifdef UNUSED
-static void set_multicast_list(struct net_device *dev)
-{
- struct switch_enet_private *fep;
- unsigned int i, bit, data, crc;
- struct netdev_hw_addr *ha;
+ uint int_events;
+ irqreturn_t ret = IRQ_NONE;
- fep = netdev_priv(dev);
+ /* Get the interrupt events that caused us to be here. */
+ do {
+ int_events = readl(fep->membase + FEC_ESW_ISR);
+ writel(int_events, fep->membase + FEC_ESW_ISR);
- 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);
- }
- }
+ /* Handle receive event in its own function. */
- }
+ if (int_events & FSL_ESW_ISR_RXF) {
+ ret = IRQ_HANDLED;
+ switch_enet_rx(dev);
}
- }
-}
-#endif
-
-/* Set a MAC change in hardware.*/
-static void switch_get_mac_address(struct net_device *dev)
-{
- struct switch_enet_private *fep = netdev_priv(dev);
- struct switch_platform_data *pdata = fep->pdev->dev.platform_data;
- unsigned char *iap, tmpaddr[ETH_ALEN];
-
- iap = macaddr;
-
- if (!is_valid_ether_addr(iap))
- if (pdata)
- memcpy(iap, pdata->mac, ETH_ALEN);
-
- if (!is_valid_ether_addr(iap)) {
- *((unsigned long *) &tmpaddr[0]) =
- be32_to_cpu(readl(fep->enetbase + FSL_FEC_PALR0));
- *((unsigned short *) &tmpaddr[4]) =
- be16_to_cpu(readl(fep->enetbase + FSL_FEC_PAUR0) >> 16);
- iap = &tmpaddr[0];
- }
-
- memcpy(dev->dev_addr, iap, ETH_ALEN);
-
- /* Adjust MAC if using macaddr */
- if (iap == macaddr)
- dev->dev_addr[ETH_ALEN-1] =
- macaddr[ETH_ALEN-1] + fep->pdev->id;
-}
-
-static void switch_hw_init(struct net_device *dev)
-{
- struct switch_enet_private *fep = netdev_priv(dev);
-
- /* Initialize MAC 0/1 */
- writel(FSL_FEC_RCR_MAX_FL(1522) | FSL_FEC_RCR_RMII_MODE | FSL_FEC_RCR_PROM
- | FSL_FEC_RCR_MII_MODE | FSL_FEC_RCR_MII_MODE,
- fep->enetbase + FSL_FEC_RCR0);
- writel(FSL_FEC_RCR_MAX_FL(1522) | FSL_FEC_RCR_RMII_MODE | FSL_FEC_RCR_PROM
- | FSL_FEC_RCR_MII_MODE | FSL_FEC_RCR_MII_MODE,
- fep->enetbase + FSL_FEC_RCR1);
-
- writel(FSL_FEC_TCR_FDEN, fep->enetbase + FSL_FEC_TCR0);
- writel(FSL_FEC_TCR_FDEN, fep->enetbase + FSL_FEC_TCR1);
-
- writel(0x1a, fep->enetbase + FSL_FEC_MSCR0);
-
- /* Set the station address for the ENET Adapter */
- writel(dev->dev_addr[3] |
- dev->dev_addr[2] << 8 |
- dev->dev_addr[1] << 16 |
- dev->dev_addr[0] << 24, fep->enetbase + FSL_FEC_PALR0);
- writel((dev->dev_addr[5] << 16) |
- (dev->dev_addr[4] << 24),
- fep->enetbase + FSL_FEC_PAUR0);
- writel(dev->dev_addr[3] |
- dev->dev_addr[2] << 8 |
- dev->dev_addr[1] << 16 |
- dev->dev_addr[0] << 24, fep->enetbase + FSL_FEC_PALR1);
- writel((dev->dev_addr[5] << 16) |
- (dev->dev_addr[4] << 24),
- fep->enetbase + FSL_FEC_PAUR1);
-
- writel(FEC_ENET_TXF | FEC_ENET_RXF, fep->enetbase + FSL_FEC_EIMR0);
- writel(FEC_ENET_TXF | FEC_ENET_RXF, fep->enetbase + FSL_FEC_EIMR1);
-
- writel(FSL_FEC_ECR_ETHER_EN | (0x1 << 8), fep->enetbase + FSL_FEC_ECR0);
- writel(FSL_FEC_ECR_ETHER_EN | (0x1 << 8), fep->enetbase + FSL_FEC_ECR1);
- udelay(20);
-}
-
-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_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);
- cbd_t *cbd_base;
- int ret = 0;
-
- /* Allocate memory for buffer descriptors. */
- cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
- GFP_KERNEL);
- if (!cbd_base) {
- printk(KERN_ERR "FEC: allocate descriptor memory failed?\n");
- return -ENOMEM;
- }
-
- spin_lock_init(&fep->hw_lock);
- spin_lock_init(&fep->mii_lock);
-
- writel(FSL_ESW_MODE_SW_RST, fep->membase + FEC_ESW_MODE);
- udelay(10);
- writel(FSL_ESW_MODE_STATRST, fep->membase + FEC_ESW_MODE);
- writel(FSL_ESW_MODE_SW_EN, fep->membase + FEC_ESW_MODE);
-
- /* Enable transmit/receive on all ports */
- writel(0xffffffff, fep->membase + FEC_ESW_PER);
-
- /* Management port configuration,
- * make port 0 as management port */
- writel(0, fep->membase + FEC_ESW_BMPC);
-
- /* Clear any outstanding interrupt.*/
- writel(0xffffffff, fep->membase + FEC_ESW_ISR);
- writel(0, fep->membase + FEC_ESW_IMR);
- udelay(100);
-
- switch_get_mac_address(dev);
-
- /* 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)fep->membase;
-
- /* The FEC Ethernet specific entries in the device structure. */
- dev->watchdog_timeo = TX_TIMEOUT;
- dev->netdev_ops = &switch_netdev_ops;
-
- fep->skb_cur = fep->skb_dirty = 0;
-
- ret = switch_alloc_buffers(dev);
- if (ret)
- return ret;
-
- /* Set receive and transmit descriptor base.*/
- writel(fep->bd_dma, fep->membase + FEC_ESW_RDSR);
- writel((unsigned long)fep->bd_dma +
- sizeof(struct bufdesc) * RX_RING_SIZE,
- fep->membase + FEC_ESW_TDSR);
-
- /*set mii*/
- switch_hw_init(dev);
- /* Clear any outstanding interrupt.*/
- writel(0xffffffff, fep->membase + FEC_ESW_ISR);
- writel(FSL_ESW_IMR_RXF | FSL_ESW_IMR_TXF, fep->membase + FEC_ESW_IMR);
- 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 ret;
-}
-
-/* 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;
- int i;
-
- fep = netdev_priv(dev);
-
- /* Whack a reset. We should wait for this.*/
- writel(1, fep->enetbase + FSL_FEC_ECR0);
- writel(1, fep->enetbase + FSL_FEC_ECR1);
- udelay(10);
-
- writel(FSL_ESW_MODE_SW_RST, fep->membase + FEC_ESW_MODE);
- udelay(10);
- writel(FSL_ESW_MODE_STATRST, fep->membase + FEC_ESW_MODE);
- writel(FSL_ESW_MODE_SW_EN, fep->membase + FEC_ESW_MODE);
-
- /* Enable transmit/receive on all ports */
- writel(0xffffffff, fep->membase + FEC_ESW_PER);
-
- /* Management port configuration,
- * make port 0 as management port */
- writel(0, fep->membase + FEC_ESW_BMPC);
-
- /* Clear any outstanding interrupt.*/
- writel(0xffffffff, fep->membase + FEC_ESW_ISR);
-
- switch_hw_init(dev);
-
- /* Set station address.*/
- switch_get_mac_address(dev);
-
- writel(0, fep->membase + FEC_ESW_IMR);
- udelay(10);
-
- /* Set maximum receive buffer size.
- */
- writel(PKT_MAXBLR_SIZE, fep->membase + FEC_ESW_MRBR);
-
- /* Set receive and transmit descriptor base.
- */
- writel(fep->bd_dma, fep->membase + FEC_ESW_RDSR);
- writel((unsigned long)fep->bd_dma +
- sizeof(struct bufdesc) * RX_RING_SIZE,
- fep->membase + FEC_ESW_TDSR);
-
- 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;
+ if (int_events & FSL_ESW_ISR_TXF) {
+ ret = IRQ_HANDLED;
+ switch_enet_tx(dev);
}
- }
- /*hardware has set in hw_init*/
- fep->full_duplex = duplex;
+ } while (int_events);
- /* Clear any outstanding interrupt.*/
- writel(0xffffffff, fep->membase + FEC_ESW_ISR);
- writel(FSL_ESW_IMR_RXF | FSL_ESW_IMR_TXF, fep->membase + FEC_ESW_IMR);
+ return ret;
}
-static void switch_stop(struct net_device *dev)
+static void switch_enet_mdio_remove(struct switch_enet_private *fep)
{
- struct switch_enet_private *fep = netdev_priv(dev);
-
- /* 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);
+ mdiobus_unregister(fep->mdio_bus);
+ kfree(fep->mdio_bus->irq);
+ mdiobus_free(fep->mdio_bus);
}
-static int fec_mdio_register(struct net_device *dev)
+static int fec_mdio_register(struct platform_device *pdev)
{
- int i, err = 0;
- struct switch_enet_private *fep = netdev_priv(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct switch_enet_private *fep = netdev_priv(ndev);
+ int phy_addr = 0, ret = 0;
fep->mdio_bus = mdiobus_alloc();
if (!fep->mdio_bus) {
@@ -4035,32 +1004,61 @@ static int fec_mdio_register(struct net_device *dev)
fep->mdio_bus->name = "fsl l2 switch MII Bus";
- snprintf(fep->mdio_bus->id, MII_BUS_ID_SIZE, "%x", fep->pdev->id);
+ snprintf(fep->mdio_bus->id, MII_BUS_ID_SIZE, "%x", fep->dev_id);
fep->mdio_bus->read = &fec_enet_mdio_read;
fep->mdio_bus->write = &fec_enet_mdio_write;
fep->mdio_bus->priv = fep;
+ fep->mdio_bus->parent = &pdev->dev;
fep->mdio_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!fep->mdio_bus->irq) {
- err = -ENOMEM;
- return err;
+ ret = -ENOMEM;
+ return ret;
}
- for (i = 0; i < PHY_MAX_ADDR; i++)
- fep->mdio_bus->irq[i] = PHY_POLL;
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+ fep->mdio_bus->irq[phy_addr] = PHY_POLL;
- err = mdiobus_register(fep->mdio_bus);
- if (err) {
+ ret = mdiobus_register(fep->mdio_bus);
+ if (ret) {
mdiobus_free(fep->mdio_bus);
- printk(KERN_ERR "%s: ethernet mdiobus_register fail\n",
- dev->name);
+ netdev_err(ndev, "%s: ethernet mdiobus_register fail\n",
+ ndev->name);
return -EIO;
}
printk(KERN_INFO "%s mdiobus(%s) register ok.\n",
fep->mdio_bus->name, fep->mdio_bus->id);
- return err;
+ return ret;
+}
+
+static int eth_switch_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = NULL;
+ struct switch_enet_private *fep;
+ struct switch_platform_private *chip;
+ int slot = 0;
+
+ chip = platform_get_drvdata(pdev);
+ if (chip) {
+ for (slot = 0; slot < chip->num_slots; slot++) {
+ fep = chip->fep_host[slot];
+ dev = fep->netdev;
+ fep->sequence_done = 1;
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(chip);
+
+ } else
+ netdev_err(dev, "%s: Can not get the "
+ "switch_platform_private %x\n", __func__,
+ (unsigned int)chip);
+
+ return 0;
}
static const struct of_device_id of_eth_switch_match[] = {
@@ -4070,181 +1068,116 @@ static const struct of_device_id of_eth_switch_match[] = {
MODULE_DEVICE_TABLE(of, of_eth_switch_match);
+/* TODO: suspend/resume related code */
+
static int eth_switch_probe(struct platform_device *pdev)
{
- struct net_device *ndev;
- int err;
- struct switch_enet_private *fep;
- struct task_struct *task;
- int i, irq, ret = 0;
- struct resource *res=NULL;
+ struct net_device *ndev = NULL;
+ struct switch_enet_private *fep = NULL;
+ int irq = 0, ret = 0, err = 0;
+ struct resource *res = NULL;
const struct of_device_id *match;
+ static int dev_id;
- printk(KERN_INFO "Ethernet Switch Version 1.0\n");
match = of_match_device(of_eth_switch_match, &pdev->dev);
- if (!match){
+ if (!match)
return -EINVAL;
- }
- else{
- pdev->id_entry = match->data;
- }
+ pdev->id_entry = match->data;
+
+ /* Initialize network device */
ndev = alloc_etherdev(sizeof(struct switch_enet_private));
- if (!ndev) {
- printk(KERN_ERR "%s: ethernet switch alloc_etherdev fail\n",
- ndev->name);
+ if (!ndev)
return -ENOMEM;
- }
+
SET_NETDEV_DEV(ndev, &pdev->dev);
fep = netdev_priv(ndev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- printk(KERN_ERR "get platform resource error\n");
- return -ENXIO;
+ fep->membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(fep->membase)) {
+ ret = PTR_ERR(fep->membase);
+ goto failed_ioremap;
}
- ret = of_address_to_resource(pdev->dev.of_node, 0, res);
- if (ret) {
- /* Fail */
- printk(KERN_ERR "get address resource error!\n");
- return -ENXIO;
- }
- res = request_mem_region(res->start, resource_size(res), pdev->name);
- if (!res)
- return -EBUSY;
- memset(fep, 0, sizeof(*fep));
-
- fep->membase = ioremap(res->start, resource_size(res));
- if (!fep->membase)
- return -ENOMEM;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res)
- return -ENXIO;
-
- res = request_mem_region(res->start, resource_size(res), pdev->name);
- if (!res)
- return -EBUSY;
- fep->macbase = ioremap(res->start, resource_size(res));
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
- if (!res)
- return -ENXIO;
-
- res = request_mem_region(res->start, resource_size(res), pdev->name);
- if (!res)
- return -EBUSY;
- fep->enetbase = ioremap(res->start, resource_size(res));
- if (!fep->enetbase)
- return -ENOMEM;
+ fep->enetbase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(fep->enetbase)) {
+ ret = PTR_ERR(fep->enetbase);
+ goto failed_ioremap;
+ }
fep->pdev = pdev;
+ fep->dev_id = dev_id++;
+
platform_set_drvdata(pdev, ndev);
- printk(KERN_INFO "%s: ethernet switch init\n", __func__);
+ irq = platform_get_irq(pdev, 0);
+ ret = devm_request_irq(&pdev->dev, irq, switch_enet_interrupt,
+ 0, pdev->name, ndev);
+ if (ret)
+ return ret;
- /* This device has up to three irqs on some platforms */
- for (i = 0; i < 3; i++) {
- irq = platform_get_irq(pdev, i);
- if (i && irq < 0)
- break;
- ret = request_irq(irq, switch_enet_interrupt, IRQF_DISABLED,
- pdev->name, ndev);
- if (ret) {
- while (--i >= 0) {
- irq = platform_get_irq(pdev, i);
- free_irq(irq, ndev);
- }
- return -ENOMEM;
- }
+ fep->clk_esw = devm_clk_get(&pdev->dev, "esw");
+ if (IS_ERR(fep->clk_esw)) {
+ ret = PTR_ERR(fep->clk_esw);
+ goto failed_clk;
+ }
+
+ fep->clk_enet = devm_clk_get(&pdev->dev, "enet");
+ if (IS_ERR(fep->clk_enet)) {
+ ret = PTR_ERR(fep->clk_enet);
+ goto failed_clk;
}
- fep->clk = clk_get(&pdev->dev, "switch_clk");
+ fep->clk_enet0 = devm_clk_get(&pdev->dev, "enet0");
+ if (IS_ERR(fep->clk_enet0)) {
+ ret = PTR_ERR(fep->clk_enet0);
+ goto failed_clk;
+ }
- if (IS_ERR(fep->clk)) {
- ret = PTR_ERR(fep->clk);
+ fep->clk_enet1 = devm_clk_get(&pdev->dev, "enet1");
+ if (IS_ERR(fep->clk_enet1)) {
+ ret = PTR_ERR(fep->clk_enet1);
goto failed_clk;
}
- clk_enable(fep->clk);
- err = switch_enet_init(pdev);
+ switch_enet_clk_enable(ndev, true);
+
+ err = switch_enet_init(ndev);
if (err) {
free_netdev(ndev);
platform_set_drvdata(pdev, NULL);
return -EIO;
}
- err = fec_mdio_register(ndev);
+ err = fec_mdio_register(pdev);
if (err) {
- printk(KERN_ERR "%s: L2 switch fec_mdio_register error!\n",
+ netdev_err(ndev, "%s: L2 switch fec_mdio_register error!\n",
ndev->name);
free_netdev(ndev);
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(ndev) != 0) {
- /* XXX: missing cleanup here */
- free_netdev(ndev);
- platform_set_drvdata(pdev, NULL);
- printk(KERN_ERR "%s: L2 switch register_netdev fail\n",
- ndev->name);
- return -EIO;
- }
-
- task = kthread_run(switch_enet_learning, fep,
- "fsl_l2switch_learning");
- if (IS_ERR(task)) {
- err = PTR_ERR(task);
- return err;
- }
+ /* register network device */
+ ret = register_netdev(ndev);
+ if (ret)
+ goto failed_register;
- printk(KERN_INFO "%s: ethernet switch %pM\n",
+ netdev_info(ndev, "%s: Ethernet switch %pM\n",
ndev->name, ndev->dev_addr);
- return 0;
-failed_clk:
- iounmap(fep->membase);
- return ret;
-}
-
-static int 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);
+ return 0;
- } else
- printk(KERN_ERR "%s: can not get the "
- "switch_platform_private %x\n", __func__,
- (unsigned int)chip);
+failed_register:
+ switch_enet_mdio_remove(fep);
+failed_clk:
+failed_ioremap:
+ free_netdev(ndev);
- return 0;
+ return ret;
}
static struct platform_driver eth_switch_driver = {
@@ -4257,31 +1190,6 @@ static struct platform_driver eth_switch_driver = {
},
};
-static int fec_mac_addr_setup(char *mac_addr)
-{
- char *ptr, *p = mac_addr;
- unsigned long tmp;
- int i = 0, ret = 0;
-
- while (p && (*p) && i < 6) {
- ptr = strchr(p, ':');
- if (ptr)
- *ptr++ = '\0';
-
- if (strlen(p)) {
- ret = strict_strtoul(p, 16, &tmp);
- if (ret < 0 || tmp > 0xff)
- break;
- macaddr[i++] = tmp;
- }
- p = ptr;
- }
-
- return 0;
-}
-
-__setup("fec_mac=", fec_mac_addr_setup);
-
static int __init fsl_l2_switch_init(void)
{
return platform_driver_register(&eth_switch_driver);
@@ -4292,7 +1200,6 @@ static void __exit fsl_l2_switch_exit(void)
platform_driver_unregister(&eth_switch_driver);
}
-
module_init(fsl_l2_switch_init);
module_exit(fsl_l2_switch_exit);
MODULE_LICENSE("GPL");
diff --git a/include/linux/fsl_l2_switch.h b/drivers/net/ethernet/freescale/fsl_l2_switch.h
index 8ded0d659023..b85345db1b27 100644
--- a/include/linux/fsl_l2_switch.h
+++ b/drivers/net/ethernet/freescale/fsl_l2_switch.h
@@ -11,25 +11,52 @@
#ifndef FSL_L2_SWITCH_H
#define FSL_L2_SWITCH_H
-/* The Switch stores dest/src/type, data, and checksum for receive packets. */
+/* Interrupt events/masks */
+#define FEC_ENET_HBERR BIT(31) /* Heartbeat error */
+#define FEC_ENET_BABR BIT(30) /* Babbling receiver */
+#define FEC_ENET_BABT BIT(29) /* Babbling transmitter */
+#define FEC_ENET_GRA BIT(28) /* Graceful stop complete */
+#define FEC_ENET_TXF BIT(27) /* Full frame transmitted */
+#define FEC_ENET_TXB BIT(26) /* A buffer was transmitted */
+#define FEC_ENET_RXF BIT(25) /* Full frame received */
+#define FEC_ENET_RXB BIT(24) /* A buffer was received */
+#define FEC_ENET_MII BIT(23) /* MII interrupt */
+#define FEC_ENET_EBERR BIT(22) /* SDMA bus error */
+
+#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))
+/* MII MMFR bits definition */
+#define ESW_MMFR_ST BIT(30)
+#define ESW_MMFR_OP_READ (2 << 28)
+#define ESW_MMFR_OP_WRITE BIT(28)
+#define ESW_MMFR_PA(v) ((v & 0x1f) << 23)
+#define ESW_MMFR_RA(v) ((v & 0x1f) << 18)
+#define ESW_MMFR_TA (2 << 16)
+#define ESW_MMFR_DATA(v) (v & 0xffff)
+
+#define ESW_MII_TIMEOUT 30 /* ms */
+
+/* Transmitter timeout.*/
+#define TX_TIMEOUT (2 * HZ)
+
+/* 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
+/* 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
+/* 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.
@@ -40,18 +67,18 @@
#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)
+#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 */
+#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 */
+#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
@@ -105,20 +132,20 @@
#define FEC_ESW_IPRES 0x140
-/*port0-port2 Priority Configuration 0xFC0D_C180-C188*/
+/* port0-port2 Priority Configuration 0xFC0D_C180-C188 */
#define FEC_ESW_PRES(n) (0x180 + n * 4)
-/*port0-port2 VLAN ID 0xFC0D_C200-C208*/
+/* port0-port2 VLAN ID 0xFC0D_C200-C208 */
#define FEC_ESW_PID(n) (0x200 + 4 * n)
-/*port0-port2 VLAN domain resolution entry 0xFC0D_C280-C2FC*/
+/* port0-port2 VLAN domain resolution entry 0xFC0D_C280-C2FC */
#define FEC_ESW_VRES(n) (0x280 + n * 4)
#define FEC_ESW_DISCN 0x300
#define FEC_ESW_DISCB 0x304
#define FEC_ESW_NDISCN 0x308
#define FEC_ESW_NDISCB 0x30C
-/*per port statistics 0xFC0DC310_C33C*/
+/* per port statistics 0xFC0DC310_C33C */
#define FEC_ESW_POQC(n) (0x310 + n * 16)
#define FEC_ESW_PMVID(n) (0x310 + n * 16 + 0x04)
@@ -130,8 +157,8 @@
#define FEC_ESW_RDSR 0x408 /* Receive descriptor ring */
#define FEC_ESW_TDSR 0x40C /* Transmit descriptor ring */
#define FEC_ESW_MRBR 0x410 /* Maximum receive buff size */
-#define FEC_ESW_RDAR 0x414 /* Receive descriptor active*/
-#define FEC_ESW_TDAR 0x418 /* Transmit descriptor active*/
+#define FEC_ESW_RDAR 0x414 /* Receive descriptor active */
+#define FEC_ESW_TDAR 0x418 /* Transmit descriptor active */
#define FEC_ESW_LREC0 0x500
#define FEC_ESW_LREC1 0x504
@@ -143,55 +170,6 @@ struct switch_platform_data {
unsigned char mac[ETH_ALEN];
};
-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 FSL_ESW_POQC;
- /*incoming frames discarded due to VLAN domain mismatch*/
- unsigned long FSL_ESW_PMVID;
- /*incoming frames discarded due to untagged discard*/
- unsigned long FSL_ESW_PMVTAG;
- /*incoming frames discarded due port is in blocking state*/
- unsigned long FSL_ESW_PBL;
-} esw_port_statistics_status;
-
-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 FSL_ESW_LOOKUP_MEM;*/
#define FSL_FEC_MMFR0 (0x40)
#define FSL_FEC_MSCR0 (0x44)
#define FSL_FEC_MSCR1 (0x1044)
@@ -223,271 +201,28 @@ typedef struct l2switchaddrtable {
#define FSL_FEC_ECR_ETHER_EN (0x00000002)
#define FSL_FEC_ECR_ENA_1588 (0x00000010)
-/*ioctl commands*/
-#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 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.
- */
+/* Define the buffer descriptor structure. */
typedef struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
unsigned long cbd_bufaddr; /* Buffer address */
} cbd_t;
-
typedef struct bufdesc_rx {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
unsigned long cbd_bufaddr; /* Buffer address */
} cbd_t_r;
-/* Forward declarations of some structures to support different PHYs
- */
-typedef struct {
+/* Forward declarations of some structures to support different PHYs */
+typedef struct _phy_cmd_t {
uint mii_data;
void (*funct)(uint mii_reg, struct net_device *dev);
} phy_cmd_t;
-typedef struct {
+typedef struct _phy_info_t {
uint id;
char *name;
@@ -507,27 +242,6 @@ struct port_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.
@@ -541,11 +255,17 @@ struct switch_enet_private {
void __iomem *membase;
void __iomem *macbase; /* MAC address lookup table */
void __iomem *enetbase;
- struct clk *clk;
- eswAddrTable_t *hwentry;
+
+ struct clk *clk_esw;
+ struct clk *clk_enet;
+ struct clk *clk_enet0;
+ struct clk *clk_enet1;
struct net_device *netdev;
struct platform_device *pdev;
+
+ int dev_id;
+
/* 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];
@@ -556,10 +276,10 @@ struct switch_enet_private {
/* CPM dual port RAM relative addresses */
dma_addr_t bd_dma;
- cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
+ 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. */
+ 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;
@@ -597,39 +317,14 @@ struct switch_enet_private {
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;
+ int curr_time;
+ /* flag set by timer when curr_time changed
+ * and cleared by serving function
+ */
+ int time_changed;
/* Timer for Aging */
struct timer_list timer_aging;
@@ -642,7 +337,7 @@ struct switch_platform_private {
struct switch_enet_private *fep_host[0]; /* Pointers to hosts */
};
-/* Recieve is empty */
+/* Receive is empty */
#define BD_SC_EMPTY ((unsigned short)0x8000)
/* Transmit is ready */
#define BD_SC_READY ((unsigned short)0x8000)
@@ -650,7 +345,7 @@ struct switch_platform_private {
#define BD_SC_WRAP ((unsigned short)0x2000)
/* Interrupt on change */
#define BD_SC_INTRPT ((unsigned short)0x1000)
-/* Continous mode */
+/* Continuous mode */
#define BD_SC_CM ((unsigned short)0x0200)
/* Rec'd too many idles */
#define BD_SC_ID ((unsigned short)0x0100)
@@ -679,10 +374,11 @@ struct switch_platform_private {
#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.*/
+/* 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)
@@ -696,10 +392,11 @@ struct switch_platform_private {
#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 */
+/* Copy from validation code */
#define RX_BUFFER_SIZE 1520
#define TX_BUFFER_SIZE 1520
#define NUM_RXBDS 20
@@ -752,12 +449,12 @@ struct switch_platform_private {
#define RX_BD_BDU 0x80000000
/* Address Table size in bytes(2048 64bit entry ) */
-#define ESW_ATABLE_MEM_SIZE (2048*8)
+#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)*/
+/* log2(ATABLE_ENTRY_PER_SLOT) */
#define ATABLE_ENTRY_PER_SLOT_bits 3
/* entry size in byte */
#define ATABLE_ENTRY_SIZE 8
@@ -800,15 +497,15 @@ struct switch_platform_private {
/* 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))
+ ((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))
+ ((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)
+ ((1 << AT_DENTRY_PORT_WIDTH) - 1))) >> 1)
#define TIMEDELTA(newtime, oldtime) \
((newtime - oldtime) & \
- ((1 << AT_DENTRY_TIMESTAMP_WIDTH)-1))
+ ((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)
@@ -818,8 +515,8 @@ struct switch_platform_private {
((time) = ((time)+1) & ((1 << AT_DENTRY_TIMESTAMP_WIDTH)-1))
/* Bit definitions and macros for FSL_ESW_REVISION */
-#define FSL_ESW_REVISION_CORE_REVISION(x) (((x)&0x0000FFFF)<<0)
-#define FSL_ESW_REVISION_CUSTOMER_REVISION(x) (((x)&0x0000FFFF)<<16)
+#define FSL_ESW_REVISION_CORE_REVISION(x) (((x)&0x0000FFFF) << 0)
+#define FSL_ESW_REVISION_CUSTOMER_REVISION(x) (((x)&0x0000FFFF) << 16)
/* Bit definitions and macros for FSL_ESW_PER */
#define FSL_ESW_PER_TE0 (0x00000001)
@@ -848,20 +545,21 @@ struct switch_platform_private {
#define FSL_ESW_DMCR_P2 (0x00000004)
/* Bit definitions and macros for FSL_ESW_BKLR */
-#define FSL_ESW_BKLR_BE0 (0x00000001)
-#define FSL_ESW_BKLR_BE1 (0x00000002)
-#define FSL_ESW_BKLR_BE2 (0x00000004)
-#define FSL_ESW_BKLR_LD0 (0x00010000)
-#define FSL_ESW_BKLR_LD1 (0x00020000)
-#define FSL_ESW_BKLR_LD2 (0x00040000)
+#define FSL_ESW_BKLR_BE0 (0x00000001)
+#define FSL_ESW_BKLR_BE1 (0x00000002)
+#define FSL_ESW_BKLR_BE2 (0x00000004)
+#define FSL_ESW_BKLR_LD0 (0x00010000)
+#define FSL_ESW_BKLR_LD1 (0x00020000)
+#define FSL_ESW_BKLR_LD2 (0x00040000)
+#define FSL_ESW_BKLR_LDX (0x00070007)
/* Bit definitions and macros for FSL_ESW_BMPC */
-#define FSL_ESW_BMPC_PORT(x) (((x)&0x0000000F)<<0)
+#define FSL_ESW_BMPC_PORT(x) (((x) & 0x0000000F) << 0)
#define FSL_ESW_BMPC_MSG_TX (0x00000020)
#define FSL_ESW_BMPC_EN (0x00000040)
#define FSL_ESW_BMPC_DIS (0x00000080)
-#define FSL_ESW_BMPC_PRIORITY(x) (((x)&0x00000007)<<13)
-#define FSL_ESW_BMPC_PORTMASK(x) (((x)&0x00000007)<<16)
+#define FSL_ESW_BMPC_PRIORITY(x) (((x) & 0x00000007) << 13)
+#define FSL_ESW_BMPC_PORTMASK(x) (((x) & 0x00000007) << 16)
/* Bit definitions and macros for FSL_ESW_MODE */
#define FSL_ESW_MODE_SW_RST (0x00000001)
@@ -872,14 +570,14 @@ struct switch_platform_private {
#define FSL_ESW_MODE_STATRST (0x80000000)
/* Bit definitions and macros for FSL_ESW_VIMSEL */
-#define FSL_ESW_VIMSEL_IM0(x) (((x)&0x00000003)<<0)
-#define FSL_ESW_VIMSEL_IM1(x) (((x)&0x00000003)<<2)
-#define FSL_ESW_VIMSEL_IM2(x) (((x)&0x00000003)<<4)
+#define FSL_ESW_VIMSEL_IM0(x) (((x) & 0x00000003) << 0)
+#define FSL_ESW_VIMSEL_IM1(x) (((x) & 0x00000003) << 2)
+#define FSL_ESW_VIMSEL_IM2(x) (((x) & 0x00000003) << 4)
/* Bit definitions and macros for FSL_ESW_VOMSEL */
-#define FSL_ESW_VOMSEL_OM0(x) (((x)&0x00000003)<<0)
-#define FSL_ESW_VOMSEL_OM1(x) (((x)&0x00000003)<<2)
-#define FSL_ESW_VOMSEL_OM2(x) (((x)&0x00000003)<<4)
+#define FSL_ESW_VOMSEL_OM0(x) (((x) & 0x00000003) << 0)
+#define FSL_ESW_VOMSEL_OM1(x) (((x) & 0x00000003) << 2)
+#define FSL_ESW_VOMSEL_OM2(x) (((x) & 0x00000003) << 4)
/* Bit definitions and macros for FSL_ESW_VIMEN */
#define FSL_ESW_VIMEN_EN0 (0x00000001)
@@ -887,10 +585,10 @@ struct switch_platform_private {
#define FSL_ESW_VIMEN_EN2 (0x00000004)
/* Bit definitions and macros for FSL_ESW_VID */
-#define FSL_ESW_VID_TAG(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_VID_TAG(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_MCR */
-#define FSL_ESW_MCR_PORT(x) (((x)&0x0000000F)<<0)
+#define FSL_ESW_MCR_PORT(x) (((x) & 0x0000000F) << 0)
#define FSL_ESW_MCR_MEN (0x00000010)
#define FSL_ESW_MCR_INGMAP (0x00000020)
#define FSL_ESW_MCR_EGMAP (0x00000040)
@@ -910,31 +608,31 @@ struct switch_platform_private {
#define FSL_ESW_INGMAP_ING2 (0x00000004)
/* Bit definitions and macros for FSL_ESW_INGSAL */
-#define FSL_ESW_INGSAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_INGSAL_ADDLOW(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_INGSAH */
-#define FSL_ESW_INGSAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
+#define FSL_ESW_INGSAH_ADDHIGH(x) (((x) & 0x0000FFFF) << 0)
/* Bit definitions and macros for FSL_ESW_INGDAL */
-#define FSL_ESW_INGDAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_INGDAL_ADDLOW(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_INGDAH */
-#define FSL_ESW_INGDAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
+#define FSL_ESW_INGDAH_ADDHIGH(x) (((x) & 0x0000FFFF) << 0)
/* Bit definitions and macros for FSL_ESW_ENGSAL */
-#define FSL_ESW_ENGSAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_ENGSAL_ADDLOW(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_ENGSAH */
-#define FSL_ESW_ENGSAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
+#define FSL_ESW_ENGSAH_ADDHIGH(x) (((x) & 0x0000FFFF) << 0)
/* Bit definitions and macros for FSL_ESW_ENGDAL */
-#define FSL_ESW_ENGDAL_ADDLOW(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_ENGDAL_ADDLOW(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_ENGDAH */
-#define FSL_ESW_ENGDAH_ADDHIGH(x) (((x)&0x0000FFFF)<<0)
+#define FSL_ESW_ENGDAH_ADDHIGH(x) (((x) & 0x0000FFFF) << 0)
/* Bit definitions and macros for FSL_ESW_MCVAL */
-#define FSL_ESW_MCVAL_COUNT(x) (((x)&0x000000FF)<<0)
+#define FSL_ESW_MCVAL_COUNT(x) (((x) & 0x000000FF) << 0)
/* Bit definitions and macros for FSL_ESW_MMSR */
#define FSL_ESW_MMSR_BUSY (0x00000001)
@@ -942,13 +640,13 @@ struct switch_platform_private {
#define FSL_ESW_MMSR_MEMFULL (0x00000004)
#define FSL_ESW_MMSR_MFLATCH (0x00000008)
#define FSL_ESW_MMSR_DQ_GRNT (0x00000040)
-#define FSL_ESW_MMSR_CELLS_AVAIL(x) (((x)&0x000000FF)<<16)
+#define FSL_ESW_MMSR_CELLS_AVAIL(x) (((x) & 0x000000FF) << 16)
/* Bit definitions and macros for FSL_ESW_LMT */
-#define FSL_ESW_LMT_THRESH(x) (((x)&0x000000FF)<<0)
+#define FSL_ESW_LMT_THRESH(x) (((x) & 0x000000FF) << 0)
/* Bit definitions and macros for FSL_ESW_LFC */
-#define FSL_ESW_LFC_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_LFC_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_PCSR */
#define FSL_ESW_PCSR_PC0 (0x00000001)
@@ -961,86 +659,86 @@ struct switch_platform_private {
#define FSL_ESW_IOSR_OR2 (0x00000004)
/* Bit definitions and macros for FSL_ESW_QWT */
-#define FSL_ESW_QWT_Q0WT(x) (((x)&0x0000001F)<<0)
-#define FSL_ESW_QWT_Q1WT(x) (((x)&0x0000001F)<<8)
-#define FSL_ESW_QWT_Q2WT(x) (((x)&0x0000001F)<<16)
-#define FSL_ESW_QWT_Q3WT(x) (((x)&0x0000001F)<<24)
+#define FSL_ESW_QWT_Q0WT(x) (((x) & 0x0000001F) << 0)
+#define FSL_ESW_QWT_Q1WT(x) (((x) & 0x0000001F) << 8)
+#define FSL_ESW_QWT_Q2WT(x) (((x) & 0x0000001F) << 16)
+#define FSL_ESW_QWT_Q3WT(x) (((x) & 0x0000001F) << 24)
/* Bit definitions and macros for FSL_ESW_P0BCT */
-#define FSL_ESW_P0BCT_THRESH(x) (((x)&0x000000FF)<<0)
+#define FSL_ESW_P0BCT_THRESH(x) (((x) & 0x000000FF) << 0)
/* Bit definitions and macros for FSL_ESW_P0FFEN */
#define FSL_ESW_P0FFEN_FEN (0x00000001)
-#define FSL_ESW_P0FFEN_FD(x) (((x)&0x00000003)<<2)
+#define FSL_ESW_P0FFEN_FD(x) (((x) & 0x00000003) << 2)
/* Bit definitions and macros for FSL_ESW_PSNP */
#define FSL_ESW_PSNP_EN (0x00000001)
-#define FSL_ESW_PSNP_MODE(x) (((x)&0x00000003)<<1)
+#define FSL_ESW_PSNP_MODE(x) (((x) & 0x00000003) << 1)
#define FSL_ESW_PSNP_CD (0x00000008)
#define FSL_ESW_PSNP_CS (0x00000010)
-#define FSL_ESW_PSNP_PORT_COMPARE(x) (((x)&0x0000FFFF)<<16)
+#define FSL_ESW_PSNP_PORT_COMPARE(x) (((x) & 0x0000FFFF) << 16)
/* Bit definitions and macros for FSL_ESW_IPSNP */
#define FSL_ESW_IPSNP_EN (0x00000001)
-#define FSL_ESW_IPSNP_MODE(x) (((x)&0x00000003)<<1)
-#define FSL_ESW_IPSNP_PROTOCOL(x) (((x)&0x000000FF)<<8)
+#define FSL_ESW_IPSNP_MODE(x) (((x) & 0x00000003) << 1)
+#define FSL_ESW_IPSNP_PROTOCOL(x) (((x) & 0x000000FF) << 8)
/* Bit definitions and macros for FSL_ESW_PVRES */
-#define FSL_ESW_PVRES_PRI0(x) (((x)&0x00000007)<<0)
-#define FSL_ESW_PVRES_PRI1(x) (((x)&0x00000007)<<3)
-#define FSL_ESW_PVRES_PRI2(x) (((x)&0x00000007)<<6)
-#define FSL_ESW_PVRES_PRI3(x) (((x)&0x00000007)<<9)
-#define FSL_ESW_PVRES_PRI4(x) (((x)&0x00000007)<<12)
-#define FSL_ESW_PVRES_PRI5(x) (((x)&0x00000007)<<15)
-#define FSL_ESW_PVRES_PRI6(x) (((x)&0x00000007)<<18)
-#define FSL_ESW_PVRES_PRI7(x) (((x)&0x00000007)<<21)
+#define FSL_ESW_PVRES_PRI0(x) (((x) & 0x00000007) << 0)
+#define FSL_ESW_PVRES_PRI1(x) (((x) & 0x00000007) << 3)
+#define FSL_ESW_PVRES_PRI2(x) (((x) & 0x00000007) << 6)
+#define FSL_ESW_PVRES_PRI3(x) (((x) & 0x00000007) << 9)
+#define FSL_ESW_PVRES_PRI4(x) (((x) & 0x00000007) << 12)
+#define FSL_ESW_PVRES_PRI5(x) (((x) & 0x00000007) << 15)
+#define FSL_ESW_PVRES_PRI6(x) (((x) & 0x00000007) << 18)
+#define FSL_ESW_PVRES_PRI7(x) (((x) & 0x00000007) << 21)
/* Bit definitions and macros for FSL_ESW_IPRES */
-#define FSL_ESW_IPRES_ADDRESS(x) (((x)&0x000000FF)<<0)
+#define FSL_ESW_IPRES_ADDRESS(x) (((x) & 0x000000FF) << 0)
#define FSL_ESW_IPRES_IPV4SEL (0x00000100)
-#define FSL_ESW_IPRES_PRI0(x) (((x)&0x00000003)<<9)
-#define FSL_ESW_IPRES_PRI1(x) (((x)&0x00000003)<<11)
-#define FSL_ESW_IPRES_PRI2(x) (((x)&0x00000003)<<13)
+#define FSL_ESW_IPRES_PRI0(x) (((x) & 0x00000003) << 9)
+#define FSL_ESW_IPRES_PRI1(x) (((x) & 0x00000003) << 11)
+#define FSL_ESW_IPRES_PRI2(x) (((x) & 0x00000003) << 13)
#define FSL_ESW_IPRES_READ (0x80000000)
/* Bit definitions and macros for FSL_ESW_PRES */
#define FSL_ESW_PRES_VLAN (0x00000001)
#define FSL_ESW_PRES_IP (0x00000002)
#define FSL_ESW_PRES_MAC (0x00000004)
-#define FSL_ESW_PRES_DFLT_PRI(x) (((x)&0x00000007)<<4)
+#define FSL_ESW_PRES_DFLT_PRI(x) (((x) & 0x00000007) << 4)
/* Bit definitions and macros for FSL_ESW_PID */
-#define FSL_ESW_PID_VLANID(x) (((x)&0x0000FFFF)<<0)
+#define FSL_ESW_PID_VLANID(x) (((x) & 0x0000FFFF) << 0)
/* Bit definitions and macros for FSL_ESW_VRES */
#define FSL_ESW_VRES_P0 (0x00000001)
#define FSL_ESW_VRES_P1 (0x00000002)
#define FSL_ESW_VRES_P2 (0x00000004)
-#define FSL_ESW_VRES_VLANID(x) (((x)&0x00000FFF)<<3)
+#define FSL_ESW_VRES_VLANID(x) (((x) & 0x00000FFF) << 3)
/* Bit definitions and macros for FSL_ESW_DISCN */
-#define FSL_ESW_DISCN_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_DISCN_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_DISCB */
-#define FSL_ESW_DISCB_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_DISCB_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_NDISCN */
-#define FSL_ESW_NDISCN_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_NDISCN_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_NDISCB */
-#define FSL_ESW_NDISCB_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_NDISCB_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_POQC */
-#define FSL_ESW_POQC_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_POQC_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_PMVID */
-#define FSL_ESW_PMVID_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_PMVID_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_PMVTAG */
-#define FSL_ESW_PMVTAG_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_PMVTAG_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_PBL */
-#define FSL_ESW_PBL_COUNT(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_PBL_COUNT(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_ISR */
#define FSL_ESW_ISR_EBERR (0x00000001)
@@ -1067,13 +765,13 @@ struct switch_platform_private {
#define FSL_ESW_IMR_LRN (0x00000200)
/* Bit definitions and macros for FSL_ESW_RDSR */
-#define FSL_ESW_RDSR_ADDRESS(x) (((x)&0x3FFFFFFF)<<2)
+#define FSL_ESW_RDSR_ADDRESS(x) (((x) & 0x3FFFFFFF) << 2)
/* Bit definitions and macros for FSL_ESW_TDSR */
-#define FSL_ESW_TDSR_ADDRESS(x) (((x)&0x3FFFFFFF)<<2)
+#define FSL_ESW_TDSR_ADDRESS(x) (((x) & 0x3FFFFFFF) << 2)
/* Bit definitions and macros for FSL_ESW_MRBR */
-#define FSL_ESW_MRBR_SIZE(x) (((x)&0x000003FF)<<4)
+#define FSL_ESW_MRBR_SIZE(x) (((x) & 0x000003FF) << 4)
/* Bit definitions and macros for FSL_ESW_RDAR */
#define FSL_ESW_RDAR_R_DES_ACTIVE (0x01000000)
@@ -1082,12 +780,12 @@ struct switch_platform_private {
#define FSL_ESW_TDAR_X_DES_ACTIVE (0x01000000)
/* Bit definitions and macros for FSL_ESW_LREC0 */
-#define FSL_ESW_LREC0_MACADDR0(x) (((x)&0xFFFFFFFF)<<0)
+#define FSL_ESW_LREC0_MACADDR0(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for FSL_ESW_LREC1 */
-#define FSL_ESW_LREC1_MACADDR1(x) (((x)&0x0000FFFF)<<0)
-#define FSL_ESW_LREC1_HASH(x) (((x)&0x000000FF)<<16)
-#define FSL_ESW_LREC1_SWPORT(x) (((x)&0x00000003)<<24)
+#define FSL_ESW_LREC1_MACADDR1(x) (((x) & 0x0000FFFF) << 0)
+#define FSL_ESW_LREC1_HASH(x) (((x) & 0x000000FF) << 16)
+#define FSL_ESW_LREC1_SWPORT(x) (((x) & 0x00000003) << 24)
/* Bit definitions and macros for FSL_ESW_LSR */
#define FSL_ESW_LSR_DA (0x00000001)