mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 14:13:16 +00:00
Several small fixes for ar8216 driver (patch by Jonas Gorski)
* Create defines for some magic values/masks. * Change vlan_id to u16, to allow VIDs > 255. * Add a range check to set_pvid as it isn't a VID, but the index in the vlan table. * Set the max VID to 4094, since 4095 is a reserved value and should not be used. * In mangle_rx replace the provided VID with the VID of the table entry of the port, not the index of the table. * In hw_apply, remove a redundant emptyness check (was already checked several lines above). * In no vlan mode do not set the ingress mode to secure, as there are no vlan table entries, but to use the port's destination masks. Otherwise the switch won't forward anything. * In read_status tell that the phy is up (taken from the rtl8306 driver). SVN-Revision: 20083
This commit is contained in:
parent
a5441beb82
commit
513e8c583f
@ -42,7 +42,7 @@ struct ar8216_priv {
|
|||||||
|
|
||||||
/* all fields below are cleared on reset */
|
/* all fields below are cleared on reset */
|
||||||
bool vlan;
|
bool vlan;
|
||||||
u8 vlan_id[AR8216_NUM_VLANS];
|
u16 vlan_id[AR8216_NUM_VLANS];
|
||||||
u8 vlan_table[AR8216_NUM_VLANS];
|
u8 vlan_table[AR8216_NUM_VLANS];
|
||||||
u8 vlan_tagged;
|
u8 vlan_tagged;
|
||||||
u16 pvid[AR8216_NUM_PORTS];
|
u16 pvid[AR8216_NUM_PORTS];
|
||||||
@ -133,6 +133,12 @@ static int
|
|||||||
ar8216_set_pvid(struct switch_dev *dev, int port, int vlan)
|
ar8216_set_pvid(struct switch_dev *dev, int port, int vlan)
|
||||||
{
|
{
|
||||||
struct ar8216_priv *priv = to_ar8216(dev);
|
struct ar8216_priv *priv = to_ar8216(dev);
|
||||||
|
|
||||||
|
/* make sure no invalid PVIDs get set */
|
||||||
|
|
||||||
|
if (vlan >= AR8216_NUM_VLANS)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
priv->pvid[port] = vlan;
|
priv->pvid[port] = vlan;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -228,7 +234,7 @@ ar8216_mangle_rx(struct sk_buff *skb, int napi)
|
|||||||
goto recv;
|
goto recv;
|
||||||
|
|
||||||
/* lookup port vid from local table, the switch passes an invalid vlan id */
|
/* lookup port vid from local table, the switch passes an invalid vlan id */
|
||||||
vlan = priv->pvid[port];
|
vlan = priv->vlan_id[priv->pvid[port]];
|
||||||
|
|
||||||
buf[14 + 2] &= 0xf0;
|
buf[14 + 2] &= 0xf0;
|
||||||
buf[14 + 2] |= vlan >> 8;
|
buf[14 + 2] |= vlan >> 8;
|
||||||
@ -282,7 +288,7 @@ static struct switch_attr ar8216_vlan[] = {
|
|||||||
.description = "VLAN ID",
|
.description = "VLAN ID",
|
||||||
.set = ar8216_set_vid,
|
.set = ar8216_set_vid,
|
||||||
.get = ar8216_get_vid,
|
.get = ar8216_get_vid,
|
||||||
.max = 4095,
|
.max = 4094,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -396,9 +402,6 @@ ar8216_hw_apply(struct switch_dev *dev)
|
|||||||
portmask[i] |= vp & ~mask;
|
portmask[i] |= vp & ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!priv->vlan_table[j])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ar8216_vtu_op(priv,
|
ar8216_vtu_op(priv,
|
||||||
AR8216_VTU_OP_LOAD |
|
AR8216_VTU_OP_LOAD |
|
||||||
(priv->vlan_id[j] << AR8216_VTU_VID_S),
|
(priv->vlan_id[j] << AR8216_VTU_VID_S),
|
||||||
@ -432,7 +435,11 @@ ar8216_hw_apply(struct switch_dev *dev)
|
|||||||
} else {
|
} else {
|
||||||
egress = AR8216_OUT_STRIP_VLAN;
|
egress = AR8216_OUT_STRIP_VLAN;
|
||||||
}
|
}
|
||||||
ingress = AR8216_IN_SECURE;
|
if (priv->vlan) {
|
||||||
|
ingress = AR8216_IN_SECURE;
|
||||||
|
} else {
|
||||||
|
ingress = AR8216_IN_PORT_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
ar8216_rmw(priv, AR8216_REG_PORT_CTRL(i),
|
ar8216_rmw(priv, AR8216_REG_PORT_CTRL(i),
|
||||||
AR8216_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE |
|
AR8216_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE |
|
||||||
@ -478,7 +485,7 @@ ar8216_reset_switch(struct switch_dev *dev)
|
|||||||
if (i == AR8216_PORT_CPU) {
|
if (i == AR8216_PORT_CPU) {
|
||||||
priv->write(priv, AR8216_REG_PORT_STATUS(i),
|
priv->write(priv, AR8216_REG_PORT_STATUS(i),
|
||||||
AR8216_PORT_STATUS_LINK_UP |
|
AR8216_PORT_STATUS_LINK_UP |
|
||||||
AR8216_PORT_STATUS_SPEED |
|
AR8216_PORT_SPEED_100M |
|
||||||
AR8216_PORT_STATUS_TXMAC |
|
AR8216_PORT_STATUS_TXMAC |
|
||||||
AR8216_PORT_STATUS_RXMAC |
|
AR8216_PORT_STATUS_RXMAC |
|
||||||
AR8216_PORT_STATUS_DUPLEX);
|
AR8216_PORT_STATUS_DUPLEX);
|
||||||
@ -554,6 +561,10 @@ ar8216_read_status(struct phy_device *phydev)
|
|||||||
|
|
||||||
priv->write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH);
|
priv->write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH);
|
||||||
|
|
||||||
|
phydev->state = PHY_RUNNING;
|
||||||
|
netif_carrier_on(phydev->attached_dev);
|
||||||
|
phydev->adjust_link(phydev->attached_dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,8 +584,8 @@ ar8216_probe(struct phy_device *pdev)
|
|||||||
|
|
||||||
priv.phy = pdev;
|
priv.phy = pdev;
|
||||||
val = ar8216_mii_read(&priv, AR8216_REG_CTRL);
|
val = ar8216_mii_read(&priv, AR8216_REG_CTRL);
|
||||||
rev = val & 0xff;
|
rev = val & AR8216_CTRL_REVISION;
|
||||||
id = (val >> 8) & 0xff;
|
id = (val & AR8216_CTRL_VERSION) >> AR8216_CTRL_VERSION_S;
|
||||||
if ((id != 1) || (rev != 1))
|
if ((id != 1) || (rev != 1))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
#define AR8216_NUM_VLANS 16
|
#define AR8216_NUM_VLANS 16
|
||||||
|
|
||||||
#define AR8216_REG_CTRL 0x0000
|
#define AR8216_REG_CTRL 0x0000
|
||||||
|
#define AR8216_CTRL_REVISION BITS(0, 8)
|
||||||
|
#define AR8216_CTRL_REVISION_S 0
|
||||||
|
#define AR8216_CTRL_VERSION BITS(8, 8)
|
||||||
|
#define AR8216_CTRL_VERSION_S 8
|
||||||
#define AR8216_CTRL_RESET BIT(31)
|
#define AR8216_CTRL_RESET BIT(31)
|
||||||
|
|
||||||
#define AR8216_REG_GLOBAL_CTRL 0x0030
|
#define AR8216_REG_GLOBAL_CTRL 0x0030
|
||||||
@ -73,8 +77,8 @@
|
|||||||
|
|
||||||
#define AR8216_PORT_OFFSET(_i) (0x0100 * (_i + 1))
|
#define AR8216_PORT_OFFSET(_i) (0x0100 * (_i + 1))
|
||||||
#define AR8216_REG_PORT_STATUS(_i) (AR8216_PORT_OFFSET(_i) + 0x0000)
|
#define AR8216_REG_PORT_STATUS(_i) (AR8216_PORT_OFFSET(_i) + 0x0000)
|
||||||
#define AR8216_PORT_STATUS_SPEED BIT(0)
|
#define AR8216_PORT_STATUS_SPEED BITS(0,2)
|
||||||
#define AR8216_PORT_STATUS_SPEED_ERR BIT(1)
|
#define AR8216_PORT_STATUS_SPEED_S 0
|
||||||
#define AR8216_PORT_STATUS_TXMAC BIT(2)
|
#define AR8216_PORT_STATUS_TXMAC BIT(2)
|
||||||
#define AR8216_PORT_STATUS_RXMAC BIT(3)
|
#define AR8216_PORT_STATUS_RXMAC BIT(3)
|
||||||
#define AR8216_PORT_STATUS_TXFLOW BIT(4)
|
#define AR8216_PORT_STATUS_TXFLOW BIT(4)
|
||||||
@ -126,6 +130,14 @@
|
|||||||
#define AR8216_REG_PORT_RATE(_i) (AR8216_PORT_OFFSET(_i) + 0x000c)
|
#define AR8216_REG_PORT_RATE(_i) (AR8216_PORT_OFFSET(_i) + 0x000c)
|
||||||
#define AR8216_REG_PORT_PRIO(_i) (AR8216_PORT_OFFSET(_i) + 0x0010)
|
#define AR8216_REG_PORT_PRIO(_i) (AR8216_PORT_OFFSET(_i) + 0x0010)
|
||||||
|
|
||||||
|
/* port speed */
|
||||||
|
enum {
|
||||||
|
AR8216_PORT_SPEED_10M = 0,
|
||||||
|
AR8216_PORT_SPEED_100M = 1,
|
||||||
|
AR8216_PORT_SPEED_1000M = 2,
|
||||||
|
AR8216_PORT_SPEED_ERR = 3,
|
||||||
|
};
|
||||||
|
|
||||||
/* ingress 802.1q mode */
|
/* ingress 802.1q mode */
|
||||||
enum {
|
enum {
|
||||||
AR8216_IN_PORT_ONLY = 0,
|
AR8216_IN_PORT_ONLY = 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user