OpenWrt – Rev 4

Subversion Repositories:
Rev:
From 0dff8c753c8929a478357abb38db0d1c1a60ec94 Mon Sep 17 00:00:00 2001
From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Date: Wed, 29 Aug 2012 22:08:15 +0200
Subject: net: switchlib: add framework for ethernet switch drivers

Add a generic framework similar to phylib for ethernet switch
drivers and devices. This is useful to share the init and
setup code for switch devices across different boards.

Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Joe Hershberger <joe.hershberger@gmail.com>

--- a/Makefile
+++ b/Makefile
@@ -280,6 +280,7 @@ LIBS-y += drivers/mtd/ubi/libubi.o
 LIBS-y += drivers/mtd/spi/libspi_flash.o
 LIBS-y += drivers/net/libnet.o
 LIBS-y += drivers/net/phy/libphy.o
+LIBS-y += drivers/net/switch/libswitch.o
 LIBS-y += drivers/pci/libpci.o
 LIBS-y += drivers/pcmcia/libpcmcia.o
 LIBS-y += drivers/power/libpower.o \
--- /dev/null
+++ b/drivers/net/switch/Makefile
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
+# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libswitch.o
+
+COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
--- /dev/null
+++ b/drivers/net/switch/switch.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include <switch.h>
+
+static struct list_head switch_drivers;
+static struct list_head switch_devices;
+
+void switch_init(void)
+{
+       INIT_LIST_HEAD(&switch_drivers);
+       INIT_LIST_HEAD(&switch_devices);
+
+       board_switch_init();
+}
+
+void switch_driver_register(struct switch_driver *drv)
+{
+       INIT_LIST_HEAD(&drv->list);
+       list_add_tail(&drv->list, &switch_drivers);
+}
+
+int switch_device_register(struct switch_device *dev)
+{
+       struct switch_driver *drv;
+
+       /* Add switch device only, if an adequate driver is registered */
+       list_for_each_entry(drv, &switch_drivers, list) {
+               if (!strcmp(drv->name, dev->name)) {
+                       dev->drv = drv;
+
+                       INIT_LIST_HEAD(&dev->list);
+                       list_add_tail(&dev->list, &switch_devices);
+
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+struct switch_device *switch_connect(struct mii_dev *bus)
+{
+       struct switch_device *sw;
+       int err;
+
+       list_for_each_entry(sw, &switch_devices, list) {
+               sw->bus = bus;
+
+               err = sw->drv->probe(sw);
+               if (!err)
+                       return sw;
+       }
+
+       return NULL;
+}
--- /dev/null
+++ b/include/switch.h
@@ -0,0 +1,102 @@
+/*
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
+ */
+
+#ifndef __SWITCH_H
+#define __SWITCH_H
+
+#include <linux/list.h>
+
+#define SWITCH_NAME_SIZE       32
+
+struct switch_device;
+struct mii_dev;
+
+struct switch_driver {
+       struct list_head list;
+
+       /* Switch device name */
+       const char name[SWITCH_NAME_SIZE];
+
+       /*
+        * Called to probe the switch chip. Must return 0 if the switch
+        * chip matches the given switch device/driver combination. Otherwise
+        * 1 must be returned.
+        */
+       int (*probe) (struct switch_device *dev);
+
+       /*
+        * Called to initialize the switch chip.
+        */
+       void (*setup) (struct switch_device *dev);
+};
+
+struct switch_device {
+       struct list_head list;
+       struct switch_driver *drv;
+
+       /* MII bus the switch chip is connected to */
+       struct mii_dev *bus;
+
+       /* Switch device name */
+       const char name[SWITCH_NAME_SIZE];
+
+       /* Bitmask for board specific setup of used switch ports */
+       u16 port_mask;
+
+       /* Number of switch port that is connected to host CPU */
+       u16 cpu_port;
+};
+
+/*
+ * Board specific switch initialization.
+ *
+ * Called from switch_init to register the board specific switch_device
+ * structure.
+ */
+extern int board_switch_init(void);
+
+/* Initialize switch subsystem */
+#ifdef CONFIG_SWITCH_MULTI
+extern void switch_init(void);
+#else
+static inline void switch_init(void)
+{
+}
+#endif
+
+/* Register a switch driver */
+extern void switch_driver_register(struct switch_driver *drv);
+
+/* Register a switch device */
+extern int switch_device_register(struct switch_device *dev);
+
+/*
+ * Probe the available switch chips and connect the found one
+ * with the given MII bus
+ */
+#ifdef CONFIG_SWITCH_MULTI
+extern struct switch_device *switch_connect(struct mii_dev *bus);
+#else
+static inline struct switch_device *switch_connect(struct mii_dev *bus)
+{
+       return NULL;
+}
+#endif
+
+/*
+ * Setup the given switch device
+ */
+static inline void switch_setup(struct switch_device *dev)
+{
+       if (dev->drv->setup)
+               dev->drv->setup(dev);
+}
+
+/* Init functions for supported Switch drivers */
+
+#endif /* __SWITCH_H */
+
--- a/net/eth.c
+++ b/net/eth.c
@@ -10,6 +10,7 @@
 #include <net.h>
 #include <miiphy.h>
 #include <phy.h>
+#include <switch.h>
 
 void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
 {
@@ -287,6 +288,8 @@ int eth_initialize(bd_t *bis)
        phy_init();
 #endif
 
+       switch_init();
+
        eth_env_init(bis);
 
        /*