Commit 39803243 authored by Lucas Russo's avatar Lucas Russo

emb-sw/*: ethmac now uses dynamic address from SDB

parent f2f7be9d
......@@ -9,197 +9,195 @@
#define SDB_EMPTY 0xFF
typedef struct pair64 {
uint32_t high;
uint32_t low;
uint32_t high;
uint32_t low;
} pair64_t;
struct sdb_empty {
int8_t reserved[63];
uint8_t record_type;
int8_t reserved[63];
uint8_t record_type;
};
struct sdb_product {
pair64_t vendor_id;
uint32_t device_id;
uint32_t version;
uint32_t date;
int8_t name[19];
uint8_t record_type;
pair64_t vendor_id;
uint32_t device_id;
uint32_t version;
uint32_t date;
int8_t name[19];
uint8_t record_type;
};
struct sdb_component {
pair64_t addr_first;
pair64_t addr_last;
struct sdb_product product;
pair64_t addr_first;
pair64_t addr_last;
struct sdb_product product;
};
struct sdb_device {
uint16_t abi_class;
uint8_t abi_ver_major;
uint8_t abi_ver_minor;
uint32_t bus_specific;
struct sdb_component sdb_component;
uint16_t abi_class;
uint8_t abi_ver_major;
uint8_t abi_ver_minor;
uint32_t bus_specific;
struct sdb_component sdb_component;
};
struct sdb_bridge {
pair64_t sdb_child;
struct sdb_component sdb_component;
pair64_t sdb_child;
struct sdb_component sdb_component;
};
struct sdb_interconnect {
uint32_t sdb_magic;
uint16_t sdb_records;
uint8_t sdb_version;
uint8_t sdb_bus_type;
struct sdb_component sdb_component;
uint32_t sdb_magic;
uint16_t sdb_records;
uint8_t sdb_version;
uint8_t sdb_bus_type;
struct sdb_component sdb_component;
};
typedef union sdb_record {
struct sdb_empty empty;
struct sdb_device device;
struct sdb_bridge bridge;
struct sdb_interconnect interconnect;
struct sdb_empty empty;
struct sdb_device device;
struct sdb_bridge bridge;
struct sdb_interconnect interconnect;
} sdb_record_t;
static unsigned char *find_device_deep(unsigned int base, unsigned int sdb,
unsigned int devid)
unsigned int devid)
{
sdb_record_t *record = (sdb_record_t *) sdb;
int records = record->interconnect.sdb_records;
int i;
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE) {
unsigned char *out =
find_device_deep(base +
record->bridge.sdb_component.
addr_first.low,
record->bridge.sdb_child.low,
devid);
if (out)
return out;
}
if (record->empty.record_type == SDB_DEVICE &&
record->device.sdb_component.product.device_id == devid) {
break;
}
}
if (i == records)
return 0;
return (unsigned char *)(base +
record->device.sdb_component.addr_first.low);
sdb_record_t *record = (sdb_record_t *) sdb;
int records = record->interconnect.sdb_records;
int i;
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE) {
unsigned char *out =
find_device_deep(base +
record->bridge.sdb_component.
addr_first.low,
record->bridge.sdb_child.low,
devid);
if (out)
return out;
}
if (record->empty.record_type == SDB_DEVICE &&
record->device.sdb_component.product.device_id == devid) {
break;
}
}
if (i == records)
return 0;
return (unsigned char *)(base +
record->device.sdb_component.addr_first.low);
}
static void find_device_deep_all_rec(struct dev_node **dev, unsigned int *size,
unsigned int base, unsigned int sdb, unsigned int devid)
unsigned int base, unsigned int sdb, unsigned int devid)
{
sdb_record_t *record = (sdb_record_t *) sdb;
int records = record->interconnect.sdb_records;
int i;
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE) {
find_device_deep_all_rec(dev, size, base +
record->bridge.sdb_component.addr_first.low,
record->bridge.sdb_child.low,
devid);
}
if (record->empty.record_type == SDB_DEVICE &&
record->device.sdb_component.product.device_id == devid) {
// Alloc new node device
*dev = (struct dev_node *)memmgr_alloc(sizeof(struct dev_node));
(*dev)->base = (unsigned char *)(base +
record->device.sdb_component.addr_first.low);
// Ensure a null pointer on end of list
(*dev)->next = 0;
// Pass new node address
dev = &(*dev)->next;
(*size)++;
}
}
sdb_record_t *record = (sdb_record_t *) sdb;
int records = record->interconnect.sdb_records;
int i;
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE) {
find_device_deep_all_rec(dev, size, base +
record->bridge.sdb_component.addr_first.low,
record->bridge.sdb_child.low,
devid);
}
if (record->empty.record_type == SDB_DEVICE &&
record->device.sdb_component.product.device_id == devid) {
// Alloc new node device
*dev = (struct dev_node *)memmgr_alloc(sizeof(struct dev_node));
(*dev)->base = (unsigned char *)(base +
record->device.sdb_component.addr_first.low);
// Ensure a null pointer on end of list
(*dev)->next = 0;
// Pass new node address
dev = &(*dev)->next;
(*size)++;
}
}
}
static struct dev_list *find_device_deep_all(unsigned int base, unsigned int sdb,
unsigned int devid)
unsigned int devid)
{
// Device structure list
struct dev_list *dev = (struct dev_list *)memmgr_alloc(sizeof(struct dev_list));
// Device structure list
struct dev_list *dev = (struct dev_list *)memmgr_alloc(sizeof(struct dev_list));
// Initialize structure
dev->devid = devid;
dev->size = 0;
dev->devices = 0;
// Initialize structure
dev->devid = devid;
dev->size = 0;
dev->devices = 0;
// Fill device list with the appropriate nodes
find_device_deep_all_rec(&(dev->devices), &(dev->size), base, sdb, devid);
// Fill device list with the appropriate nodes
find_device_deep_all_rec(&(dev->devices), &(dev->size), base, sdb, devid);
return dev;
return dev;
}
static void print_devices_deep(unsigned int base, unsigned int sdb)
{
sdb_record_t *record = (sdb_record_t *) sdb;
int records = record->interconnect.sdb_records;
int i;
char buf[20];
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE)
print_devices_deep(base +
record->bridge.sdb_component.
addr_first.low,
record->bridge.sdb_child.low);
if (record->empty.record_type != SDB_DEVICE)
continue;
memcpy(buf, record->device.sdb_component.product.name, 19);
buf[19] = 0;
pp_printf("%8x:%8x 0x%8x %s\n",
record->device.sdb_component.product.vendor_id.low,
record->device.sdb_component.product.device_id,
base + record->device.sdb_component.addr_first.low,
buf);
}
sdb_record_t *record = (sdb_record_t *) sdb;
int records = record->interconnect.sdb_records;
int i;
char buf[20];
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE)
print_devices_deep(base +
record->bridge.sdb_component.
addr_first.low,
record->bridge.sdb_child.low);
if (record->empty.record_type != SDB_DEVICE)
continue;
memcpy(buf, record->device.sdb_component.product.name, 19);
buf[19] = 0;
pp_printf("%8x:%8x 0x%8x %s\n",
record->device.sdb_component.product.vendor_id.low,
record->device.sdb_component.product.device_id,
base + record->device.sdb_component.addr_first.low,
buf);
}
}
static unsigned char *find_device(unsigned int devid)
{
return find_device_deep(0, SDB_ADDRESS, devid);
return find_device_deep(0, SDB_ADDRESS, devid);
}
static struct dev_list *find_device_all(unsigned int devid)
{
return find_device_deep_all(0, SDB_ADDRESS, devid);
return find_device_deep_all(0, SDB_ADDRESS, devid);
}
void sdb_print_devices(void)
{
pp_printf("-------------------------------------------\n");
pp_printf("| SDB memory map |\n");
pp_printf("-------------------------------------------\n\n");
print_devices_deep(0, SDB_ADDRESS);
pp_printf("-------------------------------------------\n");
pp_printf("| SDB memory map |\n");
pp_printf("-------------------------------------------\n\n");
print_devices_deep(0, SDB_ADDRESS);
}
void sdb_find_devices(void)
{
// Enumerate devices
// get the second device form this list. Just for testing! with the etherbone
// core
mem_devl = find_device_all(0x66cfeb52);
dma_devl = find_device_all(0xcababa56);
ethmac_devl = find_device_all(0xf8cfeb16);
ethmac_adapt_devl = find_device_all(0x2ff9a28e);
ebone_cfg_devl = find_device_all(0x68202b22);
fmc516_devl = find_device_all(0x27b95341);
spi_devl = find_device_all(0x40286417);
i2c_devl = find_device_all(0x97b6323d);
owr_devl = find_device_all(0x525fbb09);
uart_devl = find_device_all(0x8a5719ae);
gpio_devl = find_device_all(0x35aa6b95);
tics_devl = find_device_all(0xfdafb9dd);
// Enumerate devices
mem_devl = find_device_all(0x66cfeb52);
dma_devl = find_device_all(0xcababa56);
ethmac_devl = find_device_all(0xf8cfeb16);
ethmac_adapt_devl = find_device_all(0x2ff9a28e);
ebone_cfg_devl = find_device_all(0x68202b22);
fmc516_devl = find_device_all(0x27b95341);
spi_devl = find_device_all(0x40286417);
i2c_devl = find_device_all(0x97b6323d);
owr_devl = find_device_all(0x525fbb09);
uart_devl = find_device_all(0x8a5719ae);
gpio_devl = find_device_all(0x35aa6b95);
tics_devl = find_device_all(0xfdafb9dd);
}
This diff is collapsed.
......@@ -45,44 +45,53 @@ typedef unsigned int uint;
/* Ethernet configuration registers */
typedef struct _oeth_regs {
uint moder; /* Mode Register */
uint int_src; /* Interrupt Source Register */
uint int_mask; /* Interrupt Mask Register */
uint ipgt; /* Back to Bak Inter Packet Gap Register */
uint ipgr1; /* Non Back to Back Inter Packet Gap Register 1 */
uint ipgr2; /* Non Back to Back Inter Packet Gap Register 2 */
uint packet_len; /* Packet Length Register (min. and max.) */
uint collconf; /* Collision and Retry Configuration Register */
uint tx_bd_num; /* Transmit Buffer Descriptor Number Register */
uint ctrlmoder; /* Control Module Mode Register */
uint miimoder; /* MII Mode Register */
uint miicommand; /* MII Command Register */
uint miiaddress; /* MII Address Register */
uint miitx_data; /* MII Transmit Data Register */
uint miirx_data; /* MII Receive Data Register */
uint miistatus; /* MII Status Register */
uint mac_addr0; /* MAC Individual Address Register 0 */
uint mac_addr1; /* MAC Individual Address Register 1 */
uint hash_addr0; /* Hash Register 0 */
uint hash_addr1; /* Hash Register 1 */
uint moder; /* Mode Register */
uint int_src; /* Interrupt Source Register */
uint int_mask; /* Interrupt Mask Register */
uint ipgt; /* Back to Bak Inter Packet Gap Register */
uint ipgr1; /* Non Back to Back Inter Packet Gap Register 1 */
uint ipgr2; /* Non Back to Back Inter Packet Gap Register 2 */
uint packet_len; /* Packet Length Register (min. and max.) */
uint collconf; /* Collision and Retry Configuration Register */
uint tx_bd_num; /* Transmit Buffer Descriptor Number Register */
uint ctrlmoder; /* Control Module Mode Register */
uint miimoder; /* MII Mode Register */
uint miicommand; /* MII Command Register */
uint miiaddress; /* MII Address Register */
uint miitx_data; /* MII Transmit Data Register */
uint miirx_data; /* MII Receive Data Register */
uint miistatus; /* MII Status Register */
uint mac_addr0; /* MAC Individual Address Register 0 */
uint mac_addr1; /* MAC Individual Address Register 1 */
uint hash_addr0; /* Hash Register 0 */
uint hash_addr1; /* Hash Register 1 */
} oeth_regs;
/* Ethernet buffer descriptor */
typedef struct _oeth_bd {
#if 0
ushort len; /* Buffer length */
ushort status; /* Buffer status */
ushort len; /* Buffer length */
ushort status; /* Buffer status */
#else
uint len_status;
uint len_status;
#endif
uint addr; /* Buffer address */
uint addr; /* Buffer address */
} oeth_bd;
typedef volatile oeth_regs ethmac_t;
typedef volatile oeth_bd ethmac_bd_t;
typedef volatile unsigned long ethmac_buf_t;
//Just one device supported
#define OETH_ID 0
#define OETH_BUF_ID 0
// From board.h
#define ETH_BASE_ADD ETH0_BASE
//#define ETH_BASE_ADD ETH0_BASE
#define OETH_REG_BASE ETH_BASE_ADD
#define OETH_BD_BASE (ETH_BASE_ADD + 0x400)
//#define OETH_REG_BASE ETH_BASE_ADD
//#define OETH_BD_BASE (ETH_BASE_ADD + 0x400)
#define OETH_BD_BASE_OFFS 0x400
#define OETH_TOTAL_BD 128
#define OETH_MAXBUF_LEN 0x600
......@@ -100,11 +109,11 @@ typedef struct _oeth_bd {
#define OETH_TX_BD_DEFER 0x0002 /* Tx BD Defer Status */
#define OETH_TX_BD_CARRIER 0x0001 /* Tx BD Carrier Sense Lost Status */
#define OETH_TX_BD_STATS (OETH_TX_BD_UNDERRUN | \
OETH_TX_BD_RETRY | \
OETH_TX_BD_RETLIM | \
OETH_TX_BD_LATECOL | \
OETH_TX_BD_DEFER | \
OETH_TX_BD_CARRIER)
OETH_TX_BD_RETRY | \
OETH_TX_BD_RETLIM | \
OETH_TX_BD_LATECOL | \
OETH_TX_BD_DEFER | \
OETH_TX_BD_CARRIER)
/* Rx BD */
#define OETH_RX_BD_EMPTY 0x8000 /* Rx BD Empty */
......@@ -120,13 +129,13 @@ typedef struct _oeth_bd {
#define OETH_RX_BD_CRCERR 0x0002 /* Rx BD CRC Error Status */
#define OETH_RX_BD_LATECOL 0x0001 /* Rx BD Late Collision Status */
#define OETH_RX_BD_STATS (OETH_RX_BD_MISS | \
OETH_RX_BD_OVERRUN | \
OETH_RX_BD_INVSIMB | \
OETH_RX_BD_DRIBBLE | \
OETH_RX_BD_TOOLONG | \
OETH_RX_BD_SHORT | \
OETH_RX_BD_CRCERR | \
OETH_RX_BD_LATECOL)
OETH_RX_BD_OVERRUN | \
OETH_RX_BD_INVSIMB | \
OETH_RX_BD_DRIBBLE | \
OETH_RX_BD_TOOLONG | \
OETH_RX_BD_SHORT | \
OETH_RX_BD_CRCERR | \
OETH_RX_BD_LATECOL)
/* MODER Register */
#define OETH_MODER_RXEN 0x00000001 /* Receive Enable */
......@@ -191,7 +200,8 @@ typedef struct _oeth_bd {
void eth_mii_write(char phynum, short regnum, short data);
short eth_mii_read(char phynum, short regnum);
void ethmac_setup(int phynum, unsigned int buf);
//void ethmac_setup(int phynum, unsigned int buf);
void ethmac_setup(int phynum);
void ethmac_halt(void);
void oeth_interrupt(void* arg);
void tx_packet(void* data, int length);
......@@ -199,6 +209,6 @@ void tx_packet(void* data, int length);
void user_recv(unsigned char* data, int length);
/* ETHMAC init */
//int ethmac_init(void);
int ethmac_init(void);
#endif
OBJS_LIB += lib/ethmac/ethmac.o lib/ethmac/ethmac-int.o
OBJS_LIB += lib/ethmac/ethmac.o
#lib/ethmac/ethmac-int.o
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment