* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 [not found] <200101242123.NAA00986@pizda.ninka.net> @ 2001-01-25 1:40 ` Andrew Morton 2001-01-25 19:29 ` kuznet 2001-01-25 9:29 ` David S. Miller 1 sibling, 1 reply; 27+ messages in thread From: Andrew Morton @ 2001-01-25 1:40 UTC (permalink / raw) To: David S. Miller; +Cc: linux-kernel "David S. Miller" wrote: > > I'm back from OZ, and to help deal with my sudden lack of Victoria > Bitter, aww.. Poor Dave. I'll have an extra one for you. > ... > There is one critical failure I saw reported with zerocopy, where all > transmits basically failed using a 3c59x card. This indicates that > our driver checks thought the 3c59x you had supported TX checksumming > in hardware, when in fact it does not. I've tested the latest zc patch on: 3c905 (10b7/9050) 3c905B (10b7/9055) 3c905C (10b7/9200) 3c590 (10b7/5900) no problems. I simply mounted an NFS server with rsize=wsize=8192 and read a few files - I assume this is sufficient? I can test a 3c575 later today. What I suggest we do here is to add a new flag to the per-device table `HAS_HWCKSM' and use that to set the device capabilities, rather than using the IS_CYCLONE stuff. Then we can add cards individually as confirmation comes in. I do have a 200-line 3c59x patch banked up - it does the following: - fixes some interface selection problems with 3c590/3c900's - fixes a PAGE_SIZE memory leak which occurs each time the driver is unloaded (pci_free_consistent needed). - fixes the 3c556B's PM-resume behaviour So... How to coordinate these diffs? I'd propose that I implement the HAS_HWCKSM thing, test zerocopy with it on the five NICs which I have. Then what? Ask Linus to merge the non-zc parts? - - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 1:40 ` [UPDATE] Zerocopy patches, against 2.4.1-pre10 Andrew Morton @ 2001-01-25 19:29 ` kuznet 2001-01-25 20:28 ` Ion Badulescu ` (2 more replies) 0 siblings, 3 replies; 27+ messages in thread From: kuznet @ 2001-01-25 19:29 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Hello! > no problems. I simply mounted an NFS server with rsize=wsize=8192 > and read a few files - I assume this is sufficient? This is orthogonal. Only TCP uses this and you need not to do something special to test it. Any TCP connection going through 3c tests it. > rather than using the IS_CYCLONE stuff. Then we can add cards > individually as confirmation comes in. Seems, you meaned opposite way. To add this flag to all the chips, except for several, and to remove it as soon as it is "confirmed" that it does not work. 8) Also, please, reset the state. Until this snapshot, hw checksumming did not work due to bugs in netfilter, so that all the reports about failures to checksum are dubious. Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 19:29 ` kuznet @ 2001-01-25 20:28 ` Ion Badulescu 2001-01-25 20:36 ` kuznet 2001-01-25 20:43 ` David S. Miller 2001-01-26 1:27 ` Andrew Morton 2 siblings, 1 reply; 27+ messages in thread From: Ion Badulescu @ 2001-01-25 20:28 UTC (permalink / raw) To: kuznet; +Cc: linux-kernel, Andrew Morton On Thu, 25 Jan 2001 22:29:14 +0300 (MSK), kuznet@ms2.inr.ac.ru wrote: > Hello! > >> no problems. I simply mounted an NFS server with rsize=wsize=8192 >> and read a few files - I assume this is sufficient? > > This is orthogonal. > > Only TCP uses this and you need not to do something special > to test it. Any TCP connection going through 3c tests it. Well, yes and no. It's not quite orthogonal, because normally TCP will never transmit fragmented packets, and it's precisely fragmented packets that make the interesting case with a card that supports hardware TCP/UDP checksums. If the packets are not fragmented, then the card can just verify the checksums and be done with it. However, with fragments, all it can do is report a partial checksum to the driver and let the driver (or the stack) combine those partial checksums into one complete checksum once all fragments have arrived. At least that's what the Starfire card does, maybe the 3com is different. :-) Are we even bothering with the partial checksums at this point, or are we falling back to CPU checksumming if the packet is fragmented? And, on a related note: what's involved in making a driver zerocopy-aware? I haven't looked too closely to the current patch, but I was thinking of playing with the starfire driver, since I have all the chipset docs.. Thanks, Ion -- It is better to keep your mouth shut and be thought a fool, than to open it and remove all doubt. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 20:28 ` Ion Badulescu @ 2001-01-25 20:36 ` kuznet 0 siblings, 0 replies; 27+ messages in thread From: kuznet @ 2001-01-25 20:36 UTC (permalink / raw) To: Ion Badulescu; +Cc: linux-kernel, andrewm Hello! > Starfire card does, maybe the 3com is different. :-) 3com _is_ different. 8) I is not an issue, we do not make zerocopy on IP fragments. > Are we even bothering with the partial checksums at this point, or > are we falling back to CPU checksumming if the packet is fragmented? Of course, we are not bothering. > And, on a related note: what's involved in making a driver > zerocopy-aware? I haven't looked too closely to the current patch, > but I was thinking of playing with the starfire driver, since I > have all the chipset docs.. Nothing especially clever. Gather plus checksumming, as described in comment in linux/netdevice.h. Well, just look into one of existing drivers: better, sunhme. 3com and acenic are too stupid to learn something. Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 19:29 ` kuznet 2001-01-25 20:28 ` Ion Badulescu @ 2001-01-25 20:43 ` David S. Miller 2001-01-25 21:11 ` Ion Badulescu 2001-01-25 21:14 ` David S. Miller 2001-01-26 1:27 ` Andrew Morton 2 siblings, 2 replies; 27+ messages in thread From: David S. Miller @ 2001-01-25 20:43 UTC (permalink / raw) To: Ion Badulescu; +Cc: kuznet, linux-kernel, Andrew Morton Ion Badulescu writes: > Well, yes and no. It's not quite orthogonal, because normally TCP > will never transmit fragmented packets, and it's precisely fragmented > packets that make the interesting case with a card that supports > hardware TCP/UDP checksums. No it is not the interesting case for such cards. I have a feeling you have no idea what you are talking about or who you are speaking to. Alexey bascially implemented all of the zerocopy stuff in that patch, so it's a good bet that he has a good idea what is orthogonal or not. > If the packets are not fragmented, then the card can just verify the > checksums and be done with it. However, with fragments, all it can > do is report a partial checksum to the driver and let the driver > (or the stack) combine those partial checksums into one complete > checksum once all fragments have arrived. At least that's what the > Starfire card does, maybe the 3com is different. :-) On transmit, on transmit, that's all that matters on the hardware side with these changes, where the card does the checksumming for us. We've supported receive checksum verification from the hardware forever, long before these changes. The only interesting new thing on receive is that we do not linearize a fragmented packet before passing it on to UDP etc. And this has nothing to do with what the card can or cannot do, it is purely a software issue. > And, on a related note: what's involved in making a driver > zerocopy-aware? I haven't looked too closely to the current patch, When you look closely at the current patch, you will see exactly what is required. 3 hardware drivers are ported there, and are to be used as examples. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 20:43 ` David S. Miller @ 2001-01-25 21:11 ` Ion Badulescu 2001-01-26 19:43 ` kuznet 2001-01-29 22:02 ` David S. Miller 2001-01-25 21:14 ` David S. Miller 1 sibling, 2 replies; 27+ messages in thread From: Ion Badulescu @ 2001-01-25 21:11 UTC (permalink / raw) To: David S. Miller; +Cc: kuznet, linux-kernel, Andrew Morton On Thu, 25 Jan 2001, David S. Miller wrote: > > Ion Badulescu writes: > > Well, yes and no. It's not quite orthogonal, because normally TCP > > will never transmit fragmented packets, and it's precisely fragmented > > packets that make the interesting case with a card that supports > > hardware TCP/UDP checksums. > > No it is not the interesting case for such cards. I have a feeling > you have no idea what you are talking about or who you are speaking > to. Alexey bascially implemented all of the zerocopy stuff in that > patch, so it's a good bet that he has a good idea what is orthogonal > or not. Wrong feeling. :-) No, I know who Alexey is and I think I know what I'm talking about, too. We're just talking about different things, RX vs TX. Obviously there isn't much we can do with fragmented packets on TX. If only the IP people had learned from Ethernet people about a good place for a CRC/csum... > On transmit, on transmit, that's all that matters on the hardware side > with these changes, where the card does the checksumming for us. > We've supported receive checksum verification from the hardware > forever, long before these changes. Hmm, I must have missed the CHECKSUM_HW stuff. Mea culpa. Not that many drivers use it at this time, I see a grand total of 2 (hamachi and hme) in 2.4.0 -- and yes I know who wrote the hme driver, too. :) > > And, on a related note: what's involved in making a driver > > zerocopy-aware? I haven't looked too closely to the current patch, > > When you look closely at the current patch, you will see exactly what > is required. 3 hardware drivers are ported there, and are to be used > as examples. Ok. I'm just wondering, if a card supports sg but *not* TX csum, is it worth it to make use of sg? eepro100 falls into this category.. Thanks, Ion -- It is better to keep your mouth shut and be thought a fool, than to open it and remove all doubt. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 21:11 ` Ion Badulescu @ 2001-01-26 19:43 ` kuznet 2001-01-29 22:02 ` David S. Miller 1 sibling, 0 replies; 27+ messages in thread From: kuznet @ 2001-01-26 19:43 UTC (permalink / raw) To: Ion Badulescu, Dave Miller; +Cc: linux-kernel Hello! > drivers use it at this time, I see a grand total of 2 (hamachi and hme) in Plus acenic in zerocopy. Plus patch to do this is available for eepro100. > I'm just wondering, if a card supports sg but *not* TX csum, is it worth > it to make use of sg? eepro100 falls into this category.. This is simply not permitted just now. Mea culpa... Dave, seems, it is better to repair this. Code really assumes that SG cannot be used without one of CSUM flags... Actually, drivers which are able to SG without checksumming should do this. Even though just this minute this feature has no applications. Next minute it will. Not only with decnet, but for IP too. Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 21:11 ` Ion Badulescu 2001-01-26 19:43 ` kuznet @ 2001-01-29 22:02 ` David S. Miller 1 sibling, 0 replies; 27+ messages in thread From: David S. Miller @ 2001-01-29 22:02 UTC (permalink / raw) To: kuznet; +Cc: Ion Badulescu, linux-kernel kuznet@ms2.inr.ac.ru writes: > Dave, seems, it is better to repair this. Code really assumes > that SG cannot be used without one of CSUM flags... SG+CSUM requirement is enforced now in my tree, I will publish a newer zerocopy patch later today. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 20:43 ` David S. Miller 2001-01-25 21:11 ` Ion Badulescu @ 2001-01-25 21:14 ` David S. Miller 2001-01-25 21:29 ` Steve Whitehouse ` (3 more replies) 1 sibling, 4 replies; 27+ messages in thread From: David S. Miller @ 2001-01-25 21:14 UTC (permalink / raw) To: Ion Badulescu; +Cc: kuznet, linux-kernel, Andrew Morton Ion Badulescu writes: > I'm just wondering, if a card supports sg but *not* TX csum, is it worth > it to make use of sg? eepro100 falls into this category.. No, not worth it for now. In fact I'm going to mark that combination (sg without csum) as illegal in the final zerocopy patch I end up sending to Linus. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 21:14 ` David S. Miller @ 2001-01-25 21:29 ` Steve Whitehouse 2001-01-31 16:04 ` Alan Cox 2001-01-25 21:38 ` [UPDATE] Zerocopy patches, against 2.4.1-pre10 David S. Miller ` (2 subsequent siblings) 3 siblings, 1 reply; 27+ messages in thread From: Steve Whitehouse @ 2001-01-25 21:29 UTC (permalink / raw) To: David S. Miller; +Cc: Ion Badulescu, kuznet, linux-kernel, Andrew Morton Hi, Do you mean that devices will not be able to indicate support of SG seperately from hw checksum or that the IP zerocopy will simply ignore devices which do not have both ? DECnet assumes that the mac level checksum will detect all errors and does not have a checksum of its own on data, so it would only need SG to benefit from the zerocopy framework, Steve. > > > Ion Badulescu writes: > > I'm just wondering, if a card supports sg but *not* TX csum, is it worth > > it to make use of sg? eepro100 falls into this category.. > > No, not worth it for now. In fact I'm going to mark that combination > (sg without csum) as illegal in the final zerocopy patch I end up > sending to Linus. > > Later, > David S. Miller > davem@redhat.com > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > Please read the FAQ at http://www.tux.org/lkml/ > - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 21:29 ` Steve Whitehouse @ 2001-01-31 16:04 ` Alan Cox 2001-03-11 20:55 ` NBD Fix (attempt #2) Steve Whitehouse 0 siblings, 1 reply; 27+ messages in thread From: Alan Cox @ 2001-01-31 16:04 UTC (permalink / raw) To: Steve; +Cc: David S. Miller, Ion Badulescu, kuznet, linux-kernel, Andrew Morton > Do you mean that devices will not be able to indicate support of SG seperately > from hw checksum or that the IP zerocopy will simply ignore devices which > do not have both ? > > DECnet assumes that the mac level checksum will detect all errors and does > not have a checksum of its own on data, so it would only need SG to benefit > from the zerocopy framework, Ditto IPX - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* NBD Fix (attempt #2) 2001-01-31 16:04 ` Alan Cox @ 2001-03-11 20:55 ` Steve Whitehouse 0 siblings, 0 replies; 27+ messages in thread From: Steve Whitehouse @ 2001-03-11 20:55 UTC (permalink / raw) To: Alan Cox; +Cc: pavel, torvalds, axboe, linux-kernel Hi, Below is a patch which I think fixes the NBD hangs properly. It works for me and doesn't need any changes to ll_rw_blk.c like my last patch did. I've shown it to Pavel Machek who has approved it. The patch is against 2.4.2-ac18. Pavel: I've made the change you requested and also added a flag I forgot before. Alan: Please apply this patch to your kernel tree. If memory serves correctly the MSG_MORE flag only appeared in 2.4.2-ac and isn't in the standard 2.4.2 kernel so I'll prepare a separate patch for 2.4.2 if there are no plans to merge the ZC patches for a while. Is there a timescale for this or some criteria by which the ZC changes will be judged ready for merging ? The one other change which might be required is a userland change. The buffer size used for I/O by the nbd-server program is not large enough in the case that a lot of buffers get merged into a single request, this is easy to change though. If you get a message in your syslog on your server machine complaining of a request thats too large, then this is what has happened, Steve. ------------------------------------------------------------------------------ diff -r -u linux-2.4.2-ac18/drivers/block/nbd.c linux/drivers/block/nbd.c --- linux-2.4.2-ac18/drivers/block/nbd.c Sun Mar 11 21:35:14 2001 +++ linux/drivers/block/nbd.c Sun Mar 11 20:18:36 2001 @@ -26,7 +26,6 @@ * structure with userland */ -#undef NBD_PLUGGABLE #define PARANOIA #include <linux/major.h> @@ -68,8 +67,6 @@ static int requests_out; #endif -static void nbd_plug_device(request_queue_t *q, kdev_t dev) { } - static int nbd_open(struct inode *inode, struct file *file) { int dev; @@ -88,7 +85,7 @@ /* * Send or receive packet. */ -static int nbd_xmit(int send, struct socket *sock, char *buf, int size) +static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags) { mm_segment_t oldfs; int result; @@ -118,7 +115,7 @@ msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_namelen = 0; - msg.msg_flags = 0; + msg.msg_flags = msg_flags | MSG_NOSIGNAL; if (send) result = sock_sendmsg(sock, &msg, size); @@ -151,7 +148,7 @@ { int result; struct nbd_request request; - unsigned long size = req->current_nr_sectors << 9; + unsigned long size = req->nr_sectors << 9; DEBUG("NBD: sending control, "); request.magic = htonl(NBD_REQUEST_MAGIC); @@ -160,15 +157,19 @@ request.len = htonl(size); memcpy(request.handle, &req, sizeof(req)); - result = nbd_xmit(1, sock, (char *) &request, sizeof(request)); + result = nbd_xmit(1, sock, (char *) &request, sizeof(request), req->cmd == WRITE ? MSG_MORE : 0); if (result <= 0) FAIL("Sendmsg failed for control."); if (req->cmd == WRITE) { + struct buffer_head *bh = req->bh; DEBUG("data, "); - result = nbd_xmit(1, sock, req->buffer, size); - if (result <= 0) - FAIL("Send data failed."); + do { + result = nbd_xmit(1, sock, bh->b_data, bh->b_size, bh->b_reqnext == NULL ? 0 : MSG_MORE); + if (result <= 0) + FAIL("Send data failed."); + bh = bh->b_reqnext; + } while(bh); } return; @@ -186,7 +187,7 @@ DEBUG("reading control, "); reply.magic = 0; - result = nbd_xmit(0, lo->sock, (char *) &reply, sizeof(reply)); + result = nbd_xmit(0, lo->sock, (char *) &reply, sizeof(reply), MSG_WAITALL); if (result <= 0) HARDFAIL("Recv control failed."); memcpy(&xreq, reply.handle, sizeof(xreq)); @@ -201,10 +202,14 @@ if (ntohl(reply.error)) FAIL("Other side returned error."); if (req->cmd == READ) { + struct buffer_head *bh = req->bh; DEBUG("data, "); - result = nbd_xmit(0, lo->sock, req->buffer, req->current_nr_sectors << 9); - if (result <= 0) - HARDFAIL("Recv data failed."); + do { + result = nbd_xmit(0, lo->sock, bh->b_data, bh->b_size, MSG_WAITALL); + if (result <= 0) + HARDFAIL("Recv data failed."); + bh = bh->b_reqnext; + } while(bh); } DEBUG("done.\n"); return req; @@ -218,7 +223,6 @@ void nbd_do_it(struct nbd_device *lo) { struct request *req; - int dequeued; down (&lo->queue_lock); while (1) { @@ -246,11 +250,9 @@ list_del(&req->queue); up (&lo->queue_lock); - dequeued = nbd_end_request(req); + nbd_end_request(req); down (&lo->queue_lock); - if (!dequeued) - list_add(&req->queue, &lo->queue_head); } out: up (&lo->queue_lock); @@ -259,7 +261,6 @@ void nbd_clear_que(struct nbd_device *lo) { struct request *req; - int dequeued; #ifdef PARANOIA if (lo->magic != LO_MAGIC) { @@ -284,11 +285,9 @@ list_del(&req->queue); up(&lo->queue_lock); - dequeued = nbd_end_request(req); + nbd_end_request(req); down(&lo->queue_lock); - if (!dequeued) - list_add(&req->queue, &lo->queue_head); } } @@ -498,9 +497,6 @@ blksize_size[MAJOR_NR] = nbd_blksizes; blk_size[MAJOR_NR] = nbd_sizes; blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request); -#ifndef NBD_PLUGGABLE - blk_queue_pluggable(BLK_DEFAULT_QUEUE(MAJOR_NR), nbd_plug_device); -#endif blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); for (i = 0; i < MAX_NBD; i++) { nbd_dev[i].refcnt = 0; diff -r -u linux-2.4.2-ac18/include/linux/blk.h linux/include/linux/blk.h --- linux-2.4.2-ac18/include/linux/blk.h Sun Mar 11 21:35:17 2001 +++ linux/include/linux/blk.h Sun Mar 11 20:20:08 2001 @@ -42,7 +42,6 @@ extern int swimiop_init(void); extern int amiga_floppy_init(void); extern int atari_floppy_init(void); -extern int nbd_init(void); extern int ez_init(void); extern int bpcd_init(void); extern int ps2esdi_init(void); diff -r -u linux-2.4.2-ac18/include/linux/nbd.h linux/include/linux/nbd.h --- linux-2.4.2-ac18/include/linux/nbd.h Mon Dec 11 20:50:42 2000 +++ linux/include/linux/nbd.h Sun Mar 11 20:23:48 2001 @@ -31,35 +31,27 @@ extern int requests_out; #endif -static int +static void nbd_end_request(struct request *req) { + struct buffer_head *bh; + unsigned nsect; unsigned long flags; - int ret = 0; + int uptodate = (req->errors == 0) ? 1 : 0; #ifdef PARANOIA requests_out++; #endif - /* - * This is a very dirty hack that we have to do to handle - * merged requests because end_request stuff is a bit - * broken. The fact we have to do this only if there - * aren't errors looks even more silly. - */ - if (!req->errors) { - req->sector += req->current_nr_sectors; - req->nr_sectors -= req->current_nr_sectors; - } - spin_lock_irqsave(&io_request_lock, flags); - if (end_that_request_first( req, !req->errors, "nbd" )) - goto out; - ret = 1; - end_that_request_last( req ); - -out: + while((bh = req->bh) != NULL) { + nsect = bh->b_size >> 9; + blk_finished_io(nsect); + req->bh = bh->b_reqnext; + bh->b_reqnext = NULL; + bh->b_end_io(bh, uptodate); + } + blkdev_release_request(req); spin_unlock_irqrestore(&io_request_lock, flags); - return ret; } #define MAX_NBD 128 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 21:14 ` David S. Miller 2001-01-25 21:29 ` Steve Whitehouse @ 2001-01-25 21:38 ` David S. Miller 2001-01-26 6:06 ` Ion Badulescu 2001-01-26 13:13 ` David S. Miller 3 siblings, 0 replies; 27+ messages in thread From: David S. Miller @ 2001-01-25 21:38 UTC (permalink / raw) To: Steve Whitehouse; +Cc: Ion Badulescu, kuznet, linux-kernel, Andrew Morton Steve Whitehouse writes: > Do you mean that devices will not be able to indicate support of SG seperately > from hw checksum or that the IP zerocopy will simply ignore devices which > do not have both ? IP will ignore devices which do not have both. > DECnet assumes that the mac level checksum will detect all errors and does > not have a checksum of its own on data, so it would only need SG to benefit > from the zerocopy framework, Which is just fine. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 21:14 ` David S. Miller 2001-01-25 21:29 ` Steve Whitehouse 2001-01-25 21:38 ` [UPDATE] Zerocopy patches, against 2.4.1-pre10 David S. Miller @ 2001-01-26 6:06 ` Ion Badulescu 2001-01-26 13:13 ` David S. Miller 3 siblings, 0 replies; 27+ messages in thread From: Ion Badulescu @ 2001-01-26 6:06 UTC (permalink / raw) To: David S. Miller; +Cc: kuznet, linux-kernel On Thu, 25 Jan 2001, David S. Miller wrote: > Ion Badulescu writes: > > I'm just wondering, if a card supports sg but *not* TX csum, is it worth > > it to make use of sg? eepro100 falls into this category.. > > No, not worth it for now. In fact I'm going to mark that combination > (sg without csum) as illegal in the final zerocopy patch I end up > sending to Linus. Well, in the meantime I've ported the starfire driver to the zerocopy framework, it now takes almost full advantage of the card sg+csum capabilities. The patch is attached; I'd appreciate it if you could include it into the main zerocopy patch. I've tested the new driver using a dual-port starfire, and it survived all my attempts to kill it with fragmented TCP, UDP and ICMP. More testers would be welcome, though. BTW, it looks like not many people are using this driver: the original had a bug which made it spit out one printk per Tx packet, which was *not* funny. Also, the module could not be unloaded and reloaded, as it failed to release some of its resources (Alan already has a fix for that).. Thanks, Ion -- It is better to keep your mouth shut and be thought a fool, than to open it and remove all doubt. -------------------------------------------------- diff -urNX diff_kernel_excludes /usr/src/local/linux-2.4/drivers/net/starfire.c linux-2.4/drivers/net/starfire.c --- /usr/src/local/linux-2.4/drivers/net/starfire.c Fri Jan 12 12:52:48 2001 +++ linux-2.4/drivers/net/starfire.c Thu Jan 25 21:23:18 2001 @@ -34,6 +34,10 @@ LK1.1.4 (jgarzik): - Merge Becker version 1.03 + + LK1.2.0 (Ion Badulescu <ionut@cs.columbia.edu>) + - Support hardware Rx/Tx checksumming + - Add GFP firmware taken from Adaptec's Netware driver */ /* These identify the driver base version and may not be removed. */ @@ -43,7 +47,7 @@ " Updates and info at http://www.scyld.com/network/starfire.html\n"; static const char version3[] = -" (unofficial 2.4.x kernel port, version 1.1.4, August 10, 2000)\n"; +" (unofficial 2.4.x kernel port, version 1.2.0, January 25, 2001)\n"; /* The user-configurable values. These may be modified when a driver module is loaded.*/ @@ -117,6 +121,8 @@ #include <asm/bitops.h> #include <asm/io.h> +#include "starfire_firmware.h" + MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); MODULE_PARM(max_interrupt_work, "i"); @@ -256,10 +262,10 @@ TxThreshold=0x500B0, CompletionHiAddr=0x500B4, TxCompletionAddr=0x500B8, RxCompletionAddr=0x500BC, RxCompletionQ2Addr=0x500C0, - CompletionQConsumerIdx=0x500C4, + CompletionQConsumerIdx=0x500C4, RxDMACtrl=0x500D0, RxDescQCtrl=0x500D4, RxDescQHiAddr=0x500DC, RxDescQAddr=0x500E0, RxDescQIdx=0x500E8, RxDMAStatus=0x500F0, RxFilterMode=0x500F4, - TxMode=0x55000, + TxMode=0x55000, TxGfpMem=0x58000, RxGfpMem=0x5a000, }; /* Bits in the interrupt status/mask registers. */ @@ -288,8 +294,12 @@ /* Completion queue entry. You must update the page allocation, init_ring and the shift count in rx() if using a larger format. */ +#define csum_rx_status struct rx_done_desc { u32 status; /* Low 16 bits is length. */ +#ifdef csum_rx_status + u32 status2; /* Low 16 bits is csum */ +#endif #ifdef full_rx_status u32 status2; u16 vlanid; @@ -307,8 +317,9 @@ u32 addr; }; enum tx_desc_bits { - TxDescID=0xB1010000, /* Also marks single fragment, add CRC. */ - TxDescIntr=0x08000000, TxRingWrap=0x04000000, + TxDescID=0xB0000000, + TxCRCEn=0x01000000, TxDescIntr=0x08000000, + TxRingWrap=0x04000000, TxCalTCP=0x02000000, }; struct tx_done_report { u32 status; /* timestamp, index. */ @@ -318,9 +329,14 @@ }; #define PRIV_ALIGN 15 /* Required alignment mask */ -struct ring_info { +struct rx_ring_info { + struct sk_buff *skb; + dma_addr_t mapping; +}; +struct tx_ring_info { struct sk_buff *skb; dma_addr_t mapping; + int len; }; struct netdev_private { @@ -330,8 +346,8 @@ dma_addr_t rx_ring_dma; dma_addr_t tx_ring_dma; /* The addresses of rx/tx-in-place skbuffs. */ - struct ring_info rx_info[RX_RING_SIZE]; - struct ring_info tx_info[TX_RING_SIZE]; + struct rx_ring_info rx_info[RX_RING_SIZE]; + struct tx_ring_info tx_info[TX_RING_SIZE]; /* Pointers to completion queues (full pages). I should cache line pad..*/ u8 pad0[100]; struct rx_done_desc *rx_done_q; @@ -435,6 +451,9 @@ printk(KERN_INFO "%s: %s at 0x%lx, ", dev->name, netdrv_tbl[chip_idx].name, ioaddr); + /* Starfire can do SG and TCP/UDP checksumming */ + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + /* Serial EEPROM reads are hidden by the hardware. */ for (i = 0; i < 6; i++) dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i); @@ -565,7 +584,7 @@ if (np->tx_done_q == 0) np->tx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_done_q_dma); if (np->rx_done_q == 0) - np->rx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_done_q_dma); + np->rx_done_q = pci_alloc_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, &np->rx_done_q_dma); if (np->tx_ring == 0) np->tx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_ring_dma); if (np->rx_ring == 0) @@ -576,7 +595,7 @@ pci_free_consistent(np->pci_dev, PAGE_SIZE, np->tx_done_q, np->tx_done_q_dma); if (np->rx_done_q) - pci_free_consistent(np->pci_dev, PAGE_SIZE, + pci_free_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, np->rx_done_q, np->rx_done_q_dma); if (np->tx_ring) pci_free_consistent(np->pci_dev, PAGE_SIZE, @@ -591,6 +610,8 @@ init_ring(dev); /* Set the size of the Rx buffers. */ writel((np->rx_buf_sz<<16) | 0xA000, ioaddr + RxDescQCtrl); + /* Make the card reject bad csum TCP/UDP packets */ + writel(0x03000604, ioaddr + RxDMACtrl); /* Set Tx descriptor to type 1 and padding to 0 bytes. */ writel(0x02000401, ioaddr + TxDescCtrl); @@ -608,7 +629,15 @@ writel(np->tx_ring_dma, ioaddr + TxRingPtr); writel(np->tx_done_q_dma, ioaddr + TxCompletionAddr); +#ifdef full_rx_status + writel(np->rx_done_q_dma | 0x30, ioaddr + RxCompletionAddr); +#else +#ifdef csum_rx_status + writel(np->rx_done_q_dma | 0x20, ioaddr + RxCompletionAddr); +#else writel(np->rx_done_q_dma, ioaddr + RxCompletionAddr); +#endif +#endif if (debug > 1) printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name); @@ -651,8 +680,13 @@ writel(0x00800000 | readl(ioaddr + PCIDeviceConfig), ioaddr + PCIDeviceConfig); - /* Enable the Rx and Tx units. */ - writel(0x000F, ioaddr + GenCtrl); + /* Load Rx/Tx firmware into the frame processors */ + for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++) + writel(cpu_to_le32(firmware_rx[i]), ioaddr + RxGfpMem + i * 4); + for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++) + writel(cpu_to_le32(firmware_tx[i]), ioaddr + TxGfpMem + i * 4); + /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ + writel(0x003F, ioaddr + GenCtrl); if (debug > 2) printk(KERN_DEBUG "%s: Done netdev_open().\n", @@ -806,6 +840,7 @@ for (i = 0; i < TX_RING_SIZE; i++) { np->tx_info[i].skb = NULL; np->tx_info[i].mapping = 0; + np->tx_info[i].len = 0; np->tx_ring[i].status = 0; } return; @@ -814,50 +849,79 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; - unsigned entry; + unsigned entry, old_entry; + int frag; /* Caution: the write order is important here, set the field with the "ownership" bits last. */ + if (np->cur_tx + skb_shinfo(skb)->nr_frags - np->dirty_tx >= TX_RING_SIZE - 1) { + np->tx_full = 1; + netif_stop_queue(dev); + return 1; + } + /* Calculate the next Tx descriptor entry. */ - entry = np->cur_tx % TX_RING_SIZE; + old_entry = entry = np->cur_tx % TX_RING_SIZE; - np->tx_info[entry].skb = skb; + if (skb_shinfo(skb)->nr_frags == 0) + np->tx_info[entry].skb = skb; + np->tx_info[entry].len = skb_headlen(skb); np->tx_info[entry].mapping = - pci_map_single(np->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); + pci_map_single(np->pci_dev, skb->data, np->tx_info[entry].len, PCI_DMA_TODEVICE); np->tx_ring[entry].addr = cpu_to_le32(np->tx_info[entry].mapping); /* Add "| TxDescIntr" to generate Tx-done interrupts. */ - np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID); + np->tx_ring[entry].status = cpu_to_le32(np->tx_info[entry].len | TxDescID | TxCRCEn); + np->tx_ring[entry].status |= cpu_to_le32((skb_shinfo(skb)->nr_frags + 1) << 16); + + if (skb->ip_summed == CHECKSUM_HW) + np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP); + + if (entry + skb_shinfo(skb)->nr_frags >= TX_RING_SIZE-1) { /* Wrap ring */ + np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr); + entry = -1; + } + if (debug > 5) { printk(KERN_DEBUG "%s: Tx #%d slot %d %8.8x %8.8x.\n", - dev->name, np->cur_tx, entry, - le32_to_cpu(np->tx_ring[entry].status), - le32_to_cpu(np->tx_ring[entry].addr)); + dev->name, np->cur_tx, old_entry, + le32_to_cpu(np->tx_ring[old_entry].status), + le32_to_cpu(np->tx_ring[old_entry].addr)); } + np->cur_tx++; -#if 1 - if (entry >= TX_RING_SIZE-1) { /* Wrap ring */ - np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr); - entry = -1; - } -#endif /* Non-x86: explicitly flush descriptor cache lines here. */ /* Update the producer index. */ writel(++entry, dev->base_addr + TxProducerIdx); - if (np->cur_tx - np->dirty_tx >= TX_RING_SIZE - 1) { - np->tx_full = 1; - netif_stop_queue(dev); + for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { + skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + + /* we already have the proper value in entry */ + if (skb_shinfo(skb)->nr_frags == frag + 1) + np->tx_info[entry].skb = skb; + np->tx_info[entry].mapping = + pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE); + np->tx_info[entry].len = this_frag->size; + + np->tx_ring[entry].addr = cpu_to_le32(np->tx_info[entry].mapping); + np->tx_ring[entry].status = cpu_to_le32(this_frag->size | TxDescID); + if (debug > 5) { + printk(KERN_DEBUG "%s: Tx #%d slot %d %8.8x %8.8x.\n", + dev->name, np->cur_tx, entry, + le32_to_cpu(np->tx_ring[entry].status), + le32_to_cpu(np->tx_ring[entry].addr)); + } + np->cur_tx++; + /* Update the producer index. */ + writel(++entry, dev->base_addr + TxProducerIdx); } + dev->trans_start = jiffies; - if (debug > 4) { - printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n", - dev->name, np->cur_tx, entry); - } return 0; } @@ -923,15 +987,18 @@ u16 entry = tx_status; /* Implicit truncate */ entry >>= 3; - skb = np->tx_info[entry].skb; pci_unmap_single(np->pci_dev, - np->tx_info[entry].mapping, - skb->len, PCI_DMA_TODEVICE); - - /* Scavenge the descriptor. */ - dev_kfree_skb_irq(skb); - np->tx_info[entry].skb = NULL; + np->tx_info[entry].mapping, + np->tx_info[entry].len, PCI_DMA_TODEVICE); np->tx_info[entry].mapping = 0; + np->tx_info[entry].len = 0; + + skb = np->tx_info[entry].skb; + if (skb != NULL) { + /* Scavenge the descriptor. */ + dev_kfree_skb_irq(skb); + np->tx_info[entry].skb = NULL; + } np->dirty_tx++; } np->tx_done_q[np->tx_done].status = 0; @@ -1038,14 +1105,16 @@ temp = skb_put(skb, pkt_len); np->rx_info[entry].skb = NULL; np->rx_info[entry].mapping = 0; +#if 0 #ifndef final_version /* Remove after testing. */ - if (le32_to_cpu(np->rx_ring[entry].rxaddr & ~3) != ((unsigned long) temp)) + if ((le32_to_cpu(np->rx_ring[entry].rxaddr) & ~3) != ((unsigned long) temp)) printk(KERN_ERR "%s: Internal fault: The skbuff addresses " - "do not match in netdev_rx: %d vs. %p / %p.\n", + "do not match in netdev_rx: %x vs. %p / %p.\n", dev->name, le32_to_cpu(np->rx_ring[entry].rxaddr), skb->head, temp); #endif +#endif } #ifndef final_version /* Remove after testing. */ /* You will want this info for the initial debug. */ @@ -1061,9 +1130,23 @@ skb->data[17]); #endif skb->protocol = eth_type_trans(skb, dev); -#ifdef full_rx_status - if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) +#if defined(full_rx_status) || defined(csum_rx_status) + if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) { skb->ip_summed = CHECKSUM_UNNECESSARY; + } + /* + * This feature doesn't seem to be working, at least + * with the two firmware versions I have. If the GFP sees + * a fragment, it either ignores it completely, or reports + * "bad checksum" on it. + * + * Maybe I missed something -- corrections are welcome. -Ion + */ + else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) { + skb->ip_summed = CHECKSUM_HW; + skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff; + printk(KERN_DEBUG "sf: checksum_hw, status2 = %x\n", np->rx_done_q[np->rx_done].status2); + } #endif netif_rx(skb); dev->last_rx = jiffies; @@ -1340,6 +1423,7 @@ } np->tx_info[i].skb = NULL; np->tx_info[i].mapping = 0; + np->tx_info[i].len = 0; } MOD_DEC_USE_COUNT; diff -urNX diff_kernel_excludes /usr/src/local/linux-2.4/drivers/net/starfire_firmware.h linux-2.4/drivers/net/starfire_firmware.h --- /usr/src/local/linux-2.4/drivers/net/starfire_firmware.h Wed Dec 31 16:00:00 1969 +++ linux-2.4/drivers/net/starfire_firmware.h Thu Jan 25 21:43:27 2001 @@ -0,0 +1,215 @@ +static u32 firmware_rx[] = { + 0x010003dc, 0x00000000, + 0x04000421, 0x00000086, + 0x80000015, 0x0000180e, + 0x81000015, 0x00006664, + 0x1a0040ab, 0x00000b06, + 0x14200011, 0x00000000, + 0x14204022, 0x0000aaaa, + 0x14204022, 0x00000300, + 0x14204022, 0x00000000, + 0x1a0040ab, 0x00000b14, + 0x14200011, 0x00000000, + 0x83000015, 0x00000002, + 0x04000021, 0x00000000, + 0x00000010, 0x00000000, + 0x04000421, 0x00000087, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00008015, 0x00000000, + 0x0000003e, 0x00000000, + 0x00000010, 0x00000000, + 0x82000015, 0x00004000, + 0x009e8050, 0x00000000, + 0x03008015, 0x00000000, + 0x86008015, 0x00000000, + 0x82000015, 0x00008000, + 0x0100001c, 0x00000000, + 0x000050a0, 0x0000010c, + 0x4e20d011, 0x00006008, + 0x1420d012, 0x00004008, + 0x0000f090, 0x00007000, + 0x0000c8b0, 0x00003000, + 0x00004040, 0x00000000, + 0x00108015, 0x00000000, + 0x00a2c150, 0x00004000, + 0x00a400b0, 0x00000014, + 0x00000020, 0x00000000, + 0x2500400d, 0x00002525, + 0x00047220, 0x00003100, + 0x00934070, 0x00000000, + 0x00000020, 0x00000000, + 0x00924460, 0x00000184, + 0x2b20c011, 0x00000000, + 0x0000c420, 0x00000540, + 0x36014018, 0x0000422d, + 0x14200011, 0x00000000, + 0x00924460, 0x00000183, + 0x3200001f, 0x00000034, + 0x02ac0015, 0x00000002, + 0x00a60110, 0x00000008, + 0x42200011, 0x00000000, + 0x00924060, 0x00000103, + 0x0000001e, 0x00000000, + 0x00000020, 0x00000100, + 0x0000001e, 0x00000000, + 0x00924460, 0x00000086, + 0x00004080, 0x00000000, + 0x0092c070, 0x00000000, + 0x00924060, 0x00000100, + 0x0000c890, 0x00005000, + 0x00a6c110, 0x00000000, + 0x00b0c090, 0x00000012, + 0x021c0015, 0x00000000, + 0x3200001f, 0x00000034, + 0x00924460, 0x00000510, + 0x44210011, 0x00000000, + 0x42000011, 0x00000000, + 0x83000015, 0x00000040, + 0x00924460, 0x00000508, + 0x45014018, 0x00004545, + 0x00808050, 0x00000000, + 0x83000015, 0x00000040, + 0x62208012, 0x00000000, + 0x82000015, 0x00000800, + 0x15200011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x80000015, 0x0000eea4, + 0x81000015, 0x0000005f, + 0x00000060, 0x00000000, + 0x00004120, 0x00000000, + 0x00004a00, 0x00004000, + 0x00924460, 0x00000190, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00934050, 0x00000018, + 0x00930050, 0x00000018, + 0x3601403a, 0x0000002d, + 0x000643a9, 0x00000000, + 0x0000c420, 0x00000140, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x000642a9, 0x00000000, + 0x00024420, 0x00000183, + 0x5601401a, 0x00005956, + 0x82000015, 0x00002000, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, +}; /* 104 Rx instructions */ +#define FIRMWARE_RX_SIZE 104 + +static u32 firmware_tx[] = { + 0x010003dc, 0x00000000, + 0x04000421, 0x00000086, + 0x80000015, 0x0000180e, + 0x81000015, 0x00006664, + 0x1a0040ab, 0x00000b06, + 0x14200011, 0x00000000, + 0x14204022, 0x0000aaaa, + 0x14204022, 0x00000300, + 0x14204022, 0x00000000, + 0x1a0040ab, 0x00000b14, + 0x14200011, 0x00000000, + 0x83000015, 0x00000002, + 0x04000021, 0x00000000, + 0x00000010, 0x00000000, + 0x14204022, 0x0000000c, + 0x04000421, 0x00000087, + 0x00000010, 0x00000000, + 0x00008015, 0x00000000, + 0x0000003e, 0x00000000, + 0x00000010, 0x00000000, + 0x82000015, 0x00004000, + 0x009e8050, 0x00000000, + 0x03008015, 0x00000000, + 0x86008015, 0x00000000, + 0x82000015, 0x00008000, + 0x0100001c, 0x00000000, + 0x000050a0, 0x0000010c, + 0x4e20d011, 0x00006008, + 0x1420d012, 0x00004008, + 0x0000f090, 0x00007000, + 0x0000c8b0, 0x00003000, + 0x00004040, 0x00000000, + 0x00108015, 0x00000000, + 0x00a2c150, 0x00004000, + 0x00a400b0, 0x00000014, + 0x00000020, 0x00000000, + 0x2500400d, 0x00002525, + 0x00047220, 0x00003100, + 0x00934070, 0x00000000, + 0x00000020, 0x00000000, + 0x00924460, 0x00000184, + 0x2b20c011, 0x00000000, + 0x0000c420, 0x00000540, + 0x36014018, 0x00004b2d, + 0x14200011, 0x00000000, + 0x00924460, 0x00000183, + 0x3200001f, 0x00000034, + 0x02ac0015, 0x00000002, + 0x00a60110, 0x00000008, + 0x42200011, 0x00000000, + 0x00924060, 0x00000103, + 0x0000001e, 0x00000000, + 0x00000020, 0x00000100, + 0x0000001e, 0x00000000, + 0x00924460, 0x00000086, + 0x00004080, 0x00000000, + 0x0092c070, 0x00000000, + 0x00924060, 0x00000100, + 0x0000c890, 0x00005000, + 0x00a6c110, 0x00000000, + 0x00b0c090, 0x00000012, + 0x021c0015, 0x00000000, + 0x3200001f, 0x00000034, + 0x00924460, 0x00000510, + 0x45210011, 0x00000000, + 0x42000011, 0x00000000, + 0x43014018, 0x00004343, + 0x83000015, 0x00000040, + 0x00924460, 0x00000508, + 0x00808050, 0x00000000, + 0x62208012, 0x00000000, + 0x82000015, 0x00000800, + 0x15200011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000050, 0x00000000, + 0x00070050, 0x00000000, + 0x36014018, 0x0000422d, + 0x80000015, 0x0000eea4, + 0x81000015, 0x0000005f, + 0x00000060, 0x00000000, + 0x00004120, 0x00000000, + 0x00004a00, 0x00004000, + 0x00924460, 0x00000190, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00934050, 0x00000018, + 0x00930050, 0x00000018, + 0x3601403a, 0x0000002d, + 0x000643a9, 0x00000000, + 0x0000c420, 0x00000140, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x000642a9, 0x00000000, + 0x00024420, 0x00000183, + 0x5601401a, 0x00005956, + 0x82000015, 0x00002000, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, +}; /* 104 Tx instructions */ +#define FIRMWARE_TX_SIZE 104 diff -urNX diff_kernel_excludes /usr/src/local/linux-2.4/drivers/net/starfire_firmware.pl linux-2.4/drivers/net/starfire_firmware.pl --- /usr/src/local/linux-2.4/drivers/net/starfire_firmware.pl Wed Dec 31 16:00:00 1969 +++ linux-2.4/drivers/net/starfire_firmware.pl Thu Jan 25 21:43:27 2001 @@ -0,0 +1,31 @@ +#!/usr/bin/perl + +# This script can be used to generate a new starfire_firmware.h +# from GFP_RX.DAT and GFP_TX.DAT, files included with the DDK +# and also with the Novell drivers. + +open FW, "GFP_RX.DAT" || die; +open FWH, ">starfire_firmware.h" || die; + +printf(FWH "static u32 firmware_rx[] = {\n"); +$counter = 0; +while ($foo = <FW>) { + chomp; + printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4)); + $counter++; +} + +close FW; +open FW, "GFP_TX.DAT" || die; + +printf(FWH "};\t/* %d Rx instructions */\n#define FIRMWARE_RX_SIZE %d\n\nstatic u32 firmware_tx[] = {\n", $counter, $counter); +$counter = 0; +while ($foo = <FW>) { + chomp; + printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4)); + $counter++; +} + +close FW; +printf(FWH "};\t/* %d Tx instructions */\n#define FIRMWARE_TX_SIZE %d\n", $counter, $counter); +close(FWH); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 21:14 ` David S. Miller ` (2 preceding siblings ...) 2001-01-26 6:06 ` Ion Badulescu @ 2001-01-26 13:13 ` David S. Miller 2001-01-26 20:43 ` Ion Badulescu 3 siblings, 1 reply; 27+ messages in thread From: David S. Miller @ 2001-01-26 13:13 UTC (permalink / raw) To: Ion Badulescu; +Cc: kuznet, linux-kernel Ion Badulescu writes: > Well, in the meantime I've ported the starfire driver to the zerocopy > framework, it now takes almost full advantage of the card sg+csum > capabilities. The patch is attached; I'd appreciate it if you could > include it into the main zerocopy patch. Great, some commentary, see below. > BTW, it looks like not many people are using this driver: the original had > a bug which made it spit out one printk per Tx packet, which was *not* > funny. Also, the module could not be unloaded and reloaded, as it failed > to release some of its resources (Alan already has a fix for that).. Indeed. Firstly, I would not configure the card to drop packets with bad checksums. If you do this, the errors do not propagate into the correct ipv4 snmp tables, which is bad. Also consider the case where the card has some bug and it erroneously verifies rx checksums in some strange cases, we would be hard pressed to find out with how you are configuring it in this way. Next, please remove the unconditional: + printk(KERN_DEBUG "sf: checksum_hw, status2 = %x\n", np->rx_done_q[np->rx_done].status2); or at the very least make it print out netdev->name instead of the cryptic "sf: " prefix. Finally, what are the listed distribution terms of this firmware? I want to make sure it is legal to distribute it. Deal with these three issues, and I'll stick this into my zerocopy patch sets. Thanks again. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-26 13:13 ` David S. Miller @ 2001-01-26 20:43 ` Ion Badulescu 2001-01-27 0:55 ` Ion Badulescu 0 siblings, 1 reply; 27+ messages in thread From: Ion Badulescu @ 2001-01-26 20:43 UTC (permalink / raw) To: David S. Miller; +Cc: kuznet, linux-kernel On Fri, 26 Jan 2001, David S. Miller wrote: > Firstly, I would not configure the card to drop packets with bad > checksums. If you do this, the errors do not propagate into the > correct ipv4 snmp tables, which is bad. Also consider the case where > the card has some bug and it erroneously verifies rx checksums in some > strange cases, we would be hard pressed to find out with how you are > configuring it in this way. Ok. Makes sense. Consider it done. > Next, please remove the unconditional: > > + printk(KERN_DEBUG "sf: checksum_hw, status2 = %x\n", np->rx_done_q[np->rx_done].status2); > > or at the very least make it print out netdev->name instead of the > cryptic "sf: " prefix. I'll change the prefix, but I want to leave it there, because it never triggered in my testing. And I'd really like it to annoy people so much when it does trigger, that they report it back. :-) > Finally, what are the listed distribution terms of this firmware? > I want to make sure it is legal to distribute it. Hmm, that's a very good question. I got the two firmware files from Adaptec's Netware driver, and there is nothing in the archive or in those files even remotely similar to a license or distribution terms. I guess the best way to go about it would be to get an official answer from Adaptec. Is there anybody out there with some Adaptec contacts who is willing to step in and help with this? In any case, I have the architecture description and instruction set of the frame processor, so in the worst case I could simply reimplement the code. It wouldn't be much different than the Adaptec aic7xxx sequencer case. Besides, I've done some more testing last night, and there are some problems. The FP doesn't seem to like tinygrams too much, every once in a while (but *not* always) it decides to send one with a bad checksum. I'm talking especially about telnet tinygrams, where the second fragment is 1 byte. What's worse, it will also resend it with a bad checksum, effectively killing the connection. Could this be a bug in the upper layers, instead? How would I go about to verify this? The only way I can think of is to verify that the checksum field is zero initially, correct? Also, after putting some more stress on the card, I managed to get it to generate an abnormal interrupt (the "Something Wicked happened" thing), and the error code translates to "GFP unable to calculate the checksum (???) or not responding for 16 transmit cycles". And, since the reset procedure is not implemented in the driver, this is quite deadly. So I want to try and switch the transmit descriptor to the one used by Netware, maybe the firmware was only tested with that descriptor. It also fits the new Linux model a bit better, as it has one descriptor per packet, not one per fragment (like the current implementation). Thanks, Ion -- It is better to keep your mouth shut and be thought a fool, than to open it and remove all doubt. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-26 20:43 ` Ion Badulescu @ 2001-01-27 0:55 ` Ion Badulescu 2001-01-27 18:39 ` kuznet 0 siblings, 1 reply; 27+ messages in thread From: Ion Badulescu @ 2001-01-27 0:55 UTC (permalink / raw) To: David S. Miller; +Cc: kuznet, linux-kernel On Fri, 26 Jan 2001, Ion Badulescu wrote: > Besides, I've done some more testing last night, and there are some > problems. The FP doesn't seem to like tinygrams too much, every once in a > while (but *not* always) it decides to send one with a bad checksum. I'm > talking especially about telnet tinygrams, where the second fragment is 1 > byte. What's worse, it will also resend it with a bad checksum, > effectively killing the connection. > > Could this be a bug in the upper layers, instead? How would I go about to > verify this? The only way I can think of is to verify that the checksum > field is zero initially, correct? [...] > So I want to try and switch the transmit descriptor to the one used by > Netware, maybe the firmware was only tested with that descriptor. It also > fits the new Linux model a bit better, as it has one descriptor per > packet, not one per fragment (like the current implementation). So, I've re-implemented the Tx code to use the type0 Tx descriptor, and the code is definitely cleaner. However, the card still has an issue with tinygrams. A TCP packet whose second fragment is 1-byte long usually goes over the wire with the wrong checksum. If the second fragment is 3-byte long, it is checksummed correctly (so it's not an even/odd problem). Any ideas? Is there even the slightest chance that something might not be ok in the skb received from above? Thanks, Ion -- It is better to keep your mouth shut and be thought a fool, than to open it and remove all doubt. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-27 0:55 ` Ion Badulescu @ 2001-01-27 18:39 ` kuznet 2001-01-27 21:18 ` Ion Badulescu 2001-01-30 6:02 ` David S. Miller 0 siblings, 2 replies; 27+ messages in thread From: kuznet @ 2001-01-27 18:39 UTC (permalink / raw) To: Ion Badulescu; +Cc: davem, linux-kernel Hello! > verify this? The only way I can think of is to verify that the checksum > field is zero initially, correct? It is not zero. It contains checksum of pseudoheader. > fits the new Linux model a bit better, as it has one descriptor per > packet, not one per fragment (like the current implementation). Yes. Absence of such mode with acenic is big pain in ass. > tinygrams. A TCP packet whose second fragment is 1-byte long usually goes > over the wire with the wrong checksum. If the second fragment is 3-byte > long, it is checksummed correctly (so it's not an even/odd problem). Seems, this is pretty common bug. At least, perfect checksumming of chunks with any size and alignment is so big boast of alteon people, that it is clearly rather exception than rule. 8)8) I think you have to check for wrong combination of alignment/size and to call skb_checksum_help() and to disable checksumming if combination is bad. Alexey - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-27 18:39 ` kuznet @ 2001-01-27 21:18 ` Ion Badulescu 2001-01-30 6:02 ` David S. Miller 1 sibling, 0 replies; 27+ messages in thread From: Ion Badulescu @ 2001-01-27 21:18 UTC (permalink / raw) To: kuznet; +Cc: davem, linux-kernel [-- Attachment #1: Type: TEXT/PLAIN, Size: 2173 bytes --] Hi Alexey, On Sat, 27 Jan 2001 kuznet@ms2.inr.ac.ru wrote: > > fits the new Linux model a bit better, as it has one descriptor per > > packet, not one per fragment (like the current implementation). > > Yes. Absence of such mode with acenic is big pain in ass. And, at least for the starfire, using buffer descriptors eats up more resources than using packet descriptors. So buffer descriptors are gone, forever. > Seems, this is pretty common bug. At least, perfect checksumming > of chunks with any size and alignment is so big boast of > alteon people, that it is clearly rather exception than rule. 8)8) Oh well. Don't we wish hardware were perfect.. :-) It's not too bad for the starfire, either, as it doesn't appear to suffer from any alignment issues, and the only fragments it has problem with are 1-byte fragments (2-byte and larger are ok). And I'm still hoping that Adaptec will release updated firmware (and that they will also approve the inclusion of their firmware with the Linux driver). If they don't approve it, maybe I'll add a config option so that the user can download their own copy of the firmware from Adaptec's site, place it in /etc somewhere, give the location to the driver and have the driver open the files from kernel space and process them. It would be ugly though, and a big PITA. > I think you have to check for wrong combination of alignment/size and > to call skb_checksum_help() and to disable checksumming if combination > is bad. Good, thanks a lot for the pointer. Maybe I went a bit overboard with my fix, as I revert to CPU checksumming if *any* fragment (not just the last one in the chain) has only 1 byte. But it seems to work well now. I've attached a diff for the latest driver (and firmware) version, against 2.4.1pre10+zerocopy. Sorry about MIME, but my pine is currently broken (strips trailing spaces/tabs). And, one final question: is it worth it for me to extract just the Rx checksumming changes and send them to Linux/Alan, or should I just wait for zerocopy to be included? Thanks, Ion -- It is better to keep your mouth shut and be thought a fool, than to open it and remove all doubt. [-- Attachment #2: Type: TEXT/PLAIN, Size: 29627 bytes --] diff -urNX diff_kernel_excludes /usr/src/local/linux-2.4.vanilla/drivers/net/starfire.c linux-2.4/drivers/net/starfire.c --- /usr/src/local/linux-2.4.vanilla/drivers/net/starfire.c Fri Aug 11 15:57:58 2000 +++ linux-2.4/drivers/net/starfire.c Sat Jan 27 12:44:35 2001 @@ -34,6 +34,10 @@ LK1.1.4 (jgarzik): - Merge Becker version 1.03 + + LK1.2.0 (Ion Badulescu <ionut@cs.columbia.edu>) + - Support hardware Rx/Tx checksumming + - Add GFP firmware taken from Adaptec's Netware driver */ /* These identify the driver base version and may not be removed. */ @@ -43,11 +47,17 @@ " Updates and info at http://www.scyld.com/network/starfire.html\n"; static const char version3[] = -" (unofficial 2.4.x kernel port, version 1.1.4, August 10, 2000)\n"; +" (unofficial 2.4.x kernel port, version 1.2.0, January 25, 2001)\n"; /* The user-configurable values. These may be modified when a driver module is loaded.*/ +/* + * The current frame processor firmware fails to checksum a fragment + * of length 1. If and when this is fixed, the #define below can be removed. + */ +#define HAS_BROKEN_FIRMWARE + /* Used for tuning interrupt latency vs. overhead. */ static int interrupt_mitigation = 0x0; @@ -117,12 +127,15 @@ #include <asm/bitops.h> #include <asm/io.h> +#include "starfire_firmware.h" + MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); MODULE_PARM(max_interrupt_work, "i"); MODULE_PARM(mtu, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(interrupt_mitigation, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); @@ -256,19 +269,31 @@ TxThreshold=0x500B0, CompletionHiAddr=0x500B4, TxCompletionAddr=0x500B8, RxCompletionAddr=0x500BC, RxCompletionQ2Addr=0x500C0, - CompletionQConsumerIdx=0x500C4, + CompletionQConsumerIdx=0x500C4, RxDMACtrl=0x500D0, RxDescQCtrl=0x500D4, RxDescQHiAddr=0x500DC, RxDescQAddr=0x500E0, RxDescQIdx=0x500E8, RxDMAStatus=0x500F0, RxFilterMode=0x500F4, - TxMode=0x55000, + TxMode=0x55000, TxGfpMem=0x58000, RxGfpMem=0x5a000, }; /* Bits in the interrupt status/mask registers. */ enum intr_status_bits { - IntrNormalSummary=0x8000, IntrAbnormalSummary=0x02000000, - IntrRxDone=0x0300, IntrRxEmpty=0x10040, IntrRxPCIErr=0x80000, - IntrTxDone=0x4000, IntrTxEmpty=0x1000, IntrTxPCIErr=0x80000, - StatsMax=0x08000000, LinkChange=0xf0000000, - IntrTxDataLow=0x00040000, + IntrLinkChange=0xf0000000, IntrStatsMax=0x08000000, + IntrAbnormalSummary=0x02000000, IntrGeneralTimer=0x01000000, + IntrSoftware=0x800000, IntrRxComplQ1Low=0x400000, + IntrTxComplQLow=0x200000, IntrPCI=0x100000, + IntrDMAErr=0x080000, IntrTxDataLow=0x040000, + IntrRxComplQ2Low=0x020000, IntrRxDescQ1Low=0x010000, + IntrNormalSummary=0x8000, IntrTxDone=0x4000, + IntrTxDMADone=0x2000, IntrTxEmpty=0x1000, + IntrEarlyRxQ2=0x0800, IntrEarlyRxQ1=0x0400, + IntrRxQ2Done=0x0200, IntrRxQ1Done=0x0100, + IntrRxGFPDead=0x80, IntrRxDescQ2Low=0x40, + IntrNoTxCsum=0x20, IntrTxBadID=0x10, + IntrHiPriTxBadID=0x08, IntrRxGfp=0x04, + IntrTxGfp=0x02, IntrPCIPad=0x01, + /* not quite bits */ + IntrRxDone=IntrRxQ2Done | IntrRxQ1Done, + IntrRxEmpty=IntrRxDescQ1Low | IntrRxDescQ2Low, }; /* Bits in the RxFilterMode register. */ @@ -277,6 +302,37 @@ AcceptMulticast=0x10, AcceptMyPhys=0xE040, }; +/* Bits in the TxDescCtrl register. */ +enum tx_ctrl_bits { + TxDescSpaceUnlim=0x00, TxDescSpace32=0x10, TxDescSpace64=0x20, + TxDescSpace128=0x30, TxDescSpace256=0x40, + TxDescType0=0x00, TxDescType1=0x01, TxDescType2=0x02, + TxDescType3=0x03, TxDescType4=0x04, + TxNoDMACompletion=0x08, TxDescQ64bit=0x80, + TxHiPriFIFOThreshShift=24, TxPadLenShift=16, + TxDMABurstSizeShift=8, +}; + +/* Bits in the RxDescQCtrl register. */ +enum rx_ctrl_bits { + RxBufferLenShift=16, RxMinDescrThreshShift=0, + RxPrefetchMode=0x8000, Rx2048QEntries=0x4000, + RxVariableQ=0x2000, RxDesc64bit=0x1000, + RxDescQAddr64bit=0x0100, + RxDescSpace4=0x000, RxDescSpace8=0x100, + RxDescSpace16=0x200, RxDescSpace32=0x300, + RxDescSpace64=0x400, RxDescSpace128=0x500, + RxConsumerWrEn=0x80, +}; + +/* Bits in the RxCompletionAddr register */ +enum rx_compl_bits { + RxComplQAddr64bit=0x80, TxComplProducerWrEn=0x40, + RxComplType0=0x00, RxComplType1=0x10, + RxComplType2=0x20, RxComplType3=0x30, + RxComplThreshShift=0, +}; + /* The Rx and Tx buffer descriptors. */ struct starfire_rx_desc { u32 rxaddr; /* Optionally 64 bits. */ @@ -288,8 +344,12 @@ /* Completion queue entry. You must update the page allocation, init_ring and the shift count in rx() if using a larger format. */ +#define csum_rx_status struct rx_done_desc { u32 status; /* Low 16 bits is length. */ +#ifdef csum_rx_status + u32 status2; /* Low 16 bits is csum */ +#endif #ifdef full_rx_status u32 status2; u16 vlanid; @@ -301,14 +361,24 @@ RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000, }; -/* Type 1 Tx descriptor. */ +/* Type 0 Tx descriptor. */ +/* If more fragments are needed, don't forget to change the + descriptor spacing as well! */ struct starfire_tx_desc { - u32 status; /* Upper bits are status, lower 16 length. */ - u32 addr; + u32 status; + u32 nbufs; + u32 first_addr; + u16 first_len; + u16 total_len; + struct { + u32 addr; + u32 len; + } frag[6]; }; enum tx_desc_bits { - TxDescID=0xB1010000, /* Also marks single fragment, add CRC. */ - TxDescIntr=0x08000000, TxRingWrap=0x04000000, + TxDescID=0xB0000000, + TxCRCEn=0x01000000, TxDescIntr=0x08000000, + TxRingWrap=0x04000000, TxCalTCP=0x02000000, }; struct tx_done_report { u32 status; /* timestamp, index. */ @@ -318,10 +388,15 @@ }; #define PRIV_ALIGN 15 /* Required alignment mask */ -struct ring_info { +struct rx_ring_info { struct sk_buff *skb; dma_addr_t mapping; }; +struct tx_ring_info { + struct sk_buff *skb; + dma_addr_t first_mapping; + dma_addr_t frag_mapping[6]; +}; struct netdev_private { /* Descriptor rings first for alignment. */ @@ -330,8 +405,8 @@ dma_addr_t rx_ring_dma; dma_addr_t tx_ring_dma; /* The addresses of rx/tx-in-place skbuffs. */ - struct ring_info rx_info[RX_RING_SIZE]; - struct ring_info tx_info[TX_RING_SIZE]; + struct rx_ring_info rx_info[RX_RING_SIZE]; + struct tx_ring_info tx_info[TX_RING_SIZE]; /* Pointers to completion queues (full pages). I should cache line pad..*/ u8 pad0[100]; struct rx_done_desc *rx_done_q; @@ -390,16 +465,17 @@ static int card_idx = -1; static int printed_version = 0; long ioaddr; - int drv_flags, io_size = netdrv_tbl[chip_idx].io_size; + int drv_flags, io_size; card_idx++; option = card_idx < MAX_UNITS ? options[card_idx] : 0; - + if (!printed_version++) printk(KERN_INFO "%s" KERN_INFO "%s" KERN_INFO "%s", version1, version2, version3); ioaddr = pci_resource_start (pdev, 0); + io_size = pci_resource_len (pdev, 0); if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_MEM) == 0)) { printk (KERN_ERR "starfire %d: no PCI MEM resources, aborting\n", card_idx); return -ENODEV; @@ -410,6 +486,7 @@ printk (KERN_ERR "starfire %d: cannot alloc etherdev, aborting\n", card_idx); return -ENOMEM; } + SET_MODULE_OWNER(dev); irq = pdev->irq; @@ -434,6 +511,9 @@ printk(KERN_INFO "%s: %s at 0x%lx, ", dev->name, netdrv_tbl[chip_idx].name, ioaddr); + /* Starfire can do SG and TCP/UDP checksumming */ + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + /* Serial EEPROM reads are hidden by the hardware. */ for (i = 0; i < 6; i++) dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i); @@ -546,13 +626,9 @@ /* Do we ever need to reset the chip??? */ - MOD_INC_USE_COUNT; - retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev); - if (retval) { - MOD_DEC_USE_COUNT; + if (retval) return retval; - } /* Disable the Rx and Tx, and reset the chip. */ writel(0, ioaddr + GenCtrl); @@ -564,7 +640,7 @@ if (np->tx_done_q == 0) np->tx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_done_q_dma); if (np->rx_done_q == 0) - np->rx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_done_q_dma); + np->rx_done_q = pci_alloc_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, &np->rx_done_q_dma); if (np->tx_ring == 0) np->tx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_ring_dma); if (np->rx_ring == 0) @@ -575,7 +651,7 @@ pci_free_consistent(np->pci_dev, PAGE_SIZE, np->tx_done_q, np->tx_done_q_dma); if (np->rx_done_q) - pci_free_consistent(np->pci_dev, PAGE_SIZE, + pci_free_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, np->rx_done_q, np->rx_done_q_dma); if (np->tx_ring) pci_free_consistent(np->pci_dev, PAGE_SIZE, @@ -583,16 +659,23 @@ if (np->rx_ring) pci_free_consistent(np->pci_dev, PAGE_SIZE, np->rx_ring, np->rx_ring_dma); - MOD_DEC_USE_COUNT; return -ENOMEM; } init_ring(dev); /* Set the size of the Rx buffers. */ - writel((np->rx_buf_sz<<16) | 0xA000, ioaddr + RxDescQCtrl); - - /* Set Tx descriptor to type 1 and padding to 0 bytes. */ - writel(0x02000401, ioaddr + TxDescCtrl); + writel((np->rx_buf_sz << RxBufferLenShift) | + (0 << RxMinDescrThreshShift) | + RxPrefetchMode | RxVariableQ | + RxDescSpace4, + ioaddr + RxDescQCtrl); + + /* Set Tx descriptor to type 0 and spacing to 64 bytes. */ + writel((2 << TxHiPriFIFOThreshShift) | + (0 << TxPadLenShift) | + (4 << TxDMABurstSizeShift) | + TxDescSpace64 | TxDescType0, + ioaddr + TxDescCtrl); #if defined(ADDR_64BITS) && defined(__alpha__) /* XXX We really need a 64-bit PCI dma interfaces too... -DaveM */ @@ -607,7 +690,24 @@ writel(np->tx_ring_dma, ioaddr + TxRingPtr); writel(np->tx_done_q_dma, ioaddr + TxCompletionAddr); - writel(np->rx_done_q_dma, ioaddr + RxCompletionAddr); +#ifdef full_rx_status + writel(np->rx_done_q_dma | + RxComplType3 | + (0 << RxComplThreshShift), + ioaddr + RxCompletionAddr); +#else +#ifdef csum_rx_status + writel(np->rx_done_q_dma | + RxComplType2 | + (0 << RxComplThreshShift), + ioaddr + RxCompletionAddr); +#else + writel(np->rx_done_q_dma | + RxComplType0 | + (0 << RxComplThreshShift), + ioaddr + RxCompletionAddr); +#endif +#endif if (debug > 1) printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name); @@ -643,15 +743,21 @@ check_duplex(dev, 1); /* Set the interrupt mask and enable PCI interrupts. */ - writel(IntrRxDone | IntrRxEmpty | IntrRxPCIErr | - IntrTxDone | IntrTxEmpty | IntrTxPCIErr | - StatsMax | LinkChange | IntrNormalSummary | IntrAbnormalSummary - | 0x0010 , ioaddr + IntrEnable); + writel(IntrRxDone | IntrRxEmpty | IntrDMAErr | + IntrTxDone | IntrStatsMax | IntrLinkChange | + IntrNormalSummary | IntrAbnormalSummary | + IntrRxGFPDead | IntrNoTxCsum | IntrTxBadID, + ioaddr + IntrEnable); writel(0x00800000 | readl(ioaddr + PCIDeviceConfig), ioaddr + PCIDeviceConfig); - /* Enable the Rx and Tx units. */ - writel(0x000F, ioaddr + GenCtrl); + /* Load Rx/Tx firmware into the frame processors */ + for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++) + writel(cpu_to_le32(firmware_rx[i]), ioaddr + RxGfpMem + i * 4); + for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++) + writel(cpu_to_le32(firmware_tx[i]), ioaddr + TxGfpMem + i * 4); + /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ + writel(0x003F, ioaddr + GenCtrl); if (debug > 2) printk(KERN_DEBUG "%s: Done netdev_open().\n", @@ -765,7 +871,7 @@ static void init_ring(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; - int i; + int i, j; np->tx_full = 0; np->cur_rx = np->cur_tx = 0; @@ -804,7 +910,9 @@ for (i = 0; i < TX_RING_SIZE; i++) { np->tx_info[i].skb = NULL; - np->tx_info[i].mapping = 0; + np->tx_info[i].first_mapping = 0; + for (j = 0; j < 6; j++) + np->tx_info[i].frag_mapping[j] = 0; np->tx_ring[i].status = 0; } return; @@ -814,6 +922,7 @@ { struct netdev_private *np = (struct netdev_private *)dev->priv; unsigned entry; + int i; /* Caution: the write order is important here, set the field with the "ownership" bits last. */ @@ -821,42 +930,87 @@ /* Calculate the next Tx descriptor entry. */ entry = np->cur_tx % TX_RING_SIZE; +#ifdef HAS_BROKEN_FIRMWARE + { + int has_bad_length = 0; + + if (skb_headlen(skb) == 1) + has_bad_length = 1; + else { + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) + if (skb_shinfo(skb)->frags[i].size == 1) { + has_bad_length = 1; + break; + } + } + + if (has_bad_length) + skb_checksum_help(skb); + } +#endif /* HAS_BROKEN_FIRMWARE */ + np->tx_info[entry].skb = skb; - np->tx_info[entry].mapping = - pci_map_single(np->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); + np->tx_info[entry].first_mapping = + pci_map_single(np->pci_dev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE); - np->tx_ring[entry].addr = cpu_to_le32(np->tx_info[entry].mapping); + np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping); + np->tx_ring[entry].first_len = cpu_to_le32(skb_headlen(skb)); + np->tx_ring[entry].total_len = cpu_to_le32(skb->len); /* Add "| TxDescIntr" to generate Tx-done interrupts. */ - np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID); + np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn); + if (entry >= TX_RING_SIZE-1) /* Wrap ring */ + np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr); + np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1); + + if (skb->ip_summed == CHECKSUM_HW) + np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP); + if (debug > 5) { - printk(KERN_DEBUG "%s: Tx #%d slot %d %8.8x %8.8x.\n", + printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x nbufs %d len %4.4x/%4.4x.\n", dev->name, np->cur_tx, entry, le32_to_cpu(np->tx_ring[entry].status), - le32_to_cpu(np->tx_ring[entry].addr)); + le32_to_cpu(np->tx_ring[entry].nbufs), + le32_to_cpu(np->tx_ring[entry].first_len), + le32_to_cpu(np->tx_ring[entry].total_len)); + } + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i]; + + /* we already have the proper value in entry */ + np->tx_info[entry].frag_mapping[i] = + pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE); + + np->tx_ring[entry].frag[i].addr = cpu_to_le32(np->tx_info[entry].frag_mapping[i]); + np->tx_ring[entry].frag[i].len = cpu_to_le32(this_frag->size); + if (debug > 5) { + printk(KERN_DEBUG "%s: Tx #%d frag %d len %4.4x.\n", + dev->name, np->cur_tx, i, + le32_to_cpu(np->tx_ring[entry].frag[i].len)); + } } + np->cur_tx++; -#if 1 - if (entry >= TX_RING_SIZE-1) { /* Wrap ring */ - np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr); + + if (entry >= TX_RING_SIZE-1) /* Wrap ring */ entry = -1; - } -#endif + entry++; /* Non-x86: explicitly flush descriptor cache lines here. */ + /* Ensure everything is written back above before the transmit is + initiated. - Jes */ + wmb(); /* Update the producer index. */ - writel(++entry, dev->base_addr + TxProducerIdx); + writel(entry * (sizeof(struct starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx); if (np->cur_tx - np->dirty_tx >= TX_RING_SIZE - 1) { np->tx_full = 1; netif_stop_queue(dev); } + dev->trans_start = jiffies; - if (debug > 4) { - printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n", - dev->name, np->cur_tx, entry); - } return 0; } @@ -919,18 +1073,29 @@ np->stats.tx_packets++; } else if ((tx_status & 0xe0000000) == 0x80000000) { struct sk_buff *skb; + int i; u16 entry = tx_status; /* Implicit truncate */ - entry >>= 3; + entry /= sizeof(struct starfire_tx_desc); skb = np->tx_info[entry].skb; + np->tx_info[entry].skb = NULL; pci_unmap_single(np->pci_dev, - np->tx_info[entry].mapping, - skb->len, PCI_DMA_TODEVICE); + np->tx_info[entry].first_mapping, + skb_headlen(skb), + PCI_DMA_TODEVICE); + np->tx_info[entry].first_mapping = 0; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + pci_unmap_single(np->pci_dev, + np->tx_info[entry].frag_mapping[i], + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + np->tx_info[entry].frag_mapping[i] = 0; + } /* Scavenge the descriptor. */ dev_kfree_skb_irq(skb); - np->tx_info[entry].skb = NULL; - np->tx_info[entry].mapping = 0; + np->dirty_tx++; } np->tx_done_q[np->tx_done].status = 0; @@ -1037,14 +1202,6 @@ temp = skb_put(skb, pkt_len); np->rx_info[entry].skb = NULL; np->rx_info[entry].mapping = 0; -#ifndef final_version /* Remove after testing. */ - if (le32_to_cpu(np->rx_ring[entry].rxaddr & ~3) != ((unsigned long) temp)) - printk(KERN_ERR "%s: Internal fault: The skbuff addresses " - "do not match in netdev_rx: %d vs. %p / %p.\n", - dev->name, - le32_to_cpu(np->rx_ring[entry].rxaddr), - skb->head, temp); -#endif } #ifndef final_version /* Remove after testing. */ /* You will want this info for the initial debug. */ @@ -1060,9 +1217,23 @@ skb->data[17]); #endif skb->protocol = eth_type_trans(skb, dev); -#ifdef full_rx_status - if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) +#if defined(full_rx_status) || defined(csum_rx_status) + if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) { skb->ip_summed = CHECKSUM_UNNECESSARY; + } + /* + * This feature doesn't seem to be working, at least + * with the two firmware versions I have. If the GFP sees + * a fragment, it either ignores it completely, or reports + * "bad checksum" on it. + * + * Maybe I missed something -- corrections are welcome. -Ion + */ + else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) { + skb->ip_summed = CHECKSUM_HW; + skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff; + printk(KERN_DEBUG "%s: checksum_hw, status2 = %x\n", dev->name, np->rx_done_q[np->rx_done].status2); + } #endif netif_rx(skb); dev->last_rx = jiffies; @@ -1109,28 +1280,26 @@ { struct netdev_private *np = (struct netdev_private *)dev->priv; - if (intr_status & LinkChange) { + if (intr_status & IntrLinkChange) { printk(KERN_NOTICE "%s: Link changed: Autonegotiation advertising" " %4.4x partner %4.4x.\n", dev->name, mdio_read(dev, np->phys[0], 4), mdio_read(dev, np->phys[0], 5)); check_duplex(dev, 0); } - if (intr_status & StatsMax) { + if (intr_status & IntrStatsMax) { get_stats(dev); } /* Came close to underrunning the Tx FIFO, increase threshold. */ if (intr_status & IntrTxDataLow) writel(++np->tx_threshold, dev->base_addr + TxThreshold); if ((intr_status & - ~(IntrAbnormalSummary|LinkChange|StatsMax|IntrTxDataLow|1)) && debug) + ~(IntrAbnormalSummary|IntrLinkChange|IntrStatsMax|IntrTxDataLow|1)) && debug) printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", dev->name, intr_status); - /* Hmmmmm, it's not clear how to recover from PCI faults. */ - if (intr_status & IntrTxPCIErr) + /* Hmmmmm, it's not clear how to recover from DMA faults. */ + if (intr_status & IntrDMAErr) np->stats.tx_fifo_errors++; - if (intr_status & IntrRxPCIErr) - np->stats.rx_fifo_errors++; } static struct net_device_stats *get_stats(struct net_device *dev) @@ -1280,7 +1449,7 @@ { long ioaddr = dev->base_addr; struct netdev_private *np = (struct netdev_private *)dev->priv; - int i; + int i, j; netif_stop_queue(dev); @@ -1305,7 +1474,7 @@ for (i = 0; i < 8 /* TX_RING_SIZE is huge! */; i++) printk(KERN_DEBUG " #%d desc. %8.8x %8.8x -> %8.8x.\n", i, le32_to_cpu(np->tx_ring[i].status), - le32_to_cpu(np->tx_ring[i].addr), + le32_to_cpu(np->tx_ring[i].first_addr), le32_to_cpu(np->tx_done_q[i].status)); printk(KERN_DEBUG " Rx ring at %8.8x -> %p:\n", np->rx_ring_dma, np->rx_done_q); @@ -1333,16 +1502,23 @@ struct sk_buff *skb = np->tx_info[i].skb; if (skb != NULL) { pci_unmap_single(np->pci_dev, - np->tx_info[i].mapping, - skb->len, PCI_DMA_TODEVICE); + np->tx_info[i].first_mapping, + skb_headlen(skb), PCI_DMA_TODEVICE); + np->tx_info[i].first_mapping = 0; dev_kfree_skb(skb); + np->tx_info[i].skb = NULL; + for (j = 0; j < 6; j++) + if (np->tx_info[i].frag_mapping[j]) { + pci_unmap_single(np->pci_dev, + np->tx_info[i].frag_mapping[j], + skb_shinfo(skb)->frags[j].size, + PCI_DMA_TODEVICE); + np->tx_info[i].frag_mapping[j] = 0; + } else + break; } - np->tx_info[i].skb = NULL; - np->tx_info[i].mapping = 0; } - MOD_DEC_USE_COUNT; - return 0; } @@ -1359,6 +1535,9 @@ unregister_netdev(dev); iounmap((char *)dev->base_addr); + + release_mem_region(pci_resource_start (pdev, 0), + pci_resource_len (pdev, 0)); if (np->tx_done_q) pci_free_consistent(np->pci_dev, PAGE_SIZE, diff -urNX diff_kernel_excludes /usr/src/local/linux-2.4.vanilla/drivers/net/starfire_firmware.h linux-2.4/drivers/net/starfire_firmware.h --- /usr/src/local/linux-2.4.vanilla/drivers/net/starfire_firmware.h Wed Dec 31 16:00:00 1969 +++ linux-2.4/drivers/net/starfire_firmware.h Sat Jan 27 13:03:06 2001 @@ -0,0 +1,215 @@ +static u32 firmware_rx[] = { + 0x010003dc, 0x00000000, + 0x04000421, 0x00000086, + 0x80000015, 0x0000180e, + 0x81000015, 0x00006664, + 0x1a0040ab, 0x00000b06, + 0x14200011, 0x00000000, + 0x14204022, 0x0000aaaa, + 0x14204022, 0x00000300, + 0x14204022, 0x00000000, + 0x1a0040ab, 0x00000b14, + 0x14200011, 0x00000000, + 0x83000015, 0x00000002, + 0x04000021, 0x00000000, + 0x00000010, 0x00000000, + 0x04000421, 0x00000087, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00008015, 0x00000000, + 0x0000003e, 0x00000000, + 0x00000010, 0x00000000, + 0x82000015, 0x00004000, + 0x009e8050, 0x00000000, + 0x03008015, 0x00000000, + 0x86008015, 0x00000000, + 0x82000015, 0x00008000, + 0x0100001c, 0x00000000, + 0x000050a0, 0x0000010c, + 0x4e20d011, 0x00006008, + 0x1420d012, 0x00004008, + 0x0000f090, 0x00007000, + 0x0000c8b0, 0x00003000, + 0x00004040, 0x00000000, + 0x00108015, 0x00000000, + 0x00a2c150, 0x00004000, + 0x00a400b0, 0x00000014, + 0x00000020, 0x00000000, + 0x2500400d, 0x00002525, + 0x00047220, 0x00003100, + 0x00934070, 0x00000000, + 0x00000020, 0x00000000, + 0x00924460, 0x00000184, + 0x2b20c011, 0x00000000, + 0x0000c420, 0x00000540, + 0x36014018, 0x0000422d, + 0x14200011, 0x00000000, + 0x00924460, 0x00000183, + 0x3200001f, 0x00000034, + 0x02ac0015, 0x00000002, + 0x00a60110, 0x00000008, + 0x42200011, 0x00000000, + 0x00924060, 0x00000103, + 0x0000001e, 0x00000000, + 0x00000020, 0x00000100, + 0x0000001e, 0x00000000, + 0x00924460, 0x00000086, + 0x00004080, 0x00000000, + 0x0092c070, 0x00000000, + 0x00924060, 0x00000100, + 0x0000c890, 0x00005000, + 0x00a6c110, 0x00000000, + 0x00b0c090, 0x00000012, + 0x021c0015, 0x00000000, + 0x3200001f, 0x00000034, + 0x00924460, 0x00000510, + 0x44210011, 0x00000000, + 0x42000011, 0x00000000, + 0x83000015, 0x00000040, + 0x00924460, 0x00000508, + 0x45014018, 0x00004545, + 0x00808050, 0x00000000, + 0x62208012, 0x00000000, + 0x82000015, 0x00000800, + 0x15200011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x80000015, 0x0000eea4, + 0x81000015, 0x0000005f, + 0x00000060, 0x00000000, + 0x00004120, 0x00000000, + 0x00004a00, 0x00004000, + 0x00924460, 0x00000190, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00934050, 0x00000018, + 0x00930050, 0x00000018, + 0x3601403a, 0x0000002d, + 0x000643a9, 0x00000000, + 0x0000c420, 0x00000140, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x000642a9, 0x00000000, + 0x00024420, 0x00000183, + 0x5601401a, 0x00005956, + 0x82000015, 0x00002000, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, +}; /* 104 Rx instructions */ +#define FIRMWARE_RX_SIZE 104 + +static u32 firmware_tx[] = { + 0x010003dc, 0x00000000, + 0x04000421, 0x00000086, + 0x80000015, 0x0000180e, + 0x81000015, 0x00006664, + 0x1a0040ab, 0x00000b06, + 0x14200011, 0x00000000, + 0x14204022, 0x0000aaaa, + 0x14204022, 0x00000300, + 0x14204022, 0x00000000, + 0x1a0040ab, 0x00000b14, + 0x14200011, 0x00000000, + 0x83000015, 0x00000002, + 0x04000021, 0x00000000, + 0x00000010, 0x00000000, + 0x04000421, 0x00000087, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00008015, 0x00000000, + 0x0000003e, 0x00000000, + 0x00000010, 0x00000000, + 0x82000015, 0x00004000, + 0x009e8050, 0x00000000, + 0x03008015, 0x00000000, + 0x86008015, 0x00000000, + 0x82000015, 0x00008000, + 0x0100001c, 0x00000000, + 0x000050a0, 0x0000010c, + 0x4e20d011, 0x00006008, + 0x1420d012, 0x00004008, + 0x0000f090, 0x00007000, + 0x0000c8b0, 0x00003000, + 0x00004040, 0x00000000, + 0x00108015, 0x00000000, + 0x00a2c150, 0x00004000, + 0x00a400b0, 0x00000014, + 0x00000020, 0x00000000, + 0x2500400d, 0x00002525, + 0x00047220, 0x00003100, + 0x00934070, 0x00000000, + 0x00000020, 0x00000000, + 0x00924460, 0x00000184, + 0x2b20c011, 0x00000000, + 0x0000c420, 0x00000540, + 0x36014018, 0x0000422d, + 0x14200011, 0x00000000, + 0x00924460, 0x00000183, + 0x3200001f, 0x00000034, + 0x02ac0015, 0x00000002, + 0x00a60110, 0x00000008, + 0x42200011, 0x00000000, + 0x00924060, 0x00000103, + 0x0000001e, 0x00000000, + 0x00000020, 0x00000100, + 0x0000001e, 0x00000000, + 0x00924460, 0x00000086, + 0x00004080, 0x00000000, + 0x0092c070, 0x00000000, + 0x00924060, 0x00000100, + 0x0000c890, 0x00005000, + 0x00a6c110, 0x00000000, + 0x00b0c090, 0x00000012, + 0x021c0015, 0x00000000, + 0x3200001f, 0x00000034, + 0x00924460, 0x00000510, + 0x44210011, 0x00000000, + 0x42000011, 0x00000000, + 0x83000015, 0x00000040, + 0x00924460, 0x00000508, + 0x45014018, 0x00004545, + 0x00808050, 0x00000000, + 0x62208012, 0x00000000, + 0x82000015, 0x00000800, + 0x15200011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x80000015, 0x0000eea4, + 0x81000015, 0x0000005f, + 0x00000060, 0x00000000, + 0x00004120, 0x00000000, + 0x00004a00, 0x00004000, + 0x00924460, 0x00000190, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00934050, 0x00000018, + 0x00930050, 0x00000018, + 0x3601403a, 0x0000002d, + 0x000643a9, 0x00000000, + 0x0000c420, 0x00000140, + 0x5601401a, 0x00005956, + 0x14000011, 0x00000000, + 0x00000010, 0x00000000, + 0x00000010, 0x00000000, + 0x000642a9, 0x00000000, + 0x00024420, 0x00000183, + 0x5601401a, 0x00005956, + 0x82000015, 0x00002000, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, + 0x82000015, 0x00000010, + 0x15200011, 0x00000000, +}; /* 104 Tx instructions */ +#define FIRMWARE_TX_SIZE 104 diff -urNX diff_kernel_excludes /usr/src/local/linux-2.4.vanilla/drivers/net/starfire_firmware.pl linux-2.4/drivers/net/starfire_firmware.pl --- /usr/src/local/linux-2.4.vanilla/drivers/net/starfire_firmware.pl Wed Dec 31 16:00:00 1969 +++ linux-2.4/drivers/net/starfire_firmware.pl Thu Jan 25 21:43:27 2001 @@ -0,0 +1,31 @@ +#!/usr/bin/perl + +# This script can be used to generate a new starfire_firmware.h +# from GFP_RX.DAT and GFP_TX.DAT, files included with the DDK +# and also with the Novell drivers. + +open FW, "GFP_RX.DAT" || die; +open FWH, ">starfire_firmware.h" || die; + +printf(FWH "static u32 firmware_rx[] = {\n"); +$counter = 0; +while ($foo = <FW>) { + chomp; + printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4)); + $counter++; +} + +close FW; +open FW, "GFP_TX.DAT" || die; + +printf(FWH "};\t/* %d Rx instructions */\n#define FIRMWARE_RX_SIZE %d\n\nstatic u32 firmware_tx[] = {\n", $counter, $counter); +$counter = 0; +while ($foo = <FW>) { + chomp; + printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4)); + $counter++; +} + +close FW; +printf(FWH "};\t/* %d Tx instructions */\n#define FIRMWARE_TX_SIZE %d\n", $counter, $counter); +close(FWH); ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-27 18:39 ` kuznet 2001-01-27 21:18 ` Ion Badulescu @ 2001-01-30 6:02 ` David S. Miller 1 sibling, 0 replies; 27+ messages in thread From: David S. Miller @ 2001-01-30 6:02 UTC (permalink / raw) To: Ion Badulescu; +Cc: kuznet, linux-kernel Ion Badulescu writes: > I've attached a diff for the latest driver (and firmware) version, against > 2.4.1pre10+zerocopy. Sorry about MIME, but my pine is currently broken > (strips trailing spaces/tabs). Ok. Ion, I'll start to include your Starfire changes once the firmware distribution issue is worked out, so please get it resolved for me as I want to include your work, ok? Thanks. Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-25 19:29 ` kuznet 2001-01-25 20:28 ` Ion Badulescu 2001-01-25 20:43 ` David S. Miller @ 2001-01-26 1:27 ` Andrew Morton 2 siblings, 0 replies; 27+ messages in thread From: Andrew Morton @ 2001-01-26 1:27 UTC (permalink / raw) To: kuznet; +Cc: linux-kernel kuznet@ms2.inr.ac.ru wrote: > > Hello! > > > no problems. I simply mounted an NFS server with rsize=wsize=8192 > > and read a few files - I assume this is sufficient? > > This is orthogonal. > > Only TCP uses this and you need not to do something special > to test it. Any TCP connection going through 3c tests it. OK. > > rather than using the IS_CYCLONE stuff. Then we can add cards > > individually as confirmation comes in. > > Seems, you meaned opposite way. To add this flag to all the chips, > except for several, and to remove it as soon as it is "confirmed" > that it does not work. 8) errr.. Well that certainly ensures we'll hear about it quickly :) Problem is, some of these NICs are very rare, and the driver could be broken for quite some time before we hear about it. Months. I think what I'd prefer to do is this: In vortex_close() we _know_ whether the NIC is doing hardware checksumming, so we can add: if (rx_csumhits && (dev->drv_flags&HAS_HWCKSM) == 0) printk("this NIC supports hardware checksums! Please see <some URL>") This will work well - people are quite helpful. > Also, please, reset the state. Until this snapshot, hw checksumming > did not work due to bugs in netfilter, so that all the reports about > failures to checksum are dubious. That's good to hear. It's possible that some devices in the device table are marked as Cyclone when in fact they're Boomerangs. It's pretty confusing. So these will support scatter/gather but not checksumming. Using rx_csumhits should be reliable. It's a global counter at present - I'll make it per-device. - - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 [not found] <200101242123.NAA00986@pizda.ninka.net> 2001-01-25 1:40 ` [UPDATE] Zerocopy patches, against 2.4.1-pre10 Andrew Morton @ 2001-01-25 9:29 ` David S. Miller 1 sibling, 0 replies; 27+ messages in thread From: David S. Miller @ 2001-01-25 9:29 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel Andrew Morton writes: > What I suggest we do here is to add a new flag to the per-device > table `HAS_HWCKSM' and use that to set the device capabilities, > rather than using the IS_CYCLONE stuff. Then we can add cards > individually as confirmation comes in. This idea sounds just fine. > I do have a 200-line 3c59x patch banked up - it does the following: ... > So... How to coordinate these diffs? I'd propose that I implement > the HAS_HWCKSM thing, test zerocopy with it on the five NICs which > I have. Then what? Ask Linus to merge the non-zc parts? I have a better idea. Look, all the dev->features and flag names are in the kernel tree already. The only thing which hasn't propagated which the driver will reference are the skb frag things. This code referencing the skb frags in the 3c59x hard_start_xmit method you can just protect with #ifdef MAX_SKB_FRAGS or similar. See? Later, David S. Miller davem@redhat.com - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [UPDATE] Zerocopy patches, against 2.4.1-pre10
@ 2001-01-24 21:52 Jonathan Earle
2001-01-24 23:33 ` Peter Samuelson
0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Earle @ 2001-01-24 21:52 UTC (permalink / raw)
To: 'Mathieu Chouquet-Stringer', linux-kernel
> > What are "zerocopy patch set"s?
>
> Basically, if you want to send something to the network, the
> kernel has to
> copy your data to its memory space. It is an overhead and with these
> patches, the kernel doesn't has to do it. So it is faster.
> Moreover, few
> ethernet cards are able to compute the ip checksum so linux
> doesn't need
> anymore to do that.
Hmm.. so things like routing should be faster then? What caveats should one
watch for (ie: what functionalities will not work as before - if any)?
Cheers!
Jon
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-24 21:52 Jonathan Earle @ 2001-01-24 23:33 ` Peter Samuelson 0 siblings, 0 replies; 27+ messages in thread From: Peter Samuelson @ 2001-01-24 23:33 UTC (permalink / raw) To: Jonathan Earle; +Cc: 'Mathieu Chouquet-Stringer', linux-kernel [Jonathan Earle] > Hmm.. so things like routing should be faster then? Other network traffic too. Say you have an FTP server running and it wants to send a file out to a client. The old way was for it to read() the file into memory and then write() it to the network socket. To avoid having to copy all that data into the userspace buffer during read(), you can use mmap() instead. In Linux 2.1.1xx we gained a new syscall sendfile() which works like mmap()+write(), except faster since the necessary kernel memory management is a lot simpler. Using either sendfile() or mmap(), the userspace program (ftpd) doesn't have to touch the memory involved, just send it on to the socket. That was the first optimization relevant here, and it's been around awhile now. Now with mmap()+write() or sendfile(), the kernel reads the data off the disk using the page cache, then the network stack copies it to other buffers, doing the TCP checksum in the process, and eventually the Ethernet card does a DMA transfer of some sort and sends it out the wire. Notice that the CPU has to copy the data from the disk DMA buffer to the network card DMA buffer, checksumming it somewhere along the way. Depending on circumstance, of course, there may be other copying involved as well. With zerocopy, when you issue sendfile(), the kernel does the network DMA straight from the page cache, avoiding that extra copy. In the case where the network card is capable of doing the TCP checksum in hardware (as a lot of newer cards can), the kernel doesn't even have to look at the data between the disk DMA and the network DMA. This can save memory accesses and CPU data cache pollution. The only way to get a more direct route would be to do the DMA from disk controller to network card without touching main memory at all, but this can have a lot of complications and is probably not worth it in general -- see a recent discussion on this list. > What caveats should one watch for (ie: what functionalities will not > work as before - if any)? Ideally as a regular user you don't notice anything except things go perhaps a bit faster. I have no idea whether Davem's patch achieves this yet.. Peter - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [UPDATE] Zerocopy patches, against 2.4.1-pre10
@ 2001-01-24 21:34 Jonathan Earle
2001-01-24 21:45 ` Mathieu Chouquet-Stringer
0 siblings, 1 reply; 27+ messages in thread
From: Jonathan Earle @ 2001-01-24 21:34 UTC (permalink / raw)
To: 'David S. Miller', linux-kernel
> I'm back from OZ, and to help deal with my sudden lack of Victoria
> Bitter, I've made a new zerocopy patch set.
What are "zerocopy patch set"s?
Cheers!
Jon
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-24 21:34 Jonathan Earle @ 2001-01-24 21:45 ` Mathieu Chouquet-Stringer 2001-01-31 22:42 ` Rogerio Brito 0 siblings, 1 reply; 27+ messages in thread From: Mathieu Chouquet-Stringer @ 2001-01-24 21:45 UTC (permalink / raw) To: linux-kernel jearle@nortelnetworks.com ("Jonathan Earle") writes: > > I'm back from OZ, and to help deal with my sudden lack of Victoria > > Bitter, I've made a new zerocopy patch set. > > What are "zerocopy patch set"s? Basically, if you want to send something to the network, the kernel has to copy your data to its memory space. It is an overhead and with these patches, the kernel doesn't has to do it. So it is faster. Moreover, few ethernet cards are able to compute the ip checksum so linux doesn't need anymore to do that. -- Mathieu CHOUQUET-STRINGER E-Mail : mchouque@e-steel.com Learning French is trivial: the word for horse is cheval, and everything else follows in the same way. -- Alan J. Perlis - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [UPDATE] Zerocopy patches, against 2.4.1-pre10 2001-01-24 21:45 ` Mathieu Chouquet-Stringer @ 2001-01-31 22:42 ` Rogerio Brito 0 siblings, 0 replies; 27+ messages in thread From: Rogerio Brito @ 2001-01-31 22:42 UTC (permalink / raw) To: linux-kernel On Jan 24 2001, Mathieu Chouquet-Stringer wrote: > Moreover, few ethernet cards are able to compute the ip checksum so > linux doesn't need anymore to do that. I'm very ignorant when it comes to Ethernet, but I'd like to know which cards have this feature, as I'm planning on buying a new one for my small home LAN (if they aren't expensive enough). And, of course, cards whose Linux drivers are able to use this feature... Any comments are more than welcome. Thanks in advance, Roger... -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Rogerio Brito - rbrito@iname.com - http://www.ime.usp.br/~rbrito/ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2001-03-11 21:00 UTC | newest] Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <200101242123.NAA00986@pizda.ninka.net> 2001-01-25 1:40 ` [UPDATE] Zerocopy patches, against 2.4.1-pre10 Andrew Morton 2001-01-25 19:29 ` kuznet 2001-01-25 20:28 ` Ion Badulescu 2001-01-25 20:36 ` kuznet 2001-01-25 20:43 ` David S. Miller 2001-01-25 21:11 ` Ion Badulescu 2001-01-26 19:43 ` kuznet 2001-01-29 22:02 ` David S. Miller 2001-01-25 21:14 ` David S. Miller 2001-01-25 21:29 ` Steve Whitehouse 2001-01-31 16:04 ` Alan Cox 2001-03-11 20:55 ` NBD Fix (attempt #2) Steve Whitehouse 2001-01-25 21:38 ` [UPDATE] Zerocopy patches, against 2.4.1-pre10 David S. Miller 2001-01-26 6:06 ` Ion Badulescu 2001-01-26 13:13 ` David S. Miller 2001-01-26 20:43 ` Ion Badulescu 2001-01-27 0:55 ` Ion Badulescu 2001-01-27 18:39 ` kuznet 2001-01-27 21:18 ` Ion Badulescu 2001-01-30 6:02 ` David S. Miller 2001-01-26 1:27 ` Andrew Morton 2001-01-25 9:29 ` David S. Miller 2001-01-24 21:52 Jonathan Earle 2001-01-24 23:33 ` Peter Samuelson -- strict thread matches above, loose matches on Subject: below -- 2001-01-24 21:34 Jonathan Earle 2001-01-24 21:45 ` Mathieu Chouquet-Stringer 2001-01-31 22:42 ` Rogerio Brito
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).