mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Add support for changing Ethernet speeds
This commit is contained in:
@@ -188,4 +188,89 @@ devices, set 8N1 @ 115200 baud and power up the switch.
|
|||||||
The device will perform some examples and provide a minimal console, the
|
The device will perform some examples and provide a minimal console, the
|
||||||
documentation of which can be found in the source code rtlplayground.c`.
|
documentation of which can be found in the source code rtlplayground.c`.
|
||||||
|
|
||||||
|
## The command line
|
||||||
|
The command line is very rudimentary and mostly for testing purposes.
|
||||||
|
The following is a boot-log with some examples:
|
||||||
|
```
|
||||||
|
Detecting CPU
|
||||||
|
RTL8373 detected
|
||||||
|
Starting up...
|
||||||
|
Flash controller
|
||||||
|
|
||||||
|
NIC reset
|
||||||
|
rtl8372_init called
|
||||||
|
|
||||||
|
RTL837X_REG_SDS_MODES: 0x00000bed
|
||||||
|
|
||||||
|
phy_config_8224 called
|
||||||
|
|
||||||
|
phy_config_8224 done
|
||||||
|
|
||||||
|
rtl8224_phy_enable called
|
||||||
|
|
||||||
|
rtl8224_phy_enable done
|
||||||
|
X
|
||||||
|
rtl8372_init done
|
||||||
|
|
||||||
|
A minimal prompt to explore the RTL8372:
|
||||||
|
|
||||||
|
CPU detected: RTL8373
|
||||||
|
Clock register: 0x00001101
|
||||||
|
Register 0x7b20/RTL837X_REG_SDS_MODES: 0x00000bed
|
||||||
|
Verifying PHY settings:
|
||||||
|
|
||||||
|
Port State Link TxGood TxBad RxGood RxBad
|
||||||
|
1 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
2 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
3 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
4 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
5 On 2.5G 0x00000008 0x00000000 0x00000000 0x00000000
|
||||||
|
6 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
7 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
8 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
9 NO SFP Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
|
||||||
|
> port 5 1g
|
||||||
|
CMD: port 5 1g
|
||||||
|
PORT 04 1G
|
||||||
|
|
||||||
|
> stat
|
||||||
|
CMD: stat
|
||||||
|
Port State Link TxGood TxBad RxGood RxBad
|
||||||
|
1 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
2 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
3 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
4 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
5 On 1000M 0x00000035 0x00000000 0x00000017 0x00000000
|
||||||
|
6 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
7 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
8 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
9 NO SFP Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
|
||||||
|
>
|
||||||
|
<SFP-RX OK>
|
||||||
|
|
||||||
|
<MODULE INSERTED> Rate: 67 Encoding: 01
|
||||||
|
Lightron Inc. WSPXG-ES3LC-IHA 0000
|
||||||
|
|
||||||
|
|
||||||
|
> stat
|
||||||
|
CMD: stat
|
||||||
|
Port State Link TxGood TxBad RxGood RxBad
|
||||||
|
1 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
2 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
3 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
4 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
5 On 1000M 0x00000065 0x00000000 0x0000003b 0x00000000
|
||||||
|
6 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
7 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
8 On Down 0x00000000 0x00000000 0x00000000 0x00000000
|
||||||
|
9 SFP OK 10G 0x00000000 0x00000000 0x0000001c 0x00000000
|
||||||
|
|
||||||
|
> sfp
|
||||||
|
CMD: sfp
|
||||||
|
Rate: 67 Encoding: 01
|
||||||
|
Lightron Inc. WSPXG-ES3LC-IHA 0000
|
||||||
|
|
||||||
|
```
|
||||||
Enjoy playing!
|
Enjoy playing!
|
||||||
|
|||||||
+52
-1
@@ -4,10 +4,13 @@
|
|||||||
* This code is in the Public Domain
|
* This code is in the Public Domain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// #define REGDBG
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
|
#include "rtl837x_phy.h"
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
|
|
||||||
@@ -37,7 +40,7 @@ P000001.1e000400:c45c P000001.1e0003f8:c18c p001e.03f8:418c
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
__code uint16_t rtl8224_ca[41] = {
|
__code uint16_t rtl8224_ca[42] = {
|
||||||
0x4480, 0xc842,
|
0x4480, 0xc842,
|
||||||
0x0400, 0xc9c2,
|
0x0400, 0xc9c2,
|
||||||
0x6d02, 0xcc42,
|
0x6d02, 0xcc42,
|
||||||
@@ -306,3 +309,51 @@ void phy_config_8224(void) __banked
|
|||||||
|
|
||||||
print_string("\r\nphy_config_8224 done\r\n");
|
print_string("\r\nphy_config_8224 done\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set Speed, duplex and flow control mode of a PHY
|
||||||
|
* See e.g. RTL8221B datasheet
|
||||||
|
*/
|
||||||
|
void phy_set_mode(uint8_t port, uint8_t speed, uint8_t flow_control, uint8_t duplex) __banked
|
||||||
|
{
|
||||||
|
uint16_t v;
|
||||||
|
phy_read(port, 0x1f, 0xa610);
|
||||||
|
v = (((uint16_t)SFR_DATA_8) << 8) | SFR_DATA_0;
|
||||||
|
if (speed == PHY_OFF) {
|
||||||
|
phy_write(bit_mask[port], 0x1f, 0xa4610, v | 0x0800);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Port is on, make sure of it:
|
||||||
|
if (v & 0x0800)
|
||||||
|
phy_write(bit_mask[port], 0x1f, 0xa4610, v & 0xf7ff);
|
||||||
|
|
||||||
|
if (speed == PHY_SPEED_AUTO) {
|
||||||
|
// AN Advertisement Register (MMD 7.0x0010)
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x10, 0x1001); // bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||||
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x20, 0x6081); // bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x00, 0x3200); // Restart AN
|
||||||
|
} else {
|
||||||
|
// AN Control Register (MMD 7.0x0000)
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x00, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13)
|
||||||
|
// AN Advertisement Register (MMD 7.0x0010)
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x10, 0x1001); // bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||||
|
if (speed == PHY_SPEED_1G) {
|
||||||
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x20, 0x6001); // bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed
|
||||||
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
|
phy_read(port, 0x1f, 0xa412);
|
||||||
|
v = (((uint16_t)SFR_DATA_8) << 8) | SFR_DATA_0;
|
||||||
|
phy_write(bit_mask[port], 0x1f, 0xa412, v | 0x0200);
|
||||||
|
} else if (speed == PHY_SPEED_2G5) {
|
||||||
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x20, 0x6081); // bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed
|
||||||
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
|
phy_read(port, 0x1f, 0xa412);
|
||||||
|
v = (((uint16_t)SFR_DATA_8) << 8) | SFR_DATA_0;
|
||||||
|
phy_write(bit_mask[port], 0x1f, 0xa412, v & 0xfdff);
|
||||||
|
}
|
||||||
|
phy_write(bit_mask[port], 0x07, 0x00, 0x3200); // Enable AN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
#ifndef _RTL837X_PHY_H_
|
#ifndef _RTL837X_PHY_H_
|
||||||
#define _RTL837X_PHY_H_
|
#define _RTL837X_PHY_H_
|
||||||
|
|
||||||
|
#define PHY_SPEED_AUTO 0x1
|
||||||
|
#define PHY_SPEED_1G 0x2
|
||||||
|
#define PHY_SPEED_2G5 0x3
|
||||||
|
#define PHY_OFF 0xff
|
||||||
|
|
||||||
void rtl8224_phy_enable(void) __banked;
|
void rtl8224_phy_enable(void) __banked;
|
||||||
void phy_config(uint8_t phy) __banked;
|
void phy_config(uint8_t phy) __banked;
|
||||||
void phy_config_8224(void) __banked;
|
void phy_config_8224(void) __banked;
|
||||||
|
void phy_set_mode(uint8_t port, uint8_t speed, uint8_t flow_control, uint8_t duplex) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+38
-21
@@ -1492,11 +1492,6 @@ void setup_serial(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__code struct command commands[N_COMMANDS] = {
|
|
||||||
{ "reset", 1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t cmd_compare(uint8_t start, uint8_t * __code cmd)
|
uint8_t cmd_compare(uint8_t start, uint8_t * __code cmd)
|
||||||
{
|
{
|
||||||
signed char i;
|
signed char i;
|
||||||
@@ -1569,6 +1564,7 @@ void bootloader(void)
|
|||||||
rtl8224_enable(); // Power on the RTL8224
|
rtl8224_enable(); // Power on the RTL8224
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
// Reset seconds counter
|
// Reset seconds counter
|
||||||
print_string("\r\nTIMER-TEST: \r\n");
|
print_string("\r\nTIMER-TEST: \r\n");
|
||||||
REG_SET(RTL837X_REG_SEC_COUNTER, 0x0);
|
REG_SET(RTL837X_REG_SEC_COUNTER, 0x0);
|
||||||
@@ -1582,27 +1578,19 @@ void bootloader(void)
|
|||||||
print_reg(RTL837X_REG_SEC_COUNTER);
|
print_reg(RTL837X_REG_SEC_COUNTER);
|
||||||
REG_SET(RTL837X_REG_SEC_COUNTER, 0x3); write_char(' ');
|
REG_SET(RTL837X_REG_SEC_COUNTER, 0x3); write_char(' ');
|
||||||
print_reg(RTL837X_REG_SEC_COUNTER);
|
print_reg(RTL837X_REG_SEC_COUNTER);
|
||||||
|
#endif
|
||||||
|
|
||||||
print_string("\r\nStarting up...\r\n");
|
print_string("\r\nStarting up...\r\n");
|
||||||
print_string(" Flash controller\r\n");
|
print_string(" Flash controller\r\n");
|
||||||
flash_init(0);
|
flash_init(0);
|
||||||
|
|
||||||
// The following will only show something else then 0xff if it was programmed for a managed switch
|
|
||||||
print_string("\r\n Testing read Securty Register 1\r\n");
|
|
||||||
flash_read_security(0x0001000, 40);
|
|
||||||
print_string("\r\n Testing read Securty Register 2\r\n");
|
|
||||||
flash_read_security(0x0002000, 40);
|
|
||||||
print_string("\r\n Testing read Securty Register 3\r\n");
|
|
||||||
flash_read_security(0x0003000, 40);
|
|
||||||
print_string("\r\n");
|
|
||||||
|
|
||||||
// r0024:00000f80 R0024-00000f84 r0024:00000f80
|
|
||||||
// Reset NIC
|
// Reset NIC
|
||||||
reg_bit_set(0x24, 2);
|
reg_bit_set(0x24, 2);
|
||||||
do {
|
do {
|
||||||
reg_read(0x24);
|
reg_read(0x24);
|
||||||
} while (SFR_DATA_0 & 0x4);
|
} while (SFR_DATA_0 & 0x4);
|
||||||
print_string("\r\nNIC reset");
|
print_string("\r\nNIC reset");
|
||||||
|
|
||||||
rtl8372_init();
|
rtl8372_init();
|
||||||
REG_SET(0x7f94, 0x0); // BUG: Only for testing, otherwise: clear bits 0-3
|
REG_SET(0x7f94, 0x0); // BUG: Only for testing, otherwise: clear bits 0-3
|
||||||
nic_setup();
|
nic_setup();
|
||||||
@@ -1659,12 +1647,13 @@ void bootloader(void)
|
|||||||
// Identify command
|
// Identify command
|
||||||
signed char i = cmd_words_b[0];
|
signed char i = cmd_words_b[0];
|
||||||
if (i >= 0 && cmd_words_b[1] >= 0) {
|
if (i >= 0 && cmd_words_b[1] >= 0) {
|
||||||
// print_string("\r\n THERE may be a command: ");
|
/* print_string("\r\n THERE may be a command: ");
|
||||||
// print_short(i); print_string("\r\n");
|
print_short(i); print_string("\r\n");
|
||||||
// print_short(cmd_words_b[0]); print_string("\r\n");
|
print_short(cmd_words_b[0]); print_string("\r\n");
|
||||||
// print_short(cmd_words_b[1]); print_string("\r\n");
|
print_short(cmd_words_b[1]); print_string("\r\n");
|
||||||
// print_short(cmd_words_b[2]); print_string("\r\n");
|
print_short(cmd_words_b[2]); print_string("\r\n");
|
||||||
// print_short(cmd_words_b[3]); print_string("\r\n");
|
print_short(cmd_words_b[3]); print_string("\r\n");
|
||||||
|
*/
|
||||||
if (cmd_compare(0, "reset")) {
|
if (cmd_compare(0, "reset")) {
|
||||||
print_string("\r\nRESET\n\n");
|
print_string("\r\nRESET\n\n");
|
||||||
reset_chip();
|
reset_chip();
|
||||||
@@ -1683,6 +1672,13 @@ void bootloader(void)
|
|||||||
if (cmd_compare(0, "stat")) {
|
if (cmd_compare(0, "stat")) {
|
||||||
port_stats_print();
|
port_stats_print();
|
||||||
}
|
}
|
||||||
|
if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'r') {
|
||||||
|
print_string("\r\nPRINT SECURITY REGISTERS\r\n");
|
||||||
|
// The following will only show something else then 0xff if it was programmed for a managed switch
|
||||||
|
flash_read_security(0x0001000, 40);
|
||||||
|
flash_read_security(0x0002000, 40);
|
||||||
|
flash_read_security(0x0003000, 40);
|
||||||
|
}
|
||||||
if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'd') {
|
if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'd') {
|
||||||
print_string("\r\nDUMPING FLASH\r\n");
|
print_string("\r\nDUMPING FLASH\r\n");
|
||||||
flash_dump(0, 255);
|
flash_dump(0, 255);
|
||||||
@@ -1712,6 +1708,27 @@ void bootloader(void)
|
|||||||
flash_buf[i] = greeting[i];
|
flash_buf[i] = greeting[i];
|
||||||
flash_write_bytes(0x20000, flash_buf, 20);
|
flash_write_bytes(0x20000, flash_buf, 20);
|
||||||
}
|
}
|
||||||
|
if (cmd_compare(0, "port") && cmd_words_b[1] > 0) {
|
||||||
|
print_string("\r\nPORT ");
|
||||||
|
uint8_t p = sbuf[cmd_words_b[1]] - '1';
|
||||||
|
print_byte(p);
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "2g5")) {
|
||||||
|
print_string(" 2.5G\r\n");
|
||||||
|
phy_set_mode(p, PHY_SPEED_2G5, 0, 0);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "1g")) {
|
||||||
|
print_string(" 1G\r\n");
|
||||||
|
phy_set_mode(p, PHY_SPEED_1G, 0, 0);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "auto")) {
|
||||||
|
print_string(" AUTO\r\n");
|
||||||
|
phy_set_mode(p, PHY_SPEED_AUTO, 0, 0);
|
||||||
|
}
|
||||||
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "off")) {
|
||||||
|
print_string(" OFF\r\n");
|
||||||
|
phy_set_mode(p, PHY_OFF, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print_string("\r\n> ");
|
print_string("\r\n> ");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user