AR8216_PORT_CTRL_MIRROR_TX);
}
+static inline u32
+ar8xxx_age_time_val(int age_time)
+{
+ return (age_time + AR8XXX_REG_ARL_CTRL_AGE_TIME_SECS / 2) /
+ AR8XXX_REG_ARL_CTRL_AGE_TIME_SECS;
+}
+
+static inline void
+ar8xxx_set_age_time(struct ar8xxx_priv *priv, int reg)
+{
+ u32 age_time = ar8xxx_age_time_val(priv->arl_age_time);
+ ar8xxx_rmw(priv, reg, AR8216_ATU_CTRL_AGE_TIME, age_time << AR8216_ATU_CTRL_AGE_TIME_S);
+}
+
int
ar8xxx_sw_hw_apply(struct switch_dev *dev)
{
struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+ const struct ar8xxx_chip *chip = priv->chip;
u8 portmask[AR8X16_MAX_PORTS];
int i, j;
portmask[i] |= vp & ~mask;
}
- priv->chip->vtu_load_vlan(priv, priv->vlan_id[j],
- priv->vlan_table[j]);
+ chip->vtu_load_vlan(priv, priv->vlan_id[j],
+ priv->vlan_table[j]);
}
} else {
/* vlan disabled:
/* update the port destination mask registers and tag settings */
for (i = 0; i < dev->ports; i++) {
- priv->chip->setup_port(priv, i, portmask[i]);
+ chip->setup_port(priv, i, portmask[i]);
}
- priv->chip->set_mirror_regs(priv);
+ chip->set_mirror_regs(priv);
+
+ /* set age time */
+ if (chip->reg_arl_ctrl)
+ ar8xxx_set_age_time(priv, chip->reg_arl_ctrl);
mutex_unlock(&priv->reg_mutex);
return 0;
priv->mirror_tx = false;
priv->source_port = 0;
priv->monitor_port = 0;
+ priv->arl_age_time = AR8XXX_DEFAULT_ARL_AGE_TIME;
chip->init_globals(priv);
return ret;
}
+int
+ar8xxx_sw_set_arl_age_time(struct switch_dev *dev, const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+ int age_time = val->value.i;
+ u32 age_time_val;
+
+ if (age_time < 0)
+ return -EINVAL;
+
+ age_time_val = ar8xxx_age_time_val(age_time);
+ if (age_time_val == 0 || age_time_val > 0xffff)
+ return -EINVAL;
+
+ priv->arl_age_time = age_time;
+ return 0;
+}
+
+int
+ar8xxx_sw_get_arl_age_time(struct switch_dev *dev, const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+ val->value.i = priv->arl_age_time;
+ return 0;
+}
+
int
ar8xxx_sw_get_arl_table(struct switch_dev *dev,
const struct switch_attr *attr,
.reg_port_stats_start = 0x19000,
.reg_port_stats_length = 0xa0,
+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL,
.name = "Atheros AR8216",
.ports = AR8216_NUM_PORTS,
.reg_port_stats_start = 0x20000,
.reg_port_stats_length = 0x100,
+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL,
.name = "Atheros AR8236",
.ports = AR8216_NUM_PORTS,
.reg_port_stats_start = 0x20000,
.reg_port_stats_length = 0x100,
+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL,
.name = "Atheros AR8316",
.ports = AR8216_NUM_PORTS,
#define AR8X16_PROBE_RETRIES 10
#define AR8X16_MAX_PORTS 8
+#define AR8XXX_REG_ARL_CTRL_AGE_TIME_SECS 7
+#define AR8XXX_DEFAULT_ARL_AGE_TIME 300
+
/* Atheros specific MII registers */
#define MII_ATH_MMD_ADDR 0x0d
#define MII_ATH_MMD_DATA 0x0e
unsigned reg_port_stats_start;
unsigned reg_port_stats_length;
+ unsigned reg_arl_ctrl;
+
int (*hw_init)(struct ar8xxx_priv *priv);
void (*cleanup)(struct ar8xxx_priv *priv);
u8 vlan_table[AR8X16_MAX_VLANS];
u8 vlan_tagged;
u16 pvid[AR8X16_MAX_PORTS];
+ int arl_age_time;
/* mirroring */
bool mirror_rx;
const struct switch_attr *attr,
struct switch_val *val);
int
+ar8xxx_sw_get_arl_age_time(struct switch_dev *dev,
+ const struct switch_attr *attr,
+ struct switch_val *val);
+int
+ar8xxx_sw_set_arl_age_time(struct switch_dev *dev,
+ const struct switch_attr *attr,
+ struct switch_val *val);
+int
ar8xxx_sw_get_arl_table(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val);
.get = ar8xxx_sw_get_mirror_source_port,
.max = AR8327_NUM_PORTS - 1
},
+ {
+ .type = SWITCH_TYPE_INT,
+ .name = "arl_age_time",
+ .description = "ARL age time (secs)",
+ .set = ar8xxx_sw_set_arl_age_time,
+ .get = ar8xxx_sw_get_arl_age_time,
+ },
{
.type = SWITCH_TYPE_STRING,
.name = "arl_table",
.reg_port_stats_start = 0x1000,
.reg_port_stats_length = 0x100,
+ .reg_arl_ctrl = AR8327_REG_ARL_CTRL,
.hw_init = ar8327_hw_init,
.cleanup = ar8327_cleanup,
.reg_port_stats_start = 0x1000,
.reg_port_stats_length = 0x100,
+ .reg_arl_ctrl = AR8327_REG_ARL_CTRL,
.hw_init = ar8327_hw_init,
.cleanup = ar8327_cleanup,