swconfig: cleanup of kernel drivers and interface - add some comments to a few data structures - add a switch_dev_ops data structure for attributes and callback to replace the stupid template memcpy - get rid of the switch_dev.priv pointer - using container_of() is better
SVN-Revision: 22476
This commit is contained in:
parent
86b209211e
commit
bd6324190f
11 changed files with 223 additions and 304 deletions
|
@ -52,7 +52,6 @@ struct ar8216_priv {
|
|||
u8 vlan_tagged;
|
||||
u16 pvid[AR8216_NUM_PORTS];
|
||||
};
|
||||
static struct switch_dev athdev;
|
||||
|
||||
#define to_ar8216(_dev) container_of(_dev, struct ar8216_priv, dev)
|
||||
|
||||
|
@ -631,11 +630,34 @@ ar8216_reset_switch(struct switch_dev *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);
|
||||
|
@ -667,14 +689,22 @@ ar8216_config_init(struct phy_device *pdev)
|
|||
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) {
|
||||
|
@ -782,32 +812,6 @@ ar8216_remove(struct phy_device *pdev)
|
|||
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",
|
||||
|
|
|
@ -323,6 +323,7 @@ struct ip17xx_state {
|
|||
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)
|
||||
{
|
||||
|
@ -734,7 +735,7 @@ static int ip175d_reset(struct ip17xx_state *state)
|
|||
|
||||
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;
|
||||
|
@ -756,7 +757,7 @@ static void ip17xx_reset_vlan_config(struct ip17xx_state *state)
|
|||
|
||||
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;
|
||||
|
@ -774,7 +775,7 @@ static int ip17xx_set_enable_vlan(struct switch_dev *dev, const struct switch_at
|
|||
|
||||
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;
|
||||
|
@ -802,7 +803,7 @@ static int ip17xx_get_ports(struct switch_dev *dev, struct switch_val *val)
|
|||
|
||||
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)
|
||||
|
@ -826,7 +827,7 @@ static int ip17xx_set_ports(struct switch_dev *dev, struct switch_val *val)
|
|||
|
||||
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);
|
||||
|
@ -841,7 +842,7 @@ static int ip17xx_apply(struct switch_dev *dev)
|
|||
|
||||
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)) {
|
||||
|
@ -874,7 +875,7 @@ static int ip17xx_reset(struct switch_dev *dev)
|
|||
|
||||
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))
|
||||
|
@ -892,7 +893,7 @@ static int ip17xx_get_tagged(struct switch_dev *dev, const struct switch_attr *a
|
|||
|
||||
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);
|
||||
|
@ -908,7 +909,7 @@ static int ip17xx_set_tagged(struct switch_dev *dev, const struct switch_attr *a
|
|||
/** 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;
|
||||
|
@ -917,7 +918,7 @@ static int ip17xx_get_phy(struct switch_dev *dev, const struct switch_attr *attr
|
|||
/** 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)
|
||||
|
@ -930,7 +931,7 @@ static int ip17xx_set_phy(struct switch_dev *dev, const struct switch_attr *attr
|
|||
/** 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;
|
||||
|
@ -939,7 +940,7 @@ static int ip17xx_get_reg(struct switch_dev *dev, const struct switch_attr *attr
|
|||
/** 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)
|
||||
|
@ -952,7 +953,7 @@ static int ip17xx_set_reg(struct switch_dev *dev, const struct switch_attr *attr
|
|||
/** 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);
|
||||
|
@ -968,7 +969,7 @@ static int ip17xx_get_val(struct switch_dev *dev, const struct switch_attr *attr
|
|||
/** 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;
|
||||
|
@ -980,14 +981,14 @@ static int ip17xx_set_val(struct switch_dev *dev, const struct switch_attr *attr
|
|||
|
||||
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)
|
||||
|
@ -999,7 +1000,7 @@ static int ip17xx_get_tag(struct switch_dev *dev, const struct switch_attr *attr
|
|||
|
||||
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;
|
||||
|
||||
|
@ -1015,7 +1016,7 @@ static int ip17xx_set_tag(struct switch_dev *dev, const struct switch_attr *attr
|
|||
|
||||
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;
|
||||
|
@ -1052,7 +1053,7 @@ static int ip17xx_set_port_speed(struct switch_dev *dev, const struct switch_att
|
|||
|
||||
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;
|
||||
|
||||
|
@ -1079,7 +1080,7 @@ static int ip17xx_get_port_speed(struct switch_dev *dev, const struct switch_att
|
|||
|
||||
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;
|
||||
|
@ -1123,7 +1124,7 @@ static int ip17xx_get_port_status(struct switch_dev *dev, const struct switch_at
|
|||
|
||||
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;
|
||||
|
@ -1131,7 +1132,7 @@ static int ip17xx_get_pvid(struct switch_dev *dev, int port, int *val)
|
|||
|
||||
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;
|
||||
|
@ -1243,6 +1244,28 @@ static const struct switch_attr ip17xx_port[] = {
|
|||
},
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -1258,21 +1281,7 @@ static int ip17xx_probe(struct phy_device *pdev)
|
|||
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;
|
||||
|
||||
|
@ -1284,6 +1293,7 @@ static int ip17xx_probe(struct phy_device *pdev)
|
|||
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;
|
||||
|
|
|
@ -250,11 +250,6 @@ static const struct rtl_reg rtl_regs[] = {
|
|||
};
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -706,64 +701,6 @@ rtl_set_ports(struct switch_dev *dev, struct switch_val *val)
|
|||
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,
|
||||
|
@ -897,11 +834,7 @@ static struct switch_attr rtl_vlan[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* 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),
|
||||
|
@ -920,6 +853,65 @@ static struct switch_dev rtldev = {
|
|||
.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)
|
||||
|
|
|
@ -849,12 +849,7 @@ static struct switch_attr rtl8366rb_vlan[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* 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),
|
||||
|
@ -880,8 +875,11 @@ static int rtl8366rb_switch_init(struct rtl8366_smi *smi)
|
|||
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);
|
||||
|
|
|
@ -876,12 +876,7 @@ static struct switch_attr rtl8366s_vlan[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* 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),
|
||||
|
@ -907,8 +902,11 @@ static int rtl8366s_switch_init(struct rtl8366_smi *smi)
|
|||
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);
|
||||
|
|
|
@ -65,10 +65,10 @@ swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr,
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,7 @@ static int
|
|||
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)
|
||||
|
@ -85,18 +86,19 @@ swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr,
|
|||
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
|
||||
|
@ -105,10 +107,10 @@ swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct
|
|||
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
|
||||
|
@ -117,30 +119,30 @@ swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, struct
|
|||
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 {
|
||||
|
@ -194,14 +196,16 @@ static struct switch_attr default_vlan[] = {
|
|||
|
||||
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 */
|
||||
|
@ -335,7 +339,7 @@ swconfig_send_multipart(struct swconfig_callback *cb, void *arg)
|
|||
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;
|
||||
|
@ -371,19 +375,19 @@ swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info)
|
|||
|
||||
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);
|
||||
|
@ -419,7 +423,7 @@ swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info)
|
|||
if (!cb.msg)
|
||||
return 0;
|
||||
|
||||
return genlmsg_unicast(cb.msg, info->snd_pid);
|
||||
return genlmsg_reply(cb.msg, info);
|
||||
|
||||
error:
|
||||
if (cb.msg)
|
||||
|
@ -449,14 +453,14 @@ swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info,
|
|||
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);
|
||||
|
@ -468,7 +472,7 @@ swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info,
|
|||
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);
|
||||
|
@ -732,7 +736,7 @@ swconfig_get_attr(struct sk_buff *skb, struct genl_info *info)
|
|||
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)
|
||||
|
|
|
@ -102,16 +102,50 @@ struct switch_attrlist;
|
|||
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 */
|
||||
|
@ -121,19 +155,14 @@ struct switch_dev {
|
|||
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 {
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
--- 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)
|
|
@ -1,29 +0,0 @@
|
|||
--- 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)
|
|
@ -1,29 +0,0 @@
|
|||
--- 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)
|
|
@ -1,29 +0,0 @@
|
|||
--- 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)
|
Loading…
Reference in a new issue