swconfig: revert the portmapping patches, they seem to cause a segfault
Revert "kernel/swconfig: remove obsolete portmapping feature from swconfig" This reverts commit675407baa4. Revert "swconfig: remove obsolete portmapping feature" This reverts commitfca1eb349e. Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		@@ -41,6 +41,7 @@ enum {
 | 
				
			|||||||
	CMD_LOAD,
 | 
						CMD_LOAD,
 | 
				
			||||||
	CMD_HELP,
 | 
						CMD_HELP,
 | 
				
			||||||
	CMD_SHOW,
 | 
						CMD_SHOW,
 | 
				
			||||||
 | 
						CMD_PORTMAP,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -284,6 +285,10 @@ int main(int argc, char **argv)
 | 
				
			|||||||
				print_usage();
 | 
									print_usage();
 | 
				
			||||||
			cmd = CMD_LOAD;
 | 
								cmd = CMD_LOAD;
 | 
				
			||||||
			ckey = argv[++i];
 | 
								ckey = argv[++i];
 | 
				
			||||||
 | 
							} else if (!strcmp(arg, "portmap")) {
 | 
				
			||||||
 | 
								if (i + 1 < argc)
 | 
				
			||||||
 | 
									csegment = argv[++i];
 | 
				
			||||||
 | 
								cmd = CMD_PORTMAP;
 | 
				
			||||||
		} else if (!strcmp(arg, "show")) {
 | 
							} else if (!strcmp(arg, "show")) {
 | 
				
			||||||
			cmd = CMD_SHOW;
 | 
								cmd = CMD_SHOW;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
@@ -357,6 +362,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	case CMD_HELP:
 | 
						case CMD_HELP:
 | 
				
			||||||
		list_attributes(dev);
 | 
							list_attributes(dev);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case CMD_PORTMAP:
 | 
				
			||||||
 | 
							swlib_print_portmap(dev, csegment);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case CMD_SHOW:
 | 
						case CMD_SHOW:
 | 
				
			||||||
		if (cport >= 0 || cvlan >= 0) {
 | 
							if (cport >= 0 || cvlan >= 0) {
 | 
				
			||||||
			if (cport >= 0)
 | 
								if (cport >= 0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,6 +46,11 @@ static struct nla_policy port_policy[SWITCH_ATTR_MAX] = {
 | 
				
			|||||||
	[SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG },
 | 
						[SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct nla_policy portmap_policy[SWITCH_PORTMAP_MAX] = {
 | 
				
			||||||
 | 
						[SWITCH_PORTMAP_SEGMENT] = { .type = NLA_STRING },
 | 
				
			||||||
 | 
						[SWITCH_PORTMAP_VIRT] = { .type = NLA_U32 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct nla_policy link_policy[SWITCH_LINK_ATTR_MAX] = {
 | 
					static struct nla_policy link_policy[SWITCH_LINK_ATTR_MAX] = {
 | 
				
			||||||
	[SWITCH_LINK_FLAG_LINK] = { .type = NLA_FLAG },
 | 
						[SWITCH_LINK_FLAG_LINK] = { .type = NLA_FLAG },
 | 
				
			||||||
	[SWITCH_LINK_FLAG_DUPLEX] = { .type = NLA_FLAG },
 | 
						[SWITCH_LINK_FLAG_DUPLEX] = { .type = NLA_FLAG },
 | 
				
			||||||
@@ -696,6 +701,41 @@ struct swlib_scan_arg {
 | 
				
			|||||||
	struct switch_dev *ptr;
 | 
						struct switch_dev *ptr;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					add_port_map(struct switch_dev *dev, struct nlattr *nla)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nlattr *p;
 | 
				
			||||||
 | 
						int err = 0, idx = 0;
 | 
				
			||||||
 | 
						int remaining;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev->maps = malloc(sizeof(struct switch_portmap) * dev->ports);
 | 
				
			||||||
 | 
						if (!dev->maps)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						memset(dev->maps, 0, sizeof(struct switch_portmap) * dev->ports);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nla_for_each_nested(p, nla, remaining) {
 | 
				
			||||||
 | 
							struct nlattr *tb[SWITCH_PORTMAP_MAX+1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (idx >= dev->ports)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = nla_parse_nested(tb, SWITCH_PORTMAP_MAX, p, portmap_policy);
 | 
				
			||||||
 | 
							if (err < 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (tb[SWITCH_PORTMAP_SEGMENT] && tb[SWITCH_PORTMAP_VIRT]) {
 | 
				
			||||||
 | 
								dev->maps[idx].segment = strdup(nla_get_string(tb[SWITCH_PORTMAP_SEGMENT]));
 | 
				
			||||||
 | 
								dev->maps[idx].virt = nla_get_u32(tb[SWITCH_PORTMAP_VIRT]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							idx++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
add_switch(struct nl_msg *msg, void *arg)
 | 
					add_switch(struct nl_msg *msg, void *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -733,6 +773,8 @@ add_switch(struct nl_msg *msg, void *arg)
 | 
				
			|||||||
		dev->vlans = nla_get_u32(tb[SWITCH_ATTR_VLANS]);
 | 
							dev->vlans = nla_get_u32(tb[SWITCH_ATTR_VLANS]);
 | 
				
			||||||
	if (tb[SWITCH_ATTR_CPU_PORT])
 | 
						if (tb[SWITCH_ATTR_CPU_PORT])
 | 
				
			||||||
		dev->cpu_port = nla_get_u32(tb[SWITCH_ATTR_CPU_PORT]);
 | 
							dev->cpu_port = nla_get_u32(tb[SWITCH_ATTR_CPU_PORT]);
 | 
				
			||||||
 | 
						if (tb[SWITCH_ATTR_PORTMAP])
 | 
				
			||||||
 | 
							add_port_map(dev, tb[SWITCH_ATTR_PORTMAP]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!sa->head) {
 | 
						if (!sa->head) {
 | 
				
			||||||
		sa->head = dev;
 | 
							sa->head = dev;
 | 
				
			||||||
@@ -774,6 +816,34 @@ swlib_list(void)
 | 
				
			|||||||
	swlib_priv_free();
 | 
						swlib_priv_free();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					swlib_print_portmap(struct switch_dev *dev, char *segment)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (segment) {
 | 
				
			||||||
 | 
							if (!strcmp(segment, "cpu")) {
 | 
				
			||||||
 | 
								printf("%d ", dev->cpu_port);
 | 
				
			||||||
 | 
							} else if (!strcmp(segment, "disabled")) {
 | 
				
			||||||
 | 
								for (i = 0; i < dev->ports; i++)
 | 
				
			||||||
 | 
									if (!dev->maps[i].segment)
 | 
				
			||||||
 | 
										printf("%d ", i);
 | 
				
			||||||
 | 
							} else for (i = 0; i < dev->ports; i++) {
 | 
				
			||||||
 | 
								if (dev->maps[i].segment && !strcmp(dev->maps[i].segment, segment))
 | 
				
			||||||
 | 
									printf("%d ", i);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							printf("%s - %s\n", dev->dev_name, dev->name);
 | 
				
			||||||
 | 
							for (i = 0; i < dev->ports; i++)
 | 
				
			||||||
 | 
								if (i == dev->cpu_port)
 | 
				
			||||||
 | 
									printf("port%d:\tcpu\n", i);
 | 
				
			||||||
 | 
								else if (dev->maps[i].segment)
 | 
				
			||||||
 | 
									printf("port%d:\t%s.%d\n", i, dev->maps[i].segment, dev->maps[i].virt);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									printf("port%d:\tdisabled\n", i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct switch_dev *
 | 
					struct switch_dev *
 | 
				
			||||||
swlib_connect(const char *name)
 | 
					swlib_connect(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -811,12 +881,26 @@ swlib_free_attributes(struct switch_attr **head)
 | 
				
			|||||||
	*head = NULL;
 | 
						*head = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					swlib_free_port_map(struct switch_dev *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dev || !dev->maps)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < dev->ports; i++)
 | 
				
			||||||
 | 
							free(dev->maps[i].segment);
 | 
				
			||||||
 | 
						free(dev->maps);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
swlib_free(struct switch_dev *dev)
 | 
					swlib_free(struct switch_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	swlib_free_attributes(&dev->ops);
 | 
						swlib_free_attributes(&dev->ops);
 | 
				
			||||||
	swlib_free_attributes(&dev->port_ops);
 | 
						swlib_free_attributes(&dev->port_ops);
 | 
				
			||||||
	swlib_free_attributes(&dev->vlan_ops);
 | 
						swlib_free_attributes(&dev->vlan_ops);
 | 
				
			||||||
 | 
						swlib_free_port_map(dev);
 | 
				
			||||||
	free(dev->name);
 | 
						free(dev->name);
 | 
				
			||||||
	free(dev->alias);
 | 
						free(dev->alias);
 | 
				
			||||||
	free(dev);
 | 
						free(dev);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -129,6 +129,7 @@ struct switch_dev {
 | 
				
			|||||||
	struct switch_attr *ops;
 | 
						struct switch_attr *ops;
 | 
				
			||||||
	struct switch_attr *port_ops;
 | 
						struct switch_attr *port_ops;
 | 
				
			||||||
	struct switch_attr *vlan_ops;
 | 
						struct switch_attr *vlan_ops;
 | 
				
			||||||
 | 
						struct switch_portmap *maps;
 | 
				
			||||||
	struct switch_dev *next;
 | 
						struct switch_dev *next;
 | 
				
			||||||
	void *priv;
 | 
						void *priv;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -161,6 +162,11 @@ struct switch_port {
 | 
				
			|||||||
	unsigned int flags;
 | 
						unsigned int flags;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct switch_portmap {
 | 
				
			||||||
 | 
						unsigned int virt;
 | 
				
			||||||
 | 
						char *segment;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct switch_port_link {
 | 
					struct switch_port_link {
 | 
				
			||||||
	int link:1;
 | 
						int link:1;
 | 
				
			||||||
	int duplex:1;
 | 
						int duplex:1;
 | 
				
			||||||
@@ -177,6 +183,12 @@ struct switch_port_link {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void swlib_list(void);
 | 
					void swlib_list(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * swlib_print_portmap: get portmap
 | 
				
			||||||
 | 
					 * @dev: switch device struct
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void swlib_print_portmap(struct switch_dev *dev, char *segment);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * swlib_connect: connect to the switch through netlink
 | 
					 * swlib_connect: connect to the switch through netlink
 | 
				
			||||||
 * @name: name of the ethernet interface,
 | 
					 * @name: name of the ethernet interface,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -915,7 +915,9 @@ static int
 | 
				
			|||||||
swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 | 
					swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 | 
				
			||||||
		const struct switch_dev *dev)
 | 
							const struct switch_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct nlattr *p = NULL, *m = NULL;
 | 
				
			||||||
	void *hdr;
 | 
						void *hdr;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hdr = genlmsg_put(msg, pid, seq, &switch_fam, flags,
 | 
						hdr = genlmsg_put(msg, pid, seq, &switch_fam, flags,
 | 
				
			||||||
			SWITCH_CMD_NEW_ATTR);
 | 
								SWITCH_CMD_NEW_ATTR);
 | 
				
			||||||
@@ -937,6 +939,24 @@ swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 | 
				
			|||||||
	if (nla_put_u32(msg, SWITCH_ATTR_CPU_PORT, dev->cpu_port))
 | 
						if (nla_put_u32(msg, SWITCH_ATTR_CPU_PORT, dev->cpu_port))
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m = nla_nest_start(msg, SWITCH_ATTR_PORTMAP);
 | 
				
			||||||
 | 
						if (!m)
 | 
				
			||||||
 | 
							goto nla_put_failure;
 | 
				
			||||||
 | 
						for (i = 0; i < dev->ports; i++) {
 | 
				
			||||||
 | 
							p = nla_nest_start(msg, SWITCH_ATTR_PORTS);
 | 
				
			||||||
 | 
							if (!p)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (dev->portmap[i].s) {
 | 
				
			||||||
 | 
								if (nla_put_string(msg, SWITCH_PORTMAP_SEGMENT,
 | 
				
			||||||
 | 
											dev->portmap[i].s))
 | 
				
			||||||
 | 
									goto nla_put_failure;
 | 
				
			||||||
 | 
								if (nla_put_u32(msg, SWITCH_PORTMAP_VIRT,
 | 
				
			||||||
 | 
											dev->portmap[i].virt))
 | 
				
			||||||
 | 
									goto nla_put_failure;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							nla_nest_end(msg, p);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						nla_nest_end(msg, m);
 | 
				
			||||||
	genlmsg_end(msg, hdr);
 | 
						genlmsg_end(msg, hdr);
 | 
				
			||||||
	return msg->len;
 | 
						return msg->len;
 | 
				
			||||||
nla_put_failure:
 | 
					nla_put_failure:
 | 
				
			||||||
@@ -1029,6 +1049,51 @@ static struct genl_ops swconfig_ops[] = {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_OF
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					of_switch_load_portmap(struct switch_dev *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct device_node *port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dev->of_node)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for_each_child_of_node(dev->of_node, port) {
 | 
				
			||||||
 | 
							const __be32 *prop;
 | 
				
			||||||
 | 
							const char *segment;
 | 
				
			||||||
 | 
							int size, phys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!of_device_is_compatible(port, "swconfig,port"))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (of_property_read_string(port, "swconfig,segment", &segment))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							prop = of_get_property(port, "swconfig,portmap", &size);
 | 
				
			||||||
 | 
							if (!prop)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (size != (2 * sizeof(*prop))) {
 | 
				
			||||||
 | 
								pr_err("%s: failed to parse port mapping\n",
 | 
				
			||||||
 | 
										port->name);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							phys = be32_to_cpup(prop++);
 | 
				
			||||||
 | 
							if ((phys < 0) | (phys >= dev->ports)) {
 | 
				
			||||||
 | 
								pr_err("%s: physical port index out of range\n",
 | 
				
			||||||
 | 
										port->name);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dev->portmap[phys].s = kstrdup(segment, GFP_KERNEL);
 | 
				
			||||||
 | 
							dev->portmap[phys].virt = be32_to_cpup(prop);
 | 
				
			||||||
 | 
							pr_debug("Found port: %s, physical: %d, virtual: %d\n",
 | 
				
			||||||
 | 
								segment, phys, dev->portmap[phys].virt);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
register_switch(struct switch_dev *dev, struct net_device *netdev)
 | 
					register_switch(struct switch_dev *dev, struct net_device *netdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1051,6 +1116,12 @@ register_switch(struct switch_dev *dev, struct net_device *netdev)
 | 
				
			|||||||
				dev->ports, GFP_KERNEL);
 | 
									dev->ports, GFP_KERNEL);
 | 
				
			||||||
		if (!dev->portbuf)
 | 
							if (!dev->portbuf)
 | 
				
			||||||
			return -ENOMEM;
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
							dev->portmap = kzalloc(sizeof(struct switch_portmap) *
 | 
				
			||||||
 | 
									dev->ports, GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!dev->portmap) {
 | 
				
			||||||
 | 
								kfree(dev->portbuf);
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	swconfig_defaults_init(dev);
 | 
						swconfig_defaults_init(dev);
 | 
				
			||||||
	mutex_init(&dev->sw_mutex);
 | 
						mutex_init(&dev->sw_mutex);
 | 
				
			||||||
@@ -1072,6 +1143,11 @@ register_switch(struct switch_dev *dev, struct net_device *netdev)
 | 
				
			|||||||
		return -ENFILE;
 | 
							return -ENFILE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_OF
 | 
				
			||||||
 | 
						if (dev->ports)
 | 
				
			||||||
 | 
							of_switch_load_portmap(dev);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* fill device name */
 | 
						/* fill device name */
 | 
				
			||||||
	snprintf(dev->devname, IFNAMSIZ, SWCONFIG_DEVNAME, i);
 | 
						snprintf(dev->devname, IFNAMSIZ, SWCONFIG_DEVNAME, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,6 +105,7 @@ struct switch_dev_ops {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct switch_dev {
 | 
					struct switch_dev {
 | 
				
			||||||
 | 
						struct device_node *of_node;
 | 
				
			||||||
	const struct switch_dev_ops *ops;
 | 
						const struct switch_dev_ops *ops;
 | 
				
			||||||
	/* will be automatically filled */
 | 
						/* will be automatically filled */
 | 
				
			||||||
	char devname[IFNAMSIZ];
 | 
						char devname[IFNAMSIZ];
 | 
				
			||||||
@@ -125,6 +126,7 @@ struct switch_dev {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	struct mutex sw_mutex;
 | 
						struct mutex sw_mutex;
 | 
				
			||||||
	struct switch_port *portbuf;
 | 
						struct switch_port *portbuf;
 | 
				
			||||||
 | 
						struct switch_portmap *portmap;
 | 
				
			||||||
	struct switch_port_link linkbuf;
 | 
						struct switch_port_link linkbuf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char buf[128];
 | 
						char buf[128];
 | 
				
			||||||
@@ -139,6 +141,11 @@ struct switch_port {
 | 
				
			|||||||
	u32 flags;
 | 
						u32 flags;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct switch_portmap {
 | 
				
			||||||
 | 
						u32 virt;
 | 
				
			||||||
 | 
						const char *s;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct switch_val {
 | 
					struct switch_val {
 | 
				
			||||||
	const struct switch_attr *attr;
 | 
						const struct switch_attr *attr;
 | 
				
			||||||
	int port_vlan;
 | 
						int port_vlan;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,7 @@ enum {
 | 
				
			|||||||
	SWITCH_ATTR_NAME,
 | 
						SWITCH_ATTR_NAME,
 | 
				
			||||||
	SWITCH_ATTR_VLANS,
 | 
						SWITCH_ATTR_VLANS,
 | 
				
			||||||
	SWITCH_ATTR_PORTS,
 | 
						SWITCH_ATTR_PORTS,
 | 
				
			||||||
 | 
						SWITCH_ATTR_PORTMAP,
 | 
				
			||||||
	SWITCH_ATTR_CPU_PORT,
 | 
						SWITCH_ATTR_CPU_PORT,
 | 
				
			||||||
	/* attributes */
 | 
						/* attributes */
 | 
				
			||||||
	SWITCH_ATTR_OP_ID,
 | 
						SWITCH_ATTR_OP_ID,
 | 
				
			||||||
@@ -56,6 +57,14 @@ enum {
 | 
				
			|||||||
	SWITCH_ATTR_MAX
 | 
						SWITCH_ATTR_MAX
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						/* port map */
 | 
				
			||||||
 | 
						SWITCH_PORTMAP_PORTS,
 | 
				
			||||||
 | 
						SWITCH_PORTMAP_SEGMENT,
 | 
				
			||||||
 | 
						SWITCH_PORTMAP_VIRT,
 | 
				
			||||||
 | 
						SWITCH_PORTMAP_MAX
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* commands */
 | 
					/* commands */
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	SWITCH_CMD_UNSPEC,
 | 
						SWITCH_CMD_UNSPEC,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,6 +93,36 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
&esw {
 | 
					&esw {
 | 
				
			||||||
	mediatek,portmap = <0x2f>;
 | 
						mediatek,portmap = <0x2f>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port@0 {
 | 
				
			||||||
 | 
							compatible = "swconfig,port";
 | 
				
			||||||
 | 
							swconfig,segment = "lan";
 | 
				
			||||||
 | 
							swconfig,portmap = <0 4>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port@1 {
 | 
				
			||||||
 | 
							compatible = "swconfig,port";
 | 
				
			||||||
 | 
							swconfig,segment = "lan";
 | 
				
			||||||
 | 
							swconfig,portmap = <1 3>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port@2 {
 | 
				
			||||||
 | 
							compatible = "swconfig,port";
 | 
				
			||||||
 | 
							swconfig,segment = "lan";
 | 
				
			||||||
 | 
							swconfig,portmap = <2 2>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port@3 {
 | 
				
			||||||
 | 
							compatible = "swconfig,port";
 | 
				
			||||||
 | 
							swconfig,segment = "lan";
 | 
				
			||||||
 | 
							swconfig,portmap = <3 1>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port@4 {
 | 
				
			||||||
 | 
							compatible = "swconfig,port";
 | 
				
			||||||
 | 
							swconfig,segment = "wan";
 | 
				
			||||||
 | 
							swconfig,portmap = <4 0>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
&wmac {
 | 
					&wmac {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -865,11 +865,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
 	struct rt305x_esw *esw;
 | 
					 	struct rt305x_esw *esw;
 | 
				
			||||||
 	struct resource *irq;
 | 
					 	struct resource *irq;
 | 
				
			||||||
 	int ret;
 | 
					 	int ret;
 | 
				
			||||||
@@ -568,6 +1353,20 @@ static int esw_probe(struct platform_dev
 | 
					@@ -568,6 +1353,21 @@ static int esw_probe(struct platform_dev
 | 
				
			||||||
 	if (reg_init)
 | 
					 	if (reg_init)
 | 
				
			||||||
 		esw->reg_led_polarity = be32_to_cpu(*reg_init);
 | 
					 		esw->reg_led_polarity = be32_to_cpu(*reg_init);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
+	swdev = &esw->swdev;
 | 
					+	swdev = &esw->swdev;
 | 
				
			||||||
 | 
					+	swdev->of_node = pdev->dev.of_node;
 | 
				
			||||||
+	swdev->name = "rt305x-esw";
 | 
					+	swdev->name = "rt305x-esw";
 | 
				
			||||||
+	swdev->alias = "rt305x";
 | 
					+	swdev->alias = "rt305x";
 | 
				
			||||||
+	swdev->cpu_port = RT305X_ESW_PORT6;
 | 
					+	swdev->cpu_port = RT305X_ESW_PORT6;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user