Hi,
I'm working with RT 1062 where the ENET2 controller is connected to a KSZ8895 ethernet switch chip.
The switch's bootstraps are configured such that it is in SMI serial interface mode. We can read register values in the restricted MIIM set via ENET2's MDIO interface, but when attempting to read in SMI mode (i.e. the entire register set), it seems that only 0xFFFF value are returned.
From an application note document (http://ww1.microchip.com/downloads/en/DeviceDoc/ANLAN207_Management_Interfaces.pdf) it seems that the MDIO frame format for SMI *should* be the same as MIIM for this chip, see table below:
See below waveform for attempted read using the MDIO interface from ENET2:
Since chips such as KSZ8863 have required a "bit bang" solution in the past for SMI (in particular from Kinetis chips), we also attempted this from the RT 1062 to KSZ8895, but with the same result:
Is this issue familiar to others? Perhaps there is some other device configuration we have overlooked whereby the registers are accessible in MIIM mode but not in SMI.
Thanks for you help!
Patrick
Solved! Go to Solution.
HI Patrick
Have you double-checked the boot strap to be absolutely sure that it is not in one of the other modes?
When I originally started using the KSZ8863 (pre-KSZ8895) it was in pre-Kinetis times with the Coldfires. These have the same ENET core module as in Kinetis and in i.MX RTs and I found that writes could be achieved using the MII management interface but not reads since there was a bit value needed that couldn't be controlled. They used always the OP code 0x00 (and read/write bit in the PHY address[4]) and I believe that the Coldfire/Kinets/i.MX RT ENET won't operate in the read sense when this OP code is set because there is nothing indicating to the controller that a read is required. Therefore bit-banging reads was the only possible method, whereby MII writes work.
The SMI protocol as used by the KSZ8895 has been adjusted to control the access via the PHY address bits [2:1] instead, which makes if fully compatible with the ENET controller of all of these parts.
In your case you have shown that neither MII generated nor bit-banged waveforms corresponding to the specified sequence cause the PHY to return data which strongly suggests the issue to be at the PHY (eg. the mode is not successfully set to SMI mode), especially since all reads are expected to return 0x00 as most significant bytes and 0xffff indicated that it is never driving the bus.
Note that the ENET driver in the uTasker project allows both MII and SMI writes via the same HAL function, whereby PHY address 0 is considered to be SMI writes (since PHY address 0 is usually never used as address):
if (_mpadr == 0) {
ptrEnet->ENET_MMFR = ((MII_TA | MII_ST) | _mwdata); // command SMI write to given SMI register
}
else {
ptrEnet->ENET_MMFR = (MII_WRITE | (_mpadr << 23) | (_mradr << 18) | _mwdata); // command write to given MII address
}
This is suitable for the SMI interface as found in the KSZ8863.
In the case of the revised SMI mode compatibility is achieved when writes to PHY address 0 are performed with
ptrEnet->ENET_MMFR = ((MII_WRITE | (((_mradr >> 5) & 1) | ((_mradr >>3) & 0x18) | 0x6) << 23) | ((_mradr & 0x1f) << 18) | _mwdata); // command write to given SMI register
instead.
Since bit-banged reads are not needed the read direction can be performed with
if (_mpadr == 0) {
ptrEnet->ENET_MMFR = ((MII_READ | (((_mradr >> 5) & 1) | ((_mradr >> 3) & 0x18) | 0x6) << 23) | ((_mradr & 0x1f) << 18)); // command read from given SMI address
}
else {
ptrEnet->ENET_MMFR = (MII_READ | (_mpadr << 23) | (_mradr << 18)); // start the read from MII register
}
But first the PHY has to at least respond!!!
Good luck
Regards
Mark
HI Patrick
Have you double-checked the boot strap to be absolutely sure that it is not in one of the other modes?
When I originally started using the KSZ8863 (pre-KSZ8895) it was in pre-Kinetis times with the Coldfires. These have the same ENET core module as in Kinetis and in i.MX RTs and I found that writes could be achieved using the MII management interface but not reads since there was a bit value needed that couldn't be controlled. They used always the OP code 0x00 (and read/write bit in the PHY address[4]) and I believe that the Coldfire/Kinets/i.MX RT ENET won't operate in the read sense when this OP code is set because there is nothing indicating to the controller that a read is required. Therefore bit-banging reads was the only possible method, whereby MII writes work.
The SMI protocol as used by the KSZ8895 has been adjusted to control the access via the PHY address bits [2:1] instead, which makes if fully compatible with the ENET controller of all of these parts.
In your case you have shown that neither MII generated nor bit-banged waveforms corresponding to the specified sequence cause the PHY to return data which strongly suggests the issue to be at the PHY (eg. the mode is not successfully set to SMI mode), especially since all reads are expected to return 0x00 as most significant bytes and 0xffff indicated that it is never driving the bus.
Note that the ENET driver in the uTasker project allows both MII and SMI writes via the same HAL function, whereby PHY address 0 is considered to be SMI writes (since PHY address 0 is usually never used as address):
if (_mpadr == 0) {
ptrEnet->ENET_MMFR = ((MII_TA | MII_ST) | _mwdata); // command SMI write to given SMI register
}
else {
ptrEnet->ENET_MMFR = (MII_WRITE | (_mpadr << 23) | (_mradr << 18) | _mwdata); // command write to given MII address
}
This is suitable for the SMI interface as found in the KSZ8863.
In the case of the revised SMI mode compatibility is achieved when writes to PHY address 0 are performed with
ptrEnet->ENET_MMFR = ((MII_WRITE | (((_mradr >> 5) & 1) | ((_mradr >>3) & 0x18) | 0x6) << 23) | ((_mradr & 0x1f) << 18) | _mwdata); // command write to given SMI register
instead.
Since bit-banged reads are not needed the read direction can be performed with
if (_mpadr == 0) {
ptrEnet->ENET_MMFR = ((MII_READ | (((_mradr >> 5) & 1) | ((_mradr >> 3) & 0x18) | 0x6) << 23) | ((_mradr & 0x1f) << 18)); // command read from given SMI address
}
else {
ptrEnet->ENET_MMFR = (MII_READ | (_mpadr << 23) | (_mradr << 18)); // start the read from MII register
}
But first the PHY has to at least respond!!!
Good luck
Regards
Mark
Hi Mark,
Thanks for your response on this issue.
Indeed, it seems our issue was bootstrap-related, after all. In summary, the PS0/PS1 signals of the KSZ8895 in our design are controlled as GPIOs from the MCU. However, we had to apply a mod which applies a hard pull-up to the PS1 signal. As such, after a reset the KSZ8895 is found to be in SPI mode.
We are able to work with the device in SPI mode, since it gives us the same register access as SMI mode for our purposes.
A key point to note, which may confuse other users, is that it seems the MIIM registers of the KSZ8895 are accessible over the MDIO bus, regardless of whether the device's serial bus mode for "full" register access is set as SPI or SMI.
Thanks again for your help!
Patrick
Hi Patrick
Yes, the SMI/SPI modes are parallel to the MDIO bus so the MDIO method to access the base registers is always present and so compatible, however configured.
Regards
Mark