1/*
2 * swlib.h: Switch configuration API (user space part)
3 *
4 * Copyright (C) 2008-2009 Felix Fietkau <nbd@nbd.name>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * version 2.1 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15
16Usage of the library functions:
17
18  The main datastructure for a switch is the struct switch_device
19  To get started, you first need to use switch_connect() to probe
20  for switches and allocate an instance of this struct.
21
22  There are two possible usage modes:
23    dev = switch_connect("eth0");
24      - this call will look for a switch registered for the linux device
25  	  "eth0" and only allocate a switch_device for this particular switch.
26
27    dev = switch_connect(NULL)
28      - this will return one switch_device struct for each available
29  	  switch. The switch_device structs are chained with by ->next pointer
30
31  Then to query a switch for all available attributes, use:
32    swlib_scan(dev);
33
34  All allocated datastructures for the switch_device struct can be freed with
35    swlib_free(dev);
36  or
37    swlib_free_all(dev);
38
39  The latter traverses a whole chain of switch_device structs and frees them all
40
41  Switch attributes (struct switch_attr) are divided into three groups:
42    dev->ops:
43      - global settings
44    dev->port_ops:
45      - per-port settings
46    dev->vlan_ops:
47      - per-vlan settings
48
49  switch_lookup_attr() is a small helper function to locate attributes
50  by name.
51
52  switch_set_attr() and switch_get_attr() can alter or request the values
53  of attributes.
54
55Usage of the switch_attr struct:
56
57  ->atype: attribute group, one of:
58    - SWLIB_ATTR_GROUP_GLOBAL
59    - SWLIB_ATTR_GROUP_VLAN
60    - SWLIB_ATTR_GROUP_PORT
61
62  ->id: identifier for the attribute
63
64  ->type: data type, one of:
65    - SWITCH_TYPE_INT
66    - SWITCH_TYPE_STRING
67    - SWITCH_TYPE_PORT
68
69  ->name: short name of the attribute
70  ->description: longer description
71  ->next: pointer to the next attribute of the current group
72
73
74Usage of the switch_val struct:
75
76  When setting attributes, following members of the struct switch_val need
77  to be set up:
78
79    ->len (for attr->type == SWITCH_TYPE_PORT)
80    ->port_vlan:
81      - port number (for attr->atype == SWLIB_ATTR_GROUP_PORT), or:
82      - vlan number (for attr->atype == SWLIB_ATTR_GROUP_VLAN)
83    ->value.i (for attr->type == SWITCH_TYPE_INT)
84    ->value.s (for attr->type == SWITCH_TYPE_STRING)
85      - owned by the caller, not stored in the library internally
86    ->value.ports (for attr->type == SWITCH_TYPE_PORT)
87      - must point to an array of at lest val->len * sizeof(struct switch_port)
88
89  When getting string attributes, val->value.s must be freed by the caller
90  When getting port list attributes, an internal static buffer is used,
91  which changes from call to call.
92
93 */
94
95#ifndef __SWLIB_H
96#define __SWLIB_H
97
98enum swlib_attr_group {
99	SWLIB_ATTR_GROUP_GLOBAL,
100	SWLIB_ATTR_GROUP_VLAN,
101	SWLIB_ATTR_GROUP_PORT,
102};
103
104enum swlib_port_flags {
105	SWLIB_PORT_FLAG_TAGGED = (1 << 0),
106};
107
108enum swlib_link_flags {
109	SWLIB_LINK_FLAG_EEE_100BASET = (1 << 0),
110	SWLIB_LINK_FLAG_EEE_1000BASET = (1 << 1),
111};
112
113struct switch_dev;
114struct switch_attr;
115struct switch_port;
116struct switch_port_map;
117struct switch_port_link;
118struct switch_val;
119struct uci_package;
120
121struct switch_dev {
122	int id;
123	char dev_name[IFNAMSIZ];
124	char *name;
125	char *alias;
126	int ports;
127	int vlans;
128	int cpu_port;
129	struct switch_attr *ops;
130	struct switch_attr *port_ops;
131	struct switch_attr *vlan_ops;
132	struct switch_portmap *maps;
133	struct switch_dev *next;
134	void *priv;
135};
136
137struct switch_val {
138	struct switch_attr *attr;
139	int len;
140	int err;
141	int port_vlan;
142	union {
143		char *s;
144		int i;
145		struct switch_port *ports;
146		struct switch_port_link *link;
147	} value;
148};
149
150struct switch_attr {
151	struct switch_dev *dev;
152	int atype;
153	int id;
154	int type;
155	char *name;
156	char *description;
157	struct switch_attr *next;
158};
159
160struct switch_port {
161	unsigned int id;
162	unsigned int flags;
163};
164
165struct switch_portmap {
166	unsigned int virt;
167	char *segment;
168};
169
170struct switch_port_link {
171	int link:1;
172	int duplex:1;
173	int aneg:1;
174	int tx_flow:1;
175	int rx_flow:1;
176	int speed;
177	/* in ethtool adv_t format */
178	uint32_t eee;
179};
180
181/**
182 * swlib_list: list all switches
183 */
184void swlib_list(void);
185
186/**
187 * swlib_print_portmap: get portmap
188 * @dev: switch device struct
189 */
190void swlib_print_portmap(struct switch_dev *dev, char *segment);
191
192/**
193 * swlib_connect: connect to the switch through netlink
194 * @name: name of the ethernet interface,
195 *
196 * if name is NULL, it connect and builds a chain of all switches
197 */
198struct switch_dev *swlib_connect(const char *name);
199
200/**
201 * swlib_free: free all dynamically allocated data for the switch connection
202 * @dev: switch device struct
203 *
204 * all members of a switch device chain (generated by swlib_connect(NULL))
205 * must be freed individually
206 */
207void swlib_free(struct switch_dev *dev);
208
209/**
210 * swlib_free_all: run swlib_free on all devices in the chain
211 * @dev: switch device struct
212 */
213void swlib_free_all(struct switch_dev *dev);
214
215/**
216 * swlib_scan: probe the switch driver for available commands/attributes
217 * @dev: switch device struct
218 */
219int swlib_scan(struct switch_dev *dev);
220
221/**
222 * swlib_lookup_attr: look up a switch attribute
223 * @dev: switch device struct
224 * @type: global, port or vlan
225 * @name: name of the attribute
226 */
227struct switch_attr *swlib_lookup_attr(struct switch_dev *dev,
228		enum swlib_attr_group atype, const char *name);
229
230/**
231 * swlib_set_attr: set the value for an attribute
232 * @dev: switch device struct
233 * @attr: switch attribute struct
234 * @val: attribute value pointer
235 * returns 0 on success
236 */
237int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr,
238		struct switch_val *val);
239
240/**
241 * swlib_set_attr_string: set the value for an attribute with type conversion
242 * @dev: switch device struct
243 * @attr: switch attribute struct
244 * @port_vlan: port or vlan (if applicable)
245 * @str: string value
246 * returns 0 on success
247 */
248int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *attr,
249		int port_vlan, const char *str);
250
251/**
252 * swlib_get_attr: get the value for an attribute
253 * @dev: switch device struct
254 * @attr: switch attribute struct
255 * @val: attribute value pointer
256 * returns 0 on success
257 * for string attributes, the result string must be freed by the caller
258 */
259int swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr,
260		struct switch_val *val);
261
262/**
263 * swlib_apply_from_uci: set up the switch from a uci configuration
264 * @dev: switch device struct
265 * @p: uci package which contains the desired global config
266 */
267int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p);
268
269#endif
270