|
|
|
@ -681,59 +681,47 @@ static int rtl8366rb_sw_set_learning_enable(struct switch_dev *dev, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const char *rtl8366rb_speed_str(unsigned speed) |
|
|
|
|
{ |
|
|
|
|
switch (speed) { |
|
|
|
|
case 0: |
|
|
|
|
return "10baseT"; |
|
|
|
|
case 1: |
|
|
|
|
return "100baseT"; |
|
|
|
|
case 2: |
|
|
|
|
return "1000baseT"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return "unknown"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int rtl8366rb_sw_get_port_link(struct switch_dev *dev, |
|
|
|
|
const struct switch_attr *attr, |
|
|
|
|
struct switch_val *val) |
|
|
|
|
int port, |
|
|
|
|
struct switch_port_link *link) |
|
|
|
|
{ |
|
|
|
|
struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); |
|
|
|
|
u32 len = 0, data = 0; |
|
|
|
|
u32 data = 0; |
|
|
|
|
u32 speed; |
|
|
|
|
|
|
|
|
|
if (val->port_vlan >= RTL8366RB_NUM_PORTS) |
|
|
|
|
if (port >= RTL8366RB_NUM_PORTS) |
|
|
|
|
return -EINVAL; |
|
|
|
|
|
|
|
|
|
memset(smi->buf, '\0', sizeof(smi->buf)); |
|
|
|
|
rtl8366_smi_read_reg(smi, RTL8366RB_PORT_LINK_STATUS_BASE + |
|
|
|
|
(val->port_vlan / 2), &data); |
|
|
|
|
rtl8366_smi_read_reg(smi, RTL8366RB_PORT_LINK_STATUS_BASE + (port / 2), |
|
|
|
|
&data); |
|
|
|
|
|
|
|
|
|
if (val->port_vlan % 2) |
|
|
|
|
if (port % 2) |
|
|
|
|
data = data >> 8; |
|
|
|
|
|
|
|
|
|
if (data & RTL8366RB_PORT_STATUS_LINK_MASK) { |
|
|
|
|
len = snprintf(smi->buf, sizeof(smi->buf), |
|
|
|
|
"port:%d link:up speed:%s %s-duplex %s%s%s", |
|
|
|
|
val->port_vlan, |
|
|
|
|
rtl8366rb_speed_str(data & |
|
|
|
|
RTL8366RB_PORT_STATUS_SPEED_MASK), |
|
|
|
|
(data & RTL8366RB_PORT_STATUS_DUPLEX_MASK) ? |
|
|
|
|
"full" : "half", |
|
|
|
|
(data & RTL8366RB_PORT_STATUS_TXPAUSE_MASK) ? |
|
|
|
|
"tx-pause ": "", |
|
|
|
|
(data & RTL8366RB_PORT_STATUS_RXPAUSE_MASK) ? |
|
|
|
|
"rx-pause " : "", |
|
|
|
|
(data & RTL8366RB_PORT_STATUS_AN_MASK) ? |
|
|
|
|
"nway ": ""); |
|
|
|
|
} else { |
|
|
|
|
len = snprintf(smi->buf, sizeof(smi->buf), "port:%d link: down", |
|
|
|
|
val->port_vlan); |
|
|
|
|
} |
|
|
|
|
link->link = !!(data & RTL8366RB_PORT_STATUS_LINK_MASK); |
|
|
|
|
if (!link->link) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
link->duplex = !!(data & RTL8366RB_PORT_STATUS_DUPLEX_MASK); |
|
|
|
|
link->rx_flow = !!(data & RTL8366RB_PORT_STATUS_RXPAUSE_MASK); |
|
|
|
|
link->tx_flow = !!(data & RTL8366RB_PORT_STATUS_TXPAUSE_MASK); |
|
|
|
|
link->aneg = !!(data & RTL8366RB_PORT_STATUS_AN_MASK); |
|
|
|
|
|
|
|
|
|
val->value.s = smi->buf; |
|
|
|
|
val->len = len; |
|
|
|
|
speed = (data & RTL8366RB_PORT_STATUS_SPEED_MASK); |
|
|
|
|
switch (speed) { |
|
|
|
|
case 0: |
|
|
|
|
link->speed = SWITCH_PORT_SPEED_10; |
|
|
|
|
break; |
|
|
|
|
case 1: |
|
|
|
|
link->speed = SWITCH_PORT_SPEED_100; |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
link->speed = SWITCH_PORT_SPEED_1000; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
link->speed = SWITCH_PORT_SPEED_UNKNOWN; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -1018,13 +1006,6 @@ static struct switch_attr rtl8366rb_globals[] = { |
|
|
|
|
|
|
|
|
|
static struct switch_attr rtl8366rb_port[] = { |
|
|
|
|
{ |
|
|
|
|
.type = SWITCH_TYPE_STRING, |
|
|
|
|
.name = "link", |
|
|
|
|
.description = "Get port link information", |
|
|
|
|
.max = 1, |
|
|
|
|
.set = NULL, |
|
|
|
|
.get = rtl8366rb_sw_get_port_link, |
|
|
|
|
}, { |
|
|
|
|
.type = SWITCH_TYPE_NOVAL, |
|
|
|
|
.name = "reset_mib", |
|
|
|
|
.description = "Reset single port MIB counters", |
|
|
|
@ -1104,6 +1085,7 @@ static const struct switch_dev_ops rtl8366_ops = { |
|
|
|
|
.get_port_pvid = rtl8366_sw_get_port_pvid, |
|
|
|
|
.set_port_pvid = rtl8366_sw_set_port_pvid, |
|
|
|
|
.reset_switch = rtl8366rb_sw_reset_switch, |
|
|
|
|
.get_port_link = rtl8366rb_sw_get_port_link, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static int rtl8366rb_switch_init(struct rtl8366_smi *smi) |
|
|
|
|