| 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); |
| |
| /* |