etherboot-developers Mailing List for Etherboot (Page 276)
Brought to you by:
marty_connor,
stefanhajnoczi
You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
(10) |
Sep
(3) |
Oct
(10) |
Nov
(47) |
Dec
(20) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(41) |
Feb
(107) |
Mar
(76) |
Apr
(103) |
May
(66) |
Jun
(72) |
Jul
(27) |
Aug
(31) |
Sep
(33) |
Oct
(18) |
Nov
(33) |
Dec
(67) |
| 2002 |
Jan
(25) |
Feb
(62) |
Mar
(79) |
Apr
(74) |
May
(67) |
Jun
(104) |
Jul
(155) |
Aug
(234) |
Sep
(87) |
Oct
(93) |
Nov
(54) |
Dec
(114) |
| 2003 |
Jan
(146) |
Feb
(104) |
Mar
(117) |
Apr
(189) |
May
(96) |
Jun
(40) |
Jul
(133) |
Aug
(136) |
Sep
(113) |
Oct
(142) |
Nov
(99) |
Dec
(185) |
| 2004 |
Jan
(233) |
Feb
(151) |
Mar
(109) |
Apr
(96) |
May
(200) |
Jun
(175) |
Jul
(162) |
Aug
(118) |
Sep
(107) |
Oct
(77) |
Nov
(121) |
Dec
(114) |
| 2005 |
Jan
(201) |
Feb
(271) |
Mar
(113) |
Apr
(119) |
May
(69) |
Jun
(46) |
Jul
(21) |
Aug
(37) |
Sep
(13) |
Oct
(4) |
Nov
(19) |
Dec
(46) |
| 2006 |
Jan
(10) |
Feb
(18) |
Mar
(85) |
Apr
(2) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(10) |
Jul
(20) |
Aug
(9) |
Sep
(11) |
Oct
(4) |
Nov
(1) |
Dec
(40) |
| 2008 |
Jan
(19) |
Feb
(8) |
Mar
(37) |
Apr
(28) |
May
(38) |
Jun
(63) |
Jul
(31) |
Aug
(22) |
Sep
(37) |
Oct
(38) |
Nov
(49) |
Dec
(24) |
| 2009 |
Jan
(48) |
Feb
(51) |
Mar
(80) |
Apr
(55) |
May
(34) |
Jun
(57) |
Jul
(20) |
Aug
(83) |
Sep
(17) |
Oct
(81) |
Nov
(53) |
Dec
(40) |
| 2010 |
Jan
(55) |
Feb
(28) |
Mar
(36) |
Apr
(7) |
May
|
Jun
|
Jul
(7) |
Aug
|
Sep
|
Oct
(1) |
Nov
(3) |
Dec
|
| 2011 |
Jan
(1) |
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
|
Nov
(10) |
Dec
|
| 2012 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2013 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Doug A. <amb...@am...> - 2001-06-10 03:54:58
|
ke...@us... writes: | >| If we could download that code etherboot get to stay smaller. | > | >Note that it is all hidden under #define for FreeBSD so if you don't have | >FreeBSD defined then there is no impact. The size if the same. | | One way you can reduce the impact of the change even for FreeBSD users | is not to copy the DHCP tag into a buffer, but rather save a pointer to | the location in the DHCP buffer and the length. The DHCP buffer is valid | right up to the moment control is handed over to the OS. As a side | effect you don't need to test for buffer overflow since Etherboot has | told DHCP how big a reply it can take so the DHCP server will ensure | that the reply fits in the buffer. This way you can replace the 1024 | byte global buffer with a pointer and an int. I tried that but it broke the DHCP buffer and then the resulting parsing. The issue is that I need a null-terminated string. I tried to null terminate the string and set a pointer to that. It broke parsing anything after that string. Now I might have had an off by one error and I will try it again. However, isc-dhcp distribution had a "bug" for a while in that it took the length literally and if the that string was null terminated your parameter would be returned as "<string>/000" which messed up things if it was your domain name for example. We this was required to make some Windows platform work. Several of us went round and round with Ted on this and he refused to change his position (even though by accident prior versions didn't have this problem). Strangely this has been fixed in a different way later on with no mention of why. So I'm a little nervous if we can really assume space for a null terminated string. | Another strategy is to allocate the buffer in a known memory location. | Since all of 0x90000-0x9ffff is off limits to the booted OS, you could | use say 0x93000 which is just below the Etherboot code. That might be a reasonable thing to do. Doug A. |
|
From: <ke...@us...> - 2001-06-09 23:27:08
|
>that the reply fits in the buffer. This way you can replace the 1024 >byte global buffer with a pointer and an int. Oh and I don't think you can pass more than 255 bytes of environment since the DHCP option length is one byte. |
|
From: <ke...@us...> - 2001-06-09 22:50:44
|
>| If we could download that code etherboot get to stay smaller. > >Note that it is all hidden under #define for FreeBSD so if you don't have >FreeBSD defined then there is no impact. The size if the same. One way you can reduce the impact of the change even for FreeBSD users is not to copy the DHCP tag into a buffer, but rather save a pointer to the location in the DHCP buffer and the length. The DHCP buffer is valid right up to the moment control is handed over to the OS. As a side effect you don't need to test for buffer overflow since Etherboot has told DHCP how big a reply it can take so the DHCP server will ensure that the reply fits in the buffer. This way you can replace the 1024 byte global buffer with a pointer and an int. Another strategy is to allocate the buffer in a known memory location. Since all of 0x90000-0x9ffff is off limits to the booted OS, you could use say 0x93000 which is just below the Etherboot code. |
|
From: Doug A. <amb...@am...> - 2001-06-09 20:19:33
|
Eric W. Biederman writes: | ke...@us... writes: | | > >This applies to version 5.1.0 in the src directory. It added the | > >capability to define FreeBSD kernel environment or do it via a DHCP option. | > | > Thanks, will put it in next version. | | Is there anyway we can do some kind of DHCP pass through, and just | accept extra options we are passed and pass those along? | | > >Comments on picking which option value would be helpfull. I picked 133 | > >since it was the next one after 132 which is used for the boot how to | > >flags. ISC-DHCP did something strange when I added it to the list | > >of options to request. | > | > Please voice opinions, pro or con, in this mailing list. | | Somehow if a tag is OS specific it would be nice if the OS did | the allocation itself instead of etherboot... And if not that we at The OS (really kernel) is not active at this point. These parameters given to the kernel before it starts. The only thing the kernel can access at this time is memory. No devices have been probed and this environment could effect that probe. | least would put the complexity in mknbi. I hate to see etherboot | clutered up with OS specific code, when it has size constraints. | | If we could download that code etherboot get to stay smaller. Note that it is all hidden under #define for FreeBSD so if you don't have FreeBSD defined then there is no impact. The size if the same. Well we sort-of have that type of thing. It's called the third stage loader and is PXE compliant. If EtherBoot or Nilo or whatever exposed a PXE compliant environment then this would be done. I don't see how mknbi is going to help since it at best passes static info to whatever it loads and they is no network API exposed to it to send and receive packets. Part of this patch is to be able to dynamically send parameters controled by DHCP. BTW the isc-dhcpd is getting pretty cool in the way you can classify replies and various criteria so you don't overflow the DHCP reply. For example I have parameter just for EtherBoot then parameters for the OS after device drivers are running and it can bring up the network stack and then potentially final OS configuration depending on mode of request via dhclient. This I find really powerful. The only thing missing is a fully functional UNDI PXE compliant DHCP server and a generic open source PXE boot rom. So doing PXE would let us really trim things down. I might not have been clear in my question but I was wondering if I used a previously defined option tag that had some bad side effect as opposed to just some bug that I tickled. I will try to narrow down why isc-dhcp (from the latest CVS sources had a problem) and post the results. Doug A. |
|
From: <ebi...@ln...> - 2001-06-09 17:53:40
|
ke...@us... writes: > >This applies to version 5.1.0 in the src directory. It added the > >capability to define FreeBSD kernel environment or do it via a DHCP option. > > Thanks, will put it in next version. Is there anyway we can do some kind of DHCP pass through, and just accept extra options we are passed and pass those along? > >Comments on picking which option value would be helpfull. I picked 133 > >since it was the next one after 132 which is used for the boot how to > >flags. ISC-DHCP did something strange when I added it to the list > >of options to request. > > Please voice opinions, pro or con, in this mailing list. Somehow if a tag is OS specific it would be nice if the OS did the allocation itself instead of etherboot... And if not that we at least would put the complexity in mknbi. I hate to see etherboot clutered up with OS specific code, when it has size constraints. If we could download that code etherboot get to stay smaller. Eric |
|
From: <ebi...@ln...> - 2001-06-09 12:06:32
|
Markus Gutschke <ma...@gu...> writes: > It's been forever since I looked into this, so I am probably getting > all the details wrong. I believe that PNP devices are completely > invisible, until the system probes for them and activates them. > Probing works by writing some "magic" bit patterns that somehow > allow for enumerating all PNP devices. There are some shared ports, and the enumeration works by allowing multiple devices to respond at once. Then after you have an idea of the maximal set of bits that can be set you simply narrow the addresses down. > Once a PNP device has been > found, it can be queried for the resources that it requires. The BIOS > or the OS should then compare these requirements with all the other > resources used by all other hardware, allocate the resources and > configured the PNP device accordingly. Only now does the device show > up in the system. Pretty much. For practical purposes this is the same as PCI. 2.4.x has support in the kernel for doing all of that. > Ken is probably right that some interaction with the BIOS is > involved, but I am even more hazy on those issues. Normally there is a bios option PNP OS. As long as you tell it your OS is not PNP your BIOS should setup the device with a valid range of ports. > I just checked with the source code of Linux v2.4.5ac10 and there is > code for ISA PNP in linux/drivers/pnp. I don't think that this code > by itself provides sufficient information to write PNP support for > etherboot, but if you also track down the specs, then you could probably > write a couple of lines of code that allow etherboot to activate a PNP > networking card. Actually it should be if you assume the BIOS allocates resources for the device. In which case it should simply be a matter of doing pnp to discover the device, and it's currently assigned resources. It should be able to be used much like pci.c is used now. > You probably have to be careful not to activate any > other cards, not to activate any interrupts or DMA, querying the BIOS > for a range of addresses that is unused and deactivating the device > after use. If the BIOS won't set up resources for the card you have problems. It is hard to get the assignments of all devices on the system. On the other hand it is probably reasonable to have a default set of resources that you assume are going to work, if the BIOS hasn't done it's job and set up those resources. Eric |
|
From: <ke...@us...> - 2001-06-09 07:20:03
|
>This applies to version 5.1.0 in the src directory. It added the >capability to define FreeBSD kernel environment or do it via a DHCP option. Thanks, will put it in next version. >Comments on picking which option value would be helpfull. I picked 133 >since it was the next one after 132 which is used for the boot how to >flags. ISC-DHCP did something strange when I added it to the list >of options to request. Please voice opinions, pro or con, in this mailing list. |
|
From: Doug A. <amb...@am...> - 2001-06-09 03:13:50
|
This applies to version 5.1.0 in the src directory. It added the
capability to define FreeBSD kernel environment or do it via a DHCP option.
Comments on picking which option value would be helpfull. I picked 133
since it was the next one after 132 which is used for the boot how to
flags. ISC-DHCP did something strange when I added it to the list
of options to request.
Doug A.
diff -r -c ./Config /usr/home/ambrisko/etherboot-5.1.0.orig/src/Config
*** ./Config Sun May 6 22:55:54 2001
--- /usr/home/ambrisko/etherboot-5.1.0.orig/src/Config Fri Jun 8 14:32:07 2001
***************
*** 126,131 ****
--- 126,133 ----
# -DIMAGE_FREEBSD
# Add FreeBSD image loading support (requires at least
# -DAOUT_IMAGE and/or -DELF_IMAGE).
+ # -DFREEBSD_KERNEL_ENV
+ # Pass in FreeBSD kernel environment
# -DDOWNLOAD_PROTO_TFTP
# If defined, boots by tftp (recommended).
# -DDOWNLOAD_PROTO_NFS
diff -r -c ./etherboot.h /usr/home/ambrisko/etherboot-5.1.0.orig/src/etherboot.h
*** ./etherboot.h Sat May 26 16:47:14 2001
--- /usr/home/ambrisko/etherboot-5.1.0.orig/src/etherboot.h Fri Jun 8 14:15:36 2001
***************
*** 221,226 ****
--- 221,227 ----
#define RFC1533_VENDOR_ETHDEV 130
#ifdef IMAGE_FREEBSD
#define RFC1533_VENDOR_HOWTO 132
+ #define RFC1533_VENDOR_KERNEL_ENV 133
#endif
#define RFC1533_VENDOR_MNUOPTS 160
#define RFC1533_VENDOR_SELECTION 176
***************
*** 579,584 ****
--- 580,586 ----
extern unsigned char *end_of_rfc1533;
#ifdef IMAGE_FREEBSD
extern int freebsd_howto;
+ extern char freebsd_kernel_env[1024];
#endif
/* config.c */
diff -r -c ./main.c /usr/home/ambrisko/etherboot-5.1.0.orig/src/main.c
*** ./main.c Sat May 26 16:47:14 2001
--- /usr/home/ambrisko/etherboot-5.1.0.orig/src/main.c Fri Jun 8 14:21:08 2001
***************
*** 49,54 ****
--- 49,55 ----
#ifdef IMAGE_FREEBSD
int freebsd_howto = 0;
+ char freebsd_kernel_env[1024];
#endif
#ifndef BOOTP_DATA_AT_0x93C00
***************
*** 97,102 ****
--- 98,106 ----
RFC1533_VENDOR_ETHDEV,
#ifdef IMAGE_FREEBSD
RFC1533_VENDOR_HOWTO,
+ /*
+ RFC1533_VENDOR_KERNEL_ENV,
+ */
#endif
RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
/* 8 MOTD entries */
***************
*** 999,1004 ****
--- 1003,1014 ----
any troubles with this but I have without it
*/
vendorext_isvalid = 1;
+ #ifdef FREEBSD_KERNEL_ENV
+ memcpy(freebsd_kernel_env, FREEBSD_KERNEL_ENV,
+ strlen(FREEBSD_KERNEL_ENV));
+ #else
+ freebsd_kernel_env[0]='\000';
+ #endif
#else
vendorext_isvalid = 0;
#endif
***************
*** 1072,1077 ****
--- 1082,1094 ----
#ifdef IMAGE_FREEBSD
else if (c == RFC1533_VENDOR_HOWTO)
freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];
+ else if (c == RFC1533_VENDOR_KERNEL_ENV){
+ if(*(p + 1) < sizeof(freebsd_kernel_env)){
+ memcpy(freebsd_kernel_env,p+2,*(p+1));
+ }else{
+ printf("Only support %d bytes in Kernel Env %d\n",sizeof(freebsd_kernel_env));
+ }
+ }
#endif
#ifdef IMAGE_MENU
else if (c == RFC1533_VENDOR_MNUOPTS)
diff -r -c ./osloader.c /usr/home/ambrisko/etherboot-5.1.0.orig/src/osloader.c
*** ./osloader.c Sat May 26 16:51:17 2001
--- /usr/home/ambrisko/etherboot-5.1.0.orig/src/osloader.c Fri Jun 8 14:27:15 2001
***************
*** 502,507 ****
--- 502,512 ----
info.bsdinfo.bi_kernelname = KERNEL_BUF;
info.bsdinfo.bi_nfs_diskless = NULL;
info.bsdinfo.bi_size = sizeof(info.bsdinfo);
+ #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
+ if(strlen(freebsd_kernel_env)>0){
+ freebsd_howto |= RB_BOOTINFO;
+ info.bsdinfo.bi_envp = freebsd_kernel_env;
+ }
/* Check if we have symbols loaded, and if so,
* made the meta_data needed to pass those to
|
|
From: Markus G. <ma...@gu...> - 2001-06-09 02:17:13
|
It's been forever since I looked into this, so I am probably getting all the details wrong. I believe that PNP devices are completely invisible, until the system probes for them and activates them. Probing works by writing some "magic" bit patterns that somehow allow for enumerating all PNP devices. Once a PNP device has been found, it can be queried for the resources that it requires. The BIOS or the OS should then compare these requirements with all the other resources used by all other hardware, allocate the resources and configured the PNP device accordingly. Only now does the device show up in the system. Ken is probably right that some interaction with the BIOS is involved, but I am even more hazy on those issues. I just checked with the source code of Linux v2.4.5ac10 and there is code for ISA PNP in linux/drivers/pnp. I don't think that this code by itself provides sufficient information to write PNP support for etherboot, but if you also track down the specs, then you could probably write a couple of lines of code that allow etherboot to activate a PNP networking card. You probably have to be careful not to activate any other cards, not to activate any interrupts or DMA, querying the BIOS for a range of addresses that is unused and deactivating the device after use. Good luck, Markus Ken Yap wrote: > [Further discussion diverted to developers list.] > > >>The computer is a tulip 486DX4-100, it's made entirely from laptop-hardware: >>it is very flat, has onboard audio, video and nic, and has pcmcia. >>The networkcard is an AMD lance ne2100 (isa), and has bootrom. >>... >>.000021.0000 loadedROM segment 0x900 length 0x4000 reloc 0x9400 >>Boot from (N)etwork of from (L)ocal? N >>Etherboot 5.0.1 (GPL) Tagged ELF for [NE2100] >>Probing...[NE2100]No adapter found<sleep> >>---------------------------------------------------------------------- >>The last line repeats. >> >>The problem is (I think) that it's an isa pnp card; it requires some >>work to get it functioning properly in linux. >>In linux, I have to do the following to use it: >> >>---------------------------------------------------------------------- >># pnpdump > /etc/isapnp.conf >><edit /etc/isapnp.conf, and change the values corresponding to the AMD >> lance. Irq in the file is 3, I have to change it to 9. DMA is 3 and >> stays that way. The i/o address is changed from 0x200 to 0x300.> >># isapnp /etc/isapnp.conf >># modprobe lance >>---------------------------------------------------------------------- >> >>I looked through etherboots source (main.c, config.c and lance.c), but >>I found nothing I could do to make it work. >>The probes with the 4 default i/o adresses (0x300, 0x320, 0x340, 0x360) >>plain fail, and when I forced the lance_probe1() with i/o = 0x300, it >>would crash on boot. >>I also noticed that the docs say isapnp bios support is lacking >>(which I found out the hard way), but my knowledge of how isa pnp works, >>and thus what is required to use this nic from bootrim, is not adequate. >> >>I was hoping you could tell what the exact problem is, what I can do to >>make it work anyway, or some pointers to where I could get help or more >>information on isa pnp. >> > > I honestly don't know what's invoved in ISA PnP support. I think it > requires structures in the ROM header similar to PCI PnP support, but > I haven't seen any docs on it, maybe you could do a search on the net. > Then of course for floppy booting you'd need to somehow hook into what > the BIOS discovered. Good luck. > > _______________________________________________ > Etherboot-developers mailing list > Eth...@li... > http://lists.sourceforge.net/lists/listinfo/etherboot-developers > -- -- Markus Gutschke Resonate, Inc. 3637 Fillmore Street #106 385 Moffett Park Drive San Francisco, CA 94123-1600 Sunnyvale, CA 94089 +1-415-567-8449 +1-408-548-5528 ma...@gu... mgu...@re... |
|
From: Ken Y. <ke...@bi...> - 2001-06-09 01:11:34
|
[Further discussion diverted to developers list.] >The computer is a tulip 486DX4-100, it's made entirely from laptop-hardware: >it is very flat, has onboard audio, video and nic, and has pcmcia. >The networkcard is an AMD lance ne2100 (isa), and has bootrom. >... >.000021.0000 loadedROM segment 0x900 length 0x4000 reloc 0x9400 >Boot from (N)etwork of from (L)ocal? N >Etherboot 5.0.1 (GPL) Tagged ELF for [NE2100] >Probing...[NE2100]No adapter found<sleep> >---------------------------------------------------------------------- >The last line repeats. > >The problem is (I think) that it's an isa pnp card; it requires some >work to get it functioning properly in linux. >In linux, I have to do the following to use it: > >---------------------------------------------------------------------- ># pnpdump > /etc/isapnp.conf ><edit /etc/isapnp.conf, and change the values corresponding to the AMD > lance. Irq in the file is 3, I have to change it to 9. DMA is 3 and > stays that way. The i/o address is changed from 0x200 to 0x300.> ># isapnp /etc/isapnp.conf ># modprobe lance >---------------------------------------------------------------------- > >I looked through etherboots source (main.c, config.c and lance.c), but >I found nothing I could do to make it work. >The probes with the 4 default i/o adresses (0x300, 0x320, 0x340, 0x360) >plain fail, and when I forced the lance_probe1() with i/o = 0x300, it >would crash on boot. >I also noticed that the docs say isapnp bios support is lacking >(which I found out the hard way), but my knowledge of how isa pnp works, >and thus what is required to use this nic from bootrim, is not adequate. > >I was hoping you could tell what the exact problem is, what I can do to >make it work anyway, or some pointers to where I could get help or more >information on isa pnp. I honestly don't know what's invoved in ISA PnP support. I think it requires structures in the ROM header similar to PCI PnP support, but I haven't seen any docs on it, maybe you could do a search on the net. Then of course for floppy booting you'd need to somehow hook into what the BIOS discovered. Good luck. |
|
From: Jason M. <jmc...@li...> - 2001-06-08 17:19:24
|
This is that patch that is required for the
NatSemi DP83815/NetGear FA311 patch
Description: PCI 'read_config_dword' and PCI bus patch
Fix: export 'pcibios_read_config_dword'
Fix: support PCI busses up to 127 (yes, I have such a machine)
Requires: Etherboot-5.0.1
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/pci.c etherboot-5.0.1.new/src/pci.c
--- etherboot-5.0.1/src/pci.c Mon Apr 2 05:00:04 2001
+++ etherboot-5.0.1.new/src/pci.c Fri Jun 8 12:50:58 2001
@@ -48,7 +48,7 @@
return PCIBIOS_SUCCESSFUL;
}
-static int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
+int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
unsigned int where, unsigned int *value)
{
outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
@@ -170,7 +170,7 @@
return (int) (ret & 0xff00) >> 8;
}
-static int pcibios_read_config_dword(unsigned int bus,
+int pcibios_read_config_dword(unsigned int bus,
unsigned int device_fn, unsigned int where, unsigned int *value)
{
unsigned long ret;
@@ -365,7 +365,7 @@
int i, reg;
unsigned int pci_ioaddr = 0;
- buses=1;
+ buses=127;
for (bus = 0; bus < buses; ++bus) {
for (devfn = 0; devfn < 0xff; ++devfn) {
if (PCI_FUNC (devfn) == 0)
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/pci.h etherboot-5.0.1.new/src/pci.h
--- etherboot-5.0.1/src/pci.h Wed Apr 18 11:22:51 2001
+++ etherboot-5.0.1.new/src/pci.h Thu Jun 7 09:59:07 2001
@@ -174,5 +176,6 @@
extern int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char value);
extern int pcibios_read_config_word(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short *value);
extern int pcibios_write_config_word (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short value);
+extern int pcibios_read_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int *value);
extern int pcibios_write_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value);
#endif /* PCI_H */
--
Jason McMullan, Senior Linux Consultant
Linuxcare, Inc. 412.432.6457 tel, 412.656.3519 cell
jmc...@li..., http://www.linuxcare.com/
Linuxcare. Putting open source to work.
|
|
From: Jason M. <jmc...@li...> - 2001-06-08 17:17:07
|
Actually, it's two patches... (the required
PCI patch follows).
Description: Nation Semiconductor DP83815 support
Card: NetGear FA311
Card: NetGear FA312 (untested)
Requires: PCI 'pcibios_read_config_dword' patch
Requires: Etherboot-5.0.1
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/Makefile etherboot-5.0.1.new/src/Makefile
--- etherboot-5.0.1/src/Makefile Thu May 3 11:56:23 2001
+++ etherboot-5.0.1.new/src/Makefile Thu Jun 7 09:10:03 2001
@@ -120,6 +120,7 @@
EPIC100FLAGS= -DINCLUDE_EPIC100
EXOS205FLAGS= -DINCLUDE_EXOS205
LANCEFLAGS= -DINCLUDE_LANCE # Lance/PCI!
+NATSEMIFLAGS= -DINCLUDE_NATSEMI # Netgear FA311/FA312
NE2100FLAGS= -DINCLUDE_NE2100
NEFLAGS= -DINCLUDE_NE -DNE_SCAN=0x300,0x280,0x320,0x340,0x380
NS8390FLAGS= -DINCLUDE_NS8390 # NE2000/PCI!
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/NIC etherboot-5.0.1.new/src/NIC
--- etherboot-5.0.1/src/NIC Thu Apr 26 10:03:19 2001
+++ etherboot-5.0.1.new/src/NIC Thu Jun 7 09:08:45 2001
@@ -162,6 +162,8 @@
ne ns8390
# 3Com503, aka Etherlink II, also /16 model
3c503 ns8390
+# Netgear FA311 and FA312
+fa311 natsemi 0x100b,0x0020
# SMC 83c170 EPIC/100
epic100 epic100 0x10b8,0x0005
# 3c509, ISA/EISA
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/cards.h etherboot-5.0.1.new/src/cards.h
--- etherboot-5.0.1/src/cards.h Tue Feb 27 18:46:10 2001
+++ etherboot-5.0.1.new/src/cards.h Thu Jun 7 10:02:34 2001
@@ -170,4 +170,9 @@
PCI_ARG(struct pci_device *));
#endif
+#ifdef INCLUDE_NATSEMI
+extern struct nic *natsemi_probe(struct nic *, unsigned short *
+ PCI_ARG(struct pci_device *));
+#endif
+
#endif /* CARDS_H */
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/config.c etherboot-5.0.1.new/src/config.c
--- etherboot-5.0.1/src/config.c Wed Apr 25 05:34:08 2001
+++ etherboot-5.0.1.new/src/config.c Thu Jun 7 10:01:24 2001
@@ -9,7 +9,7 @@
#include "nic.h"
#undef INCLUDE_PCI
-#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900)
+#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900) || defined(INCLUDE_NATSEMI)
/* || others later */
#define INCLUDE_PCI
#include "pci.h"
@@ -170,6 +170,10 @@
{ PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
"SIS7016", 0, 0, 0, 0},
#endif
+#ifdef INCLUDE_NATSEMI
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_DP83815,
+ "National Semiconductor DP83815", 0, 0, 0, 0},
+#endif
/* other PCI NICs go here */
{0, 0, NULL, 0, 0, 0, 0}
@@ -287,6 +291,9 @@
#endif
#ifdef INCLUDE_W89C840
{ "W89C840F", w89c840_probe, pci_ioaddrs },
+#endif
+#ifdef INCLUDE_NATSEMI
+ { "NS DP83815", natsemi_probe, pci_ioaddrs },
#endif
/* this entry must always be last to mark the end of list */
{ 0, 0, 0 }
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/natsemi.c etherboot-5.0.1.new/src/natsemi.c
--- etherboot-5.0.1/src/natsemi.c Wed Dec 31 19:00:00 1969
+++ etherboot-5.0.1.new/src/natsemi.c Fri Jun 8 12:49:01 2001
@@ -0,0 +1,864 @@
+/* natsemi.c: A Linux PCI Ethernet driver for the NatSemi DP8381x series. */
+/*
+ Written/copyright 1999-2001 by Donald Becker.
+ Modified for Etherboot 2001, Jason McMullan <jmc...@li...>
+
+ This software may be used and distributed according to the terms of
+ the GNU General Public License (GPL), incorporated herein by reference.
+ Drivers based on or derived from this code fall under the GPL and must
+ retain the authorship, copyright and license notice. This file is not
+ a complete program and may only be used when the entire operating
+ system is licensed under the GPL. License for under other terms may be
+ available. Contact the original author for details.
+
+ The original author may be reached as be...@sc..., or at
+ Scyld Computing Corporation
+ 410 Severn Ave., Suite 210
+ Annapolis MD 21403
+
+ Support information and updates available at
+ http://www.scyld.com/network/netsemi.html
+
+
+ Linux kernel modifications:
+
+ Version 1.0.1.e: (Jason McMullan <jmc...@li...> )
+ - Modified from Linux driver for etherboot
+ Version 1.0.1:
+ - Spinlock fixes
+ - Bug fixes and better intr performance (Tjeerd)
+ Version 1.0.2:
+ - Now reads correct MAC address from eeprom
+ Version 1.0.3:
+ - Eliminate redundant priv->tx_full flag
+ - Call netif_start_queue from dev->tx_timeout
+ - wmb() in start_tx() to flush data
+ - Update Tx locking
+ - Clean up PCI enable (davej)
+ Version 1.0.4:
+ - Merge Donald Becker's natsemi.c version 1.07
+ Version 1.0.5:
+ - { fill me in }
+ Version 1.0.6:
+ * ethtool support (jgarzik)
+ * Proper initialization of the card (which sometimes
+ fails to occur and leaves the card in a non-functional
+ state). (uzi)
+
+ * Some documented register settings to optimize some
+ of the 100Mbit autodetection circuitry in rev C cards. (uzi)
+
+ * Polling of the PHY intr for stuff like link state
+ change and auto- negotiation to finally work properly. (uzi)
+
+ * One-liner removal of a duplicate declaration of
+ natsemi_error(). (uzi)
+
+*/
+
+#define DRV_NAME "natsemi"
+#define DRV_VERSION "1.07+LK1.0.6"
+#define DRV_RELDATE "May 18, 2001"
+
+
+/* Updated to recommendations in pci-skeleton v2.03. */
+
+/* Automatically extracted configuration info:
+probe-func: natsemi_probe
+config-in: tristate 'National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI
+
+c-help-name: National Semiconductor DP8381x series PCI Ethernet support
+c-help-symbol: CONFIG_NATSEMI
+c-help: This driver is for the National Semiconductor DP8381x series,
+c-help: including the 83815 chip.
+c-help: More specific information and updates are available from
+c-help: http://www.scyld.com/network/natsemi.html
+*/
+
+/* The user-configurable values.
+ These may be modified when a driver module is loaded.*/
+
+static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 20;
+static int mtu;
+/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
+ This chip uses a 512 element hash table based on the Ethernet CRC. */
+static int multicast_filter_limit = 100;
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
+ Setting to > 1518 effectively disables this feature. */
+static int rx_copybreak;
+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+ The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+ Making the Tx ring too large decreases the effectiveness of channel
+ bonding and packet priority.
+ There are no ill effects from too-large receive rings. */
+#define TX_RING_SIZE 4
+#define RX_RING_SIZE 4
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT (2*HZ)
+
+#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
+
+#define DEBUGMSG(level, format, args...) { if (debug >= level) printf(format , ##args); }
+
+#if !defined(__OPTIMIZE__)
+#warning You must compile this file with the correct options!
+#warning See the last lines of the source file.
+#error You must compile this driver with "-O".
+#endif
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+
+#ifdef __KERNEL__
+/* These identify the driver base version and may not be removed. */
+static char version[] __devinitdata =
+KERN_INFO DRV_NAME ".c:v1.07 1/9/2001 Written by Donald Becker <be...@sc...>\n"
+KERN_INFO " http://www.scyld.com/network/natsemi.html\n"
+KERN_INFO " (unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE " Jeff Garzik, Tjeerd Mulder)\n";
+#endif
+
+/* Condensed operations for readability. */
+#define cpu_to_le32(x) ((unsigned long)(x))
+#define le32_to_cpu(x) ((unsigned long)(x))
+#define bus_to_virt(x) ((unsigned long)(x))
+#define virt_to_le32desc(addr) cpu_to_le32(addr)
+#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
+
+static int eeprom_read(long addr, int location);
+static int mdio_read(struct nic *dev, int phy_id, int location);
+static void natsemi_reset(struct nic *dev);
+static void check_duplex(struct nic *dev);
+static void init_ring(struct nic *dev);
+static void natsemi_tx(struct nic *dev, const char *dest, unsigned int type, unsigned int size, const char *pack);
+static int natsemi_poll(struct nic *dev);
+static int natsemi_rx(struct nic *dev);
+static void natsemi_error(struct nic *dev, int intr_status);
+static void set_rx_mode(struct nic *dev);
+static void natsemi_disable(struct nic *dev);
+
+/*
+ Theory of Operation
+
+I. Board Compatibility
+
+This driver is designed for National Semiconductor DP83815 PCI Ethernet NIC.
+It also works with other chips in in the DP83810 series.
+
+II. Board-specific settings
+
+This driver requires the PCI interrupt line to be valid.
+It honors the EEPROM-set values.
+
+III. Driver operation
+
+IIIa. Ring buffers
+
+This driver uses two statically allocated fixed-size descriptor lists
+formed into rings by a branch from the final descriptor to the beginning of
+the list. The ring sizes are set at compile time by RX/TX_RING_SIZE.
+The NatSemi design uses a 'next descriptor' pointer that the driver forms
+into a list.
+
+IIIb/c. Transmit/Receive Structure
+
+This driver uses a zero-copy receive and transmit scheme.
+The driver allocates full frame size skbuffs for the Rx ring buffers at
+open() time and passes the skb->data field to the chip as receive data
+buffers. When an incoming frame is less than RX_COPYBREAK bytes long,
+a fresh skbuff is allocated and the frame is copied to the new skbuff.
+When the incoming frame is larger, the skbuff is passed directly up the
+protocol stack. Buffers consumed this way are replaced by newly allocated
+skbuffs in a later phase of receives.
+
+The RX_COPYBREAK value is chosen to trade-off the memory wasted by
+using a full-sized skbuff for small frames vs. the copying costs of larger
+frames. New boards are typically used in generously configured machines
+and the underfilled buffers have negligible impact compared to the benefit of
+a single allocation size, so the default value of zero results in never
+copying packets. When copying is done, the cost is usually mitigated by using
+a combined copy/checksum routine. Copying also preloads the cache, which is
+most useful with small frames.
+
+A subtle aspect of the operation is that unaligned buffers are not permitted
+by the hardware. Thus the IP header at offset 14 in an ethernet frame isn't
+longword aligned for further processing. On copies frames are put into the
+skbuff at an offset of "+2", 16-byte aligning the IP header.
+
+IIId. Synchronization
+
+The driver runs as two independent, single-threaded flows of control. One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag. The other thread is the interrupt handler, which is single
+threaded by the hardware and interrupt handling software.
+
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets
+the 'lp->tx_full' flag.
+
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring. After reaping the stats, it marks the Tx queue entry as
+empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
+clears both the tx_full and tbusy flags.
+
+IV. Notes
+
+NatSemi PCI network controllers are very uncommon.
+
+IVb. References
+
+http://www.scyld.com/expert/100mbps.html
+http://www.scyld.com/expert/NWay.html
+Datasheet is available from:
+http://www.national.com/pf/DP/DP83815.html
+
+IVc. Errata
+
+None characterised.
+*/
+
+
+
+enum pcistuff {
+ PCI_USES_IO = 0x01,
+ PCI_USES_MEM = 0x02,
+ PCI_USES_MASTER = 0x04,
+ PCI_ADDR0 = 0x08,
+ PCI_ADDR1 = 0x10,
+};
+
+/* MMIO operations required */
+#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
+
+/* Offsets to the device registers.
+ Unlike software-only systems, device drivers interact with complex hardware.
+ It's not useful to define symbolic names for every register bit in the
+ device.
+*/
+enum register_offsets {
+ ChipCmd=0x00, ChipConfig=0x04, EECtrl=0x08, PCIBusCfg=0x0C,
+ IntrStatus=0x10, IntrMask=0x14, IntrEnable=0x18,
+ TxRingPtr=0x20, TxConfig=0x24,
+ RxRingPtr=0x30, RxConfig=0x34, ClkRun=0x3C,
+ WOLCmd=0x40, PauseCmd=0x44, RxFilterAddr=0x48, RxFilterData=0x4C,
+ BootRomAddr=0x50, BootRomData=0x54, SiliconRev=0x58, StatsCtrl=0x5C,
+ StatsData=0x60, RxPktErrs=0x60, RxMissed=0x68, RxCRCErrs=0x64,
+ PCIPM=0x44, PhyStatus=0xC0, MIntrCtrl=0xC4, MIntrStatus=0xC8,
+
+ /* These are from the spec, around page 78... on a separate table. */
+ PGSEL=0xCC, PMDCSR=0xE4, TSTDAT=0xFC, DSPCFG=0xF4, SDCFG=0x8C
+};
+
+/* Bit in ChipCmd. */
+enum ChipCmdBits {
+ ChipReset=0x100, RxReset=0x20, TxReset=0x10, RxOff=0x08, RxOn=0x04,
+ TxOff=0x02, TxOn=0x01,
+};
+
+/* Bits in the interrupt status/mask registers. */
+enum intr_status_bits {
+ IntrRxDone=0x0001, IntrRxIntr=0x0002, IntrRxErr=0x0004, IntrRxEarly=0x0008,
+ IntrRxIdle=0x0010, IntrRxOverrun=0x0020,
+ IntrTxDone=0x0040, IntrTxIntr=0x0080, IntrTxErr=0x0100,
+ IntrTxIdle=0x0200, IntrTxUnderrun=0x0400,
+ StatsMax=0x0800, LinkChange=0x4000,
+ WOLPkt=0x2000,
+ RxResetDone=0x1000000, TxResetDone=0x2000000,
+ IntrPCIErr=0x00f00000,
+ IntrNormalSummary=0x0251, IntrAbnormalSummary=0xED20,
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+ AcceptErr=0x20, AcceptRunt=0x10,
+ AcceptBroadcast=0xC0000000,
+ AcceptMulticast=0x00200000, AcceptAllMulticast=0x20000000,
+ AcceptAllPhys=0x10000000, AcceptMyPhys=0x08000000,
+};
+
+/* The Rx and Tx buffer descriptors. */
+/* Note that using only 32 bit fields simplifies conversion to big-endian
+ architectures. */
+struct natsemi_desc {
+ unsigned long next_desc;
+ signed long cmd_status;
+ unsigned long addr;
+ unsigned long software_use;
+};
+
+typedef char packet[PKT_BUF_SZ];
+
+struct natsemi_queue {
+ struct natsemi_desc desc[RX_RING_SIZE];
+ packet buff[RX_RING_SIZE]; /* Packet buffers */
+ int curr; /* Head of queue */
+};
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+ DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000,
+ DescNoCRC=0x10000000,
+ DescPktOK=0x08000000, RxTooLong=0x00400000,
+};
+
+#define PRIV_ALIGN 15 /* Required alignment mask */
+struct natsemi_private {
+ /* Descriptor rings first for alignment. */
+ struct natsemi_queue rx_ring;
+ struct natsemi_queue tx_ring;
+
+ /* Frequently used values: keep some adjacent for cache effect. */
+ unsigned int rx_buf_sz; /* Based on MTU+slack. */
+ /* These values are keep track of the transceiver/media in use. */
+ unsigned int medialock:1; /* Do not sense media. */
+ unsigned int default_port:4; /* Last dev->if_port value. */
+ /* Rx filter. */
+ unsigned long cur_rx_mode;
+ unsigned long rx_filter[16];
+ /* FIFO and PCI burst thresholds. */
+ unsigned long tx_config, rx_config;
+ /* original contents of ClkRun register */
+ unsigned long SavedClkRun;
+ /* MII transceiver section. */
+ unsigned short advertising; /* NWay media advertisement */
+
+ unsigned long ioaddr;
+} npx;
+
+
+struct nic *natsemi_probe(struct nic *dev, unsigned short *io_addrs, struct pci_device *pdev)
+{
+ struct natsemi_private *np;
+ int i, option;
+ unsigned long ioaddr;
+ const int pcibar = 1; /* PCI base address register */
+ int prev_eedata;
+ int tmp;
+
+ if (pdev == 0 || pdev->membase == 0)
+ return NULL;
+
+ ioaddr = pdev->membase;
+
+ printf("%s: MMIO region %X\n", DRV_NAME, ioaddr);
+
+ /* point to private storage */
+ np = &npx;
+ np->ioaddr = ioaddr;
+
+ /* natsemi has a non-standard PM control register
+ * in PCI config space. Some boards apparently need
+ * to be brought to D0 in this manner.
+ */
+ pcibios_read_config_dword(pdev->bus, pdev->devfn, PCIPM, &tmp);
+ if (tmp & (0x03|0x100)) {
+ /* D0 state, disable PME assertion */
+ unsigned long newtmp = tmp & ~(0x03|0x100);
+ pcibios_write_config_dword(pdev->bus, pdev->devfn, PCIPM, newtmp);
+ }
+
+ /* Work around the dropped serial bit. */
+ prev_eedata = eeprom_read(ioaddr, 6);
+ for (i = 0; i < 3; i++) {
+ int eedata = eeprom_read(ioaddr, i + 7);
+ dev->node_addr[i*2] = (eedata << 1) + (prev_eedata >> 15);
+ dev->node_addr[i*2+1] = eedata >> 7;
+ prev_eedata = eedata;
+ }
+
+ /* Reset the chip to erase previous misconfiguration. */
+ writel(ChipReset, ioaddr + ChipCmd);
+
+ /* The chip-specific entries in the device structure. */
+ dev->reset=natsemi_reset;
+ dev->poll=natsemi_poll;
+ dev->transmit=natsemi_tx;
+ dev->disable=natsemi_disable;
+
+ printf("%s: %x:%x, ioaddr %x, MAC: %b:%b:%b:%b:%b:%b ",
+ DRV_NAME, pdev->bus, pdev->devfn, ioaddr,
+ dev->node_addr[0],dev->node_addr[1],dev->node_addr[2],
+ dev->node_addr[3],dev->node_addr[4],dev->node_addr[5]);
+
+ np->advertising = mdio_read(dev, 1, 4);
+ if ((readl(ioaddr + ChipConfig) & 0xe000) != 0xe000) {
+ unsigned long chip_config = readl(ioaddr + ChipConfig);
+ printf("%s: Transceiver default autonegotiation %s "
+ "10%s %s duplex.\n",
+ DRV_NAME,
+ chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
+ chip_config & 0x4000 ? "0" : "",
+ chip_config & 0x8000 ? "full" : "half");
+ }
+ printf("%s: Transceiver status 0x%x advertising %x.\n",
+ DRV_NAME, (int)readl(ioaddr + 0x84), np->advertising);
+
+ natsemi_reset(dev);
+
+ return dev;
+}
+
+
+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
+ The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */
+
+/* Delay between EEPROM clock transitions.
+ No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
+ a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
+ made udelay() unreliable.
+ The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
+ depricated.
+*/
+#define eeprom_delay(ee_addr) readl(ee_addr)
+
+enum EEPROM_Ctrl_Bits {
+ EE_ShiftClk=0x04, EE_DataIn=0x01, EE_ChipSelect=0x08, EE_DataOut=0x02,
+};
+#define EE_Write0 (EE_ChipSelect)
+#define EE_Write1 (EE_ChipSelect | EE_DataIn)
+
+/* The EEPROM commands include the alway-set leading bit. */
+enum EEPROM_Cmds {
+ EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
+};
+
+static int eeprom_read(long addr, int location)
+{
+ int i;
+ int retval = 0;
+ int ee_addr = addr + EECtrl;
+ int read_cmd = location | EE_ReadCmd;
+ writel(EE_Write0, ee_addr);
+
+ /* Shift the read command bits out. */
+ for (i = 10; i >= 0; i--) {
+ short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+ writel(dataval, ee_addr);
+ eeprom_delay(ee_addr);
+ writel(dataval | EE_ShiftClk, ee_addr);
+ eeprom_delay(ee_addr);
+ }
+ writel(EE_ChipSelect, ee_addr);
+ eeprom_delay(ee_addr);
+
+ for (i = 0; i < 16; i++) {
+ writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
+ eeprom_delay(ee_addr);
+ retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0;
+ writel(EE_ChipSelect, ee_addr);
+ eeprom_delay(ee_addr);
+ }
+
+ /* Terminate the EEPROM access. */
+ writel(EE_Write0, ee_addr);
+ writel(0, ee_addr);
+ return retval;
+}
+
+/* MII transceiver control section.
+ The 83815 series has an internal transceiver, and we present the
+ management registers as if they were MII connected. */
+
+static int mdio_read(struct nic *dev, int phy_id, int location)
+{
+ if (phy_id == 1 && location < 32)
+ return readl(npx.ioaddr + 0x80 + (location<<2)) & 0xffff;
+ else
+ return 0xffff;
+}
+
+
+static void natsemi_reset(struct nic *dev)
+{
+ struct natsemi_private *np = &npx;
+ long ioaddr = npx.ioaddr;
+ int i;
+
+ /* Reset the chip, just in case. */
+ writel(ChipReset, ioaddr + ChipCmd);
+
+ /* On page 78 of the spec, they recommend some settings for "optimum
+ performance" to be done in sequence. These settings optimize some
+ of the 100Mbit autodetection circuitry. Also, we only want to do
+ this for rev C of the chip.
+ */
+ if (readl(ioaddr + SiliconRev) == 0x302) {
+ writew(0x0001, ioaddr + PGSEL);
+ writew(0x189C, ioaddr + PMDCSR);
+ writew(0x0000, ioaddr + TSTDAT);
+ writew(0x5040, ioaddr + DSPCFG);
+ writew(0x008C, ioaddr + SDCFG);
+ }
+
+ /* Enable PHY Specific event based interrupts. Link state change
+ and Auto-Negotiation Completion are among the affected.
+ */
+ writew(0x0002, ioaddr + MIntrCtrl);
+
+ init_ring(dev);
+
+ writel(virt_to_le32desc(np->rx_ring.desc), ioaddr + RxRingPtr);
+ writel(virt_to_le32desc(np->tx_ring.desc), ioaddr + TxRingPtr);
+
+ for (i = 0; i < ETH_ALEN; i += 2) {
+ writel(i, ioaddr + RxFilterAddr);
+ writew(dev->node_addr[i] + (dev->node_addr[i+1] << 8),
+ ioaddr + RxFilterData);
+ }
+
+ /* Initialize other registers. */
+ /* Configure the PCI bus bursts and FIFO thresholds. */
+ /* Configure for standard, in-spec Ethernet. */
+
+ if (readl(ioaddr + ChipConfig) & 0x20000000) { /* Full duplex */
+ np->tx_config = 0xD0801002;
+ np->rx_config = 0x10000020;
+ } else {
+ np->tx_config = 0x10801002;
+ np->rx_config = 0x0020;
+ }
+ writel(np->tx_config, ioaddr + TxConfig);
+ writel(np->rx_config, ioaddr + RxConfig);
+
+ /* Disable PME:
+ * The PME bit is initialized from the EEPROM contents.
+ * PCI cards probably have PME disabled, but motherboard
+ * implementations may have PME set to enable WakeOnLan.
+ * With PME set the chip will scan incoming packets but
+ * nothing will be written to memory. */
+ np->SavedClkRun = readl(ioaddr + ClkRun);
+ writel(np->SavedClkRun & ~0x100, ioaddr + ClkRun);
+
+ check_duplex(dev);
+ set_rx_mode(dev);
+
+ /* Enable interrupts by setting the interrupt mask. */
+ writel(IntrNormalSummary | IntrAbnormalSummary | 0x1f, ioaddr + IntrMask);
+ writel(1, ioaddr + IntrEnable);
+
+ writel(RxOn | TxOn, ioaddr + ChipCmd);
+ writel(4, ioaddr + StatsCtrl); /* Clear Stats */
+
+ DEBUGMSG(2,"%s: Done natsemi_reset(), status: %x.\n",
+ DRV_NAME, (int)readl(ioaddr + ChipCmd));
+}
+
+static void check_duplex(struct nic *dev)
+{
+ struct natsemi_private *np = &npx;
+ long ioaddr = npx.ioaddr;
+ int duplex;
+
+ duplex = readl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
+ DEBUGMSG(1,"%s: Setting %s-duplex based on negotiated link"
+ " capability.\n", DRV_NAME,
+ duplex ? "full" : "half");
+ if (duplex) {
+ np->rx_config |= 0x10000000;
+ np->tx_config |= 0xC0000000;
+ } else {
+ np->rx_config &= ~0x10000000;
+ np->tx_config &= ~0xC0000000;
+ }
+ writel(np->tx_config, ioaddr + TxConfig);
+ writel(np->rx_config, ioaddr + RxConfig);
+}
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(struct nic *dev)
+{
+ struct natsemi_private *np = &npx;
+ int i;
+
+ np->rx_buf_sz = PKT_BUF_SZ;
+
+ /* Initialize all Rx descriptors. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring.desc[i].addr = virt_to_le32desc(&np->rx_ring.buff[i]);
+ np->rx_ring.desc[i].next_desc = virt_to_le32desc(&np->rx_ring.desc[i+1]);
+ np->rx_ring.desc[i].cmd_status = cpu_to_le32(DescIntr | np->rx_buf_sz);
+ }
+ /* Mark the last entry as wrapping the ring. */
+ np->rx_ring.desc[i-1].next_desc = virt_to_le32desc(&np->rx_ring.desc[0]);
+ np->rx_ring.curr=0;
+
+ /* Fill in the Tx buffers. */
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ np->tx_ring.desc[i].addr = virt_to_le32desc(&np->tx_ring.buff[i]);
+ np->tx_ring.desc[i].next_desc = virt_to_le32desc(&np->tx_ring.desc[i+1]);
+ np->tx_ring.desc[i].cmd_status = 0;
+ }
+ np->tx_ring.desc[i-1].next_desc = virt_to_le32desc(&np->tx_ring.desc[0]);
+ np->tx_ring.curr=0;
+
+ return;
+}
+
+static void natsemi_tx(struct nic *dev, const char *dest, unsigned int type, unsigned int size, const char *pack)
+{
+ struct natsemi_private *np = &npx;
+ unsigned entry;
+ unsigned int i;
+ char *p;
+
+ /* Note: Ordering is important here, set the field with the
+ "ownership" bit last, and only then increment cur_tx. */
+ entry = np->tx_ring.curr;
+
+ DEBUGMSG(3, "%s: TX (packet length %d), ring #%d\n", DRV_NAME, size, entry);
+
+ /* Calculate the next Tx descriptor entry. */
+ p=np->tx_ring.buff[entry];
+ for (i=0;i<ETH_ALEN;i++,p++) {
+ *p = dest[i];
+ *(p+ETH_ALEN)=dev->node_addr[i];
+ }
+ p += ETH_ALEN;
+ *((unsigned short *)p)=htons(type);
+ p += 2;
+ for (i=0;i<size;i++,p++)
+ *p=pack[i];
+
+ size += 2+(ETH_ALEN*2);
+ np->tx_ring.desc[entry].cmd_status = cpu_to_le32(DescOwn|DescIntr | size);
+
+ /* Wake the potentially-idle transmit channel. */
+ writel(TxOn, npx.ioaddr + ChipCmd);
+
+ /* Wait for TX to complete */
+ natsemi_poll(dev);
+
+ DEBUGMSG(3, "%s: TX complete\n", DRV_NAME);
+
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+ after the Tx thread. */
+static int natsemi_poll(struct nic *dev)
+{
+ struct natsemi_private *np;
+ long ioaddr;
+ int entry;
+ unsigned long intr_status, imr_status;
+
+ ioaddr = npx.ioaddr;
+ np = &npx;
+
+wait_some_more:
+ intr_status = readl(ioaddr + IntrStatus);
+
+ /* Acknowledge all of the current interrupt sources ASAP. */
+// writel(intr_status & 0x000ffff, ioaddr + IntrStatus);
+
+ if (intr_status != 0)
+ DEBUGMSG(4, "%s: poll, status %x.\n",
+ DRV_NAME, intr_status);
+
+ entry=np->tx_ring.curr;
+
+ /* Abnormal error summary/uncommon events handlers. */
+ if (intr_status & IntrAbnormalSummary)
+ natsemi_error(dev, intr_status);
+
+ /* Only do RX if there is no TX pending
+ */
+ if ((intr_status & IntrRxDone) &&
+ (np->tx_ring.desc[entry].cmd_status == 0))
+ return natsemi_rx(dev);
+
+ /* Still waiting for TX? */
+ if ((intr_status & IntrTxDone) == 0 &&
+ np->tx_ring.desc[entry].cmd_status != 0)
+ goto wait_some_more;
+
+ if (intr_status & IntrTxDone) {
+ if (np->tx_ring.desc[entry].cmd_status & cpu_to_le32(0x08000000)) {
+ DEBUGMSG(5, "%s: TX done\n", DRV_NAME);
+ /* TX went ok! */
+ } else { /* Various Tx errors */
+ int tx_status = le32_to_cpu(np->tx_ring.desc[entry].cmd_status);
+ if (tx_status & 0x04010000)
+ printf("%s: TX aborted\n", DRV_NAME);
+ if (tx_status & 0x02000000)
+ printf("%s: TX FIFO error\n", DRV_NAME);
+ if (tx_status & 0x01000000)
+ printf("%s: TX carrier error\n", DRV_NAME);
+ if (tx_status & 0x00200000)
+ printf("%s: TX window error\n");
+ printf("%s: TX status error %X\n", DRV_NAME, tx_status);
+ }
+ np->tx_ring.desc[entry].cmd_status = 0;
+ np->tx_ring.curr = (++np->tx_ring.curr) % TX_RING_SIZE;
+ }
+
+exit_ok:
+ return 0;
+}
+
+/* This routine is logically part of the interrupt handler, but separated
+ for clarity and better register allocation. */
+static int natsemi_rx(struct nic *dev)
+{
+ struct natsemi_private *np = &npx;
+ int entry, gotone=0;
+ unsigned long desc_status;
+
+ entry = np->rx_ring.curr;
+ desc_status = le32_to_cpu(np->rx_ring.desc[entry].cmd_status);
+
+ DEBUGMSG(3, "%s: RX enter\n", DRV_NAME);
+
+ /* If the driver owns the next entry it's a new packet. Send it up. */
+ if (desc_status & DescOwn) {
+ DEBUGMSG(4, " In natsemi_rx() entry %d status was %X.\n",
+ entry, desc_status);
+ if ((desc_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
+ if (desc_status & DescMore) {
+ printf("%s: Oversized(?) Ethernet frame spanned "
+ "multiple buffers, status %x.\n",
+ DRV_NAME, desc_status);
+ } else {
+ /* There was a error. */
+ DEBUGMSG(4, " natsemi_rx() Rx error was %X.\n",
+ desc_status);
+ if (desc_status & 0x06000000)
+ printf("%s: RX overrun\n", DRV_NAME);
+ if (desc_status & 0x00600000)
+ printf("%s: RX length error\n", DRV_NAME);
+ if (desc_status & 0x00140000)
+ printf("%s: RX frame error\n", DRV_NAME);
+ if (desc_status & 0x00080000)
+ printf("%s: RX CRC error\n", DRV_NAME);
+ }
+ } else {
+ int pkt_len = (desc_status & 0x0fff);
+ memcpy(dev->packet, np->rx_ring.buff[entry], pkt_len);
+ dev->packetlen=pkt_len;
+ DEBUGMSG(4,"%s: RX %d bytes\n",DRV_NAME, pkt_len);
+ gotone=1;
+ }
+ /* Refill the Rx ring buffers. */
+ np->rx_ring.desc[entry].cmd_status = cpu_to_le32(DescIntr | np->rx_buf_sz);
+ np->rx_ring.curr = (++np->rx_ring.curr) % RX_RING_SIZE;
+ }
+
+
+ /* Restart Rx engine if stopped. */
+ writel(RxOn, npx.ioaddr + ChipCmd);
+
+ DEBUGMSG(3, "%s: RX done\n", DRV_NAME);
+
+ return gotone;
+}
+
+static void natsemi_error(struct nic *dev, int intr_status)
+{
+ struct natsemi_private *np = &npx;
+ long ioaddr = npx.ioaddr;
+
+ if (intr_status & LinkChange) {
+ printf("%s: Link changed: Autonegotiation advertising"
+ " %x partner %x.\n", DRV_NAME,
+ (int)readl(ioaddr + 0x90), (int)readl(ioaddr + 0x94));
+ /* read MII int status to clear the flag */
+ readw(ioaddr + MIntrStatus);
+ check_duplex(dev);
+ }
+ if (intr_status & IntrTxUnderrun) {
+ if ((np->tx_config & 0x3f) < 62)
+ np->tx_config += 2;
+ writel(np->tx_config, ioaddr + TxConfig);
+ }
+ if (intr_status & WOLPkt) {
+ int wol_status = readl(ioaddr + WOLCmd);
+ printf("%s: Link wake-up event %X",
+ DRV_NAME, wol_status);
+ }
+ if (intr_status & ~(LinkChange|StatsMax|RxResetDone|TxResetDone|0xA7ff))
+ DEBUGMSG(1, "%s: Something Wicked happened! %x.\n",
+ DRV_NAME, intr_status);
+ /* Hmmmmm, it's not clear how to recover from PCI faults. */
+ if (intr_status & IntrPCIErr) {
+ printf("%s: Ack! PCI fault!\n", DRV_NAME);
+ }
+}
+
+/* The little-endian AUTODIN II ethernet CRC calculations.
+ A big-endian version is also available.
+ This is slow but compact code. Do not use this routine for bulk data,
+ use a table-based routine instead.
+ This is common code and should be moved to net/core/crc.c.
+ Chips may use the upper or lower CRC bits, and may reverse and/or invert
+ them. Select the endian-ness that results in minimal calculations.
+*/
+static unsigned const ethernet_polynomial_le = 0xedb88320U;
+static inline unsigned ether_crc_le(int length, unsigned char *data)
+{
+ unsigned int crc = 0xffffffff; /* Initial value. */
+ while(--length >= 0) {
+ unsigned char current_octet = *data++;
+ int bit;
+ for (bit = 8; --bit >= 0; current_octet >>= 1) {
+ if ((crc ^ current_octet) & 1) {
+ crc >>= 1;
+ crc ^= ethernet_polynomial_le;
+ } else
+ crc >>= 1;
+ }
+ }
+ return crc;
+}
+
+static void set_rx_mode(struct nic *dev)
+{
+ long ioaddr = npx.ioaddr;
+ struct natsemi_private *np = &npx;
+ unsigned long rx_mode;
+
+ rx_mode = AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys;
+ writel(rx_mode, ioaddr + RxFilterAddr);
+ np->cur_rx_mode = rx_mode;
+}
+
+static void natsemi_disable(struct nic *dev)
+{
+ long ioaddr = npx.ioaddr;
+ struct natsemi_private *np = &npx;
+ int i;
+
+ DEBUGMSG(2, "%s: Shutting down ethercard, status was %x "
+ "Int %x.\n",
+ DRV_NAME, (int)readl(ioaddr + ChipCmd),
+ (int)readl(ioaddr + IntrStatus));
+
+ /* Disable interrupts using the mask. */
+ writel(0, ioaddr + IntrMask);
+ writel(0, ioaddr + IntrEnable);
+ writel(2, ioaddr + StatsCtrl); /* Freeze Stats */
+
+ /* Stop the chip's Tx and Rx processes. */
+ writel(RxOff | TxOff, ioaddr + ChipCmd);
+
+ /* Free all the skbuffs in the Rx queue. */
+ i=0;
+ np->rx_ring.desc[i].cmd_status = 0;
+ np->rx_ring.desc[i].addr = 0xBADF00D0; /* An invalid address. */
+
+ /* Restore PME enable bit */
+ writel(np->SavedClkRun, ioaddr + ClkRun);
+#if 0
+ writel(0x0200, ioaddr + ChipConfig); /* Power down Xcvr. */
+#endif
+
+ return;
+}
diff --exclude=*~ --recursive --new-file -u etherboot-5.0.1/src/pci.h etherboot-5.0.1.new/src/pci.h
--- etherboot-5.0.1/src/pci.h Wed Apr 18 11:22:51 2001
+++ etherboot-5.0.1.new/src/pci.h Thu Jun 7 09:59:07 2001
@@ -158,6 +158,8 @@
#define PCI_DEVICE_ID_SIS7016 0x7016
#define PCI_VENDOR_ID_DLINK 0x1186
#define PCI_DEVICE_ID_DFE530TXP 0x1300
+#define PCI_VENDOR_ID_NS 0x100b
+#define PCI_DEVICE_ID_NS_DP83815 0x0020
struct pci_device {
unsigned short vendor, dev_id;
--
Jason McMullan, Senior Linux Consultant
Linuxcare, Inc. 412.432.6457 tel, 412.656.3519 cell
jmc...@li..., http://www.linuxcare.com/
Linuxcare. Putting open source to work.
|
|
From: <ke...@us...> - 2001-06-03 14:50:18
|
I have released mknbi-1.2-2 at http://etherboot.sourceforge.net/distribution.html This release fixes two bugs: - Forgot to update consistency checking code in mknbi-*dos to take into account full version number. - Moving Etherboot to 0x94000 broke mknbi-fdos because setup segment was at 0x97000. Move setup segment to 0x93000. Actually ($reloc + 0x300) * 16. mknbi-linux only users need not update. |
|
From: <ke...@us...> - 2001-05-31 08:58:56
|
I have released Etherboot 5.1.0 at http://etherboot.sourceforge.net/distribution.html This is a development release as the changes are extensive, however the changes will be backported to 5.0.x when they have been verified. Please test this release as the improvements are very worthwhile. Changes from 5.0.1: + Arkadiusz Miskiewicz pointed out that --oformat should be used instead of -oformat as old ld accepts both while new ld requires --oformat. + contrib/{tftp-hpa,atftp} are distributed separately from the distribution page to make them easy to update. + Eric Biederman contributed many small changes in the code to improve the behaviour in exceptions and generally improve the code structure: 1) Cleanup etherboot restarting. There is now only one place that needs to test for EMERGENCYBOOTDISK. 2) Change pci.c as I have suggested. It is setup to scan every possible pci bus until it finds an etherboot card. 3) Change osloader.c so that if an image that can return, but isn't supposed to it restarts etherboot with -2 instead of the returned value. 4) Rewrites the delay logic so that we compute how long we should sleep, and then sleep the whole time in await_reply so in a congested networks we don't miss slow packets. 5) divides load into load & load_configuration. This removes the need for the weird bootp_completed variable. And makes it a little more explicit what we are doing. 6) add an interruptible_sleep function so that we can sleep and still process keystrokes. 7) rewrites the restart logic: - renames jmp_bootmenu to restart_etherboot. - removes bootmenu (The function isn't) - It explicitly does an eth_reset & eth_probe pair to reinitialize the interface. This should help if someone has plugged the interface into a different switch since booting started. - moves ASK_BOOT and TRY_FLOPPY_FIRST into their own functions. - On every restart calls ask_boot and try_floppy_first. Allowing you to change your mind on how you want to boot after network booting starts. 8) In cleanup calls both eth_disable (to disable the interface) & eth_reset to make certain the interface can be initialized from linux. (If nothing else this should cause more hidden bugs to show up). 9) Restart etherboot when downloading a bootfile fails, instead of just looping trying to get that file. Allowing typos in dhcpd.conf to be corrected without having to reboot the client machine running etherboot. MD5 sums: ef6c508dfb1167a9a0fff30693a43e09 etherboot-5.1.0.tar.bz2 6cae24fc8fc937f90ea1214d890ed323 etherboot-5.1.0.tar.gz |
|
From: Ken Y. <ke...@bi...> - 2001-05-31 04:01:54
|
I have released Etherboot 5.1.0 (development) at http://etherboot.sourceforge.net/distribution.html This release contains some major restructuring, thanks to Eric W. Biederman, which improves Etherboot's response to exceptions, so please test it. The features will be backported to 5.0.x in time. Changes from 5.0.1: + Arkadiusz Miskiewicz pointed out that --oformat should be used instead of -oformat as old ld accepts both while new ld requires --oformat. + contrib/{tftp-hpa,atftp} are distributed separately from the distribution page to make them easy to update. + Eric Biederman contributed many small changes in the code to improve the behaviour in exceptions and generally improve the code structure: 1) Cleanup etherboot restarting. There is now only one place that needs to test for EMERGENCYBOOTDISK. 2) Change pci.c as I have suggested. It is setup to scan every possible pci bus until it finds an etherboot card. 3) Change osloader.c so that if an image that can return, but isn't supposed to it restarts etherboot with -2 instead of the returned value. 4) Rewrites the delay logic so that we compute how long we should sleep, and then sleep the whole time in await_reply so in a congested networks we don't miss slow packets. 5) divides load into load & load_configuration. This removes the need for the weird bootp_completed variable. And makes it a little more explicit what we are doing. 6) add an interruptible_sleep function so that we can sleep and still process keystrokes. 7) rewrites the restart logic: - renames jmp_bootmenu to restart_etherboot. - removes bootmenu (The function isn't) - It explicitly does an eth_reset & eth_probe pair to reinitialize the interface. This should help if someone has plugged the interface into a different switch since booting started. - moves ASK_BOOT and TRY_FLOPPY_FIRST into their own functions. - On every restart calls ask_boot and try_floppy_first. Allowing you to change your mind on how you want to boot after network booting starts. 8) In cleanup calls both eth_disable (to disable the interface) & eth_reset to make certain the interface can be initialized from linux. (If nothing else this should cause more hidden bugs to show up). 9) Restart etherboot when downloading a bootfile fails, instead of just looping trying to get that file. Allowing typos in dhcpd.conf to be corrected without having to reboot the client machine running etherboot. MD5 sums: ef6c508dfb1167a9a0fff30693a43e09 etherboot-5.1.0.tar.bz2 6cae24fc8fc937f90ea1214d890ed323 etherboot-5.1.0.tar.gz |
|
From: Marty C. <md...@th...> - 2001-05-30 17:26:10
|
[ we may be getting into Etherboot-Developers territory, but I think some
people might be interested in the subtle kinds of interactions that
happen when you get close to the hardware. figuring out "whose bug it
is" is not always easy, because often at this level, it a question of
semantics - that is that both sides are doing something that is legal,
but because of timing or protocol they are not able to communicate. The
tulip driver is an especially complicated because DEC wrote the spec and
people made clone cards that sort of followed the spec, but there was
room for variance and interpretation, and so there are times where things
don't work as we think they should. Anyway, onward we go. ]
On 5/27/01 2:51 AM Michael Stein ma...@uc... wrote:
>PS: Why is the number of loops 1000? The loop might only
> be a few clocks long and at 2 ns/clock (466 Mhz, almost 500 Mhz)
> that's only a few ms. Perhaps it just takes longer.
The inl(...) instruction takes a bus cycle, which would be 33/66/100 MHZ,
so the loop is slowed down by that.
> Or the problem is something else and is completely unrelated to this.
Looking at the code again and comparing to the Linux driver, I have
another thought. Etherboot drivers don't use interrupts, and so where in
the kernel, you can do things like set "next_tick" and then run_at, we
have to do things other ways.
What it looks like to me (and boy would it be nice if I had a Cisco
hub/switch to test this with) is that there is a time delay (and recheck)
needed after media selection.
Here is the place I think we might be coming to (need to verify this with
a printf):
else {
/* Start with 10mbps to do autonegotiation. */
outl(0x32, ioaddr + CSR12);
tp->csr6 = 0x00420000;
outl(0x0001B078, ioaddr + 0xB8);
outl(0x0201B078, ioaddr + 0xB8);
next_tick = 1*HZ;
}
That "next_tick" statement is later followed (in the Linux driver) by:
/* Set the timer to switch to check for link beat and perhaps
switch
to an alternate media type. */
init_timer(&tp->timer);
tp->timer.expires = RUN_AT(next_tick);
tp->timer.data = (unsigned long)dev;
tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
add_timer(&tp->timer);
In Etherboot we don't have this interrupt functionality. But since we're
single-threaded serial processing, we could just wait, and run the
"pnic_timer" code inline for this card.
I think the reason it works for me and not for you at 100BASE-T is
because I'm using a Netgear 10/100 hub, and autonegotiation with the
Netgear FA310TX is very fast on my end. Some Cisco switches/hubs have
autonegotiation issues, especially with duplex. Certain Macintosh
internal ethernet interfaces for example can't reliably synch up with
them.
So, I think I have a good handle on what might be causing the problem,
and it fits well with past reports that I could not replicate. I bet if
I tried this with a Cisco 4000 hub I'd see the problem too.
The way to fix this I think is to first isolate the code path (stuff that
only happens with LC82C168) and then compare with the Linux and Etherboot
code paths. We've been cheating a little, by not inserting a N second
wait, followed by a recheck of the speed/duplex parameters, which the
linux driver does asynchronously.
I won't be able to work more on this problem for a few days, but if
you're willing to help debug, I'm sure we can figure it out. My first
thought is add a tulip_wait() call after the autonegotiation code,
followed by the code in pnic_timer() which will check and reset the
speed/duplex, which may have settled down by then. I suspect if we
looked closely we'd find that the card duplex was not matching the
switch/hub duplex so the card is happily transmitting at the wrong speed
or duplex, and the hub is not hearing any of it because it is listening
differently. The brute-force test for this is to insert a cheap 10
BASE-T hub in between you and the Cisco, and see if it magically works.
Anyway, thanks for your patience and help, and if you're willing to help
debug this, I'm sure we can figure it out. (and anybody else who wants
to help, just let me know.)
Marty
---
Try: http://rom-o-matic.net/ to make Etherboot images instantly.
Name: Marty Connor
US Mail: Entity Cyber, Inc.; P.O. Box 391827; Cambridge, MA 02139; USA
Voice: (617) 491-6935, Fax: (617) 491-7046
Email: md...@th...
Web: http://www.thinguin.org/
|
|
From: Marty C. <md...@th...> - 2001-05-30 17:26:05
|
There is a test version of an Etherboot driver for the National Semiconductor DP83815 NIC (a.k.a. Netgear FA311/FA312) on http://rom-o-matic.net/ To get the driver, use the development release "5.0.1-mc1". The addition of the DP83815 driver is the only change. I would like to thank the generous folks of Sicom Systems (http://www.sicompos.com) for funding the development of this driver. Someday when you go into your local fast food restaurant, you may be using a POS (point of sale) terminal that has been booted with Etherboot!! If you have such a card, please try this driver let us know how it works. Marty --- Try: http://rom-o-matic.net/ to make Etherboot images instantly. Name: Marty Connor US Mail: Entity Cyber, Inc.; P.O. Box 391827; Cambridge, MA 02139; USA Voice: (617) 491-6935, Fax: (617) 491-7046 Email: md...@th... Web: http://www.thinguin.org/ |
|
From: Marty C. <md...@th...> - 2001-05-30 17:26:01
|
On 5/29/01 9:26 PM Michael Stein ma...@uc... wrote:
>I just tested the barrier version of tulip.c (compiled with gcc 2.96)
>and it acts the same. Fails on 100 Mbit cisco-4000 port and works
>on 10 Mbit cisco-1700 port.
Yes, I kind of expected that. If you have the capability (and are
willing), there is another test that would shed some light.
I believe the speed is correctly negotiated, but what is broken is duplex.
If it were possible to tie the Cisco 4000 port to half-duplex, I suspect
it would work. If that's not easy to do, don't worry about it.
I think we need to add a routine called "tulip_check_duplex" and call it
after we've done the autonegotiation to set the duplex according to what
the negotiated link returned. If you want to take a crack at it, go
ahead -- the Linux 2.4.5 sources have a routine we can modify and test.
Otherwise I'll get to it in a few days.
Thanks for your patience and excellent debugging help.
Marty
---
Try: http://rom-o-matic.net/ to make Etherboot images instantly.
Name: Marty Connor
US Mail: Entity Cyber, Inc.; P.O. Box 391827; Cambridge, MA 02139; USA
Voice: (617) 491-6935, Fax: (617) 491-7046
Email: md...@th...
Web: http://www.thinguin.org/
|
|
From: <ebi...@ln...> - 2001-05-30 04:17:53
|
"dinesh Icenet acct" <dk...@ic...> writes: > Dear , > Is there a solution , where we can choose the DHCP fro where we boot , > if there are more than one DHCP servers in the network . There is a patch given > in the contrib directory , under the dhcpid/ but that patch does not apply to > etherboot-5.1 . Any pointers will be appreciated. Yes. The option REQUIRE_VCI_ETHERBOOT. The implementation is rather different than the dhcpid patch but it works fine. It is in the documentation as wel. Eric |
|
From: dinesh I. a. <dk...@ic...> - 2001-05-30 04:02:32
|
Dear ,=20
Is there a solution , where we can choose the DHCP fro where we =
boot , if there are more than one DHCP servers in the network . There is =
a patch given in the contrib directory , under the dhcpid/ but that =
patch does not apply to etherboot-5.1 . Any pointers will be =
appreciated.
thanks in advance=20
Dinesh
|
|
From: Michael S. <ma...@uc...> - 2001-05-30 01:26:49
|
# So the barrier caused ioaddr to be refetched each time around the # loop. This could effect the timing, but I doubt that ioaddr is # actually changing. # So I'm doubting that this will fix the problem. I'll try it anyway when # I get a chance (tuesday at best). I just tested the barrier version of tulip.c (compiled with gcc 2.96) and it acts the same. Fails on 100 Mbit cisco-4000 port and works on 10 Mbit cisco-1700 port. |
|
From: Charles D. <CD...@cc...> - 2001-05-29 15:13:41
|
I am not sure if this is the correct list for this question or not. Has anyone had success in remote booting LynxOS using Etherboot? Charles Dobson -- Firmware Development Engineer Email: cd...@cc... |
|
From: Michael S. <ma...@uc...> - 2001-05-28 04:25:12
|
On Sun, May 27, 2001 at 12:54:56PM -0400, Marty Connor wrote: > Looking at the code again and comparing to the Linux driver, I have > another thought. Etherboot drivers don't use interrupts, and so where in > the kernel, you can do things like set "next_tick" and then run_at, we > have to do things other ways. > > What it looks like to me (and boy would it be nice if I had a Cisco > hub/switch to test this with) is that there is a time delay (and recheck) > needed after media selection. That makes sense -- the linux tulip driver messages at boot look like: May 25 17:47:17 d01 kernel: eth0: Lite-On 82c168 PNIC rev 32 at 0xe400, 00:A0:CC:56:99:E9, IRQ 11. May 25 17:47:17 d01 kernel: eth0: MII transceiver #1 config 3000 status 7829 advertising 01e1. May 25 17:47:17 d01 network: Bringing up interface eth0: succeeded May 25 17:47:19 d01 kernel: eth0: Setting full-duplex based on MII#1 link partner capability of 41e1. Depending on how exactly the time stamps work possibly it's over a second to get to 100 Mbit/full-duplex with the linux driver and the Cisco-4000. > differently. The brute-force test for this is to insert a cheap 10 > BASE-T hub in between you and the Cisco, and see if it magically works. Etherboot does boot if the machine is connected to a cisco-1700 switch on the same subnet (10 Mbit). |
|
From: Marty C. <md...@en...> - 2001-05-27 16:57:55
|
[ we may be getting into Etherboot-Developers territory, but I think some
people might be interested in the subtle kinds of interactions that
happen when you get close to the hardware. figuring out "whose bug it
is" is not always easy, because often at this level, it a question of
semantics - that is that both sides are doing something that is legal,
but because of timing or protocol they are not able to communicate. The
tulip driver is an especially complicated because DEC wrote the spec and
people made clone cards that sort of followed the spec, but there was
room for variance and interpretation, and so there are times where things
don't work as we think they should. Anyway, onward we go. ]
On 5/27/01 2:51 AM Michael Stein ma...@uc... wrote:
>PS: Why is the number of loops 1000? The loop might only
> be a few clocks long and at 2 ns/clock (466 Mhz, almost 500 Mhz)
> that's only a few ms. Perhaps it just takes longer.
The inl(...) instruction takes a bus cycle, which would be 33/66/100 MHZ,
so the loop is slowed down by that.
> Or the problem is something else and is completely unrelated to this.
Looking at the code again and comparing to the Linux driver, I have
another thought. Etherboot drivers don't use interrupts, and so where in
the kernel, you can do things like set "next_tick" and then run_at, we
have to do things other ways.
What it looks like to me (and boy would it be nice if I had a Cisco
hub/switch to test this with) is that there is a time delay (and recheck)
needed after media selection.
Here is the place I think we might be coming to (need to verify this with
a printf):
else {
/* Start with 10mbps to do autonegotiation. */
outl(0x32, ioaddr + CSR12);
tp->csr6 = 0x00420000;
outl(0x0001B078, ioaddr + 0xB8);
outl(0x0201B078, ioaddr + 0xB8);
next_tick = 1*HZ;
}
That "next_tick" statement is later followed (in the Linux driver) by:
/* Set the timer to switch to check for link beat and perhaps
switch
to an alternate media type. */
init_timer(&tp->timer);
tp->timer.expires = RUN_AT(next_tick);
tp->timer.data = (unsigned long)dev;
tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
add_timer(&tp->timer);
In Etherboot we don't have this interrupt functionality. But since we're
single-threaded serial processing, we could just wait, and run the
"pnic_timer" code inline for this card.
I think the reason it works for me and not for you at 100BASE-T is
because I'm using a Netgear 10/100 hub, and autonegotiation with the
Netgear FA310TX is very fast on my end. Some Cisco switches/hubs have
autonegotiation issues, especially with duplex. Certain Macintosh
internal ethernet interfaces for example can't reliably synch up with
them.
So, I think I have a good handle on what might be causing the problem,
and it fits well with past reports that I could not replicate. I bet if
I tried this with a Cisco 4000 hub I'd see the problem too.
The way to fix this I think is to first isolate the code path (stuff that
only happens with LC82C168) and then compare with the Linux and Etherboot
code paths. We've been cheating a little, by not inserting a N second
wait, followed by a recheck of the speed/duplex parameters, which the
linux driver does asynchronously.
I won't be able to work more on this problem for a few days, but if
you're willing to help debug, I'm sure we can figure it out. My first
thought is add a tulip_wait() call after the autonegotiation code,
followed by the code in pnic_timer() which will check and reset the
speed/duplex, which may have settled down by then. I suspect if we
looked closely we'd find that the card duplex was not matching the
switch/hub duplex so the card is happily transmitting at the wrong speed
or duplex, and the hub is not hearing any of it because it is listening
differently. The brute-force test for this is to insert a cheap 10
BASE-T hub in between you and the Cisco, and see if it magically works.
Anyway, thanks for your patience and help, and if you're willing to help
debug this, I'm sure we can figure it out. (and anybody else who wants
to help, just let me know.)
Marty
---
Martin D. Connor, CEO & President, Entity Cyber, Inc.
US Mail: P.O. Box 391827, Cambridge, MA 02139 USA
Voice: (617) 491-6935, Fax: (617) 491-7046, Net: md...@en...
Web: http://www.entity.com/
|
|
From: Michael S. <ma...@uc...> - 2001-05-27 06:51:11
|
> /* Optimization barrier */
> /* The "volatile" is due to gcc bugs */
> #define barrier() __asm__ __volatile__("": : :"memory")
Here's a description of the meaning/usage of barrier:
http://www.tux.org/hypermail/linux-gcc/1998-Jun/0068.html
I compiled etherboot's tulip.c with and without your changes and
looked at the assembly output of the relevant part of mdio_read:
They're both basicly the same -- here's the changed c source:
if (tp->chip_id == LC82C168) {
int i = 1000;
outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
inl(ioaddr + 0xA0);
inl(ioaddr + 0xA0);
while (--i > 0) {
barrier();
if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
return retval & 0xffff;
}
return 0xffff;
}
Here's the asm code of the while loop:
.L111:
.stabn 68,0,588,.LM24-mdio_read
.LM24:
#APP
.stabn 68,0,589,.LM25-mdio_read
.LM25:
#NO_APP
movw ioaddr, %dx
addl $160, %edx
.stabs "../etherboot-5.0.1/src/linux-asm-io.h",132,0,0,.Ltext7
.Ltext7:
.stabn 68,0,108,.LM26-mdio_read
.LM26:
#APP
inl %dx,%eax
#NO_APP
movl %eax, %edi
.stabs "tulip.c",132,0,0,.Ltext8
.Ltext8:
.stabn 68,0,589,.LM27-mdio_read
.LM27:
testl %edi, %edi
jns .L198
.stabn 68,0,591,.LM28-mdio_read
.LM28:
decl %ecx
testl %ecx, %ecx
jg .L111
Here's the asm for the while loop for the original code:
.L111:
.stabs "../etherboot-5.0.1/src/linux-asm-io.h",132,0,0,.Ltext7
.Ltext7:
.stabn 68,0,108,.LM24-mdio_read
.LM24:
#APP
inl %dx,%eax
#NO_APP
movl %eax, %edi
.stabs "tulip-orig.c",132,0,0,.Ltext8
.Ltext8:
.stabn 68,0,584,.LM25-mdio_read
.LM25:
testl %edi, %edi
jns .L198
decl %ecx
testl %ecx, %ecx
jg .L111
So the barrier caused ioaddr to be refetched each time around the
loop. This could effect the timing, but I doubt that ioaddr is
actually changing.
So I'm doubting that this will fix the problem. I'll try it anyway when
I get a chance (tuesday at best).
This was with gcc:
[mas@s02 test]$ gcc --version
2.96
Then I wondered what kgcc would do:
[mas@s02 test]$ kgcc --version
egcs-2.91.66
-- with kgcc & barrier:
.L113:
.stabn 68,0,588,.LM16-mdio_read
.LM16:
.LBB15:
.LBB16:
.LBE16:
.LBE15:
.LBB17:
.LBB18:
.LBE18:
.LBE17:
#APP
#NO_APP
.stabn 68,0,589,.LM17-mdio_read
.LM17:
movw ioaddr,%dx
addl $160,%edx
.stabs "../etherboot-5.0.1/src/linux-asm-io.h",132,0,0,.Ltext5
.Ltext5:
.stabn 68,0,108,.LM18-mdio_read
.LM18:
#APP
inl %dx,%eax
#NO_APP
movl %eax,%ebx
.stabs "tulip.c",132,0,0,.Ltext6
.Ltext6:
.stabn 68,0,589,.LM19-mdio_read
.LM19:
testl %ebx,%ebx
jge .L213
.stabn 68,0,591,.LM20-mdio_read
.LM20:
decl %ecx
testl %ecx,%ecx
jg .L113
-- with kgcc and original code:
.L113:
.stabs "../etherboot-5.0.1/src/linux-asm-io.h",132,0,0,.Ltext5
.Ltext5:
.stabn 68,0,108,.LM16-mdio_read
.LM16:
.LBB15:
.LBB16:
.LBE16:
.LBE15:
.LBB17:
.LBB18:
.LBE18:
.LBE17:
movl %esi,%edx
#APP
inl %dx,%eax
#NO_APP
movl %eax,%ebx
.stabs "tulip-orig.c",132,0,0,.Ltext6
.Ltext6:
.stabn 68,0,584,.LM17-mdio_read
.LM17:
testl %ebx,%ebx
jge .L213
decl %ecx
testl %ecx,%ecx
jg .L113
So it doesn't look like kgcc is different either..
PS: Why is the number of loops 1000? The loop might only
be a few clocks long and at 2 ns/clock (466 Mhz, almost 500 Mhz)
that's only a few ms. Perhaps it just takes longer. Or
the problem is something else and is completely unrelated to this.
|