u8 vlan_tagged;
u16 pvid[AR8216_NUM_PORTS];
};
-static struct switch_dev athdev;
#define to_ar8216(_dev) container_of(_dev, struct ar8216_priv, dev)
return ar8216_hw_apply(dev);
}
+
+static const struct switch_dev_ops ar8216_ops = {
+ .attr_global = {
+ .attr = ar8216_globals,
+ .n_attr = ARRAY_SIZE(ar8216_globals),
+ },
+ .attr_port = {
+ .attr = ar8216_port,
+ .n_attr = ARRAY_SIZE(ar8216_port),
+ },
+ .attr_vlan = {
+ .attr = ar8216_vlan,
+ .n_attr = ARRAY_SIZE(ar8216_vlan),
+ },
+ .get_port_pvid = ar8216_get_pvid,
+ .set_port_pvid = ar8216_set_pvid,
+ .get_vlan_ports = ar8216_get_ports,
+ .set_vlan_ports = ar8216_set_ports,
+ .apply_config = ar8216_hw_apply,
+ .reset_switch = ar8216_reset_switch,
+};
+
static int
ar8216_config_init(struct phy_device *pdev)
{
struct ar8216_priv *priv;
struct net_device *dev = pdev->attached_dev;
+ struct switch_dev *swdev;
int ret;
priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL);
mutex_init(&priv->reg_mutex);
priv->read = ar8216_mii_read;
priv->write = ar8216_mii_write;
- memcpy(&priv->dev, &athdev, sizeof(struct switch_dev));
+
pdev->priv = priv;
+ swdev = &priv->dev;
+ swdev->cpu_port = AR8216_PORT_CPU;
+ swdev->ops = &ar8216_ops;
+
if (priv->chip == AR8316) {
- priv->dev.name = "Atheros AR8316";
- priv->dev.vlans = AR8X16_MAX_VLANS;
+ swdev->name = "Atheros AR8316";
+ swdev->vlans = AR8X16_MAX_VLANS;
/* port 5 connected to the other mac, therefore unusable */
- priv->dev.ports = (AR8216_NUM_PORTS - 1);
+ swdev->ports = (AR8216_NUM_PORTS - 1);
+ } else {
+ swdev->name = "Atheros AR8216";
+ swdev->vlans = AR8216_NUM_VLANS;
+ swdev->ports = AR8216_NUM_PORTS;
}
if ((ret = register_switch(&priv->dev, pdev->attached_dev)) < 0) {
kfree(priv);
}
-/* template */
-static struct switch_dev athdev = {
- .name = "Atheros AR8216",
- .cpu_port = AR8216_PORT_CPU,
- .ports = AR8216_NUM_PORTS,
- .vlans = AR8216_NUM_VLANS,
- .attr_global = {
- .attr = ar8216_globals,
- .n_attr = ARRAY_SIZE(ar8216_globals),
- },
- .attr_port = {
- .attr = ar8216_port,
- .n_attr = ARRAY_SIZE(ar8216_port),
- },
- .attr_vlan = {
- .attr = ar8216_vlan,
- .n_attr = ARRAY_SIZE(ar8216_vlan),
- },
- .get_port_pvid = ar8216_get_pvid,
- .set_port_pvid = ar8216_set_pvid,
- .get_vlan_ports = ar8216_get_ports,
- .set_vlan_ports = ar8216_set_ports,
- .apply_config = ar8216_hw_apply,
- .reset_switch = ar8216_reset_switch,
-};
-
static struct phy_driver ar8216_driver = {
.phy_id = 0x004d0000,
.name = "Atheros AR8216/AR8316",
char buf[80];
};
+#define get_state(_dev) container_of((_dev), struct ip17xx_state, dev)
static int ip_phy_read(struct ip17xx_state *state, int port, int reg)
{
static int ip17xx_get_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
val->value.i = state->vlan_enabled;
return 0;
static int ip17xx_set_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int enable;
enable = val->value.i;
static int ip17xx_get_ports(struct switch_dev *dev, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int b;
int ind;
unsigned int ports;
static int ip17xx_set_ports(struct switch_dev *dev, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int i;
if (val->port_vlan >= dev->vlans || val->port_vlan < 0)
static int ip17xx_apply(struct switch_dev *dev)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
if (REG_SUPP(state->regs->MII_REGISTER_EN)) {
int val = getPhy(state, state->regs->MII_REGISTER_EN);
static int ip17xx_reset(struct switch_dev *dev)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int i, err;
if (REG_SUPP(state->regs->RESET_REG)) {
static int ip17xx_get_tagged(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
if (state->add_tag & (1<<val->port_vlan)) {
if (state->remove_tag & (1<<val->port_vlan))
static int ip17xx_set_tagged(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
state->add_tag &= ~(1<<val->port_vlan);
state->remove_tag &= ~(1<<val->port_vlan);
/** Get the current phy address */
static int ip17xx_get_phy(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
val->value.i = state->proc_mii.p;
return 0;
/** Set a new phy address for low level access to registers */
static int ip17xx_set_phy(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int new_reg = val->value.i;
if (new_reg < 0 || new_reg > 31)
/** Get the current register number */
static int ip17xx_get_reg(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
val->value.i = state->proc_mii.m;
return 0;
/** Set a new register address for low level access to registers */
static int ip17xx_set_reg(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int new_reg = val->value.i;
if (new_reg < 0 || new_reg > 31)
/** Get the register content of state->proc_mii */
static int ip17xx_get_val(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int retval = -EINVAL;
if (REG_SUPP(state->proc_mii))
retval = getPhy(state, state->proc_mii);
/** Write a value to the register defined by phy/reg above */
static int ip17xx_set_val(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int myval, err = -EINVAL;
myval = val->value.i;
static int ip17xx_read_name(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
val->value.s = state->regs->NAME; // Just a const pointer, won't be freed by swconfig.
return 0;
}
static int ip17xx_get_tag(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int vlan = val->port_vlan;
if (vlan < 0 || vlan >= MAX_VLANS)
static int ip17xx_set_tag(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int vlan = val->port_vlan;
int tag = val->value.i;
static int ip17xx_set_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int nr = val->port_vlan;
int ctrl;
int autoneg;
static int ip17xx_get_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int nr = val->port_vlan;
int speed, status;
static int ip17xx_get_port_status(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
int ctrl, speed, status;
int nr = val->port_vlan;
int len;
static int ip17xx_get_pvid(struct switch_dev *dev, int port, int *val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
*val = state->ports[port].pvid;
return 0;
static int ip17xx_set_pvid(struct switch_dev *dev, int port, int val)
{
- struct ip17xx_state *state = dev->priv;
+ struct ip17xx_state *state = get_state(dev);
if (val < 0 || val >= MAX_VLANS)
return -EINVAL;
},
};
+static const struct switch_dev_ops ip17xx_ops = {
+ .attr_global = {
+ .attr = ip17xx_global,
+ .n_attr = ARRAY_SIZE(ip17xx_global),
+ },
+ .attr_port = {
+ .attr = ip17xx_port,
+ .n_attr = ARRAY_SIZE(ip17xx_port),
+ },
+ .attr_vlan = {
+ .attr = ip17xx_vlan,
+ .n_attr = ARRAY_SIZE(ip17xx_vlan),
+ },
+
+ .get_port_pvid = ip17xx_get_pvid,
+ .set_port_pvid = ip17xx_set_pvid,
+ .get_vlan_ports = ip17xx_get_ports,
+ .set_vlan_ports = ip17xx_set_ports,
+ .apply_config = ip17xx_apply,
+ .reset_switch = ip17xx_reset,
+};
+
static int ip17xx_probe(struct phy_device *pdev)
{
struct ip17xx_state *state;
return -ENOMEM;
dev = &state->dev;
- dev->attr_global.attr = ip17xx_global;
- dev->attr_global.n_attr = ARRAY_SIZE(ip17xx_global);
- dev->attr_port.attr = ip17xx_port;
- dev->attr_port.n_attr = ARRAY_SIZE(ip17xx_port);
- dev->attr_vlan.attr = ip17xx_vlan;
- dev->attr_vlan.n_attr = ARRAY_SIZE(ip17xx_vlan);
-
- dev->get_port_pvid = ip17xx_get_pvid;
- dev->set_port_pvid = ip17xx_set_pvid;
- dev->get_vlan_ports = ip17xx_get_ports;
- dev->set_vlan_ports = ip17xx_set_ports;
- dev->apply_config = ip17xx_apply;
- dev->reset_switch = ip17xx_reset;
-
- dev->priv = state;
+
pdev->priv = state;
state->mii_bus = pdev->bus;
dev->cpu_port = state->regs->CPU_PORT;
dev->ports = state->regs->NUM_PORTS;
dev->name = state->regs->NAME;
+ dev->ops = &ip17xx_ops;
pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->dev));
return 0;
};
-/* IFXMIPS compat stuff - remove after PHY layer migration */
-static struct switch_dev rtldev;
-/* END IFXMIPS compat stuff */
-
-
static inline void
rtl_set_page(struct rtl_priv *priv, unsigned int page)
{
return 0;
}
-static int
-rtl8306_config_init(struct phy_device *pdev)
-{
- struct net_device *netdev = pdev->attached_dev;
- struct rtl_priv *priv = pdev->priv;
- struct switch_dev *dev = &priv->dev;
- struct switch_val val;
- unsigned int chipid, chipver, chiptype;
- int err;
-
- /* Only init the switch for the primary PHY */
- if (pdev->addr != 0)
- return 0;
-
- val.value.i = 1;
- memcpy(&priv->dev, &rtldev, sizeof(struct switch_dev));
- priv->do_cpu = 0;
- priv->page = -1;
- priv->bus = pdev->bus;
-
- dev->priv = priv;
-
- chipid = rtl_get(dev, RTL_REG_CHIPID);
- chipver = rtl_get(dev, RTL_REG_CHIPVER);
- chiptype = rtl_get(dev, RTL_REG_CHIPTYPE);
- switch(chiptype) {
- case 0:
- case 2:
- strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname));
- priv->type = RTL_TYPE_S;
- break;
- case 1:
- strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname));
- priv->type = RTL_TYPE_SD;
- break;
- case 3:
- strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname));
- priv->type = RTL_TYPE_SDM;
- break;
- default:
- strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname));
- break;
- }
-
- dev->name = priv->hwname;
- rtl_hw_init(dev);
-
- printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver);
-
- err = register_switch(dev, netdev);
- if (err < 0) {
- kfree(priv);
- return err;
- }
-
- return 0;
-}
-
static struct switch_attr rtl_globals[] = {
{
.type = SWITCH_TYPE_INT,
},
};
-/* template */
-static struct switch_dev rtldev = {
- .cpu_port = RTL8306_PORT_CPU,
- .ports = RTL8306_NUM_PORTS,
- .vlans = RTL8306_NUM_VLANS,
+static const struct switch_dev_ops rtl8306_ops = {
.attr_global = {
.attr = rtl_globals,
.n_attr = ARRAY_SIZE(rtl_globals),
.apply_config = rtl_hw_apply,
};
+static int
+rtl8306_config_init(struct phy_device *pdev)
+{
+ struct net_device *netdev = pdev->attached_dev;
+ struct rtl_priv *priv = pdev->priv;
+ struct switch_dev *dev = &priv->dev;
+ struct switch_val val;
+ unsigned int chipid, chipver, chiptype;
+ int err;
+
+ /* Only init the switch for the primary PHY */
+ if (pdev->addr != 0)
+ return 0;
+
+ val.value.i = 1;
+ priv->dev.cpu_port = RTL8306_PORT_CPU;
+ priv->dev.ports = RTL8306_NUM_PORTS;
+ priv->dev.vlans = RTL8306_NUM_VLANS;
+ priv->dev.ops = &rtl8306_ops;
+ priv->do_cpu = 0;
+ priv->page = -1;
+ priv->bus = pdev->bus;
+
+ chipid = rtl_get(dev, RTL_REG_CHIPID);
+ chipver = rtl_get(dev, RTL_REG_CHIPVER);
+ chiptype = rtl_get(dev, RTL_REG_CHIPTYPE);
+ switch(chiptype) {
+ case 0:
+ case 2:
+ strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname));
+ priv->type = RTL_TYPE_S;
+ break;
+ case 1:
+ strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname));
+ priv->type = RTL_TYPE_SD;
+ break;
+ case 3:
+ strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname));
+ priv->type = RTL_TYPE_SDM;
+ break;
+ default:
+ strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname));
+ break;
+ }
+
+ dev->name = priv->hwname;
+ rtl_hw_init(dev);
+
+ printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver);
+
+ err = register_switch(dev, netdev);
+ if (err < 0) {
+ kfree(priv);
+ return err;
+ }
+
+ return 0;
+}
+
static int
rtl8306_fixup(struct phy_device *pdev)
},
};
-/* template */
-static struct switch_dev rtl8366_switch_dev = {
- .name = "RTL8366S",
- .cpu_port = RTL8366RB_PORT_NUM_CPU,
- .ports = RTL8366RB_NUM_PORTS,
- .vlans = RTL8366RB_NUM_VLANS,
+static const struct switch_dev_ops rtl8366_ops = {
.attr_global = {
.attr = rtl8366rb_globals,
.n_attr = ARRAY_SIZE(rtl8366rb_globals),
struct switch_dev *dev = &smi->sw_dev;
int err;
- memcpy(dev, &rtl8366_switch_dev, sizeof(struct switch_dev));
- dev->priv = smi;
+ dev->name = "RTL8366RB";
+ dev->cpu_port = RTL8366RB_PORT_NUM_CPU;
+ dev->ports = RTL8366RB_NUM_PORTS;
+ dev->vlans = RTL8366RB_NUM_VLANS;
+ dev->ops = &rtl8366_ops;
dev->devname = dev_name(smi->parent);
err = register_switch(dev, NULL);
},
};
-/* template */
-static struct switch_dev rtl8366_switch_dev = {
- .name = "RTL8366S",
- .cpu_port = RTL8366S_PORT_NUM_CPU,
- .ports = RTL8366S_NUM_PORTS,
- .vlans = RTL8366S_NUM_VLANS,
+static const struct switch_dev_ops rtl8366_ops = {
.attr_global = {
.attr = rtl8366s_globals,
.n_attr = ARRAY_SIZE(rtl8366s_globals),
struct switch_dev *dev = &smi->sw_dev;
int err;
- memcpy(dev, &rtl8366_switch_dev, sizeof(struct switch_dev));
- dev->priv = smi;
+ dev->name = "RTL8366S";
+ dev->cpu_port = RTL8366S_PORT_NUM_CPU;
+ dev->ports = RTL8366S_NUM_PORTS;
+ dev->vlans = RTL8366S_NUM_VLANS;
+ dev->ops = &rtl8366_ops;
dev->devname = dev_name(smi->parent);
err = register_switch(dev, NULL);
if (val->port_vlan >= dev->vlans)
return -EINVAL;
- if (!dev->get_vlan_ports)
+ if (!dev->ops->get_vlan_ports)
return -EOPNOTSUPP;
- ret = dev->get_vlan_ports(dev, val);
+ ret = dev->ops->get_vlan_ports(dev, val);
return ret;
}
swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
struct switch_port *ports = val->value.ports;
+ const struct switch_dev_ops *ops = dev->ops;
int i;
if (val->port_vlan >= dev->vlans)
if (val->len > dev->ports)
return -EINVAL;
- if (!dev->set_vlan_ports)
+ if (!ops->set_vlan_ports)
return -EOPNOTSUPP;
for (i = 0; i < val->len; i++) {
if (ports[i].id >= dev->ports)
return -EINVAL;
- if (dev->set_port_pvid && !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED)))
- dev->set_port_pvid(dev, ports[i].id, val->port_vlan);
+ if (ops->set_port_pvid &&
+ !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED)))
+ ops->set_port_pvid(dev, ports[i].id, val->port_vlan);
}
- return dev->set_vlan_ports(dev, val);
+ return ops->set_vlan_ports(dev, val);
}
static int
if (val->port_vlan >= dev->ports)
return -EINVAL;
- if (!dev->set_port_pvid)
+ if (!dev->ops->set_port_pvid)
return -EOPNOTSUPP;
- return dev->set_port_pvid(dev, val->port_vlan, val->value.i);
+ return dev->ops->set_port_pvid(dev, val->port_vlan, val->value.i);
}
static int
if (val->port_vlan >= dev->ports)
return -EINVAL;
- if (!dev->get_port_pvid)
+ if (!dev->ops->get_port_pvid)
return -EOPNOTSUPP;
- return dev->get_port_pvid(dev, val->port_vlan, &val->value.i);
+ return dev->ops->get_port_pvid(dev, val->port_vlan, &val->value.i);
}
static int
swconfig_apply_config(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
/* don't complain if not supported by the switch driver */
- if (!dev->apply_config)
+ if (!dev->ops->apply_config)
return 0;
- return dev->apply_config(dev);
+ return dev->ops->apply_config(dev);
}
static int
swconfig_reset_switch(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
{
/* don't complain if not supported by the switch driver */
- if (!dev->reset_switch)
+ if (!dev->ops->reset_switch)
return 0;
- return dev->reset_switch(dev);
+ return dev->ops->reset_switch(dev);
}
enum global_defaults {
static void swconfig_defaults_init(struct switch_dev *dev)
{
+ const struct switch_dev_ops *ops = dev->ops;
+
dev->def_global = 0;
dev->def_vlan = 0;
dev->def_port = 0;
- if (dev->get_vlan_ports || dev->set_vlan_ports)
+ if (ops->get_vlan_ports || ops->set_vlan_ports)
set_bit(VLAN_PORTS, &dev->def_vlan);
- if (dev->get_port_pvid || dev->set_port_pvid)
+ if (ops->get_port_pvid || ops->set_port_pvid)
set_bit(PORT_PVID, &dev->def_port);
/* always present, can be no-op */
if (cb->close(cb, arg) < 0)
goto error;
}
- err = genlmsg_unicast(cb->msg, info->snd_pid);
+ err = genlmsg_reply(cb->msg, info);
cb->msg = NULL;
if (err < 0)
goto error;
switch(hdr->cmd) {
case SWITCH_CMD_LIST_GLOBAL:
- alist = &dev->attr_global;
+ alist = &dev->ops->attr_global;
def_list = default_global;
def_active = &dev->def_global;
n_def = ARRAY_SIZE(default_global);
break;
case SWITCH_CMD_LIST_VLAN:
- alist = &dev->attr_vlan;
+ alist = &dev->ops->attr_vlan;
def_list = default_vlan;
def_active = &dev->def_vlan;
n_def = ARRAY_SIZE(default_vlan);
break;
case SWITCH_CMD_LIST_PORT:
- alist = &dev->attr_port;
+ alist = &dev->ops->attr_port;
def_list = default_port;
def_active = &dev->def_port;
n_def = ARRAY_SIZE(default_port);
if (!cb.msg)
return 0;
- return genlmsg_unicast(cb.msg, info->snd_pid);
+ return genlmsg_reply(cb.msg, info);
error:
if (cb.msg)
switch(hdr->cmd) {
case SWITCH_CMD_SET_GLOBAL:
case SWITCH_CMD_GET_GLOBAL:
- alist = &dev->attr_global;
+ alist = &dev->ops->attr_global;
def_list = default_global;
def_active = &dev->def_global;
n_def = ARRAY_SIZE(default_global);
break;
case SWITCH_CMD_SET_VLAN:
case SWITCH_CMD_GET_VLAN:
- alist = &dev->attr_vlan;
+ alist = &dev->ops->attr_vlan;
def_list = default_vlan;
def_active = &dev->def_vlan;
n_def = ARRAY_SIZE(default_vlan);
break;
case SWITCH_CMD_SET_PORT:
case SWITCH_CMD_GET_PORT:
- alist = &dev->attr_port;
+ alist = &dev->ops->attr_port;
def_list = default_port;
def_active = &dev->def_port;
n_def = ARRAY_SIZE(default_port);
goto nla_put_failure;
swconfig_put_dev(dev);
- return genlmsg_unicast(msg, info->snd_pid);
+ return genlmsg_reply(msg, info);
nla_put_failure:
if (msg)
int register_switch(struct switch_dev *dev, struct net_device *netdev);
void unregister_switch(struct switch_dev *dev);
+/**
+ * struct switch_attrlist - attribute list
+ *
+ * @n_attr: number of attributes
+ * @attr: pointer to the attributes array
+ */
struct switch_attrlist {
- /* filled in by the driver */
int n_attr;
const struct switch_attr *attr;
};
+/**
+ * struct switch_dev_ops - switch driver operations
+ *
+ * @attr_global: global switch attribute list
+ * @attr_port: port attribute list
+ * @attr_vlan: vlan attribute list
+ *
+ * Callbacks:
+ *
+ * @get_vlan_ports: read the port list of a VLAN
+ * @set_vlan_ports: set the port list of a VLAN
+ *
+ * @get_port_pvid: get the primary VLAN ID of a port
+ * @set_port_pvid: set the primary VLAN ID of a port
+ *
+ * @apply_config: apply all changed settings to the switch
+ * @reset_switch: resetting the switch
+ */
+struct switch_dev_ops {
+ struct switch_attrlist attr_global, attr_port, attr_vlan;
+
+ int (*get_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
+ int (*set_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
+
+ int (*get_port_pvid)(struct switch_dev *dev, int port, int *val);
+ int (*set_port_pvid)(struct switch_dev *dev, int port, int val);
+
+ int (*apply_config)(struct switch_dev *dev);
+ int (*reset_switch)(struct switch_dev *dev);
+};
struct switch_dev {
- int id;
- void *priv;
+ const struct switch_dev_ops *ops;
const char *name;
/* NB: either devname or netdev must be set */
int ports;
int vlans;
int cpu_port;
- struct switch_attrlist attr_global, attr_port, attr_vlan;
- spinlock_t lock;
- struct switch_port *portbuf;
+ /* the following fields are internal for swconfig */
+ int id;
struct list_head dev_list;
unsigned long def_global, def_port, def_vlan;
- int (*get_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
- int (*set_vlan_ports)(struct switch_dev *dev, struct switch_val *val);
- int (*get_port_pvid)(struct switch_dev *dev, int port, int *val);
- int (*set_port_pvid)(struct switch_dev *dev, int port, int val);
- int (*apply_config)(struct switch_dev *dev);
- int (*reset_switch)(struct switch_dev *dev);
+ spinlock_t lock;
+ struct switch_port *portbuf;
};
struct switch_port {
+++ /dev/null
---- a/drivers/net/phy/swconfig.c
-+++ b/drivers/net/phy/swconfig.c
-@@ -335,7 +335,7 @@ swconfig_send_multipart(struct swconfig_
- if (cb->close(cb, arg) < 0)
- goto error;
- }
-- err = genlmsg_unicast(cb->msg, info->snd_pid);
-+ err = genlmsg_reply(cb->msg, info);
- cb->msg = NULL;
- if (err < 0)
- goto error;
-@@ -419,7 +419,7 @@ swconfig_list_attrs(struct sk_buff *skb,
- if (!cb.msg)
- return 0;
-
-- return genlmsg_unicast(cb.msg, info->snd_pid);
-+ return genlmsg_reply(cb.msg, info);
-
- error:
- if (cb.msg)
-@@ -732,7 +732,7 @@ swconfig_get_attr(struct sk_buff *skb, s
- goto nla_put_failure;
-
- swconfig_put_dev(dev);
-- return genlmsg_unicast(msg, info->snd_pid);
-+ return genlmsg_reply(msg, info);
-
- nla_put_failure:
- if (msg)
+++ /dev/null
---- a/drivers/net/phy/swconfig.c
-+++ b/drivers/net/phy/swconfig.c
-@@ -335,7 +335,7 @@ swconfig_send_multipart(struct swconfig_
- if (cb->close(cb, arg) < 0)
- goto error;
- }
-- err = genlmsg_unicast(cb->msg, info->snd_pid);
-+ err = genlmsg_reply(cb->msg, info);
- cb->msg = NULL;
- if (err < 0)
- goto error;
-@@ -419,7 +419,7 @@ swconfig_list_attrs(struct sk_buff *skb,
- if (!cb.msg)
- return 0;
-
-- return genlmsg_unicast(cb.msg, info->snd_pid);
-+ return genlmsg_reply(cb.msg, info);
-
- error:
- if (cb.msg)
-@@ -732,7 +732,7 @@ swconfig_get_attr(struct sk_buff *skb, s
- goto nla_put_failure;
-
- swconfig_put_dev(dev);
-- return genlmsg_unicast(msg, info->snd_pid);
-+ return genlmsg_reply(msg, info);
-
- nla_put_failure:
- if (msg)
+++ /dev/null
---- a/drivers/net/phy/swconfig.c
-+++ b/drivers/net/phy/swconfig.c
-@@ -335,7 +335,7 @@ swconfig_send_multipart(struct swconfig_
- if (cb->close(cb, arg) < 0)
- goto error;
- }
-- err = genlmsg_unicast(cb->msg, info->snd_pid);
-+ err = genlmsg_reply(cb->msg, info);
- cb->msg = NULL;
- if (err < 0)
- goto error;
-@@ -419,7 +419,7 @@ swconfig_list_attrs(struct sk_buff *skb,
- if (!cb.msg)
- return 0;
-
-- return genlmsg_unicast(cb.msg, info->snd_pid);
-+ return genlmsg_reply(cb.msg, info);
-
- error:
- if (cb.msg)
-@@ -732,7 +732,7 @@ swconfig_get_attr(struct sk_buff *skb, s
- goto nla_put_failure;
-
- swconfig_put_dev(dev);
-- return genlmsg_unicast(msg, info->snd_pid);
-+ return genlmsg_reply(msg, info);
-
- nla_put_failure:
- if (msg)
+++ /dev/null
---- a/drivers/net/phy/swconfig.c
-+++ b/drivers/net/phy/swconfig.c
-@@ -335,7 +335,7 @@ swconfig_send_multipart(struct swconfig_
- if (cb->close(cb, arg) < 0)
- goto error;
- }
-- err = genlmsg_unicast(cb->msg, info->snd_pid);
-+ err = genlmsg_reply(cb->msg, info);
- cb->msg = NULL;
- if (err < 0)
- goto error;
-@@ -419,7 +419,7 @@ swconfig_list_attrs(struct sk_buff *skb,
- if (!cb.msg)
- return 0;
-
-- return genlmsg_unicast(cb.msg, info->snd_pid);
-+ return genlmsg_reply(cb.msg, info);
-
- error:
- if (cb.msg)
-@@ -732,7 +732,7 @@ swconfig_get_attr(struct sk_buff *skb, s
- goto nla_put_failure;
-
- swconfig_put_dev(dev);
-- return genlmsg_unicast(msg, info->snd_pid);
-+ return genlmsg_reply(msg, info);
-
- nla_put_failure:
- if (msg)