mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
dde_linux: enable more platforms for nic_drv
In addition to the i.MX6Q SoC, the Freescale network driver works now on i.MX6SX and i.MX53 SoCs. Ref #2749
This commit is contained in:
parent
a3171befe9
commit
2af5dbc201
@ -4,6 +4,7 @@ linux-x.x.x/drivers/net/ethernet/freescale/fec_ptp.c
|
||||
linux-x.x.x/drivers/net/phy/mdio_bus.c
|
||||
linux-x.x.x/drivers/net/phy/phy_device.c
|
||||
linux-x.x.x/drivers/net/phy/phy.c
|
||||
linux-x.x.x/drivers/net/phy/at803x.c
|
||||
linux-x.x.x/net/core/skbuff.c
|
||||
linux-x.x.x/net/ethernet/eth.c
|
||||
linux-x.x.x/include/asm-generic/atomic64.h
|
||||
@ -15,6 +16,7 @@ linux-x.x.x/include/asm-generic/bitops/fls.h
|
||||
linux-x.x.x/include/asm-generic/bitops/fls64.h
|
||||
linux-x.x.x/include/linux/errqueue.h
|
||||
linux-x.x.x/include/linux/fec.h
|
||||
linux-x.x.x/include/linux/gpio/consumer.h
|
||||
linux-x.x.x/include/linux/if_ether.h
|
||||
linux-x.x.x/include/linux/list.h
|
||||
linux-x.x.x/include/linux/list_nulls.h
|
||||
|
13
repos/dde_linux/patches/fec_tx_bounce_dma.patch
Normal file
13
repos/dde_linux/patches/fec_tx_bounce_dma.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
|
||||
index b2a3220..18629c6 100644
|
||||
--- a/drivers/net/ethernet/freescale/fec_main.c
|
||||
+++ b/drivers/net/ethernet/freescale/fec_main.c
|
||||
@@ -2825,7 +2825,7 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
|
||||
txq = fep->tx_queue[queue];
|
||||
bdp = txq->tx_bd_base;
|
||||
for (i = 0; i < txq->tx_ring_size; i++) {
|
||||
- txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
|
||||
+ txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL | GFP_LX_DMA);
|
||||
if (!txq->tx_bounce[i])
|
||||
goto err_alloc;
|
||||
|
@ -1 +1 @@
|
||||
82b2f79a8ecbbfeb42de534b776c6b348573bd60
|
||||
7f9bd747fe1d1ca7e19a46100b0f4d125698a5d4
|
||||
|
@ -225,5 +225,6 @@ PATCH_OPT(patches/intel_fb_backlight.patch) := -p1 -d$(SRC_DIR_INTEL_FB)
|
||||
|
||||
# Freescale NIC
|
||||
PATCH_OPT(patches/fec_skbuff_cast.patch) := -p1 -d$(SRC_DIR_FEC)
|
||||
PATCH_OPT(patches/fec_tx_bounce_dma.patch) := -p1 -d$(SRC_DIR_FEC)
|
||||
|
||||
# vi: set ft=make :
|
||||
|
@ -130,8 +130,7 @@ void Session_component::unblock_rx_task(napi_struct * n)
|
||||
|
||||
Nic::Mac_address Session_component::mac_address()
|
||||
{
|
||||
net_device * dev = fec_get_my_registered_net_device();
|
||||
return dev ? Nic::Mac_address(dev->dev_addr) : Nic::Mac_address();
|
||||
return _ndev ? Nic::Mac_address(_ndev->dev_addr) : Nic::Mac_address();
|
||||
}
|
||||
|
||||
|
||||
@ -170,11 +169,14 @@ void Session_component::link_state(bool link)
|
||||
}
|
||||
|
||||
|
||||
Session_component::Session_component(Genode::size_t const tx_buf_size,
|
||||
Genode::size_t const rx_buf_size,
|
||||
Genode::Allocator & rx_block_md_alloc,
|
||||
Genode::Env & env)
|
||||
Session_component::Session_component(Genode::size_t const tx_buf_size,
|
||||
Genode::size_t const rx_buf_size,
|
||||
Genode::Allocator & rx_block_md_alloc,
|
||||
Genode::Env & env,
|
||||
Genode::Session_label label)
|
||||
: Nic::Session_component(tx_buf_size, rx_buf_size, rx_block_md_alloc, env),
|
||||
_ndev(fec_get_my_registered_net_device()),
|
||||
_has_link(!(_ndev->state & (1UL << __LINK_STATE_NOCARRIER))) {
|
||||
_register_session_component(*this); }
|
||||
_ndev(_register_session_component(*this, label)),
|
||||
_has_link(_ndev ? !(_ndev->state & (1UL << __LINK_STATE_NOCARRIER)) : false)
|
||||
{
|
||||
if (!_ndev) throw Genode::Service_denied();
|
||||
}
|
||||
|
@ -15,7 +15,8 @@
|
||||
#define _SRC__DRIVERS__NIC__FEC__COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <nic/root.h>
|
||||
#include <nic/component.h>
|
||||
#include <root/component.h>
|
||||
|
||||
#include <lx_kit/scheduler.h>
|
||||
|
||||
@ -47,7 +48,8 @@ class Session_component : public Nic::Session_component
|
||||
|
||||
static void _run_tx_task(void * args);
|
||||
static void _run_rx_task(void * args);
|
||||
static void _register_session_component(Session_component &);
|
||||
static net_device * _register_session_component(Session_component &,
|
||||
Genode::Session_label);
|
||||
|
||||
Lx::Task _tx_task { _run_tx_task, &_tx_data, "tx_task",
|
||||
Lx::Task::PRIORITY_1, Lx::scheduler() };
|
||||
@ -60,10 +62,11 @@ class Session_component : public Nic::Session_component
|
||||
|
||||
public:
|
||||
|
||||
Session_component(Genode::size_t const tx_buf_size,
|
||||
Genode::size_t const rx_buf_size,
|
||||
Genode::Allocator & rx_block_md_alloc,
|
||||
Genode::Env & env);
|
||||
Session_component(Genode::size_t const tx_buf_size,
|
||||
Genode::size_t const rx_buf_size,
|
||||
Genode::Allocator & rx_block_md_alloc,
|
||||
Genode::Env & env,
|
||||
Genode::Session_label label);
|
||||
|
||||
Nic::Mac_address mac_address() override;
|
||||
bool link_state() override { return _has_link; }
|
||||
@ -72,4 +75,53 @@ class Session_component : public Nic::Session_component
|
||||
void unblock_rx_task(napi_struct * n);
|
||||
};
|
||||
|
||||
|
||||
class Root : public Genode::Root_component<Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Genode::Allocator &_md_alloc;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Session_label const label = label_from_args(args);
|
||||
|
||||
size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
|
||||
size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
||||
size_t rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0);
|
||||
|
||||
/* deplete ram quota by the memory needed for the session structure */
|
||||
size_t session_size = max(4096UL, (unsigned long)sizeof(Session_component));
|
||||
if (ram_quota < session_size)
|
||||
throw Genode::Insufficient_ram_quota();
|
||||
|
||||
/*
|
||||
* Check if donated ram quota suffices for both communication
|
||||
* buffers and check for overflow
|
||||
*/
|
||||
if (tx_buf_size + rx_buf_size < tx_buf_size ||
|
||||
tx_buf_size + rx_buf_size > ram_quota - session_size) {
|
||||
Genode::error("insufficient 'ram_quota', got ", ram_quota, ", "
|
||||
"need ", tx_buf_size + rx_buf_size + session_size);
|
||||
throw Genode::Insufficient_ram_quota();
|
||||
}
|
||||
|
||||
return new (Root::md_alloc())
|
||||
Session_component(tx_buf_size, rx_buf_size,
|
||||
_md_alloc, _env, label);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Env &env, Genode::Allocator &md_alloc)
|
||||
: Genode::Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
|
||||
_env(env), _md_alloc(md_alloc)
|
||||
{ }
|
||||
};
|
||||
|
||||
#endif /* _SRC__DRIVERS__NIC__FEC__COMPONENT_H_ */
|
||||
|
@ -34,12 +34,6 @@ int disable_irq(unsigned int irq)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int disable_irq_nosync(unsigned int irq)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int disable_irq_wake(unsigned int irq)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
@ -62,12 +56,6 @@ int enable_irq_wake(unsigned int irq)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enable_irq(unsigned int irq)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void eth_hw_addr_random(struct net_device *dev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
@ -170,53 +158,18 @@ struct timespec64 ns_to_timespec64(const s64 nsec)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool of_device_is_available(const struct device_node *device)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const void *of_get_mac_address(struct device_node *np)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct device_node *of_node_get(struct device_node *node)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void of_node_put(struct device_node *node)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
struct phy_device *of_phy_connect(struct net_device *dev, struct device_node *phy_np, void (*hndlr)(struct net_device *), u32 flags, int iface)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int of_phy_register_fixed_link(struct device_node *np)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
@ -246,16 +199,6 @@ resource_size_t resource_size(const struct resource *res)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rtnl_lock(void)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
void rtnl_unlock(void)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
}
|
||||
|
||||
bool page_is_pfmemalloc(struct page *page)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
@ -289,12 +232,6 @@ u64 timecounter_cyc2time(struct timecounter *tc, cycle_t cycle_tstamp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
u64 timecounter_read(struct timecounter *tc)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
@ -342,12 +279,6 @@ int strcmp(const char *s1, const char *s2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void class_unregister(struct class *cls)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
|
@ -16,8 +16,11 @@
|
||||
* prevent shenanigans with macro definitions.
|
||||
*/
|
||||
#include <base/attached_io_mem_dataspace.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/env.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <gpio_session/connection.h>
|
||||
#include <irq_session/client.h>
|
||||
#include <os/backtrace.h>
|
||||
|
||||
#include <component.h>
|
||||
@ -40,7 +43,6 @@ class Addr_to_page_mapping : public Genode::List<Addr_to_page_mapping>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned long _addr { 0 };
|
||||
struct page *_page { nullptr };
|
||||
|
||||
static Genode::List<Addr_to_page_mapping> & _list()
|
||||
@ -51,14 +53,13 @@ class Addr_to_page_mapping : public Genode::List<Addr_to_page_mapping>::Element
|
||||
|
||||
public:
|
||||
|
||||
Addr_to_page_mapping(unsigned long addr, struct page *page)
|
||||
: _addr(addr), _page(page) { }
|
||||
Addr_to_page_mapping(struct page *page)
|
||||
: _page(page) { }
|
||||
|
||||
static void insert(struct page * page)
|
||||
{
|
||||
Addr_to_page_mapping *m = (Addr_to_page_mapping*)
|
||||
Lx::Malloc::mem().alloc(sizeof (Addr_to_page_mapping));
|
||||
m->_addr = (unsigned long)page->addr;
|
||||
m->_page = page;
|
||||
_list().insert(m);
|
||||
}
|
||||
@ -66,7 +67,7 @@ class Addr_to_page_mapping : public Genode::List<Addr_to_page_mapping>::Element
|
||||
static struct page * remove(unsigned long addr)
|
||||
{
|
||||
for (Addr_to_page_mapping *m = _list().first(); m; m = m->next())
|
||||
if (m->_addr == addr) {
|
||||
if ((unsigned long)m->_page->addr == addr) {
|
||||
struct page * ret = m->_page;
|
||||
_list().remove(m);
|
||||
Lx::Malloc::mem().free(m);
|
||||
@ -75,6 +76,15 @@ class Addr_to_page_mapping : public Genode::List<Addr_to_page_mapping>::Element
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static struct page * find_page(void* addr)
|
||||
{
|
||||
for (Addr_to_page_mapping *m = _list().first(); m; m = m->next())
|
||||
if ((unsigned long)m->_page->addr <= (unsigned long)addr &&
|
||||
((unsigned long)m->_page->addr + m->_page->size) > (unsigned long)addr)
|
||||
return m->_page;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -145,10 +155,149 @@ class Driver : public Genode::List<Driver>::Element
|
||||
}
|
||||
};
|
||||
|
||||
static Session_component * session = nullptr;
|
||||
|
||||
void Session_component::_register_session_component(Session_component & s) {
|
||||
session = &s; }
|
||||
struct Gpio_irq : public Genode::List<Gpio_irq>::Element
|
||||
{
|
||||
unsigned irq_nr;
|
||||
bool enabled = true;
|
||||
bool pending = false;
|
||||
Gpio::Connection gpio;
|
||||
Genode::Irq_session_client irq;
|
||||
Genode::Signal_handler<Gpio_irq> sigh;
|
||||
Lx::Task task;
|
||||
irq_handler_t ihandler;
|
||||
void * dev_id;
|
||||
|
||||
/**
|
||||
* List of all currently registered irqs
|
||||
*/
|
||||
static Genode::List<Gpio_irq> *list()
|
||||
{
|
||||
static Genode::List<Gpio_irq> _list;
|
||||
return &_list;
|
||||
}
|
||||
|
||||
static void run_irq(void *args)
|
||||
{
|
||||
Gpio_irq * girq = static_cast<Gpio_irq*>(args);
|
||||
while (1) {
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
girq->ihandler(girq->irq_nr, girq->dev_id);
|
||||
girq->irq.ack_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void unblock()
|
||||
{
|
||||
if (enabled) task.unblock();
|
||||
|
||||
pending = !enabled;
|
||||
}
|
||||
|
||||
void enable()
|
||||
{
|
||||
enabled = true;
|
||||
if (pending) unblock();
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
Gpio_irq(Genode::Env &env, unsigned nr, irq_handler_t handler, void * dev_id)
|
||||
: irq_nr(nr),
|
||||
gpio(env, nr),
|
||||
irq(gpio.irq_session(Gpio::Session::LOW_LEVEL)),
|
||||
sigh(env.ep(), *this, &Gpio_irq::unblock),
|
||||
task(run_irq, this, "gpio_irq", Lx::Task::PRIORITY_3, Lx::scheduler()),
|
||||
ihandler(handler),
|
||||
dev_id(dev_id)
|
||||
{
|
||||
list()->insert(this);
|
||||
|
||||
irq.sigh(sigh);
|
||||
irq.ack_irq();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Fec
|
||||
{
|
||||
using String = Genode::String<128>;
|
||||
|
||||
struct Mdio
|
||||
{
|
||||
struct Phy
|
||||
{
|
||||
String name;
|
||||
String phy_driver;
|
||||
const unsigned phy_reg;
|
||||
const unsigned gpio_irq;
|
||||
struct phy_device * phy_dev { nullptr };
|
||||
|
||||
Phy(String name, String driver, const unsigned reg, const unsigned irq)
|
||||
: name(name), phy_driver(driver), phy_reg(reg), gpio_irq(irq) {}
|
||||
};
|
||||
|
||||
enum { MAX = 10 };
|
||||
Genode::Constructible<Phy> phys[MAX];
|
||||
|
||||
template <typename FUNC>
|
||||
void for_each(FUNC && f)
|
||||
{
|
||||
for (unsigned i = 0; i < MAX; i++)
|
||||
if (phys[i].constructed()) f(*phys[i]);
|
||||
}
|
||||
};
|
||||
|
||||
String name;
|
||||
String device;
|
||||
const unsigned irq;
|
||||
const size_t mmio;
|
||||
String phy_mode;
|
||||
const bool magic_packet;
|
||||
const int tx_queues;
|
||||
const int rx_queues;
|
||||
struct net_device * net_dev { nullptr };
|
||||
Session_component * session { nullptr };
|
||||
Genode::Attached_io_mem_dataspace io_ds { Lx_kit::env().env(), mmio, 0x4000 };
|
||||
Genode::Constructible<Mdio> mdio;
|
||||
Mdio::Phy * phy { nullptr };
|
||||
|
||||
Fec(String name, String device, const unsigned irq,
|
||||
const size_t mmio, String mode, const bool magic = true,
|
||||
const int tx_queues = 1, const int rx_queues = 1)
|
||||
: name(name), device(device), irq(irq), mmio(mmio), phy_mode(mode), magic_packet(magic),
|
||||
tx_queues(tx_queues), rx_queues(rx_queues) {};
|
||||
};
|
||||
|
||||
|
||||
static const unsigned FEC_MAX = 2;
|
||||
static Genode::Constructible<Fec> fec_devices[FEC_MAX];
|
||||
|
||||
net_device * Session_component::_register_session_component(Session_component & s,
|
||||
Genode::Session_label policy)
|
||||
{
|
||||
Genode::Session_label name = policy.last_element();
|
||||
|
||||
for (unsigned i = 0; i < FEC_MAX; i++) {
|
||||
|
||||
/* No more cards available */
|
||||
if (!fec_devices[i].constructed()) return nullptr;
|
||||
|
||||
/* Session does not match cards policy */
|
||||
if (fec_devices[i]->name.length() > 1 &&
|
||||
fec_devices[i]->name != name) continue;
|
||||
|
||||
/* Session already in use */
|
||||
if (fec_devices[i]->session) return nullptr;
|
||||
|
||||
fec_devices[i]->session = &s;
|
||||
return fec_devices[i]->net_dev;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
@ -158,18 +307,78 @@ void Session_component::_register_session_component(Session_component & s) {
|
||||
|
||||
extern "C" {
|
||||
|
||||
void lx_backtrace()
|
||||
{
|
||||
Genode::backtrace();
|
||||
}
|
||||
|
||||
void lx_backtrace() { Genode::backtrace(); }
|
||||
|
||||
int platform_driver_register(struct platform_driver * drv)
|
||||
{
|
||||
static platform_device pd_fec;
|
||||
static const char * name = "2188000.ethernet";
|
||||
pd_fec.name = name;
|
||||
return drv->probe(&pd_fec);
|
||||
using String = Fec::String;
|
||||
|
||||
try {
|
||||
unsigned i = 0;
|
||||
Genode::Attached_rom_dataspace config { Lx_kit::env().env(), "config" };
|
||||
config.xml().for_each_sub_node("card", [&] (Genode::Xml_node const node) {
|
||||
if (i == FEC_MAX) {
|
||||
Genode::error("More cards defined than available!");
|
||||
return;
|
||||
}
|
||||
|
||||
String name = node.attribute_value("name", String());
|
||||
String type = node.attribute_value("type", String());
|
||||
String mdio = node.attribute_value("mii", String());
|
||||
String phy = node.attribute_value("phy", String());
|
||||
unsigned irq = node.attribute_value("irq", 0UL);
|
||||
Genode::addr_t mmio = node.attribute_value("mmio", 0UL);
|
||||
bool magic = node.attribute_value("magic_packet", true);
|
||||
unsigned txq = node.attribute_value("tx-queues", 1UL);
|
||||
unsigned rxq = node.attribute_value("rx-queues", 1UL);
|
||||
fec_devices[i].construct(name, type, irq, mmio, mdio, magic, txq, rxq);
|
||||
|
||||
node.for_each_sub_node("mdio", [&] (Genode::Xml_node const node) {
|
||||
fec_devices[i]->mdio.construct();
|
||||
unsigned j = 0;
|
||||
node.for_each_sub_node("phy", [&] (Genode::Xml_node const node) {
|
||||
String name = node.attribute_value("name", String());
|
||||
String type = node.attribute_value("type", String());
|
||||
unsigned irq = node.attribute_value("gpio_irq", 0UL);
|
||||
unsigned reg = node.attribute_value("reg_num", 0UL);
|
||||
fec_devices[i]->mdio->phys[j].construct(name, type, reg, irq);
|
||||
j++;
|
||||
});
|
||||
});
|
||||
|
||||
for (unsigned k = 0; k <= i; k++)
|
||||
if (fec_devices[k]->mdio.constructed()) {
|
||||
fec_devices[k]->mdio->for_each([&] (Fec::Mdio::Phy & p) {
|
||||
if (p.name == phy) fec_devices[i]->phy = &p; });
|
||||
}
|
||||
|
||||
i++;
|
||||
});
|
||||
} catch(...) { }
|
||||
|
||||
if (!fec_devices[0].constructed()) {
|
||||
Genode::warning("No valid configuration provided, use default values");
|
||||
fec_devices[0].construct(String(), "fsl,imx6q-fec", 150, 0x2188000, "rgmii");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < FEC_MAX; i++) {
|
||||
if (!fec_devices[i].constructed()) break;
|
||||
|
||||
platform_device * pd = new (Lx::Malloc::dma()) platform_device();
|
||||
pd->name = fec_devices[i]->name.string();
|
||||
pd->dev.of_node = (device_node*) &fec_devices[i];
|
||||
pd->dev.plat_dev = pd;
|
||||
drv->probe(pd);
|
||||
{
|
||||
net_device * dev = fec_devices[i]->net_dev;
|
||||
int err = dev ? dev->netdev_ops->ndo_open(dev) : -1;
|
||||
if (err) {
|
||||
Genode::error("ndo_open() failed: ", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -191,6 +400,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
|
||||
|
||||
dev->gso_max_segs = GSO_MAX_SEGS;
|
||||
|
||||
setup(dev);
|
||||
|
||||
static const struct ethtool_ops default_ethtool_ops { };
|
||||
if (!dev->ethtool_ops) dev->ethtool_ops = &default_ethtool_ops;
|
||||
|
||||
@ -200,34 +411,45 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
|
||||
}
|
||||
|
||||
|
||||
bool of_device_is_available(const struct device_node *device)
|
||||
{
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
const struct device *dev)
|
||||
{
|
||||
Fec * fec = (Fec*) dev->plat_dev->dev.of_node;
|
||||
for (; matches && matches->compatible[0]; matches++)
|
||||
if (Genode::strcmp(matches->compatible, "fsl,imx6q-fec") == 0)
|
||||
if (Genode::strcmp(matches->compatible, fec->device.string()) == 0)
|
||||
return matches;
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void * devm_ioremap_resource(struct device *dev, struct resource *res)
|
||||
{
|
||||
static Genode::Attached_io_mem_dataspace io_ds(Lx_kit::env().env(),
|
||||
0x2188000, 0x1000);
|
||||
Fec * fec = (Fec*) dev->plat_dev->dev.of_node;
|
||||
|
||||
return io_ds.local_addr<void>();
|
||||
return fec->io_ds.local_addr<void>();
|
||||
}
|
||||
|
||||
|
||||
void platform_set_drvdata(struct platform_device *pdev, void *data)
|
||||
{
|
||||
pdev->dev.driver_data = data;
|
||||
struct net_device * ndev = (net_device*)data;
|
||||
ndev->dev.of_node = pdev->dev.of_node;
|
||||
}
|
||||
|
||||
int of_get_phy_mode(struct device_node *np)
|
||||
{
|
||||
Fec * fec = (Fec*) np;
|
||||
|
||||
for (int i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
|
||||
if (!Genode::strcmp("rgmii", phy_modes((phy_interface_t)i)))
|
||||
if (!Genode::strcmp(fec->phy_mode.string(),
|
||||
phy_modes((phy_interface_t)i)))
|
||||
return i;
|
||||
|
||||
return -ENODEV;
|
||||
@ -255,11 +477,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
{
|
||||
void *addr = Lx::Malloc::dma().alloc_large(size);
|
||||
dma_addr_t dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(addr);
|
||||
|
||||
static unsigned waechter = 0;
|
||||
ASSERT(!waechter++);
|
||||
|
||||
*dma_handle = (dma_addr_t) addr;
|
||||
*dma_handle = (dma_addr_t) dma_addr;
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -267,7 +487,12 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
void *dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
|
||||
{
|
||||
dma_addr_t dma_addr;
|
||||
void *addr = Lx::Malloc::dma().alloc(size, 12, &dma_addr);
|
||||
void *addr;
|
||||
if (size > 2048) {
|
||||
addr = Lx::Malloc::dma().alloc_large(size);
|
||||
dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(addr);
|
||||
} else
|
||||
addr = Lx::Malloc::dma().alloc(size, 12, &dma_addr);
|
||||
|
||||
*dma_handle = dma_addr;
|
||||
return addr;
|
||||
@ -279,9 +504,18 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
|
||||
{
|
||||
dma_addr_t dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(cpu_addr);
|
||||
|
||||
if (dma_addr == ~0UL)
|
||||
Genode::error(__func__, ": virtual address ", cpu_addr,
|
||||
" not registered for DMA");
|
||||
if (dma_addr == ~0UL) {
|
||||
|
||||
struct page * p = Addr_to_page_mapping::find_page(cpu_addr);
|
||||
if (p) {
|
||||
dma_addr = (dma_addr_t) Lx::Malloc::dma().phys_addr(p->addr);
|
||||
dma_addr += (dma_addr_t)cpu_addr - (dma_addr_t)p->addr;
|
||||
}
|
||||
|
||||
if (dma_addr == ~0UL)
|
||||
Genode::error(__func__, ": virtual address ", cpu_addr,
|
||||
" not registered for DMA");
|
||||
}
|
||||
|
||||
return dma_addr;
|
||||
}
|
||||
@ -308,14 +542,18 @@ int netif_running(const struct net_device *dev)
|
||||
void netif_carrier_on(struct net_device *dev)
|
||||
{
|
||||
dev->state &= ~(1UL << __LINK_STATE_NOCARRIER);
|
||||
if (session) session->link_state(true);
|
||||
|
||||
Fec * fec = (Fec*) dev->dev.of_node;
|
||||
if (fec->session) fec->session->link_state(true);
|
||||
}
|
||||
|
||||
|
||||
void netif_carrier_off(struct net_device *dev)
|
||||
{
|
||||
dev->state |= 1UL << __LINK_STATE_NOCARRIER;
|
||||
if (session) session->link_state(false);
|
||||
|
||||
Fec * fec = (Fec*) dev->dev.of_node;
|
||||
if (fec->session) fec->session->link_state(false);
|
||||
}
|
||||
|
||||
|
||||
@ -331,7 +569,9 @@ int platform_get_irq(struct platform_device * d, unsigned int i)
|
||||
{
|
||||
if (i > 1) return -1;
|
||||
|
||||
return 150 + i;
|
||||
Fec * fec = (Fec*) d->dev.of_node;
|
||||
|
||||
return fec->irq + i;
|
||||
}
|
||||
|
||||
|
||||
@ -346,14 +586,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
static struct clk clocks[] {
|
||||
{ "ipg", 66*1000*1000 },
|
||||
{ "ahb", 132*1000*1000 },
|
||||
{ "enet_clk_ref", 500*1000*1000 } };
|
||||
{ "ahb", 198*1000*1000 },
|
||||
{ "ptp", 25*1000*1000 },
|
||||
{ "enet_out", 25*1000*1000 },
|
||||
{ "enet_clk_ref", 125*1000*1000 } };
|
||||
|
||||
for (unsigned i = 0; i < (sizeof(clocks) / sizeof(struct clk)); i++)
|
||||
if (Genode::strcmp(clocks[i].name, id) == 0)
|
||||
return &clocks[i];
|
||||
|
||||
return NULL;
|
||||
Genode::error("MISSING CLOCK: ", id);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -372,31 +615,17 @@ int is_valid_ether_addr(const u8 * a)
|
||||
}
|
||||
|
||||
|
||||
static struct net_device * my_net_device = nullptr;
|
||||
|
||||
|
||||
int register_netdev(struct net_device * d)
|
||||
{
|
||||
my_net_device = d;
|
||||
|
||||
d->state |= (1 << __LINK_STATE_START) | (1UL << __LINK_STATE_NOCARRIER);
|
||||
|
||||
int err = d->netdev_ops->ndo_open(d);
|
||||
if (err) {
|
||||
Genode::error("ndo_open() failed: ", err);
|
||||
return err;
|
||||
}
|
||||
Fec * fec = (Fec*) d->dev.of_node;
|
||||
fec->net_dev = d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct net_device * fec_get_my_registered_net_device()
|
||||
{
|
||||
return my_net_device;
|
||||
}
|
||||
|
||||
|
||||
void *kmem_cache_alloc_node(struct kmem_cache *cache, gfp_t, int)
|
||||
{
|
||||
return (void*)cache->alloc();
|
||||
@ -413,7 +642,8 @@ static struct page *allocate_pages(gfp_t gfp_mask, size_t const size)
|
||||
{
|
||||
struct page *page = (struct page *)kzalloc(sizeof(struct page), 0);
|
||||
|
||||
page->addr = Lx::Malloc::dma().alloc(size, 12);
|
||||
page->addr = Lx::Malloc::dma().alloc_large(size);
|
||||
page->size = size;
|
||||
|
||||
if (!page->addr) {
|
||||
Genode::error("alloc_pages: ", size, " failed");
|
||||
@ -451,7 +681,7 @@ void __free_page_frag(void *addr)
|
||||
if (!atomic_dec_and_test(&page->_count))
|
||||
Genode::error("page reference count != 0");
|
||||
|
||||
Lx::Malloc::dma().free(page->addr);
|
||||
Lx::Malloc::dma().free_large(page->addr);
|
||||
kfree(page);
|
||||
}
|
||||
|
||||
@ -513,7 +743,7 @@ long __wait_completion(struct completion *work, unsigned long timeout)
|
||||
|
||||
if (timeout) {
|
||||
setup_timer(&t, _completion_timeout, (unsigned long)Lx::scheduler().current());
|
||||
mod_timer(&t, timeout);
|
||||
mod_timer(&t, j);
|
||||
}
|
||||
|
||||
while (!work->done) {
|
||||
@ -533,14 +763,7 @@ long __wait_completion(struct completion *work, unsigned long timeout)
|
||||
|
||||
work->done = 0;
|
||||
|
||||
return j ? j - jiffies : 1;
|
||||
}
|
||||
|
||||
|
||||
int request_module(const char *format, ...)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
return (j || j == jiffies) ? 1 : j - jiffies;
|
||||
}
|
||||
|
||||
|
||||
@ -599,13 +822,6 @@ int dev_set_name(struct device *dev, const char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
int bus_register(struct bus_type *bus)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct device *bus_find_device_by_name(struct bus_type *bus, struct device *start, const char *name)
|
||||
{
|
||||
for (Device *dev = Device::list()->first(); dev; dev = dev->next()) {
|
||||
@ -656,7 +872,8 @@ void napi_disable(struct napi_struct *n)
|
||||
|
||||
void __napi_schedule(struct napi_struct *n)
|
||||
{
|
||||
if (session) session->unblock_rx_task(n);
|
||||
Fec * fec = (Fec*) n->dev->dev.of_node;
|
||||
if (fec->session) fec->session->unblock_rx_task(n);
|
||||
}
|
||||
|
||||
|
||||
@ -687,7 +904,8 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsig
|
||||
|
||||
gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
|
||||
{
|
||||
if (session) session->receive(skb);
|
||||
Fec * fec = (Fec*) napi->dev->dev.of_node;
|
||||
if (fec->session) fec->session->receive(skb);
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
return GRO_NORMAL;
|
||||
@ -709,6 +927,192 @@ bool netif_queue_stopped(const struct net_device *dev)
|
||||
}
|
||||
|
||||
|
||||
struct device_node *of_parse_phandle(const struct device_node *np, const char *phandle_name, int index)
|
||||
{
|
||||
Fec * fec = (Fec*) np;
|
||||
return (device_node*) fec->phy;
|
||||
}
|
||||
|
||||
|
||||
struct phy_device *of_phy_connect(struct net_device *dev,
|
||||
struct device_node *phy_np,
|
||||
void (*hndlr)(struct net_device *),
|
||||
u32 flags, int iface)
|
||||
{
|
||||
Fec::Mdio::Phy * phy = (Fec::Mdio::Phy*) phy_np;
|
||||
struct phy_device * phydev = phy ? phy->phy_dev : nullptr;
|
||||
if (!phydev) return nullptr;
|
||||
|
||||
phydev->dev_flags = flags;
|
||||
int ret = phy_connect_direct(dev, phydev, hndlr, (phy_interface_t)iface);
|
||||
return ret ? nullptr : phydev;
|
||||
}
|
||||
|
||||
|
||||
struct device_node *of_get_child_by_name(const struct device_node *node,
|
||||
const char *name)
|
||||
{
|
||||
if (Genode::strcmp("mdio", name) != 0) return nullptr;
|
||||
|
||||
Fec * fec = (Fec*) node;
|
||||
return fec->mdio.constructed() ? (device_node*) &*fec->mdio : nullptr;
|
||||
}
|
||||
|
||||
|
||||
static int of_mdiobus_register_phy(Fec::Mdio::Phy & ph, struct mii_bus *mdio)
|
||||
{
|
||||
struct phy_device * phy = get_phy_device(mdio, ph.phy_reg, false);
|
||||
|
||||
if (!phy || IS_ERR(phy)) return 1;
|
||||
|
||||
phy->irq = ph.gpio_irq;
|
||||
phy->dev.of_node = (device_node*) &ph;
|
||||
|
||||
/* All data is now stored in the phy struct;
|
||||
* register it */
|
||||
int rc = phy_device_register(phy);
|
||||
if (rc) {
|
||||
phy_device_free(phy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ph.phy_dev = phy;
|
||||
|
||||
dev_dbg(&mdio->dev, "registered phy at address %i\n", ph.phy_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
|
||||
{
|
||||
Fec::Mdio * fec_m = (Fec::Mdio*) np;
|
||||
|
||||
mdio->phy_mask = ~0;
|
||||
|
||||
/* Clear all the IRQ properties */
|
||||
if (mdio->irq)
|
||||
for (unsigned i = 0; i<PHY_MAX_ADDR; i++)
|
||||
mdio->irq[i] = PHY_POLL;
|
||||
|
||||
mdio->dev.of_node = np;
|
||||
|
||||
/* Register the MDIO bus */
|
||||
int rc = mdiobus_register(mdio);
|
||||
if (rc) return rc;
|
||||
|
||||
fec_m->for_each([&] (Fec::Mdio::Phy & phy) {
|
||||
of_mdiobus_register_phy(phy, mdio); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int of_driver_match_device(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
Fec::Mdio::Phy * phy = (Fec::Mdio::Phy*) dev->of_node;
|
||||
|
||||
return phy ? (Genode::strcmp(drv->name,
|
||||
phy->phy_driver.string()) == 0) : 0;
|
||||
}
|
||||
|
||||
|
||||
const void *of_get_property(const struct device_node *node, const char *name, int *lenp)
|
||||
{
|
||||
Fec * fec = (Fec*) node;
|
||||
if (Genode::strcmp("fsl,magic-packet", name) == 0) return (void*)fec->magic_packet;
|
||||
|
||||
TRACE_AND_STOP;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value)
|
||||
{
|
||||
Fec * fec = (Fec*) np;
|
||||
|
||||
if (Genode::strcmp("max-speed", propname) == 0) return 1;
|
||||
|
||||
if ((Genode::strcmp("fsl,num-tx-queues", propname) == 0) && fec->tx_queues)
|
||||
*out_value = fec->tx_queues;
|
||||
else if ((Genode::strcmp("fsl,num-rx-queues", propname) == 0) && fec->rx_queues)
|
||||
*out_value = fec->rx_queues;
|
||||
else
|
||||
TRACE_AND_STOP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
|
||||
{
|
||||
if (size > 2048) Genode::warning("devm_kzalloc ", size);
|
||||
return Lx::Malloc::mem().alloc(size);
|
||||
}
|
||||
|
||||
|
||||
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
|
||||
{
|
||||
new (Lx::Malloc::mem()) Gpio_irq(Lx_kit::env().env(), irq, handler, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int enable_irq(unsigned int irq)
|
||||
{
|
||||
for (Gpio_irq *girq = Gpio_irq::list()->first(); girq; girq = girq->next())
|
||||
if (girq->irq_nr == irq) {
|
||||
girq->enable();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int disable_irq_nosync(unsigned int irq)
|
||||
{
|
||||
for (Gpio_irq *girq = Gpio_irq::list()->first(); girq; girq = girq->next())
|
||||
if (girq->irq_nr == irq) {
|
||||
girq->disable();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct device_node *of_get_next_available_child(const struct device_node *node, struct device_node *prev)
|
||||
{
|
||||
TRACE_AND_STOP;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
u64 timecounter_read(struct timecounter *tc)
|
||||
{
|
||||
u64 nsec;
|
||||
|
||||
cycle_t cycle_now, cycle_delta;
|
||||
|
||||
/* increment time by nanoseconds since last call */
|
||||
{
|
||||
/* read cycle counter: */
|
||||
cycle_now = tc->cc->read(tc->cc);
|
||||
|
||||
/* calculate the delta since the last timecounter_read_delta(): */
|
||||
cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
|
||||
|
||||
/* convert to nanoseconds: */
|
||||
nsec = cyclecounter_cyc2ns(tc->cc, cycle_delta,
|
||||
tc->mask, &tc->frac);
|
||||
|
||||
/* update time stamp of timecounter_read_delta() call: */
|
||||
tc->cycle_last = cycle_now;
|
||||
}
|
||||
|
||||
nsec += tc->nsec;
|
||||
tc->nsec = nsec;
|
||||
|
||||
return nsec;
|
||||
}
|
||||
|
||||
/*********************
|
||||
** DUMMY FUNCTIONS **
|
||||
*********************/
|
||||
@ -738,31 +1142,13 @@ int device_init_wakeup(struct device *dev, bool val)
|
||||
struct regulator *__must_check devm_regulator_get(struct device *dev, const char *id)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct device_node *of_get_child_by_name( const struct device_node *node, const char *name)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev, unsigned int index)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void *of_get_property(const struct device_node *node, const char *name, int *lenp)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct device_node *of_parse_phandle(const struct device_node *np, const char *phandle_name, int index)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool of_phy_is_fixed_link(struct device_node *np)
|
||||
@ -786,7 +1172,7 @@ int pinctrl_pm_select_sleep_state(struct device *dev)
|
||||
struct resource *platform_get_resource(struct platform_device * d, unsigned r1, unsigned r2)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void pm_runtime_enable(struct device *dev)
|
||||
@ -818,7 +1204,7 @@ void pm_runtime_use_autosuspend(struct device *dev)
|
||||
struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, struct device *parent)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
return (ptp_clock*)0xdeadbeef;
|
||||
}
|
||||
|
||||
int regulator_enable(struct regulator * d)
|
||||
@ -827,12 +1213,6 @@ int regulator_enable(struct regulator * d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int of_driver_match_device(struct device *dev, const struct device_driver *drv)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int class_register(struct class_ *cls)
|
||||
{
|
||||
TRACE;
|
||||
@ -848,7 +1228,7 @@ int try_module_get(struct module *mod)
|
||||
struct device *get_device(struct device *dev)
|
||||
{
|
||||
TRACE;
|
||||
return NULL;
|
||||
return dev;
|
||||
}
|
||||
|
||||
int device_bind_driver(struct device *dev)
|
||||
@ -911,4 +1291,37 @@ void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size,
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void of_node_put(struct device_node *node)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
const void *of_get_mac_address(struct device_node *np)
|
||||
{
|
||||
TRACE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void rtnl_lock(void)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void rtnl_unlock(void)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
int request_module(const char *fmt, ...)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_register(struct bus_type *bus)
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
void lx_backtrace(void);
|
||||
|
||||
#define DEBUG_LINUX_PRINTK 1
|
||||
#define DEBUG_LINUX_PRINTK 0
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
@ -87,7 +87,7 @@ size_t iov_iter_count(struct iov_iter *i);
|
||||
#define dev_notice(dev, format, arg...) lx_printf("dev_notice: " format , ## arg)
|
||||
#define dev_crit( dev, format, arg...) lx_printf("dev_crit: " format , ## arg)
|
||||
#if DEBUG
|
||||
#define dev_dbg( dev, format, arg...) lx_printf("dev_dbg: " format , ## arg)
|
||||
#define dev_dbg( dev, format, arg...) printk("dev_dbg: " format , ## arg)
|
||||
#else
|
||||
#define dev_dbg( dev, format, arg...)
|
||||
#endif
|
||||
@ -240,6 +240,8 @@ struct attribute_group
|
||||
struct attribute ** attrs;
|
||||
};
|
||||
|
||||
struct platform_device;
|
||||
|
||||
struct device {
|
||||
char name[32];
|
||||
struct device * parent;
|
||||
@ -251,6 +253,7 @@ struct device {
|
||||
struct bus_type *bus;
|
||||
struct class *class;
|
||||
struct device_node *of_node;
|
||||
struct platform_device * plat_dev;
|
||||
};
|
||||
|
||||
struct platform_device {
|
||||
@ -340,8 +343,9 @@ enum netdev_state_t {
|
||||
|
||||
struct net_device
|
||||
{
|
||||
unsigned long state;
|
||||
netdev_features_t features;
|
||||
const char * name;
|
||||
unsigned long state;
|
||||
netdev_features_t features;
|
||||
struct net_device_stats stats;
|
||||
netdev_features_t hw_features;
|
||||
const struct net_device_ops *netdev_ops;
|
||||
@ -358,10 +362,10 @@ struct net_device
|
||||
unsigned char broadcast[MAX_ADDR_LEN];
|
||||
unsigned long tx_queue_len;
|
||||
int watchdog_timeo;
|
||||
struct timer_list watchdog_timer;
|
||||
struct device dev;
|
||||
u16 gso_max_segs;
|
||||
struct phy_device *phydev;
|
||||
char const *name;
|
||||
};
|
||||
|
||||
static inline void *netdev_priv(const struct net_device *dev) {
|
||||
@ -479,6 +483,7 @@ struct page
|
||||
void *addr;
|
||||
dma_addr_t paddr;
|
||||
unsigned long private;
|
||||
unsigned long size;
|
||||
} __attribute((packed));
|
||||
|
||||
static inline struct page *compound_head(struct page *page) { return page; }
|
||||
@ -585,8 +590,10 @@ void netif_tx_stop_queue(struct netdev_queue *dev_queue);
|
||||
void netif_tx_wake_queue(struct netdev_queue *dev_queue);
|
||||
bool netif_queue_stopped(const struct net_device *dev);
|
||||
|
||||
#define CONFIG_ARM 1
|
||||
#define CONFIG_ARCH_MXC 1
|
||||
#define CONFIG_OF_MDIO 1
|
||||
#define CONFIG_PTP_1588_CLOCK 1
|
||||
|
||||
void rtnl_lock(void);
|
||||
void rtnl_unlock(void);
|
||||
@ -1351,7 +1358,11 @@ void device_release_driver(struct device *dev);
|
||||
|
||||
struct device *class_find_device(struct class *cls, struct device *start, const void *data, int (*match)(struct device *, const void *));
|
||||
|
||||
#define for_each_available_child_of_node(parent, child) BUG(); while (0)
|
||||
struct device_node *of_get_next_available_child(const struct device_node *node, struct device_node *prev);
|
||||
|
||||
#define for_each_available_child_of_node(parent, child) \
|
||||
for (child = of_get_next_available_child(parent, NULL); child != NULL; \
|
||||
child = of_get_next_available_child(parent, child))
|
||||
|
||||
u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap);
|
||||
u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv);
|
||||
@ -1457,8 +1468,11 @@ struct packet_offload *gro_find_complete_by_type(__be16 type);
|
||||
|
||||
void dev_add_offload(struct packet_offload *po);
|
||||
|
||||
struct net_device * fec_get_my_registered_net_device(void);
|
||||
void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
|
||||
|
||||
struct pm_qos_request {};
|
||||
|
||||
#define dma_wmb() __asm__ __volatile__ ("dmb oshst" : : : "memory")
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#endif /* _SRC__DRIVERS__NIC__FEC__LX_EMUL_H_ */
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <base/log.h>
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
|
||||
#include <component.h>
|
||||
|
||||
@ -31,6 +30,7 @@
|
||||
|
||||
/* Linux module functions */
|
||||
extern "C" int module_fec_driver_init();
|
||||
extern "C" int module_phy_module_init();
|
||||
extern "C" int subsys_phy_init();
|
||||
extern "C" void skb_init();
|
||||
|
||||
@ -40,14 +40,12 @@ struct workqueue_struct *system_wq;
|
||||
struct workqueue_struct *system_power_efficient_wq;
|
||||
unsigned long jiffies;
|
||||
|
||||
|
||||
struct Main
|
||||
{
|
||||
Genode::Env &env;
|
||||
Genode::Entrypoint &ep { env.ep() };
|
||||
Genode::Attached_rom_dataspace config { env, "config" };
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
Nic::Root<Session_component> root { env, heap };
|
||||
Genode::Env &env;
|
||||
Genode::Entrypoint &ep { env.ep() };
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
Root root { env, heap };
|
||||
|
||||
/* Linux task that handles the initialization */
|
||||
Genode::Constructible<Lx::Task> linux;
|
||||
@ -61,7 +59,6 @@ struct Main
|
||||
/* init singleton Lx::Scheduler */
|
||||
Lx::scheduler(&env);
|
||||
|
||||
//Lx::pci_init(env, env.ram(), heap);
|
||||
Lx::malloc_init(env, heap);
|
||||
|
||||
/* init singleton Lx::Timer */
|
||||
@ -95,9 +92,10 @@ static void run_linux(void * m)
|
||||
|
||||
skb_init();
|
||||
subsys_phy_init();
|
||||
module_phy_module_init();
|
||||
module_fec_driver_init();
|
||||
main.announce();
|
||||
|
||||
main.announce();
|
||||
while (1) Lx::scheduler().current()->block_and_schedule();
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ CC_OPT_skbuff = -Wno-pointer-sign -Wno-int-conversion -Wno-uninitialized
|
||||
CC_OPT_mdio_bus = -Wno-implicit-int -Wno-unused-function -Wno-pointer-sign
|
||||
CC_OPT_eth = -Wno-pointer-sign -Wno-unused-function
|
||||
CC_OPT_phy = -Wno-unused-function -Wno-unused-but-set-variable
|
||||
CC_OPT_at803x = -Wno-unused-variable
|
||||
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/net/ethernet/freescale
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/net/phy
|
||||
|
Loading…
x
Reference in New Issue
Block a user