From: Joshua Wise Date: Thu, 4 Dec 2008 22:58:36 +0000 (-0500) Subject: Lolol, boxing and unboxing? X-Git-Url: http://git.joshuawise.com/netwatch.git/commitdiff_plain/54d4b877c72b90fe057143b1bc6e49718a3cb82a?hp=-c Lolol, boxing and unboxing? --- 54d4b877c72b90fe057143b1bc6e49718a3cb82a diff --git a/net/3c90x.c b/net/3c90x.c index 64dd655..3a6c958 100644 --- a/net/3c90x.c +++ b/net/3c90x.c @@ -224,8 +224,10 @@ typedef struct { unsigned int DnNextPtr; unsigned int FrameStartHeader; - unsigned int DataAddr; - unsigned int DataLength; + struct { + unsigned int addr; + unsigned int len; + } __attribute ((aligned(8))) segments[64]; } TXD __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */ @@ -473,17 +475,16 @@ static void a3c90x_reset(void) *** pkt - the pointer to the packet data itself. ***/ static void -a3c90x_transmit(unsigned int size, const char *pkt) +a3c90x_transmit(struct pbuf *p) { unsigned char status; static unsigned int stillwaiting = 0; + unsigned int n, len; if (stillwaiting) { - outputf("Waiting for network completion..."); while (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_TXCOMPLETE) && oneshot_running()) ; - outputf("Done"); if (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_TXCOMPLETE)) { outputf("3c90x: tx timeout? txstat %02x", inb(INF_3C90X.IOAddr + regTxStatus_b)); @@ -498,11 +499,20 @@ a3c90x_transmit(unsigned int size, const char *pkt) /** Setup the DPD (download descriptor) **/ INF_3C90X.TransmitDPD.DnNextPtr = 0; + len = 0; + n = 0; + for (; p; p = p->next) + { + INF_3C90X.TransmitDPD.segments[n].addr = (unsigned int)p->payload; + INF_3C90X.TransmitDPD.segments[n].len = p->len | (p->next ? 0 : (1 << 31)); + len += p->len; + n++; + } /** set notification for transmission completion (bit 15) **/ - INF_3C90X.TransmitDPD.FrameStartHeader = (size) | 0x8000; - INF_3C90X.TransmitDPD.DataAddr = v2p((void*)pkt); - INF_3C90X.TransmitDPD.DataLength = size + (1<<31); + INF_3C90X.TransmitDPD.FrameStartHeader = (len) | 0x8000; + outputf("3c90x: Sending %d byte %d seg packet", len, n); + /** Send the packet **/ outl(INF_3C90X.IOAddr + regDnListPtr_l, v2p(&(INF_3C90X.TransmitDPD))); _issue_command(INF_3C90X.IOAddr, cmdStallCtl, 3 /* Unstall download */); diff --git a/net/etherboot-compat.h b/net/etherboot-compat.h index e769ce8..6982a21 100644 --- a/net/etherboot-compat.h +++ b/net/etherboot-compat.h @@ -2,6 +2,7 @@ #define _ETHERBOOT_COMPAT_H #include +#include "lwip/pbuf.h" #define ETH_ALEN 6 @@ -19,7 +20,7 @@ struct nic { unsigned char hwaddr[6]; int (*poll) (struct nic *nic, int retrieve); - void (*transmit) (unsigned int size, const char *pkt); + void (*transmit) (struct pbuf *p); }; #define virt_to_bus(x) memory_v2p((void *)(x)) diff --git a/net/net.c b/net/net.c index 7fa7c46..598ea75 100644 --- a/net/net.c +++ b/net/net.c @@ -96,19 +96,16 @@ void eth_poll() static err_t _transmit(struct netif *netif, struct pbuf *p) { struct nic *nic = netif->state; - struct pbuf *q; - unsigned char pkt[1600]; - unsigned int len = 0; - for(q = p; q != NULL; q = q->next) +/* for(q = p; q != NULL; q = q->next) { memcpy(pkt + len, q->payload, q->len); len += q->len; - } + }*/ - outputf("NIC: Transmit packet: %d bytes", len); + outputf("NIC: Transmit packet"); - nic->transmit(len, pkt); + nic->transmit(p); LINK_STATS_INC(link.xmit); diff --git a/net/net.h b/net/net.h index c665216..7b522f0 100644 --- a/net/net.h +++ b/net/net.h @@ -1,5 +1,5 @@ -#ifndef _3C905_H -#define _3C905_H +#ifndef _NET_H +#define _NET_H #include "etherboot-compat.h"