[Etherboot-developers] Lance/HomePNA patches + problems.
Brought to you by:
marty_connor,
stefanhajnoczi
|
From: Mark V. <ma...@pi...> - 2000-12-20 22:08:29
|
I started working on hacking support for HomePNA ethernet cards into
netboot, and uncovered a couple of problems.
For those of you who don't know what they are, the HomePNA ethernet
cards are 1Mbit network cards which use existing phoneline wiring to
communicate. I use them in my house to keep from stringing additional
ethernet cables throughout the four rooms that have computers in my
house, and use them to share cable modem access to everyone.
The project I have in mind is to take a set-top box like the one that
SuperTek makes, and netboot it to run a small version of FreeBSD, and
then use it to stream mp3s or the like from my main network server.
In any case, these cards are based upon the AMD 79C978 chipset, which
is a variant of their PC-net chipset, which is compatible with the old
lance drivers.
Well, for the most part.
The following patch is a start. The primary modifications in the patch
below are to get the card recognized and probed properly, which it
seems to do. The HomePNA cards also require a tiny bit of code to set
the media properly to use the phoneline transciever (some of them also
have regular 10Mbit ethernet transcievers).
While digging this, I also uncovered a bug in the reset code, where
chip_table[chip_version] is examined. This should really be
chip_table[lance_version]. This patch fixes a couple of those problems.
Unfortunately, I still seem to be having trouble after enabling these
changes. The system properly requests and receives DHCP messages, and
uses TFTP to download a MOTD. I then tried to download a DRDOS
(version 7.02) netboot image I made with mknbi-dos, which hangs while
trying to load from the network. When I recompiled the lancpci.fd0
module with debugging on, I notice that just before timing out, it
receives a packet which has CSR0 set to 4B3, which indicates
bit 15 ERR
bit 11 MERR memory error
bit 9 TINT transmit interrupt
bit 8 IDON initialization done
bit 1 START
bit 0 INIT
The normal value is apparently 33, which indicates Receive Interrupt,
Transmit Interrupt, and START and INIT.
I'm wondering if there is some problem with the error handling in
lance_poll(). I've downloaded some of AMDs specs for the chipset, and
it seems roughly allright, but I'm no device driver expert (haven't
written any in 15 years) and certainly no expert on the lance.
Anybody with any suggestions? I'll keep hacking away on it, but I
thought I'd let these patches out in hopes that someone else might
be able to help.
Thanks!
diff -c /home/markv/etherboot-4.7.14/src/config.c ./config.c
*** /home/markv/etherboot-4.7.14/src/config.c Thu Dec 14 04:10:36 2000
--- ./config.c Mon Dec 18 22:11:34 2000
***************
*** 85,90 ****
--- 85,92 ----
#ifdef INCLUDE_LANCE
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
"AMD Lance/PCI", 0, 0, 0, 0},
+ { PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA,
+ "AMD Lance/HomePNA", 0, 0, 0, 0},
#endif
#ifdef INCLUDE_RTL8139
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
diff -c /home/markv/etherboot-4.7.14/src/lance.c ./lance.c
*** /home/markv/etherboot-4.7.14/src/lance.c Thu Dec 14 04:27:30 2000
--- ./lance.c Mon Dec 18 22:05:14 2000
***************
*** 89,94 ****
--- 89,95 ----
#define LANCE_MUST_PAD 0x00000001
#define LANCE_ENABLE_AUTOSELECT 0x00000002
+ #define LANCE_SELECT_PHONELINE 0x00000004
#define LANCE_MUST_UNRESET 0x00000008
/* A mapping from the chip ID number to the part number and features.
***************
*** 114,119 ****
--- 115,122 ----
LANCE_ENABLE_AUTOSELECT},
{0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
LANCE_ENABLE_AUTOSELECT},
+ {0x2626, "PCnet/HomePNA 79C978",
+ LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
{0x0, "PCnet (unknown)",
LANCE_ENABLE_AUTOSELECT},
};
***************
*** 123,128 ****
--- 126,132 ----
#define virt_to_bus(x) ((unsigned long)x)
static int chip_version;
+ static int lance_version;
static unsigned short ioaddr;
#ifndef INCLUDE_LANCE
static int dma;
***************
*** 205,213 ****
/* Reset the LANCE */
(void)inw(ioaddr+LANCE_RESET);
/* Un-Reset the LANCE, needed only for the NE2100 */
! if (chip_table[chip_version].flags & LANCE_MUST_UNRESET)
outw(0, ioaddr+LANCE_RESET);
! if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT)
{
/* This is 79C960 specific; Turn on auto-select of media
(AUI, BNC). */
--- 209,217 ----
/* Reset the LANCE */
(void)inw(ioaddr+LANCE_RESET);
/* Un-Reset the LANCE, needed only for the NE2100 */
! if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
outw(0, ioaddr+LANCE_RESET);
! if (chip_table[lance_version].flags & LANCE_ENABLE_AUTOSELECT)
{
/* This is 79C960 specific; Turn on auto-select of media
(AUI, BNC). */
***************
*** 215,220 ****
--- 219,253 ----
/* Don't touch 10base2 power bit. */
outw(inw(ioaddr+LANCE_BUS_IF) | 0x2, ioaddr+LANCE_BUS_IF);
}
+ /* HomePNA cards need to explicitly pick the phoneline interface.
+ * Some of these cards have ethernet interfaces as well, this
+ * code might require some modification for those.
+ */
+ if (chip_table[lance_version].flags & LANCE_SELECT_PHONELINE) {
+ short media, check ;
+ /* this is specific to HomePNA cards... */
+ outw(49, ioaddr+0x12) ;
+ media = inw(ioaddr+0x16) ;
+ #ifdef DEBUG
+ printf("media was %d\n", media) ;
+ #endif
+ media &= ~3 ;
+ media |= 1 ;
+ #ifdef DEBUG
+ printf("media changed to %d\n", media) ;
+ #endif
+ media &= ~3 ;
+ media |= 1 ;
+ outw(49, ioaddr+0x12) ;
+ outw(media, ioaddr+0x16) ;
+ outw(49, ioaddr+0x12) ;
+ check = inw(ioaddr+0x16) ;
+ #ifdef DEBUG
+ printf("check %s, media was set properly\n",
+ check == media ? "passed" : "FAILED" ) ;
+ #endif
+ }
+
/* Re-initialise the LANCE, and start it when done. */
/* Set station address */
for (i = 0; i < ETH_ALEN; ++i)
***************
*** 352,358 ****
static int lance_probe1(struct nic *nic)
#endif
{
! int reset_val, lance_version;
unsigned int i;
Address l;
short dma_channels;
--- 385,391 ----
static int lance_probe1(struct nic *nic)
#endif
{
! int reset_val ;
unsigned int i;
Address l;
short dma_channels;
diff -c /home/markv/etherboot-4.7.14/src/pci.h ./pci.h
*** /home/markv/etherboot-4.7.14/src/pci.h Tue Dec 12 23:05:18 2000
--- ./pci.h Mon Dec 18 22:10:51 2000
***************
*** 128,133 ****
--- 128,135 ----
#define PCI_DEVICE_ID_INTEL_82562 0x2449
#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
+ #define PCI_VENDOR_ID_AMD_HOMEPNA 0x1022
+ #define PCI_DEVICE_ID_AMD_HOMEPNA 0x2001
#define PCI_VENDOR_ID_SMC_1211 0x1113
#define PCI_DEVICE_ID_SMC_1211 0x1211
#define PCI_VENDOR_ID_DEC 0x1011
--
/* __ __ __ ___ __ */ float m,a,r,k,v;main(_){for(;r<4;r+=.1){for(a=0;
/*| \/ | \ \ / \ \ / / */ a<4;a+=.06){k=v=0;for(_=99;--_&&k*k+v*v<4;)m=k*k
/*| |\/| | \ V / \ \/\/ / */ -v*v+a-2,v=2*k*v+r-2,k=m;putchar("X =."[_&3]);}
/*|_| |_ark \_ande\_/\_ettering <ma...@te...> */ puts("");}}
|