diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-03-09 14:35:41 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2010-03-09 14:35:41 +0000 |
commit | c477dc486067e501aff8c5ba37ef18670c504e8e (patch) | |
tree | 0d070cf1901b2c0db00fe54bab4b8ed35e5a35e5 /target/linux/generic-2.6/files | |
parent | e6787703069a40a98e2cc5701df979f54e438edc (diff) | |
download | upstream-c477dc486067e501aff8c5ba37ef18670c504e8e.tar.gz upstream-c477dc486067e501aff8c5ba37ef18670c504e8e.tar.bz2 upstream-c477dc486067e501aff8c5ba37ef18670c504e8e.zip |
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).
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@20083 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic-2.6/files')
-rw-r--r-- | target/linux/generic-2.6/files/drivers/net/phy/ar8216.c | 31 | ||||
-rw-r--r-- | target/linux/generic-2.6/files/drivers/net/phy/ar8216.h | 16 |
2 files changed, 35 insertions, 12 deletions
diff --git a/target/linux/generic-2.6/files/drivers/net/phy/ar8216.c b/target/linux/generic-2.6/files/drivers/net/phy/ar8216.c index 92cc9f384b..0a6eed9577 100644 --- a/target/linux/generic-2.6/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic-2.6/files/drivers/net/phy/ar8216.c @@ -42,7 +42,7 @@ struct ar8216_priv { /* all fields below are cleared on reset */ bool vlan; - u8 vlan_id[AR8216_NUM_VLANS]; + u16 vlan_id[AR8216_NUM_VLANS]; u8 vlan_table[AR8216_NUM_VLANS]; u8 vlan_tagged; u16 pvid[AR8216_NUM_PORTS]; @@ -133,6 +133,12 @@ static int ar8216_set_pvid(struct switch_dev *dev, int port, int vlan) { 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; return 0; } @@ -228,7 +234,7 @@ ar8216_mangle_rx(struct sk_buff *skb, int napi) goto recv; /* 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] |= vlan >> 8; @@ -282,7 +288,7 @@ static struct switch_attr ar8216_vlan[] = { .description = "VLAN ID", .set = ar8216_set_vid, .get = ar8216_get_vid, - .max = 4095, + .max = 4094, }, }; @@ -396,9 +402,6 @@ ar8216_hw_apply(struct switch_dev *dev) portmask[i] |= vp & ~mask; } - if (!priv->vlan_table[j]) - continue; - ar8216_vtu_op(priv, AR8216_VTU_OP_LOAD | (priv->vlan_id[j] << AR8216_VTU_VID_S), @@ -432,7 +435,11 @@ ar8216_hw_apply(struct switch_dev *dev) } else { 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_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE | @@ -478,7 +485,7 @@ ar8216_reset_switch(struct switch_dev *dev) if (i == AR8216_PORT_CPU) { priv->write(priv, AR8216_REG_PORT_STATUS(i), AR8216_PORT_STATUS_LINK_UP | - AR8216_PORT_STATUS_SPEED | + AR8216_PORT_SPEED_100M | AR8216_PORT_STATUS_TXMAC | AR8216_PORT_STATUS_RXMAC | 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); + phydev->state = PHY_RUNNING; + netif_carrier_on(phydev->attached_dev); + phydev->adjust_link(phydev->attached_dev); + return 0; } @@ -573,8 +584,8 @@ ar8216_probe(struct phy_device *pdev) priv.phy = pdev; val = ar8216_mii_read(&priv, AR8216_REG_CTRL); - rev = val & 0xff; - id = (val >> 8) & 0xff; + rev = val & AR8216_CTRL_REVISION; + id = (val & AR8216_CTRL_VERSION) >> AR8216_CTRL_VERSION_S; if ((id != 1) || (rev != 1)) return -ENODEV; diff --git a/target/linux/generic-2.6/files/drivers/net/phy/ar8216.h b/target/linux/generic-2.6/files/drivers/net/phy/ar8216.h index 741dce917d..c1b8fdbd8c 100644 --- a/target/linux/generic-2.6/files/drivers/net/phy/ar8216.h +++ b/target/linux/generic-2.6/files/drivers/net/phy/ar8216.h @@ -24,6 +24,10 @@ #define AR8216_NUM_VLANS 16 #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_REG_GLOBAL_CTRL 0x0030 @@ -73,8 +77,8 @@ #define AR8216_PORT_OFFSET(_i) (0x0100 * (_i + 1)) #define AR8216_REG_PORT_STATUS(_i) (AR8216_PORT_OFFSET(_i) + 0x0000) -#define AR8216_PORT_STATUS_SPEED BIT(0) -#define AR8216_PORT_STATUS_SPEED_ERR BIT(1) +#define AR8216_PORT_STATUS_SPEED BITS(0,2) +#define AR8216_PORT_STATUS_SPEED_S 0 #define AR8216_PORT_STATUS_TXMAC BIT(2) #define AR8216_PORT_STATUS_RXMAC BIT(3) #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_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 */ enum { AR8216_IN_PORT_ONLY = 0, |