#define RTL8367B_MIB_RXB_ID 0 /* IfInOctets */
#define RTL8367B_MIB_TXB_ID 28 /* IfOutOctets */
+#define RTL8367D_PORT_STATUS_REG(_p) (0x12d0 + (_p))
+
+#define RTL8367D_PORT_STATUS_SPEED1_MASK 0x3000
+#define RTL8367D_PORT_STATUS_SPEED1_SHIFT 10 /*12-2*/
+
+#define RTL8367D_REG_MAC0_FORCE_SELECT 0x12c0
+#define RTL8367D_REG_MAC0_FORCE_SELECT_EN 0x12c8
+
static struct rtl8366_mib_counter
rtl8367b_mib_counters[RTL8367B_NUM_MIB_COUNTERS] = {
{0, 0, 4, "ifInOctets" },
u32 val;
int err;
- mask = (RTL8367B_DI_FORCE_MODE |
- RTL8367B_DI_FORCE_NWAY |
- RTL8367B_DI_FORCE_TXPAUSE |
- RTL8367B_DI_FORCE_RXPAUSE |
- RTL8367B_DI_FORCE_LINK |
- RTL8367B_DI_FORCE_DUPLEX |
- RTL8367B_DI_FORCE_SPEED_MASK);
-
- val = pa->speed;
- val |= pa->force_mode ? RTL8367B_DI_FORCE_MODE : 0;
+ val = pa->speed & RTL8367B_DI_FORCE_SPEED_MASK;
val |= pa->nway ? RTL8367B_DI_FORCE_NWAY : 0;
val |= pa->txpause ? RTL8367B_DI_FORCE_TXPAUSE : 0;
val |= pa->rxpause ? RTL8367B_DI_FORCE_RXPAUSE : 0;
val |= pa->link ? RTL8367B_DI_FORCE_LINK : 0;
val |= pa->duplex ? RTL8367B_DI_FORCE_DUPLEX : 0;
- REG_RMW(smi, RTL8367B_DI_FORCE_REG(id), mask, val);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */
+ val |= (pa->speed << RTL8367D_PORT_STATUS_SPEED1_SHIFT) & RTL8367D_PORT_STATUS_SPEED1_MASK;
+ if (smi->cpu_port != UINT_MAX) {
+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT + smi->cpu_port, val);
+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT_EN + smi->cpu_port, pa->force_mode ? 0xffff : 0x0000);
+ }
+ } else {
+ val |= pa->force_mode ? RTL8367B_DI_FORCE_MODE : 0;
+ mask = (RTL8367B_DI_FORCE_MODE |
+ RTL8367B_DI_FORCE_NWAY |
+ RTL8367B_DI_FORCE_TXPAUSE |
+ RTL8367B_DI_FORCE_RXPAUSE |
+ RTL8367B_DI_FORCE_LINK |
+ RTL8367B_DI_FORCE_DUPLEX |
+ RTL8367B_DI_FORCE_SPEED_MASK);
+
+ REG_RMW(smi, RTL8367B_DI_FORCE_REG(id), mask, val);
+ }
return 0;
}
if (port >= RTL8367B_NUM_PORTS)
return -EINVAL;
- rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ rtl8366_smi_read_reg(smi, RTL8367D_PORT_STATUS_REG(port), &data);
+ else
+ rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data);
link->link = !!(data & RTL8367B_PORT_STATUS_LINK);
if (!link->link)
link->tx_flow = !!(data & RTL8367B_PORT_STATUS_TXPAUSE);
link->aneg = !!(data & RTL8367B_PORT_STATUS_NWAY);
- speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK) | ((data & RTL8367D_PORT_STATUS_SPEED1_MASK) >> RTL8367D_PORT_STATUS_SPEED1_SHIFT);
+ else
+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK);
switch (speed) {
- case 0:
+ case RTL8367B_PORT_STATUS_SPEED_10:
link->speed = SWITCH_PORT_SPEED_10;
break;
- case 1:
+ case RTL8367B_PORT_STATUS_SPEED_100:
link->speed = SWITCH_PORT_SPEED_100;
break;
- case 2:
+ case RTL8367B_PORT_STATUS_SPEED_1000:
link->speed = SWITCH_PORT_SPEED_1000;
break;
default: