Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146232984
D10740.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D10740.diff
View Options
Index: head/sys/dev/etherswitch/rtl8366/rtl8366rb.c
===================================================================
--- head/sys/dev/etherswitch/rtl8366/rtl8366rb.c
+++ head/sys/dev/etherswitch/rtl8366/rtl8366rb.c
@@ -54,10 +54,12 @@
#include <dev/iicbus/iicbus.h>
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
+#include <dev/mdio/mdio.h>
#include <dev/etherswitch/etherswitch.h>
#include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
+#include "mdio_if.h"
#include "iicbus_if.h"
#include "miibus_if.h"
#include "etherswitch_if.h"
@@ -74,7 +76,9 @@
struct ifnet *ifp[RTL8366_NUM_PHYS];
struct callout callout_tick;
etherswitch_info_t info;
- int chip_type; /* 0 = RTL8366RB, 1 = RTL8366SR */
+ int chip_type;
+ int phy4cpu;
+ int numphys;
};
#define RTL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
@@ -145,7 +149,7 @@
bzero(sc, sizeof(*sc));
if (smi_probe(dev) != 0)
return (ENXIO);
- if(sc->chip_type == 0)
+ if (sc->chip_type == RTL8366RB)
device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
else
device_set_desc(dev, "RTL8366SR Ethernet Switch Controller");
@@ -215,17 +219,23 @@
smi_read(dev, RTL8366_CVCR, &rev, RTL_WAITOK);
device_printf(dev, "rev. %d\n", rev & 0x000f);
- sc->info.es_nports = RTL8366_NUM_PORTS;
+ sc->phy4cpu = 0;
+ (void) resource_int_value(device_get_name(dev), device_get_unit(dev),
+ "phy4cpu", &sc->phy4cpu);
+
+ sc->numphys = sc->phy4cpu ? RTL8366_NUM_PHYS - 1 : RTL8366_NUM_PHYS;
+
+ sc->info.es_nports = sc->numphys + 1;
sc->info.es_nvlangroups = RTL8366_NUM_VLANS;
sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
- if(sc->chip_type == 0)
+ if (sc->chip_type == RTL8366RB)
sprintf(sc->info.es_name, "Realtek RTL8366RB");
else
sprintf(sc->info.es_name, "Realtek RTL8366SR");
/* attach miibus and phys */
/* PHYs need an interface, so we generate a dummy one */
- for (i = 0; i < RTL8366_NUM_PHYS; i++) {
+ for (i = 0; i < sc->numphys; i++) {
sc->ifp[i] = if_alloc(IFT_ETHER);
sc->ifp[i]->if_softc = sc;
sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
@@ -263,7 +273,7 @@
sc = device_get_softc(dev);
- for (i=0; i < RTL8366_NUM_PHYS; i++) {
+ for (i=0; i < sc->numphys; i++) {
if (sc->miibus[i])
device_delete_child(dev, sc->miibus[i]);
if (sc->ifp[i] != NULL)
@@ -319,7 +329,7 @@
uint16_t value;
int portstatus;
- for (i = 0; i < RTL8366_NUM_PHYS; i++) {
+ for (i = 0; i < sc->numphys; i++) {
mii = device_get_softc(sc->miibus[i]);
if ((i % 2) == 0) {
if (smi_read(sc->dev, RTL8366_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
@@ -365,7 +375,7 @@
iicbus = device_get_parent(dev);
iicha = device_get_parent(iicbus);
- for(i = 0; i < 2; ++i) {
+ for (i = 0; i < 2; ++i) {
iicbus_reset(iicbus, IIC_FASTEST, RTL8366_IIC_ADDR, NULL);
for (j=3; j--; ) {
IICBUS_STOP(iicha);
@@ -380,7 +390,7 @@
err = iicbus_start(iicbus, RTL8366_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
if (err != 0)
goto out;
- if(i == 0) {
+ if (i == 0) {
bytes[0] = RTL8366RB_CIR & 0xff;
bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
} else {
@@ -396,22 +406,22 @@
chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
if (i == 0 && chipid == RTL8366RB_CIR_ID8366RB) {
DPRINTF(dev, "chip id 0x%04x\n", chipid);
- sc->chip_type = 0;
+ sc->chip_type = RTL8366RB;
err = 0;
break;
}
if (i == 1 && chipid == RTL8366SR_CIR_ID8366SR) {
DPRINTF(dev, "chip id 0x%04x\n", chipid);
- sc->chip_type = 1;
+ sc->chip_type = RTL8366SR;
err = 0;
break;
}
- if(i == 0) {
+ if (i == 0) {
iicbus_stop(iicbus);
iicbus_release_bus(iicbus, dev);
}
}
- if(i == 2)
+ if (i == 2)
err = ENXIO;
out:
iicbus_stop(iicbus);
@@ -472,7 +482,7 @@
RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
- if(sc->chip_type == 1) { // RTL8366SR work around
+ if (sc->chip_type == RTL8366SR) { // RTL8366SR work around
// this is same work around at probe
for (int i=3; i--; )
IICBUS_STOP(device_get_parent(device_get_parent(dev)));
@@ -648,13 +658,18 @@
ifmr = &p->es_ifmr;
- if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
+ if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
return (ENXIO);
- vlangroup = RTL8366_PVCR_GET(p->es_port,
- rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
+ if (sc->phy4cpu && p->es_port == sc->numphys) {
+ vlangroup = RTL8366_PVCR_GET(p->es_port + 1,
+ rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port + 1)));
+ } else {
+ vlangroup = RTL8366_PVCR_GET(p->es_port,
+ rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
+ }
p->es_pvid = sc->vid[vlangroup] & ETHERSWITCH_VID_MASK;
- if (p->es_port < RTL8366_NUM_PHYS) {
+ if (p->es_port < sc->numphys) {
mii = device_get_softc(sc->miibus[p->es_port]);
ifm = &mii->mii_media;
err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
@@ -687,10 +702,11 @@
int i, err, vlangroup;
struct ifmedia *ifm;
struct mii_data *mii;
+ int port;
sc = device_get_softc(dev);
- if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
+ if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
return (ENXIO);
vlangroup = -1;
for (i = 0; i < RTL8366_NUM_VLANS; i++) {
@@ -701,12 +717,18 @@
}
if (vlangroup == -1)
return (ENXIO);
- err = smi_rmw(dev, RTL8366_PVCR_REG(p->es_port),
- RTL8366_PVCR_VAL(p->es_port, RTL8366_PVCR_PORT_MASK),
- RTL8366_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK);
+ if (sc->phy4cpu && p->es_port == sc->numphys) {
+ port = p->es_port + 1;
+ } else {
+ port = p->es_port;
+ }
+ err = smi_rmw(dev, RTL8366_PVCR_REG(port),
+ RTL8366_PVCR_VAL(port, RTL8366_PVCR_PORT_MASK),
+ RTL8366_PVCR_VAL(port, vlangroup), RTL_WAITOK);
if (err)
return (err);
- if (p->es_port == RTL8366_CPU_PORT)
+ /* CPU Port */
+ if (p->es_port == sc->numphys)
return (0);
mii = device_get_softc(sc->miibus[p->es_port]);
ifm = &mii->mii_media;
@@ -720,6 +742,7 @@
struct rtl8366rb_softc *sc;
uint16_t vmcr[3];
int i;
+ int member, untagged;
sc = device_get_softc(dev);
@@ -727,8 +750,15 @@
vmcr[i] = rtl_readreg(dev, RTL8366_VMCR(i, vg->es_vlangroup));
vg->es_vid = sc->vid[vg->es_vlangroup];
- vg->es_member_ports = RTL8366_VMCR_MEMBER(vmcr);
- vg->es_untagged_ports = RTL8366_VMCR_UNTAG(vmcr);
+ member = RTL8366_VMCR_MEMBER(vmcr);
+ untagged = RTL8366_VMCR_UNTAG(vmcr);
+ if (sc->phy4cpu) {
+ vg->es_member_ports = ((member & 0x20) >> 1) | (member & 0x0f);
+ vg->es_untagged_ports = ((untagged & 0x20) >> 1) | (untagged & 0x0f);
+ } else {
+ vg->es_member_ports = member;
+ vg->es_untagged_ports = untagged;
+ }
vg->es_fid = RTL8366_VMCR_FID(vmcr);
return (0);
}
@@ -738,6 +768,7 @@
{
struct rtl8366rb_softc *sc;
int g;
+ int member, untagged;
sc = device_get_softc(dev);
@@ -750,16 +781,26 @@
sc->vid[g] |= ETHERSWITCH_VID_VALID;
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_DOT1Q_REG, g),
(vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK);
- if(sc->chip_type == 0) {
+ if (sc->phy4cpu) {
+ /* add space at phy4 */
+ member = (vg->es_member_ports & 0x0f) |
+ ((vg->es_member_ports & 0x10) << 1);
+ untagged = (vg->es_untagged_ports & 0x0f) |
+ ((vg->es_untagged_ports & 0x10) << 1);
+ } else {
+ member = vg->es_member_ports;
+ untagged = vg->es_untagged_ports;
+ }
+ if (sc->chip_type == RTL8366RB) {
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
- ((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
- ((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
+ ((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
+ ((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_FID_REG, g),
vg->es_fid);
} else {
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
- ((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
- ((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
+ ((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
+ ((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
((vg->es_fid << RTL8366_VMCR_FID_FID_SHIFT) & RTL8366_VMCR_FID_FID_MASK));
}
return (0);
@@ -886,6 +927,10 @@
DEVMETHOD(miibus_readreg, rtl_readphy),
DEVMETHOD(miibus_writereg, rtl_writephy),
+ /* MDIO interface */
+ DEVMETHOD(mdio_readreg, rtl_readphy),
+ DEVMETHOD(mdio_writereg, rtl_writephy),
+
/* etherswitch interface */
DEVMETHOD(etherswitch_getconf, rtl_getconf),
DEVMETHOD(etherswitch_getinfo, rtl_getinfo),
@@ -907,6 +952,7 @@
DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0);
DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0);
+DRIVER_MODULE(mdio, rtl8366rb, mdio_driver, mdio_devclass, 0, 0);
DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0);
MODULE_VERSION(rtl8366rb, 1);
MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */
Index: head/sys/dev/etherswitch/rtl8366/rtl8366rbvar.h
===================================================================
--- head/sys/dev/etherswitch/rtl8366/rtl8366rbvar.h
+++ head/sys/dev/etherswitch/rtl8366/rtl8366rbvar.h
@@ -30,6 +30,9 @@
#ifndef _DEV_ETHERSWITCH_RTL8366RBVAR_H_
#define _DEV_ETHERSWITCH_RTL8366RBVAR_H_
+#define RTL8366RB 0
+#define RTL8366SR 1
+
#define RTL8366_IIC_ADDR 0xa8
#define RTL_IICBUS_TIMEOUT 100 /* us */
#define RTL_IICBUS_READ 1
@@ -173,9 +176,7 @@
(0x8000 | (1 << (((phy) & 0x1f) + 9)) | (((page) & (sc->chip_type == 0 ? 0xf : 0x7)) << 5) | ((reg) & 0x1f))
/* general characteristics of the chip */
-#define RTL8366_CPU_PORT 5
-#define RTL8366_NUM_PORTS 6
-#define RTL8366_NUM_PHYS (RTL8366_NUM_PORTS-1)
+#define RTL8366_NUM_PHYS 5
#define RTL8366_NUM_VLANS 16
#define RTL8366_NUM_PHY_REG 32
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 1, 11:50 PM (7 h, 49 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29129290
Default Alt Text
D10740.diff (9 KB)
Attached To
Mode
D10740: add mdioproxy support and phy4 is cpu port support and refactoring
Attached
Detach File
Event Timeline
Log In to Comment