diff --git a/libports/run/lwip.run b/libports/run/lwip.run
index 9723825f3..76e304f45 100644
--- a/libports/run/lwip.run
+++ b/libports/run/lwip.run
@@ -28,12 +28,16 @@ requires_installation_of lynx
# Build
#
-build {
+set build_components {
core init
drivers/pci drivers/timer drivers/nic
test/lwip/http_srv
}
+lappend_if [have_spec omap4] build_components drivers/usb
+
+build $build_components
+
create_boot_directory
#
@@ -62,14 +66,27 @@ set config {
-
-
-
-
}
+append_if [have_spec omap4] config {
+
+
+
+
+
+
+
+
+ }
+
+append_if [expr ![have_spec omap4]] config {
+
+
+
+ }
+
append_if [have_spec pci] config {
@@ -89,12 +106,13 @@ install_config $config
# generic modules
set boot_modules {
core init timer
- nic_drv
ld.lib.so libc.lib.so libc_log.lib.so lwip.lib.so test-lwip_httpsrv
}
# platform-specific modules
-lappend_if [have_spec pci] boot_modules pci_drv
+lappend_if [have_spec pci] boot_modules pci_drv
+lappend_if [have_spec omap4] boot_modules usb_drv
+lappend_if [expr ![have_spec omap4]] boot_modules nic_drv
build_boot_image $boot_modules
diff --git a/libports/src/lib/lwip/platform/nic.cc b/libports/src/lib/lwip/platform/nic.cc
index e6d6bbd04..bdbd03d6b 100644
--- a/libports/src/lib/lwip/platform/nic.cc
+++ b/libports/src/lib/lwip/platform/nic.cc
@@ -28,7 +28,7 @@ extern "C" {
/* Genode includes */
#include
#include
-#include
+#include
#include
@@ -43,6 +43,16 @@ class Nic_receiver_thread : public Genode::Thread<8192>
Packet_descriptor _rx_packet; /* actual packet received */
struct netif *_netif; /* LwIP network interface structure */
+ void _tx_ack(bool block = false)
+ {
+ /* check for acknowledgements */
+ while (nic()->tx()->ack_avail() || block) {
+ Packet_descriptor acked_packet = nic()->tx()->get_acked_packet();
+ nic()->tx()->release_packet(acked_packet);
+ block = false;
+ }
+ }
+
public:
Nic_receiver_thread(Nic::Connection *nic, struct netif *netif)
@@ -51,6 +61,29 @@ class Nic_receiver_thread : public Genode::Thread<8192>
void entry();
Nic::Connection *nic() { return _nic; };
Packet_descriptor rx_packet() { return _rx_packet; };
+
+ Packet_descriptor alloc_tx_packet(Genode::size_t size)
+ {
+ while (true) {
+ try {
+ Packet_descriptor packet = nic()->tx()->alloc_packet(size);
+ return packet;
+ } catch(Nic::Session::Tx::Source::Packet_alloc_failed) {
+ /* packet allocator exhausted, wait for acknowledgements */
+ _tx_ack(true);
+ }
+ }
+ }
+
+ void submit_tx_packet(Packet_descriptor packet)
+ {
+ nic()->tx()->submit_packet(packet);
+ /* check for acknowledgements */
+ _tx_ack();
+ }
+
+ char *content(Packet_descriptor packet) {
+ return nic()->tx()->packet_content(packet); }
};
@@ -81,39 +114,26 @@ extern "C" {
low_level_output(struct netif *netif, struct pbuf *p)
{
Nic_receiver_thread *th = reinterpret_cast(netif->state);
- Nic::Connection *nic = th->nic();
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
- try {
- Packet_descriptor tx_packet = nic->tx()->alloc_packet(p->tot_len);
- char *tx_content = nic->tx()->packet_content(tx_packet);
+ Packet_descriptor tx_packet = th->alloc_tx_packet(p->tot_len);
+ char *tx_content = th->content(tx_packet);
- /*
- * Iterate through all pbufs and
- * copy payload into packet's payload
- */
- for(struct pbuf *q = p; q != NULL; q = q->next) {
- char *src = (char*) q->payload;
- for (unsigned i = 0; i < q->len; i++)
- tx_content[i] = src[i];
- tx_content += q->len;
- }
-
- /* Submit packet */
- nic->tx()->submit_packet(tx_packet);
- } catch(Nic::Session::Tx::Source::Packet_alloc_failed)
- {
- PWRN("Packets to NIC were dropped!");
- return ERR_MEM;
+ /*
+ * Iterate through all pbufs and
+ * copy payload into packet's payload
+ */
+ for(struct pbuf *q = p; q != NULL; q = q->next) {
+ char *src = (char*) q->payload;
+ Genode::memcpy(tx_content, src, q->len);
+ tx_content += q->len;
}
- /* Check for acknowledgements */
- while (nic->tx()->ack_avail()) {
- Packet_descriptor acked_packet = nic->tx()->get_acked_packet();
- nic->tx()->release_packet(acked_packet);
- }
+ /* Submit packet */
+ th->submit_tx_packet(tx_packet);
+
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
@@ -156,10 +176,10 @@ extern "C" {
*/
for(struct pbuf *q = p; q != 0; q = q->next) {
char *dst = (char*)q->payload;
- for(unsigned i=0; i < q->len; ++i)
- dst[i] = rx_content[i];
+ Genode::memcpy(dst, rx_content, q->len);
rx_content += q->len;
}
+
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
@@ -222,12 +242,18 @@ extern "C" {
LWIP_ASSERT("netif != NULL", (netif != NULL));
/* Initialize nic-session */
- Allocator_avl *tx_block_alloc = new (env()->heap())
- Allocator_avl(env()->heap());
+ enum {
+ PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
+ RX_BUF_SIZE = Nic::Session::RX_QUEUE_SIZE * PACKET_SIZE,
+ TX_BUF_SIZE = Nic::Session::TX_QUEUE_SIZE * PACKET_SIZE,
+ };
+
+ Nic::Packet_allocator *tx_block_alloc = new (env()->heap())
+ Nic::Packet_allocator(env()->heap());
Nic::Connection *nic = 0;
try {
- nic = new (env()->heap()) Nic::Connection(tx_block_alloc);
+ nic = new (env()->heap()) Nic::Connection(tx_block_alloc, TX_BUF_SIZE, RX_BUF_SIZE);
} catch (Parent::Service_denied) {
destroy(env()->heap(), tx_block_alloc);
return ERR_IF;
diff --git a/ports/run/genode_org.run b/ports/run/genode_org.run
index 209d3d7fb..ab2c8e6c6 100644
--- a/ports/run/genode_org.run
+++ b/ports/run/genode_org.run
@@ -18,6 +18,8 @@ set build_components {
app/lighttpd
}
+lappend_if [have_spec omap4] build_components drivers/usb
+
build $build_components
create_boot_directory