mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
108 lines
4.8 KiB
Markdown
108 lines
4.8 KiB
Markdown
# SFP+ Slots
|
|
|
|
The RTL8372/3 provide support for 1 or 2 SFP+ slots, which support fiber and Ethernet
|
|
module with speeds of 1GBit, 2.5GBit and 10GBit. 5GBit could be possible but is not
|
|
implemented due to the lack of suitable modules.
|
|
|
|
When a module is inserted, it directly connects to GPIO, I2C and RX/TX data lines of
|
|
the SoC. An example schematics can be found here:
|
|
[SFP Module Schematics](https://sfp.by/source/manual/SCP6F44-GL-BWE.pdf). Another
|
|
resources is [here](https://www.sfptransceiver.com/product_pdf/SFP/SFP%20Design%20Guide.pdf).
|
|
The SoC
|
|
detects the insertion because the MOD-DEF0 line is pulled low by the module. The
|
|
corresponding bit in RTL837X_REG_GPIO_B or RTL837X_REG_GPIO_C will transition from
|
|
1 to 0. At that point, the code waits for some 100ms in order for the module to power
|
|
up and then reads the EEPROM of the module to get the type of module and in particular
|
|
the bit-rate. The EEPROM can be read via the MOD-DEF1 and MOD-DEF2 lines which
|
|
provide a standard I2C interface to the standard 24C-EEPROM. The SoCs contain a simple
|
|
I2C controller for reading such EEPROMs so that interfacing is very simple.
|
|
|
|
## I2C Controller
|
|
|
|
The I2C controller of the RTL8372/3 is very simple and probably designed specifically
|
|
for reading 24C EEPROMs. Its use is straight-forward: Configure the I2C bus used
|
|
(the code currently uses the default already set regarding what is probably timing)
|
|
in the RTL837X_REG_I2C_CTRL register. Then set the EEPROM-register's addresss to be
|
|
read in RTL837X_REG_I2C_IN (least-significant byte). The I2C transfer is started
|
|
by setting the 0-bit of RTL837X_REG_I2C_CTRL. When this bit is cleared by the
|
|
ASIC-side of the SoC, the resulting value can be read in the LSB of RTL837X_REG_I2C_OUT.
|
|
This is the code:
|
|
```
|
|
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
|
{
|
|
// Select I2C-bus according to slot
|
|
if (slot == 0) {
|
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
|
sfr_mask_data(1, 0xff, 0x72);
|
|
reg_write_m(RTL837X_REG_I2C_CTRL);
|
|
} else {
|
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
|
sfr_mask_data(1, 0xff, 0x6e);
|
|
reg_write_m(RTL837X_REG_I2C_CTRL);
|
|
}
|
|
|
|
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
|
|
|
// Execute I2C Read
|
|
reg_bit_set(RTL837X_REG_I2C_CTRL, 0);
|
|
|
|
// Wait for execution to finish
|
|
do {
|
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
|
} while (sfr_data[3] & 0x1);
|
|
|
|
reg_read_m(RTL837X_REG_I2C_OUT);
|
|
return sfr_data[3];
|
|
}
|
|
```
|
|
|
|
The description of the data stored in the EEPROM can be found in the
|
|
[SFF-8472 standard](https://members.snia.org/document/dl/25916)
|
|
The most relevant is byte 12 (0x0c), which gives the signalling rate of the module in
|
|
100MBit, including the 25% overhead for error correction. Currently the code looks like
|
|
this:
|
|
```
|
|
static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
|
|
{
|
|
if (rate == 0xd)
|
|
return SDS_1000BX_FIBER;
|
|
if (rate == 0x1f) // Ethernet 2.5 GBit
|
|
return SDS_HSG;
|
|
if (rate > 0x65 && rate < 0x70)
|
|
return SDS_10GR;
|
|
return 0xff;
|
|
}
|
|
```
|
|
For example, a 1000MBit fiber module will have a rate coding of 0xd = 13 = 1300Mbit,
|
|
which is the rounded-up value for 1250MBit, the error-corrected bit-rate of
|
|
a 1000BX fiber module.
|
|
|
|
## Interfacing the module for RX/TX
|
|
|
|
In order to transmit data or receive data from the module, the SerDes of the SoC connected
|
|
to the module needs to e properly configured. As can be seen from the
|
|
[SFP Module Schematics](https://sfp.by/source/manual/SCP6F44-GL-BWE.pdf), the Photo-transistor
|
|
of the module is optimized by an amplifier and quantized to bits, which directly arrive
|
|
at the SoC in a differential pair. This data still has the 25% overhead of the error correction
|
|
codes that were on the fiber. The switch needs to configure the SerDes correctl (sds_config())
|
|
and set up the MAC on the SoC to talk to the SDS with the correct bit-rate.
|
|
|
|
## Other SFP-module GPIOs
|
|
SFP modules also provide RX-LOS GPIOs, which pulls low when the fiber or Ethernet
|
|
cable is not attached (on either side of the link) and usually also a TX-disable GPIO,
|
|
which allows to disable the Laser in order to power down the link. There is typically
|
|
also a TX-Fault GPIO which pulls low when the laser overheated. While the RX-Los pin
|
|
is connected to the SoC and can be read for the devices with a single SFP+ slot
|
|
(for the dual-SFP+ slot KP-9000-6HX-X2 only the RX-LOS pin of the right slot seems to
|
|
be connected), the other GPIOs have not been identified and counting lines on the PCB
|
|
seems to indicate these pins are unlikely to be connected.
|
|
|
|
The RX-LOS GPIO does not provide any further benefit, since the link status can also be
|
|
read from the link-status registers of the MAC or SDS.
|
|
|
|
The easiest way to identifiy additional GPIOs of an SFP module is to take a cheap module
|
|
apart, solder wires to the pins of the on-board PCB which are then routed back through
|
|
the end of the module. By pulling e.g. TX-Fault low while printing out the GPIOs, the
|
|
correct GPIO can be identified.
|
|
|