mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
The I2C controller transfers up to sixteen bytes per transaction and page_impl.c already used that for sfp_send_data(), while sfp_read_reg() asked for one byte and every caller looped. Reading a module therefore cost one address phase per byte: 87 transactions when a module is inserted, 52 for the sfp command, 36 for the vendor block in status.json. sfp_read_block() replaces sfp_read_reg() and the callers that already wanted a run of registers ask for it once: the vendor fields as three 16 byte pages, the diagnostics as one transfer, rate and encoding together. That drops the three paths above to 8, 6 and 3 transactions, and sfp_send_data() loses its copy of the transfer. The vendor loops now run over 16..63 rather than 20..59 so the page base is a multiple of sixteen and the index into the buffer is a single AND. The four extra bytes at each end are read and discarded. The diagnostics read asks for 16 bytes rather than the 15 it uses, because 16 is a width the shipped firmware already exercises and 15 is not. The device address, the bus selection and the start bit go into the control register in one write now that the memory address is written first, so a transfer touches that register once instead of three times. The register reads take their result from the SFRs directly rather than through the sfr_data mirror. The result is a bool and the destination is sfp_buf, so a caller that cares about a failed transfer looks at the return value instead of a flag. Every caller gives up on the first failed read rather than carrying a flag to the end, which is why the module read moved out of handle_sfp into a function of its own. A module whose read fails is left marked as absent, so the next poll retries it instead of configuring the SerDes from bytes that never arrived. BANK1 -194 bytes, BANK2 +382, common segment +44, xdata +15 for the buffer, and one byte more of internal RAM free than before the series. Built for all 25 machine definitions on sdcc 4.5.0; the tightest common segment is 98 bytes free on SWTG024AS_V2_0, against 54 before this series.
181 lines
6.0 KiB
C
181 lines
6.0 KiB
C
#ifndef _RTL837X_STDIO_H_
|
|
#define _RTL837X_STDIO_H_
|
|
|
|
#include "uip/uip-conf.h"
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#define SYS_TICK_HZ 200
|
|
|
|
#define CPU_PORT 9
|
|
|
|
// Define Port-masks for 9-port devices and 6-port devices
|
|
#define PMASK_9 0x1ff
|
|
#define PMASK_6 0x1f8
|
|
#define PMASK_CPU 0x200
|
|
|
|
// Defines a port mask for dropping all packets on Lookup-miss
|
|
#define LOOKUP_MISS_DROP_6 0x00015540
|
|
#define LOOKUP_MISS_DROP_9 0x00015555
|
|
#define LOOKUP_MISS_FLOOD 0x00000000
|
|
|
|
/* Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
|
* Writing to this buffer is under the sole control of the serial ISR
|
|
* Note that key-presses such as <cursor-left> can create multiple
|
|
* keys (3 to 4) being sent via the serial line, so this must be
|
|
* sufficiently large */
|
|
#define SBUF_SIZE 16
|
|
#define SBUF_MASK (SBUF_SIZE - 1)
|
|
|
|
extern __xdata volatile uint8_t sbuf_ptr;
|
|
extern __xdata uint8_t sbuf[SBUF_SIZE];
|
|
|
|
// Define the command buffer size, Must be 2^x and <= 128
|
|
#define CMD_BUF_SIZE 128
|
|
|
|
// Size of the TCP Output buffer
|
|
#define TCP_OUTBUF_SIZE 2500
|
|
|
|
// Size of the port name, including the terminating null byte
|
|
#define PORT_NAME_SIZE 32
|
|
|
|
// Size of the memory area dedicated to VLAN-names
|
|
#define VLAN_NAMES_SIZE 1024
|
|
|
|
// Size of the flash buffer used for writing to flash, must be a multiple of the flash page size (0x100)
|
|
#define FLASH_BUF_SIZE 512
|
|
|
|
// Errors for commands
|
|
#define ERR_OK 0
|
|
#define ERR_TOO_MANY_ARGUMENTS 1
|
|
#define ERR_CMD_TOO_LONG 2
|
|
|
|
// For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4,
|
|
// the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated,
|
|
// the VLAN tag is inserted after the RTL tag
|
|
// See here for the RTL tag: https://github.com/torvalds/linux/commit/1521d5adfc2b557e15f97283c8b7ad688c3ebc40
|
|
struct rtl_tag {
|
|
uint16_t tag; // This is 0x8899 for the RTL837X
|
|
uint8_t version; // Version is 4
|
|
uint8_t reason;
|
|
uint16_t flags;
|
|
uint16_t pmask; // A bit mask for a TX pkt, 4-bit port-number for RX
|
|
};
|
|
|
|
struct vlan_tag {
|
|
uint16_t svlan; // Service VLAN
|
|
uint16_t vlan;
|
|
};
|
|
|
|
#define RTL_TAG_SIZE (sizeof (struct rtl_tag))
|
|
#define VLAN_TAG_SIZE (sizeof (struct vlan_tag))
|
|
#define RTL_FRAME_TAG_ID 0x8899
|
|
#define RTL_FRAME_TAG_VERSION 0x04
|
|
|
|
// For TX, an 8 byte (plus 4 byte padding when when VLAN is enabled)
|
|
// header describing the frame to be moved to the Asic is used
|
|
#define RTL_FRAME_DESC_SIZE 12
|
|
|
|
// This is the standard size of an Ethernet frame header
|
|
#define ETHER_HEADER_SIZE 14
|
|
|
|
#define DEFAULT_CONFIG_START 0x6f000
|
|
#define CONFIG_START 0x70000
|
|
#define CONFIG_LEN 0x1000
|
|
#define CODE0_SIZE 0x4000
|
|
#define CODE_BANK_SIZE 0xc000
|
|
|
|
// Store update image after running image
|
|
#define FIRMWARE_UPLOAD_START 0x80000
|
|
|
|
// Constants for the circular command buffer, the size must be 2^n
|
|
#define CMD_HISTORY_SIZE 0x400
|
|
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
|
|
|
enum sfp_speeds {
|
|
SFP_SPEED_AUTO = 0,
|
|
SFP_SPEED_100M,
|
|
SFP_SPEED_1G,
|
|
SFP_SPEED_2G5,
|
|
SFP_SPEED_5G,
|
|
SFP_SPEED_10G
|
|
};
|
|
|
|
/**
|
|
* Representation of a 48-bit Ethernet address.
|
|
*/
|
|
struct uip_eth_addr {
|
|
uint8_t addr[6];
|
|
};
|
|
|
|
struct flash_region_t {
|
|
uint32_t addr;
|
|
uint16_t len;
|
|
};
|
|
|
|
extern __xdata char port_names[9][PORT_NAME_SIZE];
|
|
|
|
/* System hostname (device identity). Set via `hostname <text>` and the System
|
|
* Settings page, reported in /information.json. Other modules (e.g. LLDP, which
|
|
* advertises it as the System Name TLV) read it from here. */
|
|
extern __xdata char hostname[24];
|
|
|
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
|
extern __xdata struct uip_eth_addr uip_ethaddr;
|
|
|
|
// Headers for calls in the common code area (HOME/BANK0)
|
|
void print_string_no_syslog(__code char *p);
|
|
void print_string(__code char *p);
|
|
void print_string_x(__xdata char *p);
|
|
void print_long(uint32_t a);
|
|
void print_short(uint16_t a);
|
|
void print_byte(uint8_t a);
|
|
void itoa(uint8_t v);
|
|
void print_sfr_data(void);
|
|
void print_phy_data(void);
|
|
void print_cmd_prompt(void);
|
|
void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v);
|
|
void phy_write(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t v);
|
|
void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg);
|
|
void phy_modify(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t mask, uint16_t set);
|
|
void reg_read(uint16_t reg_addr);
|
|
void reg_read_m(uint16_t reg_addr);
|
|
void reg_write(uint16_t reg_addr);
|
|
void reg_write_m(uint16_t reg_addr);
|
|
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
|
|
void sds_write_v(uint8_t sds_id, uint8_t page, uint8_t reg, uint16_t v);
|
|
void delay(uint16_t t);
|
|
void sleep(uint16_t t);
|
|
void write_char_no_syslog(char c);
|
|
void write_char(char c);
|
|
void print_reg(uint16_t reg);
|
|
bool sfp_read_block(uint8_t slot, uint8_t reg, uint8_t len) __banked __reentrant;
|
|
extern __xdata uint8_t sfp_buf[16];
|
|
void reg_bit_set(uint16_t reg_addr, char bit);
|
|
void reg_bit_clear(uint16_t reg_addr, char bit);
|
|
uint8_t reg_bit_test(uint16_t reg_addr, char bit);
|
|
void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set);
|
|
void sfr_set_zero(void);
|
|
void reset_chip(void);
|
|
void memcpy(__xdata void * __xdata dst, __xdata const void * __xdata src, uint16_t len);
|
|
void memcpyc(register __xdata uint8_t *dst, register __code uint8_t *src, register uint16_t len);
|
|
void memset(register __xdata uint8_t *dst, register __xdata uint8_t v, register uint8_t len);
|
|
uint16_t strlen(register __code const char *s);
|
|
uint16_t strlen_x(register __xdata const char *s);
|
|
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
|
uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
|
|
char strcmp(register __xdata const uint8_t *a, register __code const uint8_t *b);
|
|
void tcpip_output(void);
|
|
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
|
void get_random_32(void);
|
|
void read_reg_timer(__xdata uint32_t * tmr);
|
|
bool sfp_print_info(uint8_t sfp);
|
|
bool gpio_pin_test(uint8_t pin);
|
|
void set_sys_led_state(uint8_t state);
|
|
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
|
|
void sds_write_v(uint8_t sds_id, uint8_t page, uint8_t reg, uint16_t v);
|
|
void sds_config_mac(uint8_t sds, uint8_t mode);
|
|
void sds_config(uint8_t sds, uint8_t mode);
|
|
void handle_sfp(void);
|
|
#endif
|