+static int
+ar7240_set_mirror_monitor_port(struct switch_dev *dev,
+ const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar7240sw *as = sw_to_ar7240(dev);
+ struct mii_bus *mii = as->mii_bus;
+
+ int port = val->value.i;
+
+ if (port > 15)
+ return -EINVAL;
+
+ ar7240sw_reg_rmw(mii, AR7240_REG_CPU_PORT,
+ AR7240_MIRROR_PORT_M << AR7240_MIRROR_PORT_S,
+ port << AR7240_MIRROR_PORT_S);
+
+ return 0;
+}
+
+static int
+ar7240_get_mirror_monitor_port(struct switch_dev *dev,
+ const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar7240sw *as = sw_to_ar7240(dev);
+ struct mii_bus *mii = as->mii_bus;
+
+ u32 ret;
+
+ ret = ar7240sw_reg_read(mii, AR7240_REG_CPU_PORT);
+ val->value.i = (ret >> AR7240_MIRROR_PORT_S) & AR7240_MIRROR_PORT_M;
+
+ return 0;
+}
+
+static int
+ar7240_set_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar7240sw *as = sw_to_ar7240(dev);
+ struct mii_bus *mii = as->mii_bus;
+
+ int port = val->port_vlan;
+
+ if (port >= dev->ports)
+ return -EINVAL;
+
+ if (val && val->value.i == 1)
+ ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port),
+ AR7240_PORT_CTRL_MIRROR_RX);
+ else
+ ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port),
+ AR7240_PORT_CTRL_MIRROR_RX, 0);
+
+ return 0;
+}
+
+static int
+ar7240_get_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar7240sw *as = sw_to_ar7240(dev);
+ struct mii_bus *mii = as->mii_bus;
+
+ u32 ctrl;
+
+ int port = val->port_vlan;
+
+ if (port >= dev->ports)
+ return -EINVAL;
+
+ ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port));
+
+ if ((ctrl & AR7240_PORT_CTRL_MIRROR_RX) == AR7240_PORT_CTRL_MIRROR_RX)
+ val->value.i = 1;
+ else
+ val->value.i = 0;
+
+ return 0;
+}
+
+static int
+ar7240_set_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar7240sw *as = sw_to_ar7240(dev);
+ struct mii_bus *mii = as->mii_bus;
+
+ int port = val->port_vlan;
+
+ if (port >= dev->ports)
+ return -EINVAL;
+
+ if (val && val->value.i == 1)
+ ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port),
+ AR7240_PORT_CTRL_MIRROR_TX);
+ else
+ ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port),
+ AR7240_PORT_CTRL_MIRROR_TX, 0);
+
+ return 0;
+}
+
+static int
+ar7240_get_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar7240sw *as = sw_to_ar7240(dev);
+ struct mii_bus *mii = as->mii_bus;
+
+ u32 ctrl;
+
+ int port = val->port_vlan;
+
+ if (port >= dev->ports)
+ return -EINVAL;
+
+ ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port));
+
+ if ((ctrl & AR7240_PORT_CTRL_MIRROR_TX) == AR7240_PORT_CTRL_MIRROR_TX)
+ val->value.i = 1;
+ else
+ val->value.i = 0;
+
+ return 0;
+}
+