/* 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];
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;
}
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;
.description = "VLAN ID",
.set = ar8216_set_vid,
.get = ar8216_get_vid,
- .max = 4095,
+ .max = 4094,
},
};
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),
} 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 |
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);
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;
}
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;
#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
#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)
#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,