-ar8327_hw_init(struct ar8216_priv *priv)
-{
- struct ar8327_platform_data *pdata;
- struct ar8327_led_cfg *led_cfg;
- struct mii_bus *bus;
- u32 pos, new_pos;
- u32 t;
- int i;
-
- pdata = priv->phy->dev.platform_data;
- if (!pdata)
- return -EINVAL;
-
- t = ar8327_get_pad_cfg(pdata->pad0_cfg);
- priv->write(priv, AR8327_REG_PAD0_MODE, t);
- t = ar8327_get_pad_cfg(pdata->pad5_cfg);
- priv->write(priv, AR8327_REG_PAD5_MODE, t);
- t = ar8327_get_pad_cfg(pdata->pad6_cfg);
- priv->write(priv, AR8327_REG_PAD6_MODE, t);
-
- pos = priv->read(priv, AR8327_REG_POWER_ON_STRIP);
- new_pos = pos;
-
- led_cfg = pdata->led_cfg;
- if (led_cfg) {
- if (led_cfg->open_drain)
- new_pos |= AR8327_POWER_ON_STRIP_LED_OPEN_EN;
- else
- new_pos &= ~AR8327_POWER_ON_STRIP_LED_OPEN_EN;
-
- priv->write(priv, AR8327_REG_LED_CTRL0, led_cfg->led_ctrl0);
- priv->write(priv, AR8327_REG_LED_CTRL1, led_cfg->led_ctrl1);
- priv->write(priv, AR8327_REG_LED_CTRL2, led_cfg->led_ctrl2);
- priv->write(priv, AR8327_REG_LED_CTRL3, led_cfg->led_ctrl3);
- }
-
- if (new_pos != pos) {
- new_pos |= AR8327_POWER_ON_STRIP_POWER_ON_SEL;
- priv->write(priv, AR8327_REG_POWER_ON_STRIP, new_pos);
- }
-
- bus = priv->mii_bus;
- for (i = 0; i < AR8327_NUM_PHYS; i++) {
- ar8327_phy_fixup(priv, i);
-
- /* start aneg on the PHY */
- mdiobus_write(bus, i, MII_ADVERTISE, ADVERTISE_ALL |
- ADVERTISE_PAUSE_CAP |
- ADVERTISE_PAUSE_ASYM);
- mdiobus_write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL);
- mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
- }
-
- msleep(1000);
-
- return 0;
-}
-
-static void
-ar8327_init_globals(struct ar8216_priv *priv)
-{
- u32 t;
-
- /* enable CPU port and disable mirror port */
- t = AR8327_FWD_CTRL0_CPU_PORT_EN |
- AR8327_FWD_CTRL0_MIRROR_PORT;
- priv->write(priv, AR8327_REG_FWD_CTRL0, t);
-
- /* forward multicast and broadcast frames to CPU */
- t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
- (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
- (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
- priv->write(priv, AR8327_REG_FWD_CTRL1, t);
-
- /* setup MTU */
- ar8216_rmw(priv, AR8327_REG_MAX_FRAME_SIZE,
- AR8327_MAX_FRAME_SIZE_MTU, 1518 + 8 + 2);
-
- /* Enable MIB counters */
- ar8216_reg_set(priv, AR8327_REG_MODULE_EN,
- AR8327_MODULE_EN_MIB);
-}
-
-static void
-ar8327_config_port(struct ar8216_priv *priv, unsigned int port,
- struct ar8327_port_cfg *cfg)
-{
- u32 t;
-
- if (!cfg || !cfg->force_link) {
- priv->write(priv, AR8327_REG_PORT_STATUS(port),
- AR8216_PORT_STATUS_LINK_AUTO);
- return;
- }
-
- t = AR8216_PORT_STATUS_TXMAC | AR8216_PORT_STATUS_RXMAC;
- t |= cfg->duplex ? AR8216_PORT_STATUS_DUPLEX : 0;
- t |= cfg->rxpause ? AR8216_PORT_STATUS_RXFLOW : 0;
- t |= cfg->txpause ? AR8216_PORT_STATUS_TXFLOW : 0;
-
- switch (cfg->speed) {
- case AR8327_PORT_SPEED_10:
- t |= AR8216_PORT_SPEED_10M;
- break;
- case AR8327_PORT_SPEED_100:
- t |= AR8216_PORT_SPEED_100M;
- break;
- case AR8327_PORT_SPEED_1000:
- t |= AR8216_PORT_SPEED_1000M;
- break;
- }
-
- priv->write(priv, AR8327_REG_PORT_STATUS(port), t);
-}
-
-static void
-ar8327_init_port(struct ar8216_priv *priv, int port)
-{
- struct ar8327_platform_data *pdata;
- struct ar8327_port_cfg *cfg;
- u32 t;
-
- pdata = priv->phy->dev.platform_data;
-
- if (pdata && port == AR8216_PORT_CPU)
- cfg = &pdata->port0_cfg;
- else if (pdata && port == 6)
- cfg = &pdata->port6_cfg;
- else
- cfg = NULL;
-
- ar8327_config_port(priv, port, cfg);
-
- priv->write(priv, AR8327_REG_PORT_HEADER(port), 0);
-
- t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
- t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
- priv->write(priv, AR8327_REG_PORT_VLAN0(port), t);
-
- t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S;
- priv->write(priv, AR8327_REG_PORT_VLAN1(port), t);
-
- t = AR8327_PORT_LOOKUP_LEARN;
- t |= AR8216_PORT_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
- priv->write(priv, AR8327_REG_PORT_LOOKUP(port), t);
-}
-
-static u32
-ar8327_read_port_status(struct ar8216_priv *priv, int port)
-{
- return priv->read(priv, AR8327_REG_PORT_STATUS(port));
-}
-
-static int
-ar8327_atu_flush(struct ar8216_priv *priv)
-{
- int ret;
-
- ret = ar8216_wait_bit(priv, AR8327_REG_ATU_FUNC,
- AR8327_ATU_FUNC_BUSY, 0);
- if (!ret)
- priv->write(priv, AR8327_REG_ATU_FUNC,
- AR8327_ATU_FUNC_OP_FLUSH);
-
- return ret;
-}
-
-static void
-ar8327_vtu_op(struct ar8216_priv *priv, u32 op, u32 val)
-{
- if (ar8216_wait_bit(priv, AR8327_REG_VTU_FUNC1,
- AR8327_VTU_FUNC1_BUSY, 0))
- return;
-
- if ((op & AR8327_VTU_FUNC1_OP) == AR8327_VTU_FUNC1_OP_LOAD)
- priv->write(priv, AR8327_REG_VTU_FUNC0, val);
-
- op |= AR8327_VTU_FUNC1_BUSY;
- priv->write(priv, AR8327_REG_VTU_FUNC1, op);
-}
-
-static void
-ar8327_vtu_flush(struct ar8216_priv *priv)
-{
- ar8327_vtu_op(priv, AR8327_VTU_FUNC1_OP_FLUSH, 0);
-}
-
-static void
-ar8327_vtu_load_vlan(struct ar8216_priv *priv, u32 vid, u32 port_mask)
-{
- u32 op;
- u32 val;
- int i;
-
- op = AR8327_VTU_FUNC1_OP_LOAD | (vid << AR8327_VTU_FUNC1_VID_S);
- val = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL;
- for (i = 0; i < AR8327_NUM_PORTS; i++) {
- u32 mode;
-
- if ((port_mask & BIT(i)) == 0)
- mode = AR8327_VTU_FUNC0_EG_MODE_NOT;
- else if (priv->vlan == 0)
- mode = AR8327_VTU_FUNC0_EG_MODE_KEEP;
- else if (priv->vlan_tagged & BIT(i))
- mode = AR8327_VTU_FUNC0_EG_MODE_TAG;
- else
- mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG;
-
- val |= mode << AR8327_VTU_FUNC0_EG_MODE_S(i);
- }
- ar8327_vtu_op(priv, op, val);
-}
-
-static void
-ar8327_setup_port(struct ar8216_priv *priv, int port, u32 egress, u32 ingress,
- u32 members, u32 pvid)
-{
- u32 t;
- u32 mode;
-
- t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S;
- t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S;
- priv->write(priv, AR8327_REG_PORT_VLAN0(port), t);
-
- mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD;
- switch (egress) {
- case AR8216_OUT_KEEP:
- mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
- break;
- case AR8216_OUT_STRIP_VLAN:
- mode = AR8327_PORT_VLAN1_OUT_MODE_UNTAG;
- break;
- case AR8216_OUT_ADD_VLAN:
- mode = AR8327_PORT_VLAN1_OUT_MODE_TAG;
- break;
- }
-
- t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
- t |= mode << AR8327_PORT_VLAN1_OUT_MODE_S;
- priv->write(priv, AR8327_REG_PORT_VLAN1(port), t);
-
- t = members;
- t |= AR8327_PORT_LOOKUP_LEARN;
- t |= ingress << AR8327_PORT_LOOKUP_IN_MODE_S;
- t |= AR8216_PORT_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
- priv->write(priv, AR8327_REG_PORT_LOOKUP(port), t);
-}
-
-static const struct ar8xxx_chip ar8327_chip = {
- .caps = AR8XXX_CAP_GIGE | AR8XXX_CAP_MIB_COUNTERS,
- .hw_init = ar8327_hw_init,
- .init_globals = ar8327_init_globals,
- .init_port = ar8327_init_port,
- .setup_port = ar8327_setup_port,
- .read_port_status = ar8327_read_port_status,
- .atu_flush = ar8327_atu_flush,
- .vtu_flush = ar8327_vtu_flush,
- .vtu_load_vlan = ar8327_vtu_load_vlan,
-
- .num_mibs = ARRAY_SIZE(ar8236_mibs),
- .mib_decs = ar8236_mibs,
-};
-
-static int
-ar8216_sw_set_vlan(struct switch_dev *dev, const struct switch_attr *attr,
- struct switch_val *val)
-{
- struct ar8216_priv *priv = swdev_to_ar8216(dev);
- priv->vlan = !!val->value.i;
- return 0;
-}
-
-static int
-ar8216_sw_get_vlan(struct switch_dev *dev, const struct switch_attr *attr,
- struct switch_val *val)
-{
- struct ar8216_priv *priv = swdev_to_ar8216(dev);
- val->value.i = priv->vlan;
- return 0;
-}
-
-
-static int
-ar8216_sw_set_pvid(struct switch_dev *dev, int port, int vlan)
-{
- struct ar8216_priv *priv = swdev_to_ar8216(dev);
-
- /* make sure no invalid PVIDs get set */
-
- if (vlan >= dev->vlans)
- return -EINVAL;
-
- priv->pvid[port] = vlan;
- return 0;
-}
-
-static int
-ar8216_sw_get_pvid(struct switch_dev *dev, int port, int *vlan)
-{
- struct ar8216_priv *priv = swdev_to_ar8216(dev);
- *vlan = priv->pvid[port];
- return 0;
-}
-
-static int
-ar8216_sw_set_vid(struct switch_dev *dev, const struct switch_attr *attr,