enet: Map device registers
This commit is contained in:
parent
9edba91b34
commit
6a2b1f61bf
@ -5,6 +5,7 @@
|
|||||||
bootdriver /armv8/sbin/boot_armv8_generic
|
bootdriver /armv8/sbin/boot_armv8_generic
|
||||||
cpudriver /armv8/sbin/cpu_imx8x
|
cpudriver /armv8/sbin/cpu_imx8x
|
||||||
module /armv8/sbin/init
|
module /armv8/sbin/init
|
||||||
|
module /armv8/sbin/enet
|
||||||
module /armv8/sbin/hello echoclient
|
module /armv8/sbin/hello echoclient
|
||||||
module /armv8/sbin/memeater
|
module /armv8/sbin/memeater
|
||||||
module /armv8/sbin/mallocator
|
module /armv8/sbin/mallocator
|
||||||
|
|||||||
@ -99,7 +99,7 @@ static inline bool capref_is_null(struct capref capref)
|
|||||||
|
|
||||||
/* well-known cnodes */
|
/* well-known cnodes */
|
||||||
extern struct cnoderef cnode_root, cnode_task, cnode_base, cnode_super,
|
extern struct cnoderef cnode_root, cnode_task, cnode_base, cnode_super,
|
||||||
cnode_page, cnode_module;
|
cnode_page, cnode_module, cnode_arg;
|
||||||
|
|
||||||
/* well-known capabilities */
|
/* well-known capabilities */
|
||||||
extern struct capref cap_root, cap_monitorep, cap_irq, cap_io, cap_dispatcher,
|
extern struct capref cap_root, cap_monitorep, cap_irq, cap_io, cap_dispatcher,
|
||||||
|
|||||||
@ -126,6 +126,7 @@
|
|||||||
#define CPTR_PHYADDRCN_BASE ROOTCN_SLOT_ADDR(ROOTCN_SLOT_PACN)
|
#define CPTR_PHYADDRCN_BASE ROOTCN_SLOT_ADDR(ROOTCN_SLOT_PACN)
|
||||||
#define CPTR_MODULECN_BASE ROOTCN_SLOT_ADDR(ROOTCN_SLOT_MODULECN)
|
#define CPTR_MODULECN_BASE ROOTCN_SLOT_ADDR(ROOTCN_SLOT_MODULECN)
|
||||||
#define CPTR_PAGECN_BASE ROOTCN_SLOT_ADDR(ROOTCN_SLOT_PAGECN)
|
#define CPTR_PAGECN_BASE ROOTCN_SLOT_ADDR(ROOTCN_SLOT_PAGECN)
|
||||||
|
#define CPTR_ARGCN_BASE ROOTCN_SLOT_ADDR(ROOTCN_SLOT_ARGCN)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory region types.
|
* Memory region types.
|
||||||
|
|||||||
@ -43,6 +43,7 @@ struct spawninfo {
|
|||||||
struct cnoderef cspace_l2_cnode_slot_alloc_2; // < A third L2 Node for the slot allocator to use.
|
struct cnoderef cspace_l2_cnode_slot_alloc_2; // < A third L2 Node for the slot allocator to use.
|
||||||
struct cnoderef cspace_l2_cnode_base_pagecn; // < Each slot holds a BASE_PAGE_SIZEd RAM capability.
|
struct cnoderef cspace_l2_cnode_base_pagecn; // < Each slot holds a BASE_PAGE_SIZEd RAM capability.
|
||||||
struct cnoderef cspace_l2_cnode_pagecn; // < Contains capabilites to the pagetable
|
struct cnoderef cspace_l2_cnode_pagecn; // < Contains capabilites to the pagetable
|
||||||
|
struct cnoderef cspace_l2_cnode_argcn; // < Contains argument capabilites
|
||||||
|
|
||||||
// these capabilites are all stored in the taskcn cnode
|
// these capabilites are all stored in the taskcn cnode
|
||||||
struct capref cspace_cap_selfep; // < Endpoint to itself. You can get this capability by retyping the dispatcher capability to ObjType_EndPointLMP.
|
struct capref cspace_cap_selfep; // < Endpoint to itself. You can get this capability by retyping the dispatcher capability to ObjType_EndPointLMP.
|
||||||
|
|||||||
@ -45,6 +45,11 @@ struct cnoderef cnode_root = ROOT_CNODE_INIT;
|
|||||||
.cnode = CPTR_MODULECN_BASE, \
|
.cnode = CPTR_MODULECN_BASE, \
|
||||||
.level = CNODE_TYPE_OTHER, }
|
.level = CNODE_TYPE_OTHER, }
|
||||||
|
|
||||||
|
#define ARG_CNODE_INIT { \
|
||||||
|
.croot = CPTR_ROOTCN, \
|
||||||
|
.cnode = CPTR_ARGCN_BASE, \
|
||||||
|
.level = CNODE_TYPE_OTHER, }
|
||||||
|
|
||||||
/// Task CNode
|
/// Task CNode
|
||||||
struct cnoderef cnode_task = TASK_CNODE_INIT;
|
struct cnoderef cnode_task = TASK_CNODE_INIT;
|
||||||
|
|
||||||
@ -68,6 +73,9 @@ struct cnoderef cnode_page = PAGE_CNODE_INIT;
|
|||||||
/// Module CNode
|
/// Module CNode
|
||||||
struct cnoderef cnode_module = MODULE_CNODE_INIT;
|
struct cnoderef cnode_module = MODULE_CNODE_INIT;
|
||||||
|
|
||||||
|
/// Arg CNode
|
||||||
|
struct cnoderef cnode_arg = ARG_CNODE_INIT;
|
||||||
|
|
||||||
struct capref cap_mmstrings = {
|
struct capref cap_mmstrings = {
|
||||||
.cnode = MODULE_CNODE_INIT,
|
.cnode = MODULE_CNODE_INIT,
|
||||||
.slot = 0
|
.slot = 0
|
||||||
@ -85,6 +93,12 @@ struct capref cap_irq = {
|
|||||||
.slot = TASKCN_SLOT_IRQ
|
.slot = TASKCN_SLOT_IRQ
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Capability for Device Frame
|
||||||
|
struct capref cap_io = {
|
||||||
|
.cnode = TASK_CNODE_INIT,
|
||||||
|
.slot = TASKCN_SLOT_DEV
|
||||||
|
};
|
||||||
|
|
||||||
/// Capability for endpoint to self
|
/// Capability for endpoint to self
|
||||||
struct capref cap_selfep = {
|
struct capref cap_selfep = {
|
||||||
.cnode = TASK_CNODE_INIT,
|
.cnode = TASK_CNODE_INIT,
|
||||||
@ -724,14 +738,14 @@ errval_t frame_create(struct capref dest, size_t bytes, size_t *retbytes)
|
|||||||
/**
|
/**
|
||||||
* \brief Create a dispatcher capability and store it in the slot pointed to
|
* \brief Create a dispatcher capability and store it in the slot pointed to
|
||||||
* by 'dest'
|
* by 'dest'
|
||||||
*
|
*
|
||||||
* This function requires that dest refers to an existing but empty slot. It
|
* This function requires that dest refers to an existing but empty slot. It
|
||||||
* allocates a new RAM cap, retypes it to one of type ObjType_Dispatcher and
|
* allocates a new RAM cap, retypes it to one of type ObjType_Dispatcher and
|
||||||
* stores it at the slot pointed to by the capref struct 'dest'. The intermediate
|
* stores it at the slot pointed to by the capref struct 'dest'. The intermediate
|
||||||
* ram cap is then destroyed.
|
* ram cap is then destroyed.
|
||||||
*
|
*
|
||||||
* \param dest location to place new dispatcher cap
|
* \param dest location to place new dispatcher cap
|
||||||
*
|
*
|
||||||
* \return Either SYS_ERR_OK if no error occured or an error
|
* \return Either SYS_ERR_OK if no error occured or an error
|
||||||
* indicating what went wrong otherwise.
|
* indicating what went wrong otherwise.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
#include <spawn/multiboot.h>
|
#include <spawn/multiboot.h>
|
||||||
#include <spawn/argv.h>
|
#include <spawn/argv.h>
|
||||||
|
|
||||||
|
#include <maps/imx8x_map.h>
|
||||||
|
|
||||||
extern struct bootinfo *bi;
|
extern struct bootinfo *bi;
|
||||||
extern coreid_t my_core_id;
|
extern coreid_t my_core_id;
|
||||||
extern struct aos_urpc urpc_to_bsp;
|
extern struct aos_urpc urpc_to_bsp;
|
||||||
@ -500,6 +502,26 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
||||||
si->init_chan.remote_cap = NULL_CAP;
|
si->init_chan.remote_cap = NULL_CAP;
|
||||||
|
|
||||||
|
// Set up capability arguments. This would ideally be passed somehow as an argument to spawn instead.
|
||||||
|
size_t arg0_base = 0;
|
||||||
|
size_t arg0_size = 0;
|
||||||
|
if (strcmp(argv[0], "enet") == 0) {
|
||||||
|
arg0_base = IMX8X_ENET_BASE;
|
||||||
|
arg0_size = IMX8X_ENET_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
si->cspace_l2_cnode_argcn = NULL_CNODE;
|
||||||
|
if (arg0_base != 0) {
|
||||||
|
err = cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_ARGCN, &si->cspace_l2_cnode_argcn);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
struct capref arg0_cap = {
|
||||||
|
.cnode = si->cspace_l2_cnode_argcn,
|
||||||
|
.slot = 0
|
||||||
|
};
|
||||||
|
err = cap_retype(arg0_cap, cap_io, (arg0_base - IMX8X_START_DEV_RANGE), ObjType_DevFrame, arg0_size, 1);
|
||||||
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_RETYPE);
|
||||||
|
}
|
||||||
|
|
||||||
// - Setup the child's vspace
|
// - Setup the child's vspace
|
||||||
// afeer: create level 0 page table
|
// afeer: create level 0 page table
|
||||||
// the l0 page table is in the first slot (PAGECN_SLOT_VROOT) of the pagecn cnode.
|
// the l0 page table is in the first slot (PAGECN_SLOT_VROOT) of the pagecn cnode.
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
-- Default list of modules to build/install
|
-- Default list of modules to build/install
|
||||||
modules_common = [ "/sbin/" ++ f | f <- [ "init", "hello", "memeater", "mallocator", "stackoverflow", "echoserver"
|
modules_common = [ "/sbin/" ++ f | f <- [ "init", "hello", "memeater", "mallocator", "stackoverflow", "echoserver", "enet"
|
||||||
] ]
|
] ]
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include <aos/deferred.h>
|
#include <aos/deferred.h>
|
||||||
#include <driverkit/driverkit.h>
|
#include <driverkit/driverkit.h>
|
||||||
#include <dev/imx8x/enet_dev.h>
|
#include <dev/imx8x/enet_dev.h>
|
||||||
|
#include <maps/imx8x_map.h>
|
||||||
#include <netutil/etharp.h>
|
#include <netutil/etharp.h>
|
||||||
|
|
||||||
|
|
||||||
@ -32,19 +33,19 @@
|
|||||||
static errval_t enet_write_mdio(struct enet_driver_state* st, int8_t phyaddr,
|
static errval_t enet_write_mdio(struct enet_driver_state* st, int8_t phyaddr,
|
||||||
int8_t regaddr, int16_t data)
|
int8_t regaddr, int16_t data)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Some protocol ...
|
// Some protocol ...
|
||||||
|
|
||||||
enet_mmfr_t reg = 0;
|
enet_mmfr_t reg = 0;
|
||||||
reg = enet_mmfr_pa_insert(reg, phyaddr);
|
reg = enet_mmfr_pa_insert(reg, phyaddr);
|
||||||
reg = enet_mmfr_ra_insert(reg, regaddr);
|
reg = enet_mmfr_ra_insert(reg, regaddr);
|
||||||
reg = enet_mmfr_data_insert(reg, data);
|
reg = enet_mmfr_data_insert(reg, data);
|
||||||
reg = enet_mmfr_st_insert(reg, 0x1);
|
reg = enet_mmfr_st_insert(reg, 0x1);
|
||||||
reg = enet_mmfr_ta_insert(reg, 0x2);
|
reg = enet_mmfr_ta_insert(reg, 0x2);
|
||||||
|
|
||||||
// 1 is write 2 is read
|
// 1 is write 2 is read
|
||||||
reg = enet_mmfr_op_insert(reg, 0x1);
|
reg = enet_mmfr_op_insert(reg, 0x1);
|
||||||
|
|
||||||
ENET_DEBUG("Write MDIO: write cmd %lx \n", reg);
|
ENET_DEBUG("Write MDIO: write cmd %lx \n", reg);
|
||||||
|
|
||||||
enet_mmfr_wr(st->d, reg);
|
enet_mmfr_wr(st->d, reg);
|
||||||
@ -57,7 +58,7 @@ static errval_t enet_write_mdio(struct enet_driver_state* st, int8_t phyaddr,
|
|||||||
return ENET_ERR_MDIO_WRITE;
|
return ENET_ERR_MDIO_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_eir_mii_wrf(st->d, 0x1);
|
enet_eir_mii_wrf(st->d, 0x1);
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
@ -65,20 +66,20 @@ static errval_t enet_write_mdio(struct enet_driver_state* st, int8_t phyaddr,
|
|||||||
static errval_t enet_read_mdio(struct enet_driver_state* st, int8_t phyaddr,
|
static errval_t enet_read_mdio(struct enet_driver_state* st, int8_t phyaddr,
|
||||||
int8_t regaddr, int16_t *data)
|
int8_t regaddr, int16_t *data)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Some protocol ...
|
// Some protocol ...
|
||||||
enet_eir_mii_wrf(st->d, 0x1);
|
enet_eir_mii_wrf(st->d, 0x1);
|
||||||
|
|
||||||
enet_mmfr_t reg = 0;
|
enet_mmfr_t reg = 0;
|
||||||
reg = enet_mmfr_pa_insert(reg, phyaddr);
|
reg = enet_mmfr_pa_insert(reg, phyaddr);
|
||||||
reg = enet_mmfr_ra_insert(reg, regaddr);
|
reg = enet_mmfr_ra_insert(reg, regaddr);
|
||||||
reg = enet_mmfr_st_insert(reg, 0x1);
|
reg = enet_mmfr_st_insert(reg, 0x1);
|
||||||
reg = enet_mmfr_ta_insert(reg, 0x2);
|
reg = enet_mmfr_ta_insert(reg, 0x2);
|
||||||
// 1 is write 2 is read
|
// 1 is write 2 is read
|
||||||
reg = enet_mmfr_op_insert(reg, 0x2);
|
reg = enet_mmfr_op_insert(reg, 0x2);
|
||||||
|
|
||||||
enet_mmfr_wr(st->d, reg);
|
enet_mmfr_wr(st->d, reg);
|
||||||
|
|
||||||
ENET_DEBUG("Read MDIO: read cmd %lx \n", reg);
|
ENET_DEBUG("Read MDIO: read cmd %lx \n", reg);
|
||||||
|
|
||||||
uint16_t tries = 1000;
|
uint16_t tries = 1000;
|
||||||
@ -89,34 +90,34 @@ static errval_t enet_read_mdio(struct enet_driver_state* st, int8_t phyaddr,
|
|||||||
return ENET_ERR_MDIO_WRITE;
|
return ENET_ERR_MDIO_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_eir_mii_wrf(st->d, 0x1);
|
enet_eir_mii_wrf(st->d, 0x1);
|
||||||
*data = enet_mmfr_data_rdf(st->d);
|
*data = enet_mmfr_data_rdf(st->d);
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static errval_t enet_get_phy_id(struct enet_driver_state* st)
|
static errval_t enet_get_phy_id(struct enet_driver_state* st)
|
||||||
{
|
{
|
||||||
errval_t err;
|
errval_t err;
|
||||||
int16_t data;
|
int16_t data;
|
||||||
uint32_t phy_id;
|
uint32_t phy_id;
|
||||||
|
|
||||||
// get phy ID1
|
// get phy ID1
|
||||||
err = enet_read_mdio(st, PHY_ID, 0x2, &data);
|
err = enet_read_mdio(st, PHY_ID, 0x2, &data);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
phy_id = data << 16;
|
phy_id = data << 16;
|
||||||
|
|
||||||
// get phy ID2
|
// get phy ID2
|
||||||
err = enet_read_mdio(st, PHY_ID, 0x3, &data);
|
err = enet_read_mdio(st, PHY_ID, 0x3, &data);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_id |= data;
|
phy_id |= data;
|
||||||
st->phy_id = phy_id;
|
st->phy_id = phy_id;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,21 +136,21 @@ static errval_t enet_reset_phy(struct enet_driver_state* st)
|
|||||||
err = enet_write_mdio(st, PHY_ID, PHY_RESET_CMD, PHY_RESET);
|
err = enet_write_mdio(st, PHY_ID, PHY_RESET_CMD, PHY_RESET);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t data;
|
int16_t data;
|
||||||
err = enet_read_mdio(st, PHY_ID, PHY_RESET_CMD, &data);
|
err = enet_read_mdio(st, PHY_ID, PHY_RESET_CMD, &data);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timeout = 500;
|
int timeout = 500;
|
||||||
while ((data & PHY_RESET) && timeout > 0) {
|
while ((data & PHY_RESET) && timeout > 0) {
|
||||||
err = enet_read_mdio(st, PHY_ID, PHY_RESET_CMD, &data);
|
err = enet_read_mdio(st, PHY_ID, PHY_RESET_CMD, &data);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
barrelfish_usleep(1000);
|
barrelfish_usleep(1000);
|
||||||
timeout--;
|
timeout--;
|
||||||
}
|
}
|
||||||
@ -171,19 +172,19 @@ static errval_t enet_setup_autoneg(struct enet_driver_state* st)
|
|||||||
err = enet_read_mdio(st, PHY_ID, 0x1, &status);
|
err = enet_read_mdio(st, PHY_ID, 0x1, &status);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// READ autoneg status
|
// READ autoneg status
|
||||||
err = enet_read_mdio(st, PHY_ID, PHY_AUTONEG_CMD, &autoneg);
|
err = enet_read_mdio(st, PHY_ID, PHY_AUTONEG_CMD, &autoneg);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read BASIC contorl register
|
// Read BASIC contorl register
|
||||||
err = enet_read_mdio(st, PHY_ID, PHY_RESET_CMD, &status);
|
err = enet_read_mdio(st, PHY_ID, PHY_RESET_CMD, &status);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
@ -207,19 +208,19 @@ static errval_t enet_restart_autoneg(struct enet_driver_state* st)
|
|||||||
barrelfish_usleep(1000);
|
barrelfish_usleep(1000);
|
||||||
//barrelfish_usleep(1000);
|
//barrelfish_usleep(1000);
|
||||||
|
|
||||||
err = enet_write_mdio(st, PHY_ID, PHY_AUTONEG_CMD,
|
err = enet_write_mdio(st, PHY_ID, PHY_AUTONEG_CMD,
|
||||||
AUTONEG_100FULL | AUTONEG_100HALF | AUTONEG_10FULL |
|
AUTONEG_100FULL | AUTONEG_100HALF | AUTONEG_10FULL |
|
||||||
AUTONEG_10HALF | AUTONEG_PSB_802_3);
|
AUTONEG_10HALF | AUTONEG_PSB_802_3);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = enet_write_mdio(st, PHY_ID, PHY_RESET_CMD,
|
err = enet_write_mdio(st, PHY_ID, PHY_RESET_CMD,
|
||||||
AUTONEG_ENABLE | AUTONEG_RESTART);
|
AUTONEG_ENABLE | AUTONEG_RESTART);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,13 +231,13 @@ static errval_t enet_init_phy(struct enet_driver_state* st)
|
|||||||
err = enet_get_phy_id(st);
|
err = enet_get_phy_id(st);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = enet_reset_phy(st);
|
err = enet_reset_phy(st);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// board_phy_config in uboot driver. Don't know what
|
// board_phy_config in uboot driver. Don't know what
|
||||||
// this actually does ...
|
// this actually does ...
|
||||||
err = enet_write_mdio(st, PHY_ID, 0x1d, 0x1f);
|
err = enet_write_mdio(st, PHY_ID, 0x1d, 0x1f);
|
||||||
@ -255,7 +256,7 @@ static errval_t enet_init_phy(struct enet_driver_state* st)
|
|||||||
err = enet_setup_autoneg(st);
|
err = enet_setup_autoneg(st);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
@ -284,21 +285,21 @@ static void enet_parse_link(struct enet_driver_state* st)
|
|||||||
err = enet_read_mdio(st, PHY_ID, PHY_STATUS_CMD, &mii_reg);
|
err = enet_read_mdio(st, PHY_ID, PHY_STATUS_CMD, &mii_reg);
|
||||||
assert(err_is_ok(err));
|
assert(err_is_ok(err));
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
debug_printf("ENET not capable of 1G \n");
|
debug_printf("ENET not capable of 1G \n");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
err = enet_read_mdio(st, PHY_ID, PHY_CTRL1000_CMD, &status);
|
err = enet_read_mdio(st, PHY_ID, PHY_CTRL1000_CMD, &status);
|
||||||
assert(err_is_ok(err));
|
assert(err_is_ok(err));
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
int16_t lpa, lpa2;
|
int16_t lpa, lpa2;
|
||||||
err = enet_read_mdio(st, PHY_ID, PHY_AUTONEG_CMD, &lpa);
|
err = enet_read_mdio(st, PHY_ID, PHY_AUTONEG_CMD, &lpa);
|
||||||
assert(err_is_ok(err));
|
assert(err_is_ok(err));
|
||||||
|
|
||||||
err = enet_read_mdio(st, PHY_ID, PHY_LPA_CMD, &lpa2);
|
err = enet_read_mdio(st, PHY_ID, PHY_LPA_CMD, &lpa2);
|
||||||
assert(err_is_ok(err));
|
assert(err_is_ok(err));
|
||||||
|
|
||||||
lpa &= lpa2;
|
lpa &= lpa2;
|
||||||
if (lpa & (PHY_LPA_100FULL | PHY_LPA_100HALF)) {
|
if (lpa & (PHY_LPA_100FULL | PHY_LPA_100HALF)) {
|
||||||
if (lpa & PHY_LPA_100FULL) {
|
if (lpa & PHY_LPA_100FULL) {
|
||||||
@ -325,7 +326,7 @@ static errval_t enet_phy_startup(struct enet_driver_state* st)
|
|||||||
debug_printf("LINK already UP\n");
|
debug_printf("LINK already UP\n");
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mii_reg & PHY_STATUS_ANEG_COMP)) {
|
if (!(mii_reg & PHY_STATUS_ANEG_COMP)) {
|
||||||
|
|
||||||
debug_printf("[enet] Starting autonegotiation \n");
|
debug_printf("[enet] Starting autonegotiation \n");
|
||||||
@ -334,16 +335,16 @@ static errval_t enet_phy_startup(struct enet_driver_state* st)
|
|||||||
assert(err_is_ok(err));
|
assert(err_is_ok(err));
|
||||||
barrelfish_usleep(1000);
|
barrelfish_usleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENET_DEBUG("Autonegotation done\n");
|
ENET_DEBUG("Autonegotation done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_parse_link(st);
|
enet_parse_link(st);
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool promiscous for promiscous mode.
|
// bool promiscous for promiscous mode.
|
||||||
// This will also set it so that all multicast packets will also be received!
|
// This will also set it so that all multicast packets will also be received!
|
||||||
/*
|
/*
|
||||||
static void enet_init_multicast_filt(struct enet_driver_state* st, bool promisc)
|
static void enet_init_multicast_filt(struct enet_driver_state* st, bool promisc)
|
||||||
@ -354,7 +355,7 @@ static void enet_init_multicast_filt(struct enet_driver_state* st, bool promisc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enet_rcr_prom_wrf(st->d, 0);
|
enet_rcr_prom_wrf(st->d, 0);
|
||||||
|
|
||||||
// TODO Catching all multicast packets for now
|
// TODO Catching all multicast packets for now
|
||||||
enet_gaur_wr(st->d, 0xFFFFFFFF);
|
enet_gaur_wr(st->d, 0xFFFFFFFF);
|
||||||
enet_galr_wr(st->d, 0xFFFFFFFF);
|
enet_galr_wr(st->d, 0xFFFFFFFF);
|
||||||
@ -368,18 +369,18 @@ static void enet_init_multicast_filt(struct enet_driver_state* st, bool promisc)
|
|||||||
unsigned char data = ((uint8_t*) &st->mac)[i];
|
unsigned char data = ((uint8_t*) &st->mac)[i];
|
||||||
|
|
||||||
for (int bit = 0; bit < 8; bit++, data >>= 1) {
|
for (int bit = 0; bit < 8; bit++, data >>= 1) {
|
||||||
crc = (crc >> 1) ^ (((crc ^ data) & 1) ? ENET_CRC32_POLY : 0);
|
crc = (crc >> 1) ^ (((crc ^ data) & 1) ? ENET_CRC32_POLY : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = (crc >> (32 - ENET_HASH_BITS)) & 0x3f;
|
hash = (crc >> (32 - ENET_HASH_BITS)) & 0x3f;
|
||||||
|
|
||||||
if (hash > 31) {
|
if (hash > 31) {
|
||||||
hash_high |= 1 << (hash - 32);
|
hash_high |= 1 << (hash - 32);
|
||||||
} else {
|
} else {
|
||||||
hash_low |= 1 << hash;
|
hash_low |= 1 << hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_gaur_gaddr_wrf(st->d, hash_high);
|
enet_gaur_gaddr_wrf(st->d, hash_high);
|
||||||
enet_galr_gaddr_wrf(st->d, hash_low);
|
enet_galr_gaddr_wrf(st->d, hash_low);
|
||||||
#endif
|
#endif
|
||||||
@ -395,12 +396,12 @@ static void enet_read_mac(struct enet_driver_state* st)
|
|||||||
uint64_t mac = (lower << 16) | upper;
|
uint64_t mac = (lower << 16) | upper;
|
||||||
|
|
||||||
ENET_DEBUG("MAC %lx \n", mac);
|
ENET_DEBUG("MAC %lx \n", mac);
|
||||||
st->mac = mac;
|
st->mac = mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enet_write_mac(struct enet_driver_state* st)
|
static void enet_write_mac(struct enet_driver_state* st)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint64_t lower = st->mac >> 16;
|
uint64_t lower = st->mac >> 16;
|
||||||
uint32_t upper = st->mac & 0xFFFF;
|
uint32_t upper = st->mac & 0xFFFF;
|
||||||
|
|
||||||
@ -412,7 +413,7 @@ static errval_t enet_reset(struct enet_driver_state* st)
|
|||||||
{
|
{
|
||||||
// reset device
|
// reset device
|
||||||
ENET_DEBUG("Reset device\n");
|
ENET_DEBUG("Reset device\n");
|
||||||
|
|
||||||
uint64_t ecr = enet_ecr_rd(st->d);
|
uint64_t ecr = enet_ecr_rd(st->d);
|
||||||
enet_ecr_wr(st->d, ecr | 0x1);
|
enet_ecr_wr(st->d, ecr | 0x1);
|
||||||
int timeout = 500;
|
int timeout = 500;
|
||||||
@ -424,7 +425,7 @@ static errval_t enet_reset(struct enet_driver_state* st)
|
|||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
return ENET_ERR_DEV_RESET;
|
return ENET_ERR_DEV_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,8 +437,8 @@ static void enet_reg_setup(struct enet_driver_state* st)
|
|||||||
// Clear outstanding interrupts
|
// Clear outstanding interrupts
|
||||||
ENET_DEBUG("Clear outstanding interrupts\n");
|
ENET_DEBUG("Clear outstanding interrupts\n");
|
||||||
enet_eir_wr(st->d, 0xFFFFFFFF);
|
enet_eir_wr(st->d, 0xFFFFFFFF);
|
||||||
|
|
||||||
uint64_t reg;
|
uint64_t reg;
|
||||||
// TODO see if other fields are required, not in dump
|
// TODO see if other fields are required, not in dump
|
||||||
reg = enet_rcr_rd(st->d);
|
reg = enet_rcr_rd(st->d);
|
||||||
reg = enet_rcr_loop_insert(reg, 0x0);
|
reg = enet_rcr_loop_insert(reg, 0x0);
|
||||||
@ -446,7 +447,7 @@ static void enet_reg_setup(struct enet_driver_state* st)
|
|||||||
reg = enet_rcr_fce_insert(reg, 0x1);
|
reg = enet_rcr_fce_insert(reg, 0x1);
|
||||||
reg = enet_rcr_max_fl_insert(reg, 1522);
|
reg = enet_rcr_max_fl_insert(reg, 1522);
|
||||||
//reg = enet_rcr_prom_insert(reg, 1);
|
//reg = enet_rcr_prom_insert(reg, 1);
|
||||||
enet_rcr_wr(st->d, reg);
|
enet_rcr_wr(st->d, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static errval_t enet_open(struct enet_driver_state *st)
|
static errval_t enet_open(struct enet_driver_state *st)
|
||||||
@ -468,10 +469,10 @@ static errval_t enet_open(struct enet_driver_state *st)
|
|||||||
err = enet_phy_startup(st);
|
err = enet_phy_startup(st);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t speed = enet_ecr_speed_rdf(st->d);
|
uint8_t speed = enet_ecr_speed_rdf(st->d);
|
||||||
|
|
||||||
if (!speed) {
|
if (!speed) {
|
||||||
enet_rcr_rmii_10t_wrf(st->d, 0x0);
|
enet_rcr_rmii_10t_wrf(st->d, 0x0);
|
||||||
}
|
}
|
||||||
@ -493,7 +494,7 @@ static errval_t enet_init(struct enet_driver_state* st)
|
|||||||
|
|
||||||
enet_reg_setup(st);
|
enet_reg_setup(st);
|
||||||
|
|
||||||
uint64_t reg;
|
uint64_t reg;
|
||||||
// Set MII speed, do not drop preamble and set hold time to 10ns
|
// Set MII speed, do not drop preamble and set hold time to 10ns
|
||||||
reg = enet_mscr_rd(st->d);
|
reg = enet_mscr_rd(st->d);
|
||||||
reg = enet_mscr_mii_speed_insert(reg, 0x18);
|
reg = enet_mscr_mii_speed_insert(reg, 0x18);
|
||||||
@ -536,10 +537,10 @@ static errval_t enet_probe(struct enet_driver_state* st)
|
|||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_reg_setup(st);
|
enet_reg_setup(st);
|
||||||
|
|
||||||
uint64_t reg;
|
uint64_t reg;
|
||||||
// Set MII speed, do not drop preamble and set hold time to 10ns
|
// Set MII speed, do not drop preamble and set hold time to 10ns
|
||||||
reg = enet_mscr_rd(st->d);
|
reg = enet_mscr_rd(st->d);
|
||||||
reg = enet_mscr_mii_speed_insert(reg, 0x18);
|
reg = enet_mscr_mii_speed_insert(reg, 0x18);
|
||||||
@ -550,7 +551,7 @@ static errval_t enet_probe(struct enet_driver_state* st)
|
|||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
debug_printf("Failed PHY reset\n");
|
debug_printf("Failed PHY reset\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write back mac again
|
// Write back mac again
|
||||||
ENET_DEBUG("Reset MAC\n");
|
ENET_DEBUG("Reset MAC\n");
|
||||||
@ -558,7 +559,7 @@ static errval_t enet_probe(struct enet_driver_state* st)
|
|||||||
enet_write_mac(st);
|
enet_write_mac(st);
|
||||||
enet_read_mac(st);
|
enet_read_mac(st);
|
||||||
|
|
||||||
// TODO checked dump until here!
|
// TODO checked dump until here!
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,13 +568,22 @@ int main(int argc, char *argv[]) {
|
|||||||
errval_t err;
|
errval_t err;
|
||||||
|
|
||||||
debug_printf("Enet driver started \n");
|
debug_printf("Enet driver started \n");
|
||||||
struct enet_driver_state * st = (struct enet_driver_state*)
|
struct enet_driver_state * st = (struct enet_driver_state*)
|
||||||
calloc(1, sizeof(struct enet_driver_state));
|
calloc(1, sizeof(struct enet_driver_state));
|
||||||
assert(st != NULL);
|
assert(st != NULL);
|
||||||
|
|
||||||
/* TODO Net Project: get the capability to the register region
|
/* Net Project: get the capability to the register region
|
||||||
* and then map it so it is accessible.
|
* and then map it so it is accessible.
|
||||||
* TODO set st->d_vaddr to the memory mapped register region */
|
* set st->d_vaddr to the memory mapped register region */
|
||||||
|
struct capref cap_arg0 = {
|
||||||
|
.cnode = cnode_arg,
|
||||||
|
.slot = 0
|
||||||
|
};
|
||||||
|
err = paging_map_frame_attr(get_current_paging_state(),
|
||||||
|
(void **) &st->d_vaddr, IMX8X_ENET_SIZE,
|
||||||
|
cap_arg0, VREGION_FLAGS_READ_WRITE_NOCACHE);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
if ((void *)st->d_vaddr == NULL) {
|
if ((void *)st->d_vaddr == NULL) {
|
||||||
USER_PANIC("ENET: No register region mapped \n");
|
USER_PANIC("ENET: No register region mapped \n");
|
||||||
}
|
}
|
||||||
@ -598,9 +608,9 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug_printf("Enet driver init done \n");
|
debug_printf("Enet driver init done \n");
|
||||||
|
|
||||||
debug_printf("Creating devqs \n");
|
debug_printf("Creating devqs \n");
|
||||||
|
|
||||||
err = enet_rx_queue_create(&st->rxq, st->d);
|
err = enet_rx_queue_create(&st->rxq, st->d);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
debug_printf("Failed creating RX devq \n");
|
debug_printf("Failed creating RX devq \n");
|
||||||
@ -609,7 +619,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
err = enet_tx_queue_create(&st->txq, st->d);
|
err = enet_tx_queue_create(&st->txq, st->d);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
debug_printf("Failed creating RX devq \n");
|
debug_printf("Failed creating TX devq \n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user