diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Config.in | 398 | ||||
-rw-r--r-- | drivers/net/Makefile | 229 | ||||
-rw-r--r-- | drivers/net/Space.c | 45 | ||||
-rw-r--r-- | drivers/net/arcnet.c | 2 | ||||
-rw-r--r-- | drivers/net/ncr885_debug.h | 54 | ||||
-rw-r--r-- | drivers/net/ncr885e.c | 1458 | ||||
-rw-r--r-- | drivers/net/ncr885e.h | 367 | ||||
-rw-r--r-- | drivers/net/pcmcia/ray_cs.c | 372 | ||||
-rw-r--r-- | drivers/net/pcmcia/ray_cs.h | 9 | ||||
-rw-r--r-- | drivers/net/pcmcia/rayctl.h | 19 | ||||
-rw-r--r-- | drivers/net/sgiseeq.c | 30 | ||||
-rw-r--r-- | drivers/net/sgiseeq.h | 24 | ||||
-rw-r--r-- | drivers/net/sk_mca.c | 1 | ||||
-rw-r--r-- | drivers/net/tokenring/.cvsignore | 2 | ||||
-rw-r--r-- | drivers/net/tokenring/Config.in | 15 | ||||
-rw-r--r-- | drivers/net/tokenring/Makefile | 51 | ||||
-rw-r--r-- | drivers/net/tokenring/ibmtr.c (renamed from drivers/net/ibmtr.c) | 48 | ||||
-rw-r--r-- | drivers/net/tokenring/ibmtr.h (renamed from drivers/net/ibmtr.h) | 2 | ||||
-rw-r--r-- | drivers/net/tokenring/olympic.c (renamed from drivers/net/olympic.c) | 0 | ||||
-rw-r--r-- | drivers/net/tokenring/olympic.h (renamed from drivers/net/olympic.h) | 0 | ||||
-rw-r--r-- | drivers/net/tokenring/sktr.c (renamed from drivers/net/sktr.c) | 168 | ||||
-rw-r--r-- | drivers/net/tokenring/sktr.h (renamed from drivers/net/sktr.h) | 7 | ||||
-rw-r--r-- | drivers/net/tokenring/sktr_firmware.h (renamed from drivers/net/sktr_firmware.h) | 0 | ||||
-rw-r--r-- | drivers/net/wan/.cvsignore | 2 | ||||
-rw-r--r-- | drivers/net/wan/Config.in | 64 | ||||
-rw-r--r-- | drivers/net/wan/Makefile | 181 | ||||
-rw-r--r-- | drivers/net/wan/cosa.c (renamed from drivers/net/cosa.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/cosa.h (renamed from drivers/net/cosa.h) | 0 | ||||
-rw-r--r-- | drivers/net/wan/cycx_drv.c (renamed from drivers/net/cycx_drv.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/cycx_main.c (renamed from drivers/net/cycx_main.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/cycx_x25.c (renamed from drivers/net/cycx_x25.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/dlci.c (renamed from drivers/net/dlci.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/hostess_sv11.c (renamed from drivers/net/hostess_sv11.c) | 2 | ||||
-rw-r--r-- | drivers/net/wan/lapbether.c (renamed from drivers/net/lapbether.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/sbni.c | 1533 | ||||
-rw-r--r-- | drivers/net/wan/sbni.h | 194 | ||||
-rw-r--r-- | drivers/net/wan/sdla.c (renamed from drivers/net/sdla.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/sdla_fr.c (renamed from drivers/net/sdla_fr.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/sdla_ppp.c (renamed from drivers/net/sdla_ppp.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/sdla_x25.c (renamed from drivers/net/sdla_x25.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/sdladrv.c (renamed from drivers/net/sdladrv.c) | 1 | ||||
-rw-r--r-- | drivers/net/wan/sdlamain.c (renamed from drivers/net/sdlamain.c) | 1 | ||||
-rw-r--r-- | drivers/net/wan/sealevel.c (renamed from drivers/net/sealevel.c) | 2 | ||||
-rw-r--r-- | drivers/net/wan/syncppp.c (renamed from drivers/net/syncppp.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/syncppp.h (renamed from drivers/net/syncppp.h) | 0 | ||||
-rw-r--r-- | drivers/net/wan/x25_asy.c (renamed from drivers/net/x25_asy.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/x25_asy.h (renamed from drivers/net/x25_asy.h) | 0 | ||||
-rw-r--r-- | drivers/net/wan/z85230.c (renamed from drivers/net/z85230.c) | 0 | ||||
-rw-r--r-- | drivers/net/wan/z85230.h (renamed from drivers/net/z85230.h) | 0 |
49 files changed, 4565 insertions, 716 deletions
diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 1902e5070..b091fc5f0 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -7,12 +7,12 @@ comment 'ARCnet devices' tristate 'ARCnet support' CONFIG_ARCNET if [ "$CONFIG_ARCNET" != "n" ]; then - bool ' Enable arc0e (ARCnet "Ether-Encap" packet format)' CONFIG_ARCNET_ETH - bool ' Enable arc0s (ARCnet RFC1051 packet format)' CONFIG_ARCNET_1051 - dep_tristate ' ARCnet COM90xx (normal) chipset driver' CONFIG_ARCNET_COM90xx $CONFIG_ARCNET - dep_tristate ' ARCnet COM90xx (IO mapped) chipset driver' CONFIG_ARCNET_COM90xxIO $CONFIG_ARCNET - dep_tristate ' ARCnet COM90xx (RIM I) chipset driver' CONFIG_ARCNET_RIM_I $CONFIG_ARCNET - dep_tristate ' ARCnet COM20020 chipset driver' CONFIG_ARCNET_COM20020 $CONFIG_ARCNET + bool ' Enable arc0e (ARCnet "Ether-Encap" packet format)' CONFIG_ARCNET_ETH + bool ' Enable arc0s (ARCnet RFC1051 packet format)' CONFIG_ARCNET_1051 + dep_tristate ' ARCnet COM90xx (normal) chipset driver' CONFIG_ARCNET_COM90xx $CONFIG_ARCNET + dep_tristate ' ARCnet COM90xx (IO mapped) chipset driver' CONFIG_ARCNET_COM90xxIO $CONFIG_ARCNET + dep_tristate ' ARCnet COM90xx (RIM I) chipset driver' CONFIG_ARCNET_RIM_I $CONFIG_ARCNET + dep_tristate ' ARCnet COM20020 chipset driver' CONFIG_ARCNET_COM20020 $CONFIG_ARCNET fi endmenu @@ -20,9 +20,9 @@ endmenu tristate 'Dummy net driver support' CONFIG_DUMMY tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_NETLINK" = "y" ]; then - tristate 'Ethertap network tap' CONFIG_ETHERTAP - fi + if [ "$CONFIG_NETLINK" = "y" ]; then + tristate 'Ethertap network tap (EXPERIMENTAL)' CONFIG_ETHERTAP + fi fi tristate 'General Instruments Surfboard 1000' CONFIG_NET_SB1000 @@ -36,145 +36,154 @@ comment 'Ethernet (10 or 100Mbit)' bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET if [ "$CONFIG_NET_ETHERNET" = "y" ]; then - if [ "$CONFIG_ARM" = "y" ]; then - if [ "$CONFIG_ARCH_ACORN" != "y" ]; then - tristate 'AM79C961A support' CONFIG_ARM_AM79C961A - else - source drivers/acorn/net/Config.in - fi - fi - if [ "$CONFIG_PPC" = "y" ]; then - tristate 'MACE (Power Mac ethernet) support' CONFIG_MACE - tristate 'BMAC (G3 ethernet) support' CONFIG_BMAC - fi - if [ "$CONFIG_ZORRO" = "y" ]; then - tristate 'Ariadne support' CONFIG_ARIADNE - tristate 'Ariadne II support' CONFIG_ARIADNE2 - tristate 'A2065 support' CONFIG_A2065 - tristate 'Hydra support' CONFIG_HYDRA - fi - if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then - tristate 'MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC - fi - bool '3COM cards' CONFIG_NET_VENDOR_3COM - if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then - tristate '3c501 support' CONFIG_EL1 - tristate '3c503 support' CONFIG_EL2 - tristate '3c505 support' CONFIG_ELPLUS - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate '3c507 support' CONFIG_EL16 + if [ "$CONFIG_ARM" = "y" ]; then + if [ "$CONFIG_ARCH_ACORN" != "y" ]; then + tristate ' AM79C961A support' CONFIG_ARM_AM79C961A + else + source drivers/acorn/net/Config.in + fi + fi + if [ "$CONFIG_PPC" = "y" ]; then + tristate ' MACE (Power Mac ethernet) support' CONFIG_MACE + tristate ' BMAC (G3 ethernet) support' CONFIG_BMAC + fi + if [ "$CONFIG_ZORRO" = "y" ]; then + tristate ' Ariadne support' CONFIG_ARIADNE + tristate ' Ariadne II support' CONFIG_ARIADNE2 + tristate ' A2065 support' CONFIG_A2065 + tristate ' Hydra support' CONFIG_HYDRA + fi + if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then + tristate ' MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC + fi + bool ' 3COM cards' CONFIG_NET_VENDOR_3COM + if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then + tristate ' 3c501 support' CONFIG_EL1 + tristate ' 3c503 support' CONFIG_EL2 + tristate ' 3c505 support' CONFIG_ELPLUS + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' 3c507 support (EXPERIMENTAL)' CONFIG_EL16 + fi + tristate ' 3c509/3c529 (MCA)/3c579 support' CONFIG_EL3 + tristate ' 3c515 ISA Fast EtherLink' CONFIG_3C515 if [ "$CONFIG_MCA" = "y" ]; then - tristate '3c523 support' CONFIG_ELMC - tristate '3c527 support' CONFIG_ELMC_II + tristate ' 3c523 support' CONFIG_ELMC + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' 3c527 support (EXPERIMENTAL)' CONFIG_ELMC_II + fi fi - fi - tristate '3c509/3c579 support' CONFIG_EL3 - tristate '3c515 ISA Fast EtherLink' CONFIG_3C515 - tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX - fi - tristate 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE - bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC - if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then - tristate 'WD80*3 support' CONFIG_WD80x3 - if [ "$CONFIG_MCA" = "y" ]; then - tristate 'SMC Ultra MCA support' CONFIG_ULTRAMCA - fi - tristate 'SMC Ultra support' CONFIG_ULTRA - tristate 'SMC Ultra32 EISA support' CONFIG_ULTRA32 - tristate 'SMC 9194 support' CONFIG_SMC9194 + tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX + fi + tristate ' AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE + bool ' Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC + if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then + tristate ' WD80*3 support' CONFIG_WD80x3 + if [ "$CONFIG_MCA" = "y" ]; then + tristate ' SMC Ultra MCA support' CONFIG_ULTRAMCA + fi + tristate ' SMC Ultra support' CONFIG_ULTRA + tristate ' SMC Ultra32 EISA support' CONFIG_ULTRA32 + tristate ' SMC 9194 support' CONFIG_SMC9194 fi - bool 'Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL + bool ' Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL if [ "$CONFIG_NET_VENDOR_RACAL" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'NI5010 support' CONFIG_NI5010 + tristate ' NI5010 support (EXPERIMENTAL)' CONFIG_NI5010 fi - tristate 'NI5210 support' CONFIG_NI52 - tristate 'NI6510 support' CONFIG_NI65 + tristate ' NI5210 support' CONFIG_NI52 + tristate ' NI6510 support' CONFIG_NI65 fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139 - tristate 'SiS 900 PCI Fast Ethernet Adapter support' CONFIG_SIS900 - tristate 'Packet Engines Yellowfin Gigabit-NIC support' CONFIG_YELLOWFIN - tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC + # tristate ' Packet Engines Hamachi GNIC-II support (EXPERIMENTAL)' CONFIG_HAMACHI + tristate ' Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN + tristate ' RealTek 8129/8139 (not 8019/8029!) support (EXPERIMENTAL)' CONFIG_RTL8139 + tristate ' SiS 900 PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_SIS900 + tristate ' DM9102 PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_DM9102 + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700 + fi + tristate ' DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA + bool ' Other ISA cards' CONFIG_NET_ISA + if [ "$CONFIG_NET_ISA" = "y" ]; then + tristate ' Cabletron E21xx support' CONFIG_E2100 + tristate ' EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3 + tristate ' EtherExpress 16 support' CONFIG_EEXPRESS + tristate ' EtherExpressPro support' CONFIG_EEXPRESS_PRO + tristate ' FMV-181/182/183/184 support' CONFIG_FMV18X + tristate ' HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS + tristate ' HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN + tristate ' HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' ICL EtherTeam 16i/32 support (EXPERIMENTAL)' CONFIG_ETH16I + fi + tristate ' NE2000/NE1000 support' CONFIG_NE2000 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005 + fi + bool ' SK_G16 support' CONFIG_SK_G16 + fi + if [ "$CONFIG_MCA" = "y" ]; then + tristate ' SKnet MCA support' CONFIG_SKMC + tristate ' NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA + fi + bool ' EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA + if [ "$CONFIG_NET_EISA" = "y" ]; then + tristate ' AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32 +# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +# tristate ' Adaptec Starfire support (EXPERIMENTAL)' CONFIG_ADAPTEC_STARFIRE +# fi + tristate ' Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC if [ "$CONFIG_ACENIC" != "n" ]; then - bool 'Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I + bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 fi - fi - bool 'Other ISA cards' CONFIG_NET_ISA - if [ "$CONFIG_NET_ISA" = "y" ]; then - tristate 'AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700 - tristate 'Cabletron E21xx support' CONFIG_E2100 - tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA - tristate 'EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3 - tristate 'EtherExpress 16 support' CONFIG_EEXPRESS - tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO - tristate 'FMV-181/182/183/184 support' CONFIG_FMV18X - tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS - tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN - tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'ICL EtherTeam 16i/32 support' CONFIG_ETH16I - fi - tristate 'NE2000/NE1000 support' CONFIG_NE2000 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005 - fi - bool 'SK_G16 support' CONFIG_SK_G16 - fi - if [ "$CONFIG_MCA" = "y" ]; then - tristate 'NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA - tristate 'SKnet MCA support' CONFIG_SKMC - fi - bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA - if [ "$CONFIG_NET_EISA" = "y" ]; then - tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 - fi - tristate 'Apricot Xen-II on board Ethernet' CONFIG_APRICOT - tristate 'CS89x0 support' CONFIG_CS89x0 - tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 - tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP - tristate 'Digi Intl. RightSwitch SE-X support' CONFIG_DGRS - tristate 'EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 - tristate 'Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 - fi - tristate 'PCI NE2000 support' CONFIG_NE2K_PCI - tristate 'TI ThunderLAN support' CONFIG_TLAN - tristate 'VIA Rhine support' CONFIG_VIA_RHINE - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 - tristate 'SMC EtherPower II (EXPERIMENTAL)' CONFIG_EPIC100 - bool 'Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET - fi - tristate 'Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE - fi - bool 'Pocket and portable adaptors' CONFIG_NET_POCKET - if [ "$CONFIG_NET_POCKET" = "y" ]; then - bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP - tristate 'D-Link DE600 pocket adaptor support' CONFIG_DE600 - tristate 'D-Link DE620 pocket adaptor support' CONFIG_DE620 - fi + tristate ' Apricot Xen-II on board Ethernet' CONFIG_APRICOT + tristate ' CS89x0 support' CONFIG_CS89x0 + tristate ' Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 + tristate ' DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP + tristate ' Digi Intl. RightSwitch SE-X support' CONFIG_DGRS + tristate ' EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 + tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 + fi + tristate ' PCI NE2000 support' CONFIG_NE2K_PCI + # tristate ' Sundance Alta support' CONFIG_ALTA + tristate ' TI ThunderLAN support' CONFIG_TLAN + tristate ' VIA Rhine support' CONFIG_VIA_RHINE + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 + tristate ' SMC EtherPower II (EXPERIMENTAL)' CONFIG_EPIC100 + bool ' Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET + fi + fi + bool ' Pocket and portable adapters' CONFIG_NET_POCKET + if [ "$CONFIG_NET_POCKET" = "y" ]; then + bool ' AT-LAN-TEC/RealTek pocket adapter support' CONFIG_ATP + tristate ' D-Link DE600 pocket adapter support' CONFIG_DE600 + tristate ' D-Link DE620 pocket adapter support' CONFIG_DE620 + fi fi endmenu bool 'FDDI driver support' CONFIG_FDDI if [ "$CONFIG_FDDI" = "y" ]; then - bool 'Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX + bool ' Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI - if [ "$CONFIG_HIPPI" = "y" ]; then - tristate 'Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER - if [ "$CONFIG_ROADRUNNER" != "n" ]; then - bool ' Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS - fi - fi + bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI + if [ "$CONFIG_HIPPI" = "y" ]; then + tristate ' Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER + if [ "$CONFIG_ROADRUNNER" != "n" ]; then + bool ' Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS + fi + fi fi # @@ -182,133 +191,66 @@ fi # if [ "$CONFIG_ATALK" != "n" ]; then - mainmenu_option next_comment - comment 'Appletalk devices' - dep_tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_ATALK - dep_tristate 'COPS LocalTalk PC support' CONFIG_COPS $CONFIG_ATALK - if [ "$CONFIG_COPS" != "n" ]; then - bool 'Dayna firmware support' CONFIG_COPS_DAYNA - bool 'Tangent firmware support' CONFIG_COPS_TANGENT - fi - dep_tristate 'Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_ATALK - if [ "$CONFIG_IPDDP" != "n" ]; then - bool 'IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP - bool 'Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP - fi - endmenu + mainmenu_option next_comment + comment 'Appletalk devices' + dep_tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_ATALK + dep_tristate 'COPS LocalTalk PC support' CONFIG_COPS $CONFIG_ATALK + if [ "$CONFIG_COPS" != "n" ]; then + bool ' Dayna firmware support' CONFIG_COPS_DAYNA + bool ' Tangent firmware support' CONFIG_COPS_TANGENT + fi + dep_tristate 'Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_ATALK + if [ "$CONFIG_IPDDP" != "n" ]; then + bool ' IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP + bool ' Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP + fi + endmenu fi if [ ! "$CONFIG_PARPORT" = "n" ]; then - dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT + dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT fi tristate 'PPP (point-to-point protocol) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then - dep_tristate 'PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP - dep_tristate 'PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP - dep_tristate 'PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m + dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m fi tristate 'SLIP (serial line) support' CONFIG_SLIP if [ "$CONFIG_SLIP" != "n" ]; then - bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED - bool ' Keepalive and linefill' CONFIG_SLIP_SMART - bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 + bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED + bool ' Keepalive and linefill' CONFIG_SLIP_SMART + bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 fi +mainmenu_option next_comment +comment 'Wireless LAN (non-hamradio)' + bool 'Wireless LAN (non-hamradio)' CONFIG_NET_RADIO if [ "$CONFIG_NET_RADIO" = "y" ]; then - dep_tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET - tristate 'AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN - tristate 'Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN - -fi - -mainmenu_option next_comment -comment 'Token ring devices' + dep_tristate ' STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET + tristate ' AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN + tristate ' Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN -bool 'Token Ring driver support' CONFIG_TR -if [ "$CONFIG_TR" = "y" ]; then - tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR -# tristate 'IBM Lanstreamer PCI adaptor support' CONFIG_IBMLS - tristate 'IBM Olympic chipset PCI adapter support' CONFIG_IBMOL - tristate 'SysKonnect adapter support' CONFIG_SKTR fi endmenu +source drivers/net/tokenring/Config.in + bool 'Fibre Channel driver support' CONFIG_NET_FC if [ "$CONFIG_NET_FC" = "y" ]; then - tristate 'Interphase 5526 Tachyon chipset based adaptor support' CONFIG_IPHASE5526 + dep_tristate ' Interphase 5526 Tachyon chipset based adapter support' CONFIG_IPHASE5526 $CONFIG_SCSI fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI - tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER -fi - -# -# WAN drivers support -# - -mainmenu_option next_comment -comment 'Wan interfaces' - - -# There is no way to detect a comtrol sv11 - force it modular for now. -# -dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m -# -# The COSA/SRP driver has not been tested as non-modular yet. -# -dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m -# -# There is no way to detect a Sealevel board. Force it modular -# -dep_tristate 'Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m - -tristate 'Frame relay DLCI support' CONFIG_DLCI -if [ "$CONFIG_DLCI" != "n" ]; then - int ' Max open DLCI' CONFIG_DLCI_COUNT 24 - int ' Max DLCI per device' CONFIG_DLCI_MAX 8 - dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI + tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI + tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER fi -# -# Wan router core. -# - -if [ "$CONFIG_WAN_ROUTER" != "n" ]; then - bool 'WAN drivers' CONFIG_WAN_DRIVERS - if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then - dep_tristate 'Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA $CONFIG_WAN_DRIVERS - if [ "$CONFIG_VENDOR_SANGOMA" != "n" ]; then - int ' Maximum number of cards' CONFIG_WANPIPE_CARDS 1 - bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25 - bool ' WANPIPE Frame Relay support' CONFIG_WANPIPE_FR - bool ' WANPIPE PPP support' CONFIG_WANPIPE_PPP - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'Cyclom 2X(tm) multiprotocol cards (EXPERIMENTAL)' CONFIG_CYCLADES_SYNC $CONFIG_WAN_DRIVERS - if [ "$CONFIG_CYCLADES_SYNC" != "n" ]; then - bool ' Cyclom 2X X.25 support (EXPERIMENTAL)' CONFIG_CYCLOMX_X25 - fi - fi - fi -fi - -endmenu - - -# -# X.25 network drivers -# -if [ "$CONFIG_X25" != "n" ]; then -if [ "$CONFIG_LAPB" != "n" ]; then - dep_tristate 'LAPB over Ethernet driver' CONFIG_LAPBETHER $CONFIG_LAPB - dep_tristate 'X.25 async driver' CONFIG_X25_ASY $CONFIG_LAPB -fi -fi +source drivers/net/wan/Config.in if [ "$CONFIG_PCMCIA" != "n" ]; then source drivers/net/pcmcia/Config.in diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e1abc4c0e..4589d0ee3 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -5,7 +5,7 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) hamradio irda fc pcmcia +ALL_SUB_DIRS := $(SUB_DIRS) fc hamradio irda pcmcia tokenring wan L_TARGET := net.a L_OBJS := auto_irq.o @@ -24,10 +24,6 @@ CONFIG_7990_BUILTIN := CONFIG_7990_MODULE := CONFIG_82596_BUILTIN := CONFIG_82596_MODULE := -CONFIG_85230_BUILTIN := -CONFIG_85230_MODULE := -CONFIG_SYNCPPP_BUILTIN := -CONFIG_SYNCPPP_MODULE := ifeq ($(CONFIG_PCMCIA),y) SUB_DIRS += pcmcia @@ -60,38 +56,6 @@ ifeq ($(CONFIG_SEEQ8005),y) L_OBJS += seeq8005.o endif -ifeq ($(CONFIG_IBMTR),y) -L_OBJS += ibmtr.o -else - ifeq ($(CONFIG_IBMTR),m) - M_OBJS += ibmtr.o - endif -endif - -ifeq ($(CONFIG_IBMLS),y) -L_OBJS += lanstreamer.o -else - ifeq ($(CONFIG_IBMLS),m) - M_OBJS += lanstreamer.o - endif -endif - -ifeq ($(CONFIG_IBMOL),y) -L_OBJS += olympic.o -else - ifeq ($(CONFIG_IBMOL),m) - M_OBJS += olympic.o - endif -endif - -ifeq ($(CONFIG_SKTR),y) -L_OBJS += sktr.o -else - ifeq ($(CONFIG_SKTR),m) - M_OBJS += sktr.o - endif -endif - ifeq ($(CONFIG_ETHERTAP),y) L_OBJS += ethertap.o else @@ -123,6 +87,13 @@ else endif endif +ifeq ($(CONFIG_PCMCIA_PCNET),y) +CONFIG_8390_BUILTIN = y +else + ifeq ($(CONFIG_PCMCIA_PCNET),m) + CONFIG_8390_MODULE = y + endif +endif ifeq ($(CONFIG_SHAPER),y) L_OBJS += shaper.o @@ -609,6 +580,15 @@ else endif endif +ifeq ($(CONFIG_DM9102),y) +L_OBJS += dmfe.o +else + ifeq ($(CONFIG_DM9102),m) + M_OBJS += dmfe.o + endif +endif + + ifeq ($(CONFIG_YELLOWFIN),y) L_OBJS += yellowfin.o else @@ -811,14 +791,6 @@ else endif endif -ifeq ($(CONFIG_LAPBETHER),y) -L_OBJS += lapbether.o -else - ifeq ($(CONFIG_LAPBETHER),m) - M_OBJS += lapbether.o - endif -endif - ifeq ($(CONFIG_EPIC100),y) L_OBJS += epic100.o else @@ -827,63 +799,6 @@ else endif endif -ifeq ($(CONFIG_HOSTESS_SV11),y) -L_OBJS += hostess_sv11.o -CONFIG_85230_BUILTIN = y -CONFIG_SYNCPPP_BUILTIN = y -else - ifeq ($(CONFIG_HOSTESS_SV11),m) - CONFIG_85230_MODULE = y - CONFIG_SYNCPPP_MODULE = y - M_OBJS += hostess_sv11.o - endif -endif - -ifeq ($(CONFIG_SEALEVEL_4021),y) -L_OBJS += sealevel.o -CONFIG_85230_BUILTIN = y -CONFIG_SYNCPPP_BUILTIN = y -else - ifeq ($(CONFIG_SEALEVEL_4021),m) - CONFIG_85230_MODULE = y - CONFIG_SYNCPPP_MODULE = y - M_OBJS += sealevel.o - endif -endif - - -ifeq ($(CONFIG_COSA),y) -L_OBJS += cosa.o -CONFIG_SYNCPPP_BUILTIN = y -else - ifeq ($(CONFIG_COSA),m) - CONFIG_SYNCPPP_MODULE = y - M_OBJS += cosa.o - endif -endif - -# If anything built-in uses syncppp, then build it into the kernel also. -# If not, but a module uses it, build as a module. - -ifdef CONFIG_SYNCPPP_BUILTIN -LX_OBJS += syncppp.o -else - ifdef CONFIG_SYNCPPP_MODULE - MX_OBJS += syncppp.o - endif -endif - -# If anything built-in uses Z85230, then build it into the kernel also. -# If not, but a module uses it, build as a module. - -ifdef CONFIG_85230_BUILTIN -LX_OBJS += z85230.o -else - ifdef CONFIG_85230_MODULE - MX_OBJS += z85230.o - endif -endif - # If anything built-in uses slhc, then build it into the kernel also. # If not, but a module uses it, build as a module. ifdef CONFIG_SLHC_BUILTIN @@ -914,6 +829,14 @@ else endif endif +ifeq ($(CONFIG_PCMCIA_PCNET),y) +CONFIG_8390_BUILTIN = y +else + ifeq ($(CONFIG_PCMCIA_PCNET),m) + CONFIG_8390_MODULE = y + endif +endif + # If anything built-in uses the 8390, then build it into the kernel also. # If not, but a module uses it, build as a module. ifdef CONFIG_8390_BUILTIN @@ -1036,22 +959,6 @@ else endif endif -ifeq ($(CONFIG_SDLA),y) -L_OBJS += sdla.o -else - ifeq ($(CONFIG_SDLA),m) - M_OBJS += sdla.o - endif -endif - -ifeq ($(CONFIG_DLCI),y) -L_OBJS += dlci.o -else - ifeq ($(CONFIG_DLCI),m) - M_OBJS += dlci.o - endif -endif - ifeq ($(CONFIG_ARIADNE),y) L_OBJS += ariadne.o else @@ -1128,68 +1035,6 @@ else endif endif -ifeq ($(CONFIG_ADAPTEC_STARFIRE),y) -L_OBJS += starfire.o -else - ifeq ($(CONFIG_ADAPTEC_STARFIRE),m) - M_OBJS += starfire.o - endif -endif - -ifeq ($(CONFIG_VENDOR_SANGOMA),y) - LX_OBJS += sdladrv.o - L_OBJS += sdlamain.o - ifeq ($(CONFIG_WANPIPE_X25),y) - L_OBJS += sdla_x25.o - endif - ifeq ($(CONFIG_WANPIPE_FR),y) - L_OBJS += sdla_fr.o - endif - ifeq ($(CONFIG_WANPIPE_PPP),y) - L_OBJS += sdla_ppp.o - endif -endif - -ifeq ($(CONFIG_VENDOR_SANGOMA),m) - MX_OBJS += sdladrv.o - M_OBJS += wanpipe.o - WANPIPE_OBJS = sdlamain.o - ifeq ($(CONFIG_WANPIPE_X25),y) - WANPIPE_OBJS += sdla_x25.o - endif - ifeq ($(CONFIG_WANPIPE_FR),y) - WANPIPE_OBJS += sdla_fr.o - endif - ifeq ($(CONFIG_WANPIPE_PPP),y) - WANPIPE_OBJS += sdla_ppp.o - endif -endif - -ifeq ($(CONFIG_CYCLADES_SYNC),y) - LX_OBJS += cycx_drv.o - L_OBJS += cycx_main.o - ifeq ($(CONFIG_CYCLOMX_X25),y) - L_OBJS += cycx_x25.o - endif -endif - -ifeq ($(CONFIG_CYCLADES_SYNC),m) - MX_OBJS += cycx_drv.o - M_OBJS += cyclomx.o - CYCLOMX_OBJS = cycx_main.o - ifeq ($(CONFIG_CYCLOMX_X25),y) - CYCLOMX_OBJS += cycx_x25.o - endif -endif - -ifeq ($(CONFIG_X25_ASY),y) -L_OBJS += x25_asy.o -else - ifeq ($(CONFIG_X25_ASY),m) - M_OBJS += x25_asy.o - endif -endif - # # HIPPI adapters # @@ -1211,6 +1056,24 @@ else endif endif +ifeq ($(CONFIG_TR),y) +SUB_DIRS += tokenring +MOD_IN_SUB_DIRS += tokenring +else + ifeq ($(CONFIG_TR),m) + MOD_IN_SUB_DIRS += tokenring + endif +endif + +ifeq ($(CONFIG_WAN),y) +SUB_DIRS += wan +MOD_IN_SUB_DIRS += wan +else + ifeq ($(CONFIG_WAN),m) + MOD_IN_SUB_DIRS += wan + endif +endif + ifeq ($(CONFIG_NET_FC),y) SUB_DIRS += fc MOD_IN_SUB_DIRS += fc @@ -1225,11 +1088,5 @@ include $(TOPDIR)/Rules.make clean: rm -f core *.o *.a *.s -wanpipe.o: $(WANPIPE_OBJS) - ld -r -o $@ $(WANPIPE_OBJS) - -cyclomx.o: $(CYCLOMX_OBJS) - ld -r -o $@ $(CYCLOMX_OBJS) - rcpci.o: rcpci45.o rclanmtl.o $(LD) -r -o rcpci.o rcpci45.o rclanmtl.o diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 27c431e14..a10d519f5 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -12,6 +12,8 @@ * Donald J. Becker, <becker@super.org> * * Changelog: + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 09/1999 + * - fix sbni: s/device/net_device/ * Paul Gortmaker (06/98): * - sort probes in a sane way, make sure all (safe) probes * get run once & failed autoprobes don't autoprobe again. @@ -104,6 +106,7 @@ extern int pamsnet_probe(struct net_device *); extern int tlan_probe(struct net_device *); extern int mace_probe(struct net_device *); extern int bmac_probe(struct net_device *); +extern int ncr885e_probe(struct net_device *); extern int cs89x0_probe(struct net_device *dev); extern int ethertap_probe(struct net_device *dev); extern int ether1_probe (struct net_device *dev); @@ -118,11 +121,12 @@ extern int bagetlance_probe(struct net_device *); extern int dec_lance_probe(struct net_device *); extern int mvme147lance_probe(struct net_device *dev); extern int via_rhine_probe(struct net_device *dev); -extern int starfire_probe(struct net_device *dev); extern int tc515_probe(struct net_device *dev); extern int lance_probe(struct net_device *dev); +extern int starfire_probe(struct net_device *dev); extern int rcpci_probe(struct net_device *); extern int mac_onboard_sonic_probe(struct net_device *dev); +extern int dmfe_reg_board(struct net_device *); /* Gigabit Ethernet adapters */ extern int yellowfin_probe(struct net_device *dev); @@ -143,6 +147,9 @@ extern int rr_hippi_probe(struct net_device *); /* Fibre Channel adapters */ extern int iph5526_probe(struct net_device *dev); +/* SBNI adapters */ +extern int sbni_probe(struct net_device *); + struct devprobe { int (*probe)(struct net_device *dev); @@ -216,6 +223,11 @@ struct devprobe pci_probes[] __initdata = { #ifdef CONFIG_SIS900 {sis900_probe, 0}, #endif + +#ifdef CONFIG_DM9102 + {dmfe_reg_board, 0}, +#endif + #ifdef CONFIG_YELLOWFIN {yellowfin_probe, 0}, #endif @@ -293,10 +305,10 @@ struct devprobe mca_probes[] __initdata = { /* * ISA probes that touch addresses < 0x400 (including those that also - * look for EISA/PCI cards in addition to ISA cards). + * look for EISA/PCI/MCA cards in addition to ISA cards). */ struct devprobe isa_probes[] __initdata = { -#ifdef CONFIG_EL3 /* ISA, EISA (MCA someday) 3c5x9 */ +#ifdef CONFIG_EL3 /* ISA, EISA, MCA 3c5x9 */ {el3_probe, 0}, #endif #ifdef CONFIG_HP100 /* ISA, EISA & PCI */ @@ -458,6 +470,9 @@ struct devprobe ppc_probes[] __initdata = { #ifdef CONFIG_BMAC {bmac_probe, 0}, #endif +#ifdef CONFIG_NCR885E + {ncr885e_probe, 0}, +#endif {NULL, 0}, }; @@ -781,6 +796,7 @@ struct net_device eql_dev = { /* Token-ring device probe */ extern int ibmtr_probe(struct net_device *); extern int olympic_probe(struct net_device *); +extern int sktr_probe(struct net_device *); static int trif_probe(struct net_device *dev) @@ -876,6 +892,29 @@ static struct net_device tr0_dev = { # undef NEXT_DEV # define NEXT_DEV (&fc0_dev) #endif + + +#ifdef CONFIG_SBNI + static struct net_device sbni7_dev = + {"sbni7", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sbni_probe}; + static struct net_device sbni6_dev = + {"sbni6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni7_dev, sbni_probe}; + static struct net_device sbni5_dev = + {"sbni5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni6_dev, sbni_probe}; + static struct net_device sbni4_dev = + {"sbni4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni5_dev, sbni_probe}; + static struct net_device sbni3_dev = + {"sbni3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni4_dev, sbni_probe}; + static struct net_device sbni2_dev = + {"sbni2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni3_dev, sbni_probe}; + static struct net_device sbni1_dev = + {"sbni1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni2_dev, sbni_probe}; + static struct net_device sbni0_dev = + {"sbni0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni1_dev, sbni_probe}; + +#undef NEXT_DEV +#define NEXT_DEV (&sbni0_dev) +#endif #ifdef CONFIG_NET_SB1000 diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index d8bddd665..353b44dc8 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -474,10 +474,12 @@ arcnet_open(struct net_device *dev) lp->sdev=(struct net_device *)kmalloc(sizeof(struct net_device)+10,GFP_KERNEL); if(lp->sdev == NULL) { +#ifdef CONFIG_ARCNET_ETH if(lp->edev) kfree(lp->edev); lp->edev=NULL; return -ENOMEM; +#endif } memcpy(lp->sdev,dev,sizeof(struct net_device)); lp->sdev->name=(char *)(lp+1); diff --git a/drivers/net/ncr885_debug.h b/drivers/net/ncr885_debug.h new file mode 100644 index 000000000..bd1fead2d --- /dev/null +++ b/drivers/net/ncr885_debug.h @@ -0,0 +1,54 @@ +#ifndef _H_NCR885_DEBUG +#define _H_NCR885_DEBUG + +struct ncr885e_regs { + unsigned long tx_status; + unsigned long rx_status; + unsigned long mac_config; + unsigned long tx_control; + unsigned long rx_control; + unsigned long tx_cmd_ptr; + unsigned long rx_cmd_ptr; + unsigned long int_status; +}; + +#ifndef __KERNEL__ + +struct ncr885e_private { + + struct dbdma_cmd *head; + struct dbdma_cmd *tx_cmds; + struct dbdma_cmd *rx_cmds; + struct dbdma_cmd *stop_cmd; + + struct sk_buff *tx_skbufs[NR_TX_RING]; + struct sk_buff *rx_skbufs[NR_RX_RING]; + + int rx_current; + int rx_dirty; + + int tx_dirty; + int tx_current; + + unsigned short tx_status[NR_TX_RING]; + + unsigned char tx_fullup; + unsigned char tx_active; + + struct net_device_stats stats; + + struct device *dev; + + struct timer_list tx_timeout; + int timeout_active; + + spinlock_t lock; +}; + +#endif /* __KERNEL__ */ + + +#define NCR885E_GET_PRIV _IOR('N',1,sizeof( struct ncr885e_private )) +#define NCR885E_GET_REGS _IOR('N',2,sizeof( struct ncr885e_regs )) + +#endif diff --git a/drivers/net/ncr885e.c b/drivers/net/ncr885e.c new file mode 100644 index 000000000..277f92520 --- /dev/null +++ b/drivers/net/ncr885e.c @@ -0,0 +1,1458 @@ +/* + * An Ethernet driver for the dual-function NCR 53C885 SCSI/Ethernet + * controller. + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +static const char *version = +"ncr885e.c:v0.8 11/30/98 dan@synergymicro.com\n"; + +#include <linux/config.h> + +#ifdef MODULE +#ifdef MODVERSIONS +#include <linux/modversions.h> +#endif +#include <linux/module.h> +#include <linux/version.h> +#else +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#endif + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/timer.h> +#include <linux/ptrace.h> +#include <linux/malloc.h> +#include <linux/netdevice.h> +#include <linux/pci.h> +#include <linux/malloc.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <asm/io.h> +#include <asm/dbdma.h> +#include <asm/uaccess.h> + +#include <linux/etherdevice.h> +#include <linux/skbuff.h> + +#include "ncr885e.h" +#include "ncr885_debug.h" + +static const char *chipname = "ncr885e"; + +/* debugging flags */ +#if 0 +#define DEBUG_FUNC 0x0001 +#define DEBUG_PACKET 0x0002 +#define DEBUG_CMD 0x0004 +#define DEBUG_CHANNEL 0x0008 +#define DEBUG_INT 0x0010 +#define DEBUG_RX 0x0020 +#define DEBUG_TX 0x0040 +#define DEBUG_DMA 0x0080 +#define DEBUG_MAC 0x0100 +#define DEBUG_DRIVER 0x0200 +#define DEBUG_ALL 0x1fff +#endif + +#ifdef DEBUG_NCR885E +#define NCR885E_DEBUG 0 +#else +#define NCR885E_DEBUG 0 +#endif + +/* The 885's Ethernet PCI device id. */ +#ifndef PCI_DEVICE_ID_NCR_53C885_ETHERNET +#define PCI_DEVICE_ID_NCR_53C885_ETHERNET 0x0701 +#endif + +#define NR_RX_RING 8 +#define NR_TX_RING 8 +#define MAX_TX_ACTIVE (NR_TX_RING-1) +#define NCMDS_TX NR_TX_RING + +#define RX_BUFLEN (ETH_FRAME_LEN + 8) +#define TX_TIMEOUT 5*HZ + +#define NCR885E_TOTAL_SIZE 0xe0 + +#define TXSR (1<<6) /* tx: xfer status written */ +#define TXABORT (1<<7) /* tx: abort */ +#define EOP (1<<7) /* rx: end of packet written to buffer */ + +int ncr885e_debug = NCR885E_DEBUG; +static int print_version = 0; + +struct ncr885e_private { + + /* preserve a 1-1 marking with buffs */ + struct dbdma_cmd *head; + struct dbdma_cmd *tx_cmds; + struct dbdma_cmd *rx_cmds; + struct dbdma_cmd *stop_cmd; + + struct sk_buff *tx_skbufs[NR_TX_RING]; + struct sk_buff *rx_skbufs[NR_RX_RING]; + + int rx_current; + int rx_dirty; + + int tx_dirty; + int tx_current; + + unsigned short tx_status[NR_TX_RING]; + + unsigned char tx_fullup; + unsigned char tx_active; + + struct net_device_stats stats; + + struct net_device *dev; + + struct timer_list tx_timeout; + int timeout_active; + + spinlock_t lock; +}; + +#ifdef MODULE +static struct net_device *root_dev = NULL; +#endif + + +static int ncr885e_open( struct net_device *dev ); +static int ncr885e_close( struct net_device *dev ); +static void ncr885e_rx( struct net_device *dev ); +static void ncr885e_tx( struct net_device *dev ); +static int ncr885e_probe1( struct net_device *dev, unsigned long ioaddr, + unsigned char irq ); +static int ncr885e_xmit_start( struct sk_buff *skb, struct net_device *dev ); +static struct net_device_stats *ncr885e_stats( struct net_device *dev ); +static void ncr885e_set_multicast( struct net_device *dev ); +static void ncr885e_config( struct net_device *dev ); +static int ncr885e_set_address( struct net_device *dev, void *addr ); +static void ncr885e_interrupt( int irq, void *dev_id, struct pt_regs *regs ); +static void show_dbdma_cmd( volatile struct dbdma_cmd *cmd ); +#if 0 +static int read_eeprom( unsigned int ioadddr, int location ); +#endif + +#ifdef NCR885E_DEBUG_MII +static void show_mii( unsigned long ioaddr ); +static int read_mii( unsigned long ioaddr, int reg ); +static void write_mii( unsigned long ioaddr, int reg, int data ); +#endif /* NCR885E_DEBUG_MII */ + +#define TX_RESET_FLAGS (TX_CHANNEL_RUN|TX_CHANNEL_PAUSE|TX_CHANNEL_WAKE) +#define RX_RESET_FLAGS (RX_CHANNEL_RUN|RX_CHANNEL_PAUSE|RX_CHANNEL_WAKE) + + +#if 0 +static int +debug_ioctl( struct net_device *dev, struct ifreq *req, int cmd ) +{ + unsigned long ioaddr = dev->base_addr; + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + struct ncr885e_private *data; + struct ncr885e_regs *regs; + unsigned long flags; + + union { + struct ncr885e_regs dump; + struct ncr885e_private priv; + } temp; + + switch( cmd ) { + + /* dump the rx ring status */ + case NCR885E_GET_PRIV: + + data = (struct ncr885e_private *) &req->ifr_data; + + if ( verify_area(VERIFY_WRITE, &req->ifr_data, + sizeof( struct ncr885e_private ))) + return -EFAULT; + + memcpy((char *) &temp.priv, sp, sizeof( struct ncr885e_private )); + copy_to_user( data, (char *) &temp.priv, sizeof( struct ncr885e_private)); + break; + + case NCR885E_GET_REGS: + + regs = (struct ncr885e_regs *) &req->ifr_data; + + if ( verify_area( VERIFY_WRITE, &req->ifr_data, + sizeof( struct ncr885e_regs ))) + return -EFAULT; + + spin_lock_irqsave( &sp->lock, flags ); + + temp.dump.tx_status = inl( ioaddr + TX_CHANNEL_STATUS ); + temp.dump.rx_status = inl( ioaddr + RX_CHANNEL_STATUS ); + temp.dump.mac_config = inl( ioaddr + MAC_CONFIG ); + temp.dump.tx_control = inl( ioaddr + TX_CHANNEL_CONTROL ); + temp.dump.rx_control = inl( ioaddr + RX_CHANNEL_CONTROL ); + temp.dump.tx_cmd_ptr = inl( ioaddr + TX_CMD_PTR_LO ); + temp.dump.rx_cmd_ptr = inl( ioaddr + RX_CMD_PTR_LO ); + temp.dump.int_status = inl( ioaddr + INTERRUPT_STATUS_REG ); + + spin_unlock_irqrestore( &sp->lock, flags ); + copy_to_user( regs, (char *) &temp.dump, sizeof( struct ncr885e_regs )); + + break; + + default: + return -EOPNOTSUPP; + } + return 0; +} +#endif + +/* Enable interrupts on the 53C885 */ +static inline void +ncr885e_enable( struct net_device *dev ) + +{ + unsigned long ioaddr = dev->base_addr; + unsigned short reg; + + reg = inw(ioaddr + INTERRUPT_ENABLE); + outw(reg | INTERRUPT_INTE, ioaddr + INTERRUPT_ENABLE); +} + +/* Disable interrupts on the 53c885 */ +static inline void +ncr885e_disable( struct net_device *dev ) + +{ + unsigned long ioaddr = dev->base_addr; + unsigned short reg; + + reg = inw( ioaddr + INTERRUPT_ENABLE ); + outw( reg & ~INTERRUPT_INTE, ioaddr + INTERRUPT_ENABLE ); +} + + +static inline void +ncr885e_reset( struct net_device *dev ) + +{ + unsigned short reg; + unsigned long cntl; + int i; + unsigned long ioaddr = dev->base_addr; + + if (ncr885e_debug > 1) + printk( KERN_INFO "%s: Resetting 53C885...\n", dev->name ); + + /* disable interrupts on the 53C885 */ + ncr885e_disable( dev ); + + /* disable rx in the MAC */ + reg = inw( ioaddr + MAC_CONFIG ); + outw( reg & ~MAC_CONFIG_RXEN, ioaddr + MAC_CONFIG ); + + for( i=0; i < 100; i++ ) { + + if ( !(inw( ioaddr + MAC_CONFIG ) & MAC_CONFIG_RXEN )) + break; + udelay( 10 ); + } + + reg = inw( ioaddr + MAC_CONFIG ); + outw( reg | MAC_CONFIG_SRST, ioaddr + MAC_CONFIG ); + outw( reg, ioaddr + MAC_CONFIG ); + + /* disable both rx and tx DBDMA channels */ + outl( TX_DBDMA_ENABLE << 16, ioaddr + TX_CHANNEL_CONTROL ); + outl( RX_DBDMA_ENABLE << 16, ioaddr + RX_CHANNEL_CONTROL ); + + for( i=0; i < 100; i++ ) { + + if ( !(inw( ioaddr + TX_CHANNEL_STATUS ) & TX_DBDMA_ENABLE ) && + !(inw( ioaddr + RX_CHANNEL_STATUS ) & RX_DBDMA_ENABLE )) + break; + udelay( 10 ); + } + + /* perform a "software reset" */ + cntl = inl( ioaddr + DBDMA_CONTROL ); + outl( cntl | DBDMA_SRST, ioaddr + DBDMA_CONTROL ); + + for( i=0; i < 100; i++ ) { + + if ( !(inl( ioaddr + DBDMA_CONTROL ) & DBDMA_SRST )) + break; + udelay( 10 ); + } + + /* books says that a software reset should be done to the MAC, as + well. This true??? */ + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: reset complete\n", dev->name ); + +} + + +/* configure the 53C885 chip. + + The DBDMA command descriptors on the 53C885 can be programmed to + branch, interrupt or pause conditionally or always by using the + interrupt, branch and wait select registers. */ + +static void +ncr885e_config( struct net_device *dev ) + +{ + unsigned long ioaddr = dev->base_addr; + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: Configuring 53C885.\n", dev->name ); + + ncr885e_reset( dev ); + + /* The 53C885 can be programmed to perform conditional DBDMA + branches, interrupts or waits. + + Neither channel makes use of "wait", as it requires that the + DBDMA engine to be restarted. Don't go there. The rx channel + will branch upon the successful reception of a packet ('EOP' in + the xfer_status field). The branch address is to the STOP + DBDMA command descriptor, which shuts down the rx channel until + the interrupt is serviced. */ + + /* cause tx channel to stop after "status received" */ + outl( 0, ioaddr + TX_INT_SELECT ); + outl( (TX_WAIT_STAT_RECV << 16) | TX_WAIT_STAT_RECV, + ioaddr + TX_WAIT_SELECT ); + outl( 0, ioaddr + TX_BRANCH_SELECT ); + + /* cause rx channel to branch to the STOP descriptor on "End-of-Packet" */ +#if 0 + outl( (RX_INT_SELECT_EOP << 16) | RX_INT_SELECT_EOP, + ioaddr + RX_INT_SELECT ); +#else + outl( 0, ioaddr + RX_INT_SELECT ); +#endif +#if 0 + outl( 0, ioaddr + RX_WAIT_SELECT ); +#else + outl( (RX_WAIT_SELECT_EOP << 16) | RX_WAIT_SELECT_EOP, + ioaddr + RX_WAIT_SELECT ); +#endif +#if 1 + outl( 0, ioaddr + RX_BRANCH_SELECT ); +#else + outl( (RX_BRANCH_SELECT_EOP << 16) | RX_BRANCH_SELECT_EOP, + ioaddr + RX_BRANCH_SELECT ); +#endif + + /* configure DBDMA */ + outl( (DBDMA_BE | DBDMA_DPMRLE | DBDMA_TDPCE | + DBDMA_DDPE | DBDMA_TDPE | + (DBDMA_BURST_4 << DBDMA_TX_BST_SHIFT) | + (DBDMA_BURST_4 << DBDMA_RX_BST_SHIFT) | + (DBDMA_TX_ARBITRATION_DEFAULT) | + (DBDMA_RX_ARBITRATION_DEFAULT)), ioaddr + DBDMA_CONTROL ); + + outl( 0, ioaddr + TX_THRESHOLD ); + + /* disable MAC loopback */ + outl( (MAC_CONFIG_ITXA | MAC_CONFIG_RXEN | MAC_CONFIG_RETRYL | + MAC_CONFIG_PADEN | (0x18 << 16)), + ioaddr + MAC_CONFIG ); + + /* configure MAC */ + outl( (MAC_CONFIG_ITXA | MAC_CONFIG_RXEN | MAC_CONFIG_RETRYL | + MAC_CONFIG_PADEN | ( 0x18 << 16)), ioaddr + MAC_CONFIG ); + + outw( (0x1018), ioaddr + NBTOB_INTP_GAP ); + + /* clear and enable interrupts */ + inw( ioaddr + INTERRUPT_CLEAR ); + ncr885e_enable( dev ); + + /* and enable them in the chip */ + outl( (INTERRUPT_INTE|INTERRUPT_TX_MASK|INTERRUPT_RX_MASK)<<16, + ioaddr + INTERRUPT_ENABLE - 2); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: 53C885 config complete.\n", dev->name ); + + return; +} + + + +/* + transmit interrupt */ + +static void +ncr885e_tx( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + volatile struct dbdma_cmd *cp, *dp; + unsigned short txbits, xfer; + int i; + + del_timer( &sp->tx_timeout ); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: ncr885e_tx: active=%d, dirty=%d, current=%d\n", + dev->name, sp->tx_active, sp->tx_dirty, sp->tx_current ); + + sp->timeout_active = 0; + + i = sp->tx_dirty; + cp = sp->tx_cmds + (i*3); + dp = cp+1; + sp->tx_active--; + + xfer = inw( &dp->xfer_status ); + txbits = inw( &sp->tx_status[i] ); + + if (ncr885e_debug > 4) { + show_dbdma_cmd( cp ); + show_dbdma_cmd( dp ); + } + + /* get xmit result */ + txbits = inw( &sp->tx_status[i] ); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: tx xfer=%04x, txbits=%04x\n", dev->name, + xfer, txbits ); + + /* look for any channel status (?) */ + if ( xfer ) { + + dev_kfree_skb( sp->tx_skbufs[i] ); + mark_bh( NET_BH ); + + if ( txbits & TX_STATUS_TXOK ) { + sp->stats.tx_packets++; + sp->stats.tx_bytes += inw( &cp->req_count ); + } + + /* dropped packets */ + if ( txbits & (TX_STATUS_TDLC|TX_STATUS_TDEC) ) { + sp->stats.tx_dropped++; + } + + /* add the collisions */ + sp->stats.collisions += ( txbits & 0x04 ); + + } + + dev->tbusy = 0; + + return; +} + +/* rx interrupt handling */ +static void +ncr885e_rx( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + volatile struct dbdma_cmd *cp; + struct sk_buff *skb; + int i, nb; + unsigned short status; + unsigned char *data, *stats; + unsigned long rxbits, ioaddr = dev->base_addr; + + i = sp->rx_current; + cp = sp->rx_cmds + (i*2); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: ncr885e_rx dirty=%d, current=%d (cp@%p)\n", + dev->name, sp->rx_dirty, sp->rx_current, cp ); + + nb = inw( &cp->req_count ) - inw( &cp->res_count ); + status = inw( &cp->xfer_status ); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: (rx %d) bytes=%d, xfer_status=%04x\n", + dev->name, i, nb, status ); + + if ( status ) { + + skb = sp->rx_skbufs[i]; + data = skb->data; + stats = data + nb - 3; + rxbits = (stats[0]|stats[1]<<8|stats[2]<<16); + + if (ncr885e_debug > 3) + printk( KERN_INFO " rx_bits=%06lx\n", rxbits ); + + skb->dev = dev; + skb_put( skb, nb-3 ); + skb->protocol = eth_type_trans( skb, dev ); + netif_rx( skb ); + sp->rx_skbufs[i] = 0; + + if ( rxbits & RX_STATUS_RXOK ) { + sp->stats.rx_packets++; + sp->stats.rx_bytes += nb; + } + + if ( rxbits & RX_STATUS_MCAST ) + sp->stats.multicast++; + + } + + sp->rx_dirty = sp->rx_current; + + if ( ++sp->rx_current >= NR_RX_RING ) + sp->rx_current = 0; + + /* fix up the one we just trashed */ + cp = sp->rx_cmds + (sp->rx_dirty * 2); + + skb = dev_alloc_skb( RX_BUFLEN + 2 ); + if ( skb != 0 ) { + skb_reserve( skb, 2 ); + sp->rx_skbufs[sp->rx_dirty] = skb; + } + + if (ncr885e_debug > 2) + printk( KERN_INFO "%s: ncr885e_rx: using ring index %d, filling cp @ %p\n", + dev->name, sp->rx_current, cp ); + + outw( RX_BUFLEN, &cp->req_count ); + outw( 0, &cp->res_count ); + data = skb->data; + outl( virt_to_bus( data ), &cp->phy_addr ); + outw( 0, &cp->xfer_status ); + + cp = sp->rx_cmds + (sp->rx_current * 2); + + /* restart rx DMA */ + outl( virt_to_bus( cp ), ioaddr + RX_CMD_PTR_LO ); + outl( (RX_DBDMA_ENABLE << 16)|RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + + return; +} + +static void +ncr885e_misc_ints( struct net_device *dev, unsigned short status ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + struct dbdma_cmd *cp; + unsigned long ioaddr = dev->base_addr; + + if (ncr885e_debug > 1) + printk( KERN_INFO "miscellaneous interrupt handled; status=%02x\n", + status ); + + /* various transmit errors */ + if ( status & + (INTERRUPT_PPET | INTERRUPT_PBFT | INTERRUPT_IIDT) ) { + + /* illegal instruction in tx dma */ + if ( status & INTERRUPT_IIDT ) { + + cp = (struct dbdma_cmd *) bus_to_virt( inl( ioaddr + TX_CMD_PTR_LO )); + printk( KERN_INFO "%s: tx illegal insn:\n", dev->name ); + printk( KERN_INFO " tx DBDMA - cmd = %p, status = %04x\n", + cp, inw( ioaddr + TX_CHANNEL_STATUS )); + printk( KERN_INFO " command = %04x, phy_addr=%08x, req_count=%04x\n", + inw( &cp->command ), inw( &cp->phy_addr ), inw( &cp->req_count )); + } + + if ( status & INTERRUPT_PPET ) + printk( KERN_INFO "%s: tx PCI parity error\n", dev->name ); + + if ( status & INTERRUPT_PBFT ) + printk( KERN_INFO "%s: tx PCI bus fault\n", dev->name ); + } + + /* look for rx errors */ + if ( status & + (INTERRUPT_PPER | INTERRUPT_PBFR | INTERRUPT_IIDR)) { + + /* illegal instruction in rx dma */ + if ( status & INTERRUPT_IIDR ) { +#if 0 + cmd = inl( ioaddr + RX_CMD_PTR_LO ); +#endif + printk( KERN_ERR "%s: rx illegal DMA instruction:\n", dev->name ); + printk( KERN_ERR " channel status=%04x,\n", + inl( ioaddr + RX_CHANNEL_STATUS )); +#if 0 + show_dbdma_cmd( bus_to_virt( inl( ioaddr + RX_CMD_PTR_LO ))); + printk( KERN_ERR " instr (%08x) %08x %08x %08x\n", + (int) cmd, cmd[0], cmd[1], cmd[2] ); +#endif + } + + /* PCI parity error */ + if ( status & INTERRUPT_PPER ) + printk( KERN_INFO "%s: rx PCI parity error\n", dev->name ); + + if ( status & INTERRUPT_PBFR ) + printk( KERN_INFO "%s: rx PCI bus fault\n", dev->name ); + + sp->stats.rx_errors++; + } + + if ( status & INTERRUPT_WI ) { + printk( KERN_INFO "%s: link pulse\n", dev->name ); + } + + /* bump any counters */ + + + return; +} + +static void +ncr885e_interrupt( int irq, void *dev_id, struct pt_regs *regs ) + +{ + struct net_device *dev = (struct net_device *) dev_id; + struct ncr885e_private *sp; + unsigned short status; + int ioaddr; + + if ( dev == NULL ) { + printk( KERN_ERR "symba: Interrupt IRQ %d for unknown device\n", irq ); + return; + } + + ioaddr = dev->base_addr; + sp = (struct ncr885e_private *) dev->priv; + spin_lock( &sp->lock ); + + if ( dev->interrupt ) { + printk( KERN_ERR "%s: Re-entering interrupt handler...\n", + dev->name ); + } + + dev->interrupt = 1; + status = inw( ioaddr + INTERRUPT_CLEAR ); + + if (ncr885e_debug > 2) + printk( KERN_INFO "%s: 53C885 interrupt 0x%02x\n", dev->name, status ); + + /* handle non-tx and rx interrupts first */ + if ( status & ~(INTERRUPT_DIT|INTERRUPT_DIR)) + ncr885e_misc_ints( dev, status ); + + /* look for tx interrupt: more to transmit, DBDMA stopped, or tx done */ + if ( ( status & INTERRUPT_DIT ) ) { + + if (ncr885e_debug > 2) + printk( KERN_INFO "%s: tx int; int=%02x, chan stat=%02x\n", + dev->name, status, inw( ioaddr + TX_CHANNEL_STATUS )); + + /* turn off timer */ + del_timer( &sp->tx_timeout ); + sp->timeout_active = 0; + + /* stop DMA */ + outl( TX_DBDMA_ENABLE << 16, ioaddr + TX_CHANNEL_CONTROL ); + + ncr885e_tx( dev ); + } + + if ( status & INTERRUPT_DIR ) { + + if ( ncr885e_debug > 2 ) + printk( KERN_INFO "%s: rx interrupt; int=%02x, rx channel stat=%02x\n", + dev->name, status, inw( ioaddr + RX_CHANNEL_STATUS )); + + /* stop DMA */ + outl( RX_DBDMA_ENABLE << 16, ioaddr + RX_CHANNEL_CONTROL ); + + /* and handle the interrupt */ + ncr885e_rx( dev ); + } + + dev->interrupt = 0; + spin_unlock( &sp->lock ); + + return; +} + + +/* doesn't set the address permanently, however... */ +static int +ncr885e_set_address( struct net_device *dev, void *addr ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + struct sockaddr *saddr = addr; + unsigned long flags; + unsigned short reg[3]; + unsigned char *ioaddr, *p; + int i; + + memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len ); + + p = (unsigned char *) dev->dev_addr; + printk( KERN_INFO "%s: setting new MAC address - ", dev->name ); +#if 0 + for( p = (unsigned char *) dev->dev_addr, i=0; i < 6; i++, p++ ) + printk("%c%2.2x", i ? ':' : ' ', *p ); +#endif + + + p = (unsigned char *) ® + for( i=0; i < 6; i++ ) + p[i] = dev->dev_addr[i]; + +#if 0 + printk("%s: Setting new mac address - ", dev->name ); + for( i=0; i < 6; i++ ) { + printk("%02x", i ? ':' : ' ', p[i] ); + } + + printk("\n"); +#endif + + /* stop rx for the change */ + outl( RX_DBDMA_ENABLE << 16, ioaddr + RX_CHANNEL_CONTROL ); + + spin_lock_irqsave( &sp->lock, flags ); + + ioaddr = (unsigned char *) dev->base_addr; + + for( i = 0; i < 3; i++ ) { + reg[i] = ((reg[i] & 0xff) << 8) | ((reg[i] >> 8) & 0xff); + printk("%04x ", reg[i] ); + outw( reg[i], ioaddr + STATION_ADDRESS_0 + (i*2)); + } + printk("\n"); + + spin_unlock_irqrestore( &sp->lock, flags ); + + /* restart rx */ + outl((RX_DBDMA_ENABLE << 16)|RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + + return 0; +} + +static void +ncr885e_tx_timeout( unsigned long data ) + +{ + struct net_device *dev = (struct net_device *) data; + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + unsigned long flags, ioaddr; + int i; + + save_flags( flags ); + cli(); + + ioaddr = dev->base_addr; + sp->timeout_active = 0; + i = sp->tx_dirty; + + /* if we weren't active, bail... */ + if ( sp->tx_active == 0 ) { + printk( KERN_INFO "%s: ncr885e_timeout...tx not active!\n", dev->name ); + goto out; + } + + printk( KERN_ERR "%s: 53C885 timed out. Resetting...\n", dev->name ); + + /* disable rx and tx DMA */ + outl( (TX_DBDMA_ENABLE << 16), ioaddr + TX_CHANNEL_CONTROL ); + outl( (RX_DBDMA_ENABLE << 16), ioaddr + RX_CHANNEL_CONTROL ); + + /* reset the chip */ + ncr885e_config( dev ); + ncr885e_enable( dev ); + + /* clear the wedged skb in the tx ring */ + sp->tx_active = 0; + ++sp->stats.tx_errors; + + if ( sp->tx_skbufs[i] ) { + dev_kfree_skb( sp->tx_skbufs[i] ); + sp->tx_skbufs[i] = 0; + } + + /* start anew from the beginning of the ring buffer (why not?) */ + sp->tx_current = 0; + dev->tbusy = 0; + mark_bh( NET_BH ); + + /* restart rx dma */ + outl( (RX_DBDMA_ENABLE << 16) | RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + out: + + restore_flags( flags ); +} + +static inline void +ncr885e_set_timeout( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + unsigned long flags; + + save_flags(flags); + cli(); + + if ( sp->timeout_active ) + del_timer( &sp->tx_timeout ); + + sp->tx_timeout.expires = jiffies + TX_TIMEOUT; + sp->tx_timeout.function = ncr885e_tx_timeout; + sp->tx_timeout.data = (unsigned long) dev; + add_timer( &sp->tx_timeout ); + sp->timeout_active = 1; + restore_flags( flags ); +} + + +/* + * The goal is to set up DBDMA such that the rx ring contains only + * one DMA descriptor per ring element and the tx ring has two (using + * the cool features of branch- and wait-select. However, I'm not sure + * if it's possible. For now, we plod through it with 3 descriptors + * for tx, and two for rx. + */ + +static int +ncr885e_open( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + unsigned long ioaddr = dev->base_addr; + struct sk_buff *skb; + int i, size; + char *data; + struct dbdma_cmd *cp; + unsigned long flags; + + /* allocate enough space for the tx and rx rings and a STOP descriptor */ + size = (sizeof( struct dbdma_cmd ) * + ((NR_TX_RING * 3) + (NR_RX_RING * 2) + 1)); + + cp = kmalloc( size, GFP_KERNEL ); + + if ( cp == 0 ) { + printk( KERN_ERR "Insufficient memory (%d bytes) for DBDMA\n", size ); + return -ENOMEM; + } + + spin_lock_init( &sp->lock ); + spin_lock_irqsave( &sp->lock, flags ); + + memset((char *) cp, 0, size ); + sp->head = cp; + + sp->stop_cmd = cp; + outl( DBDMA_STOP, &cp->command ); + + sp->rx_cmds = ++cp; + + for( i = 0; i < NR_RX_RING; i++ ) { + + cp = sp->rx_cmds + (i*2); + skb = dev_alloc_skb( RX_BUFLEN + 2 ); + + /* if there is insufficient memory, make this last ring use a + static buffer and leave the loop with that skb as final one */ + if ( skb == 0 ) { + printk( KERN_ERR "%s: insufficient memory for rx ring buffer\n", + dev->name ); + break; + } + + skb_reserve( skb, 2 ); + sp->rx_skbufs[i] = skb; + data = skb->data; + + /* The DMA commands here are done such that an EOP is the only + way that we should get an interrupt. This means that we could + fill more than one skbuff before getting the interrupt at EOP. */ + + /* Handle rx DMA such that it always interrupts.... */ + outw( (INPUT_MORE|INTR_ALWAYS), &cp->command ); + outw( RX_BUFLEN, &cp->req_count ); + outw( 0, &cp->res_count ); + outl( virt_to_bus( data ), &cp->phy_addr ); + outl( virt_to_bus( sp->stop_cmd ), &cp->cmd_dep ); + outw( 0, &cp->xfer_status ); +#if 0 + printk( KERN_INFO "rx at %p\n", cp ); + show_dbdma_cmd( cp ); +#endif + ++cp; + + outw( DBDMA_STOP, &cp->command ); + + } + + /* initialize to all rx buffers are available, fill limit is the end */ + sp->rx_dirty = 0; + sp->rx_current = 0; + + /* fill the tx ring */ + sp->tx_cmds = cp+1; + + for( i = 0; i < NR_TX_RING; i++ ) { + + /* minimal setup for tx command */ + cp = sp->tx_cmds + (i*3); + outw( OUTPUT_LAST, &cp->command ); + if (ncr885e_debug > 3) { + printk( KERN_INFO "tx OUTPUT_LAST at %p\n", cp ); + show_dbdma_cmd( cp ); + } + + /* full setup for the status cmd */ + cp++; + outw( INPUT_LAST|INTR_ALWAYS|WAIT_IFCLR, &cp->command ); + outl( virt_to_bus( &sp->tx_status[i] ), &cp->phy_addr ); + outw( 2, &cp->req_count ); + if ( ncr885e_debug > 3) { + printk( KERN_INFO "tx INPUT_LAST cmd at %p\n", cp ); + show_dbdma_cmd( cp ); + } + + ++cp; + outw( DBDMA_STOP, &cp->command ); + + } +#if 0 + /* chain the last tx DMA command to the STOP cmd */ + outw((INPUT_LAST|INTR_ALWAYS|BR_ALWAYS), &cp->command ); + outl( virt_to_bus( sp->stop_cmd ), &cp->cmd_dep ); +#endif + sp->tx_active = 0; + sp->tx_current = 0; + sp->tx_dirty = 0; + + spin_unlock_irqrestore( &sp->lock, flags ); + + /* the order seems important here for some reason. If the MPIC isn't + enabled before the ethernet chip is enabled, shrapnel from the + bootloader causes us to receive interrupts even though we've not + yet enabled the tx channel. Go figure. It'd be better to configure + the chip in the probe1() routine, but then we don't see interrupts + at all. Everything looks all right on the logic analyzer, but... */ + + ncr885e_config( dev ); + + /* enable ethernet interrupts */ + if ( request_irq( dev->irq, &ncr885e_interrupt, SA_SHIRQ, chipname, dev )) { + printk( KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq ); + return -EAGAIN; + } + + (void) inw( ioaddr + INTERRUPT_CLEAR ); + + ncr885e_enable( dev ); + + /* start rx DBDMA */ + outl( virt_to_bus( sp->rx_cmds ), ioaddr + RX_CMD_PTR_LO ); + outl( (RX_DBDMA_ENABLE << 16)|RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + + dev->start = 1; + dev->tbusy = 0; + dev->interrupt = 0; + + MOD_INC_USE_COUNT; + + return 0; +} + +static int +ncr885e_xmit_start( struct sk_buff *skb, struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + volatile struct dbdma_cmd *cp, *dp; + unsigned long flags, ioaddr = dev->base_addr; + int len, next, fill, entry; + + if ( ncr885e_debug > 3) + printk( KERN_INFO "%s: xmit_start len=%d, dirty=%d, current=%d, active=%d\n", + dev->name, skb->len, sp->tx_dirty, sp->tx_current, sp->tx_active ); + + spin_lock_irqsave( &sp->lock, flags ); + + /* find the free slot in the ring buffer */ + fill = sp->tx_current; + next = fill + 1; + + if ( next >= NR_TX_RING ) + next = 0; + + /* mark ourselves as busy, even if we have too many packets waiting */ + dev->tbusy = 1; + + /* see if it's necessary to defer this packet */ + if ( sp->tx_active >= MAX_TX_ACTIVE ) { + spin_unlock_irqrestore( &sp->lock, flags ); + return -1; + } + + sp->tx_active++; /* bump "active tx" count */ + sp->tx_current = next; /* and show that we've used this buffer */ + sp->tx_dirty = fill; /* and mark this one to get picked up */ + + len = skb->len; + + if ( len > ETH_FRAME_LEN ) { + printk( KERN_DEBUG "%s: xmit frame too long (%d)\n", dev->name, len ); + len = ETH_FRAME_LEN; + } + + /* get index into the tx DBDMA chain */ + entry = fill * 3; + sp->tx_skbufs[fill] = skb; + cp = sp->tx_cmds + entry; + dp = cp + 1; + + /* update the rest of the OUTPUT_MORE descriptor */ + outw( len, &cp->req_count ); + outl( virt_to_bus( skb->data ), &cp->phy_addr ); + outw( 0, &cp->xfer_status ); + outw( 0, &cp->res_count ); + + /* and finish off the INPUT_MORE */ + outw( 0, &dp->xfer_status ); + outw( 0, &dp->res_count ); + sp->tx_status[fill] = 0; + outl( virt_to_bus( &sp->tx_status[fill] ), &dp->phy_addr ); + + if ( ncr885e_debug > 2 ) + printk(KERN_INFO "%s: xmit_start: active %d, tx_current %d, tx_dirty %d\n", + dev->name, sp->tx_active, sp->tx_current, sp->tx_dirty ); + + if ( ncr885e_debug > 4 ) { + show_dbdma_cmd( cp ); + show_dbdma_cmd( dp ); + } + + + /* restart the tx DMA engine */ + outl( virt_to_bus( cp ), ioaddr + TX_CMD_PTR_LO ); + outl( (TX_DBDMA_ENABLE << 16)|TX_CHANNEL_RUN, + ioaddr + TX_CHANNEL_CONTROL ); + + ncr885e_set_timeout( dev ); + + spin_unlock_irqrestore( &sp->lock, flags ); + dev->trans_start = jiffies; + + return 0; +} + +static int +ncr885e_close(struct net_device *dev) + +{ + int i; + struct ncr885e_private *np = (struct ncr885e_private *) dev->priv; + unsigned long ioaddr = dev->base_addr; + + dev->start = 0; + dev->tbusy = 1; + + spin_lock( &np->lock ); + + printk(KERN_INFO "%s: NCR885E Ethernet closing...\n", dev->name ); + + if (ncr885e_debug > 1) + printk(KERN_DEBUG "%s: Shutting down Ethernet chip\n", dev->name); + + ncr885e_disable(dev); + + del_timer(&np->tx_timeout); + + /* flip off rx and tx */ + outl( (RX_DBDMA_ENABLE << 16), ioaddr + RX_CHANNEL_CONTROL ); + outl( (TX_DBDMA_ENABLE << 16), ioaddr + TX_CHANNEL_CONTROL ); + + /* free up the IRQ */ + free_irq( dev->irq, dev ); + + for( i = 0; i < NR_RX_RING; i++ ) { + if (np->rx_skbufs[i]) + dev_kfree_skb( np->rx_skbufs[i] ); + np->rx_skbufs[i] = 0; + } +#if 0 + for (i = 0; i < NR_TX_RING; i++) { + if (np->tx_skbufs[i]) + dev_kfree_skb(np->tx_skbufs[i]); + np->tx_skbufs[i] = 0; + } +#endif + spin_unlock( &np->lock ); + + kfree( np->head ); + + MOD_DEC_USE_COUNT; + + return 0; +} + + +/* + * multicast promiscuous mode isn't used here. Allow code in the + * IP stack to determine which multicast packets are good or bad.... + * (this avoids having to use the hash table registers) + */ +static void +ncr885e_set_multicast( struct net_device *dev ) + +{ + int ioaddr = dev->base_addr; + + if ( ncr885e_debug > 3 ) + printk("%s: set_multicast: dev->flags = %x, AF=%04x\n", + dev->name, dev->flags, inw( ioaddr + ADDRESS_FILTER )); + + if ( dev->flags & IFF_PROMISC ) { + printk( KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name ); + outw( ADDRESS_RPPRO, ioaddr + ADDRESS_FILTER ); + } + + /* accept all multicast packets without checking the mc_list. */ + else if ( dev->flags & IFF_ALLMULTI ) { + printk( KERN_INFO "%s: Enabling all multicast packets.\n", + dev->name ); + outw( ADDRESS_RPPRM, ioaddr + ADDRESS_FILTER ); + } + + /* enable broadcast rx */ + else { + outw( ADDRESS_RPABC, ioaddr + ADDRESS_FILTER ); + } +} + +static struct net_device_stats * +ncr885e_stats( struct net_device *dev ) + +{ + struct ncr885e_private *np = (struct ncr885e_private *) dev->priv; + + return &np->stats; +} + +/* By this function, we're certain that we have a 885 Ethernet controller + * so we finish setting it up and wrap up all the required Linux ethernet + * configuration. + */ + +static int +ncr885e_probe1( struct net_device *dev, unsigned long ioaddr, unsigned char irq ) + +{ + struct ncr885e_private *sp; + unsigned short station_addr[3], val; + unsigned char *p; + int i; + + dev = init_etherdev( dev, 0 ); + + /* construct private data for the 885 ethernet */ + dev->priv = kmalloc( sizeof( struct ncr885e_private ), GFP_KERNEL ); + + if ( dev->priv == NULL ) + return -ENOMEM; + + sp = (struct ncr885e_private *) dev->priv; + memset( sp, 0, sizeof( struct ncr885e_private )); + + /* snag the station address and display it */ + for( i = 0; i < 3; i++ ) { + val = inw( ioaddr + STATION_ADDRESS_0 + (i*2)); + station_addr[i] = ((val >> 8) & 0xff) | ((val << 8) & 0xff00); + } + + printk( KERN_INFO "%s: %s at %08lx,", dev->name, chipname, ioaddr ); + + p = (unsigned char *) &station_addr; + + for( i=0; i < 6; i++ ) { + dev->dev_addr[i] = *p; + printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i] ); + p++; + } + + printk(", IRQ %d.\n", irq ); + + request_region( ioaddr, NCR885E_TOTAL_SIZE, dev->name ); + + /* set up a timer */ + init_timer( &sp->tx_timeout ); + sp->timeout_active = 0; + + dev->base_addr = ioaddr; + dev->irq = irq; + + ether_setup( dev ); + + /* everything else */ + dev->open = ncr885e_open; + dev->stop = ncr885e_close; + dev->get_stats = ncr885e_stats; + dev->hard_start_xmit = ncr885e_xmit_start; + dev->set_multicast_list = ncr885e_set_multicast; + dev->set_mac_address = ncr885e_set_address; + + return 0; +} + +/* Since the NCR 53C885 is a multi-function chip, I'm not worrying about + * trying to get the the device(s) in slot order. For our (Synergy's) + * purpose, there's just a single 53C885 on the board and we don't + * worry about the rest. + */ + +int __init ncr885e_probe( struct net_device *dev ) +{ + struct pci_dev *pdev = NULL; + unsigned int ioaddr, chips = 0; + unsigned short cmd; + unsigned char irq, latency; + + while(( pdev = pci_find_device( PCI_VENDOR_ID_NCR, + PCI_DEVICE_ID_NCR_53C885_ETHERNET, + pdev )) != NULL ) { + + if ( !print_version ) { + print_version++; + printk( KERN_INFO "%s", version ); + } + + /* Use I/O space */ + pci_read_config_dword( pdev, PCI_BASE_ADDRESS_0, &ioaddr ); + pci_read_config_byte( pdev, PCI_INTERRUPT_LINE, &irq ); + + ioaddr &= ~3; + /* Adjust around the Grackle... */ +#ifdef CONFIG_GEMINI + ioaddr |= 0xfe000000; +#endif + + if ( check_region( ioaddr, NCR885E_TOTAL_SIZE )) + continue; + + /* finish off the probe */ + if ( !(ncr885e_probe1( dev, ioaddr, irq ))) { + + chips++; + + /* Access is via I/O space, bus master enabled... */ + pci_read_config_word( pdev, PCI_COMMAND, &cmd ); + + if ( !(cmd & PCI_COMMAND_MASTER) ) { + printk( KERN_INFO " PCI master bit not set! Now setting.\n"); + cmd |= PCI_COMMAND_MASTER; + pci_write_config_word( pdev, PCI_COMMAND, cmd ); + } + + if ( !(cmd & PCI_COMMAND_IO) ) { + printk( KERN_INFO " Enabling I/O space.\n" ); + cmd |= PCI_COMMAND_IO; + pci_write_config_word( pdev, PCI_COMMAND, cmd ); + } + + pci_read_config_byte( pdev, PCI_LATENCY_TIMER, &latency ); + + if ( latency < 10 ) { + printk( KERN_INFO " PCI latency timer (CFLT) is unreasonably" + " low at %d. Setting to 255.\n", latency ); + pci_write_config_byte( pdev, PCI_LATENCY_TIMER, 255 ); + } + } + } + + if ( !chips ) + return -ENODEV; + else + return 0; +} + +/* debugging to peek at dma descriptors */ +static void +show_dbdma_cmd( volatile struct dbdma_cmd *cmd ) + +{ + printk( KERN_INFO " cmd %04x, physaddr %08x, req_count %04x\n", + inw( &cmd->command ), inl( &cmd->phy_addr ), inw( &cmd->req_count )); + printk( KERN_INFO " res_count %04x, xfer_status %04x, branch %08x\n", + inw( &cmd->res_count ), inw( &cmd->xfer_status ),inl( &cmd->cmd_dep )); +} + +#if 0 +static int +read_eeprom( unsigned int ioaddr, int location ) + +{ + int loop; + unsigned char val; + + outb( (location & 0xff), ioaddr + EE_WORD_ADDR ); + + /* take spillover from location in control reg */ + outb(EE_CONTROL_RND_READB | (location & (0x7<<8)), ioaddr + EE_CONTROL); + + loop = 1000; + while( (inb( ioaddr + EE_STATUS) & EE_SEB) && + (loop > 0) ) { + udelay( 10 ); + loop--; + } + + if ( inb( ioaddr + EE_STATUS ) & EE_SEE ) { + printk("%s: Serial EEPROM read error\n", chipname); + val = 0xff; + } + + else + val = inb( ioaddr + EE_READ_DATA ); + + return (int) val; +} +#endif + +#ifdef NCR885E_DEBUG_MII +static void +show_mii( unsigned long ioaddr ) + +{ + int phyctrl, phystat, phyadvert, phypartner, phyexpan; + + phyctrl = read_mii( ioaddr, MII_AUTO_NEGOTIATION_CONTROL ); + phystat = read_mii( ioaddr, MII_AUTO_NEGOTIATION_STATUS ); + phyadvert = read_mii( ioaddr, MII_AUTO_NEGOTIATION_ADVERTISEMENT ); + phypartner = read_mii( ioaddr, MII_AUTO_NEGOTIATION_LINK_PARTNER ); + phyexpan = read_mii( ioaddr, MII_AUTO_NEGOTIATION_EXPANSION ); + + printk( KERN_INFO "PHY: advert=%d %s, partner=%s %s, link=%d, %s%s\n", + (phyadvert & MANATECH_100BASETX_FULL_DUPLEX ? 100 : 10), + (phyctrl & MANC_AUTO_NEGOTIATION_ENABLE ? "auto" : "fixed"), + (phypartner & MANLP_ACKNOWLEDGE ? + (phypartner & MANATECH_100BASETX_FULL_DUPLEX ? "100" : "10") : + "?"), + (phyexpan & MANE_LINK_PARTNER_AUTO_ABLE ? "auto" : "fixed"), + (phyctrl & MANC_PHY_SPEED_100 ? 100 : 10), + (phystat & MANS_LINK_STATUS ? "up" : "down"), + (phyexpan & MANE_PARALLEL_DETECTION_FAULT ? " PD-fault" : "" )); + return; +} + + +static int +read_mii( unsigned long ioaddr, int reg ) + +{ + int timeout; + + + timeout = 100000; + + while( inw( ioaddr + MII_INDICATOR ) & MII_BUSY ) { + + if ( timeout-- < 0 ) { + printk( KERN_INFO "Timed out waiting for MII\n" ); + return -1; + } + } + + outw( (1<<8) + reg, ioaddr + MII_ADDRESS ); + outw( MIIM_RSTAT, ioaddr + MIIM_COMMAND ); + + timeout = 100000; + while( inw( ioaddr + MII_INDICATOR ) & MII_BUSY ) { + if ( timeout-- < 0 ) { + printk( KERN_INFO "Timed out waiting for MII\n" ); + return -1; + } + } + + return( inw( ioaddr + MII_READ_DATA )); +} + +static void +write_mii( unsigned long ioaddr, int reg, int data ) + +{ + int timeout=100000; + + printk( KERN_INFO "MII indicator: %02x\n", inw( ioaddr + MII_INDICATOR )); + + while( inw( ioaddr + MII_INDICATOR ) & MII_BUSY ) { + if ( timeout-- <= 0 ) { + printk( KERN_INFO "Timeout waiting to write to MII\n" ); + return; + } + udelay( 10 ); + } + + outw( (1<<8) + reg, ioaddr + MII_ADDRESS ); + outw( data, ioaddr + MII_WRITE_DATA ); + + return; +} + +#endif /* NCR885E_DEBUG_MII */ + +#ifdef MODULE +#if defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20118 +MODULE_AUTHOR("dan@synergymicro.com"); +MODULE_DESCRIPTION("Symbios 53C885 Ethernet driver"); +MODULE_PARM(debug, "i"); +#endif + +static int debug = 1; + +int +init_module(void) +{ + if ( debug >= 0) + ncr885e_debug = debug; + + return ncr885e_probe( NULL ); +} + +void +cleanup_module(void) +{ + struct ncr885e_private *np; + + if ( root_dev ) { + + unregister_netdev( root_dev ); + np = (struct ncr885e_private *) root_dev->priv; + release_region( root_dev->base_addr, NCR885E_TOTAL_SIZE ); + kfree( root_dev->priv ); + root_dev = NULL; + } +} +#endif /* MODULE */ + +/* + * Local variables: + * compile-command: "gcc -DMODULE -DMODVERSIONS -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O6 -c symba.c" + * End: + */ diff --git a/drivers/net/ncr885e.h b/drivers/net/ncr885e.h new file mode 100644 index 000000000..bbcc82e11 --- /dev/null +++ b/drivers/net/ncr885e.h @@ -0,0 +1,367 @@ +#ifndef _NET_H_SYMBA +#define _NET_H_SYMBA + +/* transmit status bit definitions */ +#define TX_STATUS_TXOK (1<<13) /* success */ +#define TX_STATUS_TDLC (1<<12) /* dropped for late colls */ +#define TX_STATUS_TCXSDFR (1<<11) /* excessive deferral */ +#define TX_STATUS_TDEC (1<<10) /* excessive collisions */ +#define TX_STATUS_TAUR (1<<9) /* abort on underrun/"jumbo" */ +#define TX_STATUS_PDFRD (1<<8) /* packet deferred */ +#define TX_STATUS_BCAST (1<<7) /* broadcast ok */ +#define TX_STATUS_MCAST (1<<6) /* multicast ok */ +#define TX_STATUS_CRCERR (1<<5) /* CRC error */ +#define TX_STATUS_LC (1<<4) /* late collision */ +#define TX_STATUS_CCNT_MASK 0xf /* collision count */ + +#define T_TXOK (1<<13) +#define T_TDLC (1<<12) +#define T_TCXSDFR (1<<11) +#define T_TDEC (1<<10) +#define T_TAUR (1<<9) +#define T_PDFRD (1<<8) +#define T_BCAST (1<<7) +#define T_MCAST (1<<6) +#define T_LC (1<<4) +#define T_CCNT_MASK 0xf + +/* receive status bit definitions */ +#define RX_STATUS_RXOVRN (1<<23) /* overrun */ +#define RX_STATUS_CEPS (1<<22) /* carrier event already seen */ +#define RX_STATUS_RXOK (1<<21) /* success */ +#define RX_STATUS_BCAST (1<<20) /* broadcast ok */ +#define RX_STATUS_MCAST (1<<19) /* multicast ok */ +#define RX_STATUS_CRCERR (1<<18) /* CRC error */ +#define RX_STATUS_DR (1<<17) /* dribble nibble */ +#define RX_STATUS_RCV (1<<16) /* rx code violation */ +#define RX_STATUS_PTL (1<<15) /* pkt > 1518 bytes */ +#define RX_STATUS_PTS (1<<14) /* pkt < 64 bytes */ +#define RX_STATUS_LEN_MASK 0x1fff /* length mask */ + +#define EEPROM_LENGTH 100 + + +/* Serial EEPROM interface */ +#define EE_STATUS 0xf0 +#define EE_CONTROL 0xf1 +#define EE_WORD_ADDR 0xf2 +#define EE_READ_DATA 0xf3 +#define EE_WRITE_DATA 0xf4 +#define EE_FEATURE_ENB 0xf5 + +/* Use on EE_STATUS */ +#define EE_SEB (1<<8) +#define EE_SEE 1 + +/* Serial EEPROM commands */ +#define EE_CONTROL_SEQ_READB (1<<4) +#define EE_CONTROL_RND_WRITEB (1<<5) +#define EE_CONTROL_RND_READB ((1<<4)|(1<<5)) + +/* Enable writing to serial EEPROM */ +#define EE_WRITE_ENB 1 + +/* The 885 configuration register */ +#define MAC_CONFIG 0xa0 +#define MAC_CONFIG_SRST 1<<15 +#define MAC_CONFIG_ITXA 1<<13 +#define MAC_CONFIG_RXEN 1<<12 +#define MAC_CONFIG_INTLB 1<<10 +#define MAC_CONFIG_MODE_MASK (1<<8|1<<9) +#define MAC_CONFIG_MODE_TP 1<<8 +#define MAC_CONFIG_HUGEN 1<<5 +#define MAC_CONFIG_RETRYL 1<<4 +#define MAC_CONFIG_CRCEN 1<<3 +#define MAC_CONFIG_PADEN 1<<2 +#define MAC_CONFIG_FULLD 1<<1 +#define MAC_CONFIG_NOCFR 1<<0 + + + + + +#define TX_WAIT_SELECT 0x18 +#define RX_CHANNEL_CONTROL 0x40 + +/* Tx channel status */ +#define TX_DBDMA_REG 0x00 +#define TX_CHANNEL_CONTROL 0x00 +#define TX_CHANNEL_STATUS 0x04 +#define TX_STATUS_RUN 1<<15 +#define TX_STATUS_PAUSE 1<<14 +#define TX_STATUS_WAKE 1<<12 +#define TX_STATUS_DEAD 1<<11 +#define TX_STATUS_ACTIVE 1<<10 +#define TX_STATUS_BT 1<<8 +#define TX_STATUS_TXABORT 1<<7 +#define TX_STATUS_TXSR 1<<6 + +#define TX_CHANNEL_RUN TX_STATUS_RUN +#define TX_CHANNEL_PAUSE TX_STATUS_PAUSE +#define TX_CHANNEL_WAKE TX_STATUS_WAKE +#define TX_CHANNEL_DEAD TX_STATUS_DEAD +#define TX_CHANNEL_ACTIVE TX_STATUS_ACTIVE +#define TX_CHANNEL_BT TX_STATUS_BT +#define TX_CHANNEL_TXABORT TX_STATUS_TXABORT +#define TX_CHANNEL_TXSR TX_STATUS_TXSR + +#define TX_DBDMA_ENABLE (TX_CHANNEL_WAKE | TX_CHANNEL_PAUSE | \ + TX_CHANNEL_RUN ) + +/* Transmit command ptr lo register */ +#define TX_CMD_PTR_LO 0x0c + +/* Transmit interrupt select register */ +#define TX_INT_SELECT 0x10 + +/* Transmit branch select register */ +#define TX_BRANCH_SELECT 0x14 + +/* Transmit wait select register */ +#define TX_WAIT_SELECT 0x18 +#define TX_WAIT_STAT_RECV 0x40 + +/* Rx channel status */ +#define RX_DBDMA_REG 0x40 +#define RX_CHANNEL_CONTROL 0x40 +#define RX_CHANNEL_STATUS 0x44 +#define RX_STATUS_RUN 1<<15 +#define RX_STATUS_PAUSE 1<<14 +#define RX_STATUS_WAKE 1<<12 +#define RX_STATUS_DEAD 1<<11 +#define RX_STATUS_ACTIVE 1<<10 +#define RX_STATUS_BT 1<<8 +#define RX_STATUS_EOP 1<<6 + +#define RX_CHANNEL_RUN RX_STATUS_RUN +#define RX_CHANNEL_PAUSE RX_STATUS_PAUSE +#define RX_CHANNEL_WAKE RX_STATUS_WAKE +#define RX_CHANNEL_DEAD RX_STATUS_DEAD +#define RX_CHANNEL_ACTIVE RX_STATUS_ACTIVE +#define RX_CHANNEL_BT RX_STATUS_BT +#define RX_CHANNEL_EOP RX_STATUS_EOP + +#define RX_DBDMA_ENABLE (RX_CHANNEL_WAKE | RX_CHANNEL_PAUSE | \ + RX_CHANNEL_RUN) + +/* Receive command ptr lo */ +#define RX_CMD_PTR_LO 0x4c + +/* Receive interrupt select register */ +#define RX_INT_SELECT 0x50 +#define RX_INT_SELECT_EOP 0x40 + +/* Receive branch select */ +#define RX_BRANCH_SELECT 0x54 +#define RX_BRANCH_SELECT_EOP 0x40 + +/* Receive wait select */ +#define RX_WAIT_SELECT 0x58 +#define RX_WAIT_SELECT_EOP 0x40 + +/* Event status register */ +#define EVENT_STATUS 0x80 +#define EVENT_TXSR 1<<2 +#define EVENT_EOP 1<<1 +#define EVENT_TXABORT 1<<0 + +/* Interrupt enable register */ +#define INTERRUPT_ENABLE 0x82 + +/* Interrupt clear register */ +#define INTERRUPT_CLEAR 0x84 + +/* Interrupt status register */ +#define INTERRUPT_STATUS_REG 0x86 + +/* bits for the above three interrupt registers */ +#define INTERRUPT_INTE 1<<15 /* interrupt enable */ +#define INTERRUPT_WI 1<<9 /* wakeup interrupt */ +#define INTERRUPT_ERI 1<<8 /* early recieve interrupt */ +#define INTERRUPT_PPET 1<<7 /* PCI Tx parity error */ +#define INTERRUPT_PBFT 1<<6 /* PCI Tx bus fault */ +#define INTERRUPT_IIDT 1<<5 /* illegal instruction Tx */ +#define INTERRUPT_DIT 1<<4 /* DBDMA Tx interrupt */ +#define INTERRUPT_PPER 1<<3 /* PCI Rx parity error */ +#define INTERRUPT_PBFR 1<<2 /* PCI Rx bus fault */ +#define INTERRUPT_IIDR 1<<1 /* illegal instruction Rx */ +#define INTERRUPT_DIR 1<<0 /* DBDMA Rx interrupt */ + +#define INTERRUPT_TX_MASK (INTERRUPT_PBFT|INTERRUPT_IIDT| \ + INTERRUPT_PPET|INTERRUPT_DIT) +#define INTERRUPT_RX_MASK (INTERRUPT_PBFR|INTERRUPT_IIDR| \ + INTERRUPT_PPER|INTERRUPT_DIR) + +/* chip revision register */ +#define CHIP_REVISION_REG 0x8c +#define CHIP_PCIREV_MASK (0xf<<16) +#define CHIP_PCIDEV_MASK 0xff + +/* Tx threshold register */ +#define TX_THRESHOLD 0x94 + +/* General purpose register */ +#define GEN_PURPOSE_REG 0x9e + +/* General purpose pin control reg */ +#define GEN_PIN_CONTROL_REG 0x9f + +/* DBDMA control register */ +#define DBDMA_CONTROL 0x90 +#define DBDMA_SRST 1<<31 +#define DBDMA_TDPCE 1<<23 +#define DBDMA_BE 1<<22 +#define DBDMA_TAP_MASK (1<<19|1<<20|1<<21) +#define DBDMA_RAP_MASK (1<<16|1<<17|1<<18) +#define DBDMA_DPMRLE 1<<15 +#define DBDMA_WIE 1<<14 +#define DBDMA_MP 1<<13 +#define DBDMA_SME 1<<12 +#define DBDMA_CME 1<<11 +#define DBDMA_DDPE 1<<10 +#define DBDMA_TDPE 1<<9 +#define DBDMA_EXTE 1<<8 +#define DBDMA_BST_MASK (1<<4|1<<5|1<<6) +#define DBDMA_BSR_MASK (1<<0|1<<1|1<<2) + +#define DBDMA_BURST_1 (0x00) +#define DBDMA_BURST_2 (0x01) +#define DBDMA_BURST_4 (0x02) +#define DBDMA_BURST_8 (0x03) +#define DBDMA_BURST_16 (0x04) +#define DBDMA_BURST_32 (0x05) +#define DBDMA_BURST_64 (0x06) +#define DBDMA_BURST_128 (0x07) + +#define DBDMA_TX_BST_SHIFT (4) +#define DBDMA_RX_BST_SHIFT (0) + +#define DBDMA_TX_ARBITRATION_DEFAULT ( 1 << 19 ) +#define DBDMA_RX_ARBITRATION_DEFAULT ( 2 << 16 ) + + +/* Back-to-back interpacket gap register */ +#define BTOB_INTP_GAP 0xa2 +#define BTOB_INTP_DEFAULT 0x18 + +/* Non-back-to-back interpacket gap register */ +#define NBTOB_INTP_GAP 0xa4 + +/* MIIM command register */ +#define MIIM_COMMAND 0xa6 +#define MIIM_SCAN 1<<1 +#define MIIM_RSTAT 1<<0 + +/* MII address register */ +#define MII_ADDRESS 0xa8 +#define MII_FIAD_MASK (1<<8|1<<9|1<<10|1<<11|1<<12) +#define MII_RGAD_MASK (1<<0|1<<1|1<<2|1<<3|1<<4) + +#define TPPMD_CONTROL_REG 0xa8 +#define TPPMD_FO 1<<1 +#define TPPMD_LB 1<<0 + +/* MII read and write registers */ +#define MII_WRITE_DATA 0xaa +#define MII_READ_DATA 0xac + +/* MII indicators */ +#define MII_INDICATOR 0xae +#define MII_NVALID 1<<2 +#define MII_SCAN 1<<1 +#define MII_BUSY 1<<0 + +/* Address filter */ +#define ADDRESS_FILTER 0xd0 +#define ADDRESS_RPPRM 1<<3 /* multicast promis. mode */ +#define ADDRESS_RPPRO 1<<2 /* promiscuous mode */ +#define ADDRESS_RPAMC 1<<1 /* accept multicasts */ +#define ADDRESS_RPABC 1<<0 /* accept broadcasts */ + +/* Station addresses + + Note that if the serial EEPROM is disabled, these values are all + zero. If, like us, you get the chips when they're fresh, they're + also zero and you have to initialize the address */ +#define STATION_ADDRESS_0 0xd2 +#define STATION_ADDRESS_1 0xd4 +#define STATION_ADDRESS_2 0xd6 + +/* Hash tables */ +#define HASH_TABLE_0 0xd8 +#define HASH_TABLE_1 0xda +#define HASH_TABLE_2 0xdc +#define HASH_TABLE_3 0xde + +/* PHY indentifiers */ +#define PHY_IDENTIFIER_0 0xe4 +#define PHY_IDENTIFIER_1 0xe6 + +/* MII Auto-negotiation register definitions */ + +#define MII_AUTO_NEGOTIATION_CONTROL (0x0000) +#define MANC_PHY_RESET (0x8000) +#define MANC_PHY_LOOPBACK_ENABLE (0x4000) +#define MANC_PHY_LOOPBACK_DISABLE (0x0000) +#define MANC_PHY_SPEED_100 (0x2000) +#define MANC_PHY_SPEED_10 (0x0000) +#define MANC_AUTO_NEGOTIATION_ENABLE (0x1000) +#define MANC_AUTO_NEGOTIATION_DISABLE (0x0000) +#define MANC_PHY_POWER_DOWN (0x0800) +#define MANC_PHY_POWER_UP (0x0000) +#define MANC_ISOLATE_ENABLE (0x0400) +#define MANC_ISOLATE_DISABLE (0x0000) +#define MANC_RESTART_AUTO_NEGOTIATION (0x0200) +#define MANC_FULL_DUPLEX (0x0100) +#define MANC_HALF_DUPLEX (0x0000) + +#define MII_AUTO_NEGOTIATION_STATUS (0x0001) +#define MANS_100BASE_T4_HALF_DUPLEX (0x8000) +#define MANS_100BASE_X_FULL_DUPLEX (0x4000) +#define MANS_100BASE_X_HALF_DUPLEX (0x2000) +#define MANS_10MBS_FULL_DUPLEX (0x1000) +#define MANS_10MBS_HALF_DUPLEX (0x0800) +#define MANS_AUTO_NEGOTIATION_COMPLETE (0x0020) +#define MANS_REMOTE_FAULT (0x0010) +#define MANS_AUTO_NEGOTIATION_ABILITY (0x0008) +#define MANS_LINK_STATUS (0x0004) +#define MANS_JABBER_DETECT (0x0002) +#define MANS_EXTENDED_CAPABILITY (0x0001) + +#define MII_PHY_IDENTIFIER_1 (0x0002) +#define MII_PHY_IDENTIFIER_2 (0x0003) + +#define MII_AUTO_NEGOTIATION_ADVERTISEMENT (0x0004) +#define MANA_NEXT_PAGE (0x8000) +#define MANA_REMOTE_FAULT (0x2000) +#define MANA_TECHNOLOGY_ABILITY_MASK (0x1FE0) +#define MANATECH_10BASET_HALF_DUPLEX (0x0020) +#define MANATECH_10BASET_FULL_DUPLEX (0x0040) +#define MANATECH_100BASETX_HALF_DUPLEX (0x0080) +#define MANATECH_100BASETX_FULL_DUPLEX (0x0100) +#define MANATECH_100BASET4 (0x0200) +#define MANA_SELECTOR_MASK (0x001F) +#define MANASELECTOR_802_3 (0x0001) + +#define MII_AUTO_NEGOTIATION_LINK_PARTNER (0x0005) +#define MANLP_NEXT_PAGE (0x8000) +#define MANLP_ACKNOWLEDGE (0x4000) +#define MANLP_REMOTE_FAULT (0x2000) +#define MANLP_TECHNOLOGY_ABILITY_MASK (0x1FE0) +#define MANLP_SELECTOR_MASK (0x001F) + +#define MII_AUTO_NEGOTIATION_EXPANSION (0x0006) +#define MANE_PARALLEL_DETECTION_FAULT (0x0010) +#define MANE_LINK_PARTNER_NEXT_PAGE_ABLE (0x0008) +#define MANE_NEXT_PAGE_ABLE (0x0004) +#define MANE_PAGE_RECEIVED (0x0002) +#define MANE_LINK_PARTNER_AUTO_ABLE (0x0001) + +#define MII_AUTO_NEGOTIATION_NEXT_PAGE_TRANSMIT (0x0007) +#define MANNPT_NEXT_PAGE (0x8000) +#define MANNPT_MESSAGE_PAGE (0x2000) +#define MANNPT_ACKNOWLEDGE_2 (0x1000) +#define MANNPT_TOGGLE (0x0800) +#define MANNPT_MESSAGE_FIELD_MASK (0x07FF) + +#endif diff --git a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c index 8af63739c..81bba9e60 100644 --- a/drivers/net/pcmcia/ray_cs.c +++ b/drivers/net/pcmcia/ray_cs.c @@ -57,21 +57,17 @@ left out. If you compile with PCMCIA_DEBUG=0, the debug code will be present but disabled -- but it can then be enabled for specific modules at load time with a 'pc_debug=#' option to insmod. - - I found that adding -DPCMCIA_DEBUG to the compile options during - the 'make config' resulted in cardmgr not finding any sockets. - Therefore, this module uses RAYLINK_DEBUG instead. - The module option to use is ray_debug=# - where # is 1 for modest output - 2 for more output - ... */ #ifdef RAYLINK_DEBUG -static int ray_debug = RAYLINK_DEBUG; -MODULE_PARM(ray_debug, "i"); -/* #define DEBUG(n, args...) if (ray_debug>(n)) printk(KERN_DEBUG args); */ -#define DEBUG(n, args...) if (ray_debug>(n)) printk(args); +#define PCMCIA_DEBUG RAYLINK_DEBUG +#endif +#ifdef PCMCIA_DEBUG +static int ray_debug = 0; +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */ +#define DEBUG(n, args...) if (pc_debug>(n)) printk(args); #else #define DEBUG(n, args...) #endif @@ -137,7 +133,6 @@ void start_net(u_long local); /* void start_net(ray_dev_t *local); */ int ray_cs_proc_read(char *buf, char **start, off_t off, int len, int spare); - /* Create symbol table for registering with kernel in init_module */ EXPORT_SYMBOL(ray_dev_ioctl); EXPORT_SYMBOL(ray_rx); @@ -147,40 +142,30 @@ EXPORT_SYMBOL(ray_rx); /* Bit map of interrupts to choose from */ /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ static u_long irq_mask = 0xdeb8; -MODULE_PARM(irq_mask,"i"); /* ADHOC=0, Infrastructure=1 */ static int net_type = ADHOC; -MODULE_PARM(net_type,"i"); /* Hop dwell time in Kus (1024 us units defined by 802.11) */ static int hop_dwell = 128; -MODULE_PARM(hop_dwell,"i"); /* Beacon period in Kus */ static int beacon_period = 256; -MODULE_PARM(beacon_period,"i"); /* power save mode (0 = off, 1 = save power) */ static int psm = 0; -MODULE_PARM(psm,"i"); /* String for network's Extended Service Set ID. 32 Characters max */ static char *essid = NULL; -MODULE_PARM(essid,"s"); /* Default to encapsulation unless translation requested */ static int translate = 1; -MODULE_PARM(translate,"i"); static int country = USA; -MODULE_PARM(country,"i"); static int sniffer = 0; -MODULE_PARM(sniffer,"i"); static int bc = 0; -MODULE_PARM(bc,"i"); /* 48 bit physical card address if overriding card's real physical * address is required. Since IEEE 802.11 addresses are 48 bits @@ -193,7 +178,6 @@ MODULE_PARM(bc,"i"); * things will happen if it is not 0 in a card address. */ static char *phy_addr = NULL; -MODULE_PARM(phy_addr,"s"); /* The dev_info variable is the "key" that is used to match up this @@ -214,7 +198,22 @@ static dev_link_t *dev_list = NULL; 'priv' pointer in a dev_link_t structure can be used to point to a device-specific private data structure, like this. */ -static const unsigned int ray_mem_speed = 0x2A; +static unsigned int ray_mem_speed = 0x2A; + +MODULE_AUTHOR("Corey Thomas <corey@world.std.com>"); +MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); +MODULE_PARM(irq_mask,"i"); +MODULE_PARM(net_type,"i"); +MODULE_PARM(hop_dwell,"i"); +MODULE_PARM(beacon_period,"i"); +MODULE_PARM(psm,"i"); +MODULE_PARM(essid,"s"); +MODULE_PARM(translate,"i"); +MODULE_PARM(country,"i"); +MODULE_PARM(sniffer,"i"); +MODULE_PARM(bc,"i"); +MODULE_PARM(phy_addr,"s"); +MODULE_PARM(ray_mem_speed, "i"); static UCHAR b5_default_startup_parms[] = { 0, 0, /* Adhoc station */ @@ -284,7 +283,7 @@ static UCHAR b4_default_startup_parms[] = { /*===========================================================================*/ static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0}; -static char rcsid[] = " $Id: ray_cs.c,v 1.60 1999/09/01 20:58:45 corey Exp $ - Corey Thomas corey@world.std.com"; +static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>"; #ifdef CONFIG_PROC_FS struct proc_dir_entry ray_cs_proc_entry = { @@ -358,7 +357,7 @@ dev_link_t *ray_attach(void) local->finder = link; link->dev = &local->node; local->card_status = CARD_INSERTED; - local->authentication_state = UNAUTHENTICATED; + local->authentication_state = UNAUTHENTICATED; local->num_multi = 0; DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n", link,dev,local,&ray_interrupt); @@ -442,8 +441,6 @@ void ray_detach(dev_link_t *link) if (link->state & DEV_CONFIG) { ray_release((u_long)link); if(link->state & DEV_STALE_CONFIG) { - DEBUG(0,"ray_cs: detach postponed, '%s' " - "still locked\n", link->dev->dev_name); link->state |= DEV_STALE_LINK; return; } @@ -472,7 +469,7 @@ void ray_detach(dev_link_t *link) =============================================================================*/ #define CS_CHECK(fn, args...) \ while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed -#define MAX_TUPLE_SIZE 80 +#define MAX_TUPLE_SIZE 128 void ray_config(dev_link_t *link) { client_handle_t handle = link->handle; @@ -480,7 +477,7 @@ void ray_config(dev_link_t *link) cisparse_t parse; int last_fn, last_ret; int i; - u_char buf[80]; + u_char buf[MAX_TUPLE_SIZE]; win_req_t req; memreq_t mem; struct net_device *dev = (struct net_device *)link->priv; @@ -499,6 +496,19 @@ void ray_config(dev_link_t *link) link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; + /* Determine card type and firmware version */ + buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0; + tuple.DesiredTuple = CISTPL_VERS_1; + CS_CHECK(GetFirstTuple, handle, &tuple); + tuple.TupleData = buf; + tuple.TupleDataMax = MAX_TUPLE_SIZE; + tuple.TupleOffset = 2; + CS_CHECK(GetTupleData, handle, &tuple); + + for (i=0; i<tuple.TupleDataLen - 4; i++) + if (buf[i] == 0) buf[i] = ' '; + printk(KERN_INFO "ray_cs Detected: %s\n",buf); + /* Configure card */ link->state |= DEV_CONFIG; @@ -562,7 +572,10 @@ void ray_config(dev_link_t *link) } link->state &= ~DEV_CONFIG_PENDING; - DEBUG(0, "ray_cs device loaded\n"); + printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ", + dev->name, dev->irq); + for (i = 0; i < 6; i++) + printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); return; @@ -594,7 +607,8 @@ int ray_init(struct net_device *dev) /* Check Power up test status and get mac address from card */ if (local->startup_res.startup_word != 0x80) { -DEBUG(0,"ray_init ERROR card status = %2x\n", local->startup_res.startup_word); + printk(KERN_INFO "ray_init ERROR card status = %2x\n", + local->startup_res.startup_word); local->card_status = CARD_INIT_ERROR; return -1; } @@ -619,16 +633,12 @@ DEBUG(0,"ray_init ERROR card status = %2x\n", local->startup_res.startup_word); if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr)) { p = local->sparm.b4.a_mac_addr; - DEBUG(1,"ray_cs phy address overridden = %2x %2x %2x %2x %2x %2x\n",\ - p[0],p[1],p[2],p[3],p[4],p[5]); } else { memcpy(&local->sparm.b4.a_mac_addr, &local->startup_res.station_addr, ADDRLEN); p = local->sparm.b4.a_mac_addr; - DEBUG(1,"ray_cs phy addr= %2x %2x %2x %2x %2x %2x\n",\ - p[0],p[1],p[2],p[3],p[4],p[5]); } clear_interrupt(local); /* Clear any interrupt from the card */ @@ -647,7 +657,7 @@ int dl_startup_params(struct net_device *dev) DEBUG(1,"dl_startup_params entered\n"); if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs dl_startup_params - device not present\n"); + DEBUG(2,"ray_cs dl_startup_params - device not present\n"); return -1; } @@ -661,14 +671,15 @@ int dl_startup_params(struct net_device *dev) /* Fill in the CCS fields for the ECF */ - if ((ccsindex = get_free_ccs(local)) == -1) return -1; + if ((ccsindex = get_free_ccs(local)) < 0) return -1; local->dl_param_ccs = ccsindex; pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd); DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs); /* Interrupt the firmware to process the command */ if (interrupt_ecf(local, ccsindex)) { - DEBUG(0,"ray dl_startup_params failed - ECF not ready for intr\n"); + printk(KERN_INFO "ray dl_startup_params failed - " + "ECF not ready for intr\n"); local->card_status = CARD_DL_PARAM_ERROR; writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status); return -2; @@ -723,11 +734,11 @@ void init_startup_params(ray_dev_t *local) local->sparm.b4.a_curr_country_code = country; local->sparm.b4.a_hop_pattern_length = hop_pattern_length[(int)country] - 1; - if (bc) - { - local->sparm.b4.a_ack_timeout = 0x50; - local->sparm.b4.a_sifs = 0x3f; - } + if (bc) + { + local->sparm.b4.a_ack_timeout = 0x50; + local->sparm.b4.a_sifs = 0x3f; + } } else { /* Version 5 uses real kus values */ memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms, @@ -756,30 +767,29 @@ void verify_dl_startup(u_long data) ray_dev_t *local = (ray_dev_t *)data; struct ccs *pccs = ((struct ccs *)(local->sram + CCS_BASE)) + local->dl_param_ccs; UCHAR status; -/* UCHAR *p = local->sram + HOST_TO_ECF_BASE; */ dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs verify_dl_startup - device not present\n"); + DEBUG(2,"ray_cs verify_dl_startup - device not present\n"); return; } -#ifdef RAYLINK_DEBUG - { - int i; - DEBUG(2,"verify_dl_startup parameters sent via ccs %d:\n",\ - local->dl_param_ccs); - for (i=0; i<sizeof(struct b5_startup_params); i++) - { - DEBUG(1," %2x ", readb(local->sram + HOST_TO_ECF_BASE + i)); +#ifdef PCMCIA_DEBUG + if (pc_debug > 2) { + int i; + printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n", + local->dl_param_ccs); + for (i=0; i<sizeof(struct b5_startup_params); i++) { + printk(" %2x", readb(local->sram + HOST_TO_ECF_BASE + i)); } - DEBUG(1,"\n"); + printk("\n"); } #endif status = readb(&pccs->buffer_status); if (status!= CCS_BUFFER_FREE) { - DEBUG(0,"Download startup params failed. Status = %d\n",status); + printk(KERN_INFO "Download startup params failed. Status = %d\n", + status); local->card_status = CARD_DL_PARAM_ERROR; return; } @@ -799,11 +809,11 @@ void start_net(u_long data) int ccsindex; dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs start_net - device not present\n"); + DEBUG(2,"ray_cs start_net - device not present\n"); return; } /* Fill in the CCS fields for the ECF */ - if ((ccsindex = get_free_ccs(local)) == -1) return; + if ((ccsindex = get_free_ccs(local)) < 0) return; pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; writeb(CCS_START_NETWORK, &pccs->cmd); writeb(0, &pccs->var.start_network.update_param); @@ -827,11 +837,11 @@ void join_net(u_long data) dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs join_net - device not present\n"); + DEBUG(2,"ray_cs join_net - device not present\n"); return; } /* Fill in the CCS fields for the ECF */ - if ((ccsindex = get_free_ccs(local)) == -1) return; + if ((ccsindex = get_free_ccs(local)) < 0) return; pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex; writeb(CCS_JOIN_NETWORK, &pccs->cmd); writeb(0, &pccs->var.join_network.update_param); @@ -867,7 +877,7 @@ void ray_release(u_long arg) link->state |= DEV_STALE_CONFIG; return; } - del_timer(&local->timer); + del_timer(&local->timer); if (link->dev != '\0') unregister_netdev(dev); /* Unlink the device chain */ link->dev = NULL; @@ -962,13 +972,14 @@ int ray_dev_init(struct net_device *dev) DEBUG(1,"ray_dev_init(dev=%p)\n",dev); if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_dev_init - device not present\n"); + DEBUG(2,"ray_dev_init - device not present\n"); return -1; } /* Download startup parameters */ if ( (i = dl_startup_params(dev)) < 0) { - DEBUG(0,"ray_dev_init dl_startup_params failed - returns 0x%x/n",i); + printk(KERN_INFO "ray_dev_init dl_startup_params failed - " + "returns 0x%x/n",i); return -1; } @@ -976,15 +987,6 @@ int ray_dev_init(struct net_device *dev) memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN); memset(dev->broadcast, 0xff, ETH_ALEN); -#ifdef RAYLINK_DEBUG - { - UCHAR *p; - p = (UCHAR *)(local->startup_res.station_addr); - DEBUG(1,"ray_dev_init card hardware mac addr = %2x %2x %2x %2x %2x %2x\n",\ - p[0],p[1],p[2],p[3],p[4],p[5]); - } -#endif - DEBUG(2,"ray_dev_init ending\n"); return 0; } @@ -996,7 +998,7 @@ int ray_dev_config(struct net_device *dev, struct ifmap *map) /* Dummy routine to satisfy device structure */ DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map); if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_dev_config - device not present\n"); + DEBUG(2,"ray_dev_config - device not present\n"); return -1; } @@ -1010,13 +1012,13 @@ int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) short length; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_dev_start_xmit - device not present\n"); + DEBUG(2,"ray_dev_start_xmit - device not present\n"); return -1; } DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev); if (dev->tbusy) { - DEBUG(2,"ray_dev_start_xmit busy\n"); + printk(KERN_NOTICE "ray_dev_start_xmit busy\n"); return 1; } if (local->authentication_state == NEED_TO_AUTH) { @@ -1031,7 +1033,7 @@ int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) { case XMIT_NO_CCS: - case XMIT_NEED_AUTH: + case XMIT_NEED_AUTH: dev->tbusy = 1; return 1; case XMIT_NO_INTR: @@ -1058,15 +1060,20 @@ int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev); if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) { - DEBUG(0,"ray_hw_xmit packet to large %d bytes\n",len); + printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",len); return XMIT_MSG_BAD; } - if ((ccsindex = get_free_tx_ccs(local)) == -1) - { - DEBUG(2,"ray_hw_xmit - No free tx ccs\n"); + switch (ccsindex = get_free_tx_ccs(local)) { + case ECCSBUSY: + DEBUG(2,"ray_hw_xmit tx_ccs table busy\n"); + case ECCSFULL: + DEBUG(2,"ray_hw_xmit No free tx ccs\n"); + case ECARDGONE: dev->tbusy = 1; return XMIT_NO_CCS; - } + default: + break; + } addr = TX_BUF_BASE + (ccsindex << 11); if (msg_type == DATA_TYPE) { @@ -1186,7 +1193,7 @@ int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) int err = 0; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_dev_ioctl - device not present\n"); + DEBUG(2,"ray_dev_ioctl - device not present\n"); return -1; } DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd); @@ -1258,16 +1265,14 @@ void ray_reset(struct net_device *dev) { int interrupt_ecf(ray_dev_t *local, int ccs) { int i = 50; -/* UCHAR *p = (local->amem + CIS_OFFSET + ECF_INTR_OFFSET); */ dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs interrupt_ecf - device not present\n"); + DEBUG(2,"ray_cs interrupt_ecf - device not present\n"); return -1; } DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs); -/* while ( i && (*p & ECF_INTR_SET)) i--; */ while ( i && (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET)) i--; @@ -1275,8 +1280,8 @@ int interrupt_ecf(ray_dev_t *local, int ccs) DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n"); return -1; } - - *(local->sram + SCB_BASE) = ccs; + /* Fill the mailbox, then kick the card */ + writeb(ccs, local->sram + SCB_BASE); writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET); return 0; } /* interrupt_ecf */ @@ -1290,19 +1295,26 @@ int get_free_tx_ccs(ray_dev_t *local) dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs get_free_tx_ccs - device not present\n"); - return -1; + DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n"); + return ECARDGONE; } + if (test_and_set_bit(0,&local->tx_ccs_lock)) { + DEBUG(1,"ray_cs tx_ccs_lock busy\n"); + return ECCSBUSY; + } + for (i=0; i < NUMBER_OF_TX_CCS; i++) { if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) { writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status); writeb(CCS_END_LIST, &(pccs+i)->link); + local->tx_ccs_lock = 0; return i; } } - DEBUG(1,"ray_cs ERROR no free tx CCS for raylink card\n"); - return -1; + local->tx_ccs_lock = 0; + DEBUG(2,"ray_cs ERROR no free tx CCS for raylink card\n"); + return ECCSFULL; } /* get_free_tx_ccs */ /*===========================================================================*/ /* Get next free CCS */ @@ -1314,25 +1326,33 @@ int get_free_ccs(ray_dev_t *local) dev_link_t *link = local->finder; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs get_free_ccs - device not present\n"); - return -1; + DEBUG(2,"ray_cs get_free_ccs - device not present\n"); + return ECARDGONE; } + if (test_and_set_bit(0,&local->ccs_lock)) { + DEBUG(1,"ray_cs ccs_lock busy\n"); + return ECCSBUSY; + } + for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) { if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) { writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status); writeb(CCS_END_LIST, &(pccs+i)->link); + local->ccs_lock = 0; return i; } } + local->ccs_lock = 0; DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n"); - return -1; + return ECCSFULL; } /* get_free_ccs */ /*===========================================================================*/ void authenticate_timeout(u_long data) { ray_dev_t *local = (ray_dev_t *)data; del_timer(&local->timer); - DEBUG(0,"ray_cs Authentication with access point failed - timeout\n"); + printk(KERN_INFO "ray_cs Authentication with access point failed" + " - timeout\n"); join_net((u_long)local); } /*===========================================================================*/ @@ -1381,26 +1401,26 @@ struct enet_statistics *ray_get_stats(struct net_device *dev) dev_link_t *link = local->finder; struct status *p = (struct status *)(local->sram + STATUS_BASE); if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_cs enet_statistics - device not present\n"); + DEBUG(2,"ray_cs enet_statistics - device not present\n"); return &local->stats; } - if (p->mrx_overflow_for_host) + if (readb(&p->mrx_overflow_for_host)) { - local->stats.rx_over_errors += ntohs(p->mrx_overflow); - p->mrx_overflow = 0; - p->mrx_overflow_for_host = 0; + local->stats.rx_over_errors += ntohs(readb(&p->mrx_overflow)); + writeb(0,&p->mrx_overflow); + writeb(0,&p->mrx_overflow_for_host); } - if (p->mrx_checksum_error_for_host) + if (readb(&p->mrx_checksum_error_for_host)) { - local->stats.rx_crc_errors += ntohs(p->mrx_checksum_error); - p->mrx_checksum_error = 0; - p->mrx_checksum_error_for_host = 0; + local->stats.rx_crc_errors += ntohs(readb(&p->mrx_checksum_error)); + writeb(0,&p->mrx_checksum_error); + writeb(0,&p->mrx_checksum_error_for_host); } - if (p->rx_hec_error_for_host) + if (readb(&p->rx_hec_error_for_host)) { - local->stats.rx_frame_errors += ntohs(p->rx_hec_error); - p->rx_hec_error = 0; - p->rx_hec_error_for_host = 0; + local->stats.rx_frame_errors += ntohs(readb(&p->rx_hec_error)); + writeb(0,&p->rx_hec_error); + writeb(0,&p->rx_hec_error_for_host); } return &local->stats; } @@ -1414,11 +1434,11 @@ void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len) struct ccs *pccs; if (!(link->state & DEV_PRESENT)) { - DEBUG(0,"ray_update_parm - device not present\n"); + DEBUG(2,"ray_update_parm - device not present\n"); return; } - if ((ccsindex = get_free_ccs(local)) == -1) + if ((ccsindex = get_free_ccs(local)) < 0) { DEBUG(0,"ray_update_parm - No free ccs\n"); return; @@ -1449,12 +1469,12 @@ static void ray_update_multi_list(struct net_device *dev, int all) UCHAR *p = local->sram + HOST_TO_ECF_BASE; if (!(link->state & DEV_PRESENT)) { - DEBUG(1,"ray_update_multi_list - device not present\n"); + DEBUG(2,"ray_update_multi_list - device not present\n"); return; } else - DEBUG(1,"ray_update_multi_list(%p)\n",dev); - if ((ccsindex = get_free_ccs(local)) == -1) + DEBUG(2,"ray_update_multi_list(%p)\n",dev); + if ((ccsindex = get_free_ccs(local)) < 0) { DEBUG(1,"ray_update_multi - No free ccs\n"); return; @@ -1491,7 +1511,7 @@ static void set_multicast_list(struct net_device *dev) ray_dev_t *local = (ray_dev_t *)dev->priv; UCHAR promisc; - DEBUG(1,"ray_cs set_multicast_list(%p)\n",dev); + DEBUG(2,"ray_cs set_multicast_list(%p)\n",dev); if (dev->flags & IFF_PROMISC) { @@ -1534,30 +1554,23 @@ void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) UCHAR cmd; UCHAR status; - if (dev == NULL) { - link = dev_list; - dev = (struct net_device *)link->priv; - DEBUG(4,"ray_cs interrupt dev = %p, link = %p\n",dev,link); - if (dev->irq != irq) - { - DEBUG(0,"ray_cs interrupt irq %d for unknown device.\n", irq); - return; - } - } + if ((dev == NULL) || !dev->start) + return; + DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev); - if (dev->interrupt) { + if (test_and_set_bit(0,&dev->interrupt)) { printk("ray_cs Reentering interrupt handler not allowed\n"); return; } - dev->interrupt = 1; + local = (ray_dev_t *)dev->priv; link = (dev_link_t *)local->finder; if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) { - DEBUG(1,"ray_cs interrupt from device not present or suspended.\n"); + DEBUG(2,"ray_cs interrupt from device not present or suspended.\n"); return; } - rcsindex = ((struct scb *)(local->sram))->rcs_index; + rcsindex = readb(&((struct scb *)(local->sram))->rcs_index); if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) { @@ -1602,7 +1615,7 @@ void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) case CCS_JOIN_NETWORK: if (status == CCS_COMMAND_COMPLETE) { if (readb(&pccs->var.start_network.net_initiated) == 1) { - DEBUG(0,"ray_cs interrupt network \"%s\"started\n",\ + DEBUG(0,"ray_cs interrupt network \"%s\" started\n",\ local->sparm.b4.a_current_ess_id); } else { @@ -1741,16 +1754,16 @@ void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) switch(readb(pmsg)) { case DATA_TYPE: - DEBUG(4,"ray_rx data type\n"); + DEBUG(4,"ray_rx data type\n"); rx_data(dev, prcs, pkt_addr, rx_len); break; case AUTHENTIC_TYPE: - DEBUG(4,"ray_rx authentic type\n"); + DEBUG(4,"ray_rx authentic type\n"); if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); else rx_authenticate(local, prcs, pkt_addr, rx_len); break; case DEAUTHENTIC_TYPE: - DEBUG(4,"ray_rx deauth type\n"); + DEBUG(4,"ray_rx deauth type\n"); if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); else rx_deauthenticate(local, prcs, pkt_addr, rx_len); break; @@ -1758,7 +1771,7 @@ void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) DEBUG(3,"ray_cs rx NULL msg\n"); break; case BEACON_TYPE: - DEBUG(4,"ray_rx beacon type\n"); + DEBUG(4,"ray_rx beacon type\n"); if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len); copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr, @@ -1909,19 +1922,24 @@ void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) struct ethhdr *peth; UCHAR srcaddr[ADDRLEN]; UCHAR destaddr[ADDRLEN]; - int i; - if (local->sparm.b5.a_acting_as_ap_status != TYPE_STA) + if (local->sparm.b5.a_acting_as_ap_status != TYPE_STA) memcpy(destaddr, pmac->addr_3, ADDRLEN); else memcpy(destaddr, pmac->addr_1, ADDRLEN); memcpy(srcaddr, pmac->addr_2, ADDRLEN); - DEBUG(3,"skb->data before untranslate"); +#ifdef PCMCIA_DEBUG + if (pc_debug > 3) { + int i; + printk(KERN_DEBUG "skb->data before untranslate"); for (i=0;i<64;i++) - DEBUG(3,"%02x ",skb->data[i]); - DEBUG(3,"\ntype = %08x, xsap = %08x, org = %08x\n",type,xsap,org); - DEBUG(3,"untranslate skb->data = %p\n",skb->data); + printk("%02x ",skb->data[i]); + printk("\n" KERN_DEBUG "type = %08x, xsap = %08x, org = %08x\n", + type,xsap,org); + printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data); + } +#endif if ( xsap != SNAP_ID) { /* not a snap type so leave it alone */ @@ -1971,10 +1989,15 @@ void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data); memcpy(peth->h_dest, destaddr, ADDRLEN); memcpy(peth->h_source, srcaddr, ADDRLEN); - DEBUG(3,"skb->data after untranslate:"); - for (i=0;i<64;i++) - DEBUG(3,"%02x ",skb->data[i]); - DEBUG(3,"\n"); +#ifdef PCMCIA_DEBUG + if (pc_debug > 3) { + int i; + printk(KERN_DEBUG "skb->data after untranslate:"); + for (i=0;i<64;i++) + printk("%02x ",skb->data[i]); + printk("\n"); + } +#endif } /* end untranslate */ /*===========================================================================*/ /* Copy data from circular receive buffer to PC memory. @@ -2020,7 +2043,7 @@ void authenticate(ray_dev_t *local) dev_link_t *link = local->finder; DEBUG(0,"ray_cs Starting authentication.\n"); if (!(link->state & DEV_PRESENT)) { - DEBUG(1,"ray_cs authenticate - device not present\n"); + DEBUG(2,"ray_cs authenticate - device not present\n"); return; } @@ -2046,37 +2069,37 @@ void rx_authenticate(ray_dev_t *local, struct rcs *prcs, del_timer(&local->timer); copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff); - /* if we are trying to get authenticated */ + /* if we are trying to get authenticated */ if (local->sparm.b4.a_network_type == ADHOC) { - DEBUG(1,"ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0],msg->var[1],msg->var[2],msg->var[3],msg->var[4],msg->var[5]); - if (msg->var[2] == 1) { + DEBUG(1,"ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0],msg->var[1],msg->var[2],msg->var[3],msg->var[4],msg->var[5]); + if (msg->var[2] == 1) { DEBUG(0,"ray_cs Sending authentication response.\n"); if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) { local->authentication_state = NEED_TO_AUTH; memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN); } - } - } - else /* Infrastructure network */ - { - if (local->authentication_state == AWAITING_RESPONSE) { - /* Verify authentication sequence #2 and success */ - if (msg->var[2] == 2) { - if ((msg->var[3] | msg->var[4]) == 0) { - DEBUG(1,"Authentication successful\n"); - local->card_status = CARD_AUTH_COMPLETE; - associate(local); - local->authentication_state = AUTHENTICATED; - } - else { - DEBUG(0,"Authentication refused\n"); - local->card_status = CARD_AUTH_REFUSED; - join_net((u_long)local); - local->authentication_state = UNAUTHENTICATED; - } - } - } - } + } + } + else /* Infrastructure network */ + { + if (local->authentication_state == AWAITING_RESPONSE) { + /* Verify authentication sequence #2 and success */ + if (msg->var[2] == 2) { + if ((msg->var[3] | msg->var[4]) == 0) { + DEBUG(1,"Authentication successful\n"); + local->card_status = CARD_AUTH_COMPLETE; + associate(local); + local->authentication_state = AUTHENTICATED; + } + else { + DEBUG(0,"Authentication refused\n"); + local->card_status = CARD_AUTH_REFUSED; + join_net((u_long)local); + local->authentication_state = UNAUTHENTICATED; + } + } + } + } } /* end rx_authenticate */ /*===========================================================================*/ @@ -2087,11 +2110,11 @@ void associate(ray_dev_t *local) struct net_device *dev = link->priv; int ccsindex; if (!(link->state & DEV_PRESENT)) { - DEBUG(1,"ray_cs associate - device not present\n"); + DEBUG(2,"ray_cs associate - device not present\n"); return; } /* If no tx buffers available, return*/ - if ((ccsindex = get_free_ccs(local)) == -1) + if ((ccsindex = get_free_ccs(local)) < 0) { /* TBD should never be here but... what if we are? */ DEBUG(1,"ray_cs associate - No free ccs\n"); @@ -2125,7 +2148,7 @@ void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, struct rx_msg *msg = (struct rx_msg *)buff; */ DEBUG(0,"Deauthentication frame received\n"); - local->authentication_state = UNAUTHENTICATED; + local->authentication_state = UNAUTHENTICATED; /* Need to reauthenticate or rejoin depending on reason code */ /* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff); */ @@ -2256,9 +2279,8 @@ int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) int ccsindex; /* If no tx buffers available, return */ - if ((ccsindex = get_free_tx_ccs(local)) == -1) + if ((ccsindex = get_free_tx_ccs(local)) < 0) { -/* TBD should never be here but... what if we are? */ DEBUG(1,"ray_cs send authenticate - No free tx ccs\n"); return -1; } diff --git a/drivers/net/pcmcia/ray_cs.h b/drivers/net/pcmcia/ray_cs.h index 28502954e..ae28bc71a 100644 --- a/drivers/net/pcmcia/ray_cs.h +++ b/drivers/net/pcmcia/ray_cs.h @@ -17,9 +17,14 @@ struct beacon_rx { + sizeof(struct tim_element)]; }; +/* Return values for get_free{,_tx}_ccs */ +#define ECCSFULL (-1) +#define ECCSBUSY (-2) +#define ECARDGONE (-3) + typedef struct ray_dev_t { int card_status; - int authentication_state; + int authentication_state; dev_node_t node; window_handle_t amem_handle; /* handle to window for attribute memory */ window_handle_t rmem_handle; /* handle to window for rx buffer on card */ @@ -28,6 +33,8 @@ typedef struct ray_dev_t { UCHAR *rmem; /* pointer to receive buffer window */ dev_link_t *finder; /* pointer back to dev_link_t for card */ struct timer_list timer; + int tx_ccs_lock; + int ccs_lock; int dl_param_ccs; union { struct b4_startup_params b4; diff --git a/drivers/net/pcmcia/rayctl.h b/drivers/net/pcmcia/rayctl.h index a301b0bd2..49d9b267b 100644 --- a/drivers/net/pcmcia/rayctl.h +++ b/drivers/net/pcmcia/rayctl.h @@ -142,8 +142,6 @@ struct adhoc_beacon }; /*****************************************************************************/ /*****************************************************************************/ - - /* #define C_MAC_HDR_2_WEP 0x40 */ /* TX/RX CCS constants */ #define TX_HEADER_LENGTH 0x1C @@ -151,6 +149,9 @@ struct adhoc_beacon #define TX_AUTHENTICATE_LENGTH (TX_HEADER_LENGTH + 6) #define TX_AUTHENTICATE_LENGTH_MSB (TX_AUTHENTICATE_LENGTH >> 8) #define TX_AUTHENTICATE_LENGTH_LSB (TX_AUTHENTICATE_LENGTH & 0xff) +#define TX_DEAUTHENTICATE_LENGTH (TX_HEADER_LENGTH + 2) +#define TX_DEAUTHENTICATE_LENGTH_MSB (TX_AUTHENTICATE_LENGTH >> 8) +#define TX_DEAUTHENTICATE_LENGTH_LSB (TX_AUTHENTICATE_LENGTH & 0xff) #define FCS_LEN 4 #define ADHOC 0 @@ -324,17 +325,23 @@ struct adhoc_beacon #define CARD_ASSOC_COMPLETE (6) #define CARD_ASSOC_FAILED (16) -/*** Values for authentication_state */ +/*** Values for authentication_state ***********************************/ #define UNAUTHENTICATED (0) #define AWAITING_RESPONSE (1) #define AUTHENTICATED (2) #define NEED_TO_AUTH (3) -/*** Values for authentication type */ +/*** Values for authentication type ************************************/ #define OPEN_AUTH_REQUEST (1) #define OPEN_AUTH_RESPONSE (2) - - +#define BROADCAST_DEAUTH (0xc0) +/*** Values for timer functions ****************************************/ +#define TODO_NOTHING (0) +#define TODO_VERIFY_DL_START (-1) +#define TODO_START_NET (-2) +#define TODO_JOIN_NET (-3) +#define TODO_AUTHENTICATE_TIMEOUT (-4) +#define TODO_SEND_CCS (-5) /***********************************************************************/ /* Parameter passing structure for update/report parameter CCS's */ struct object_id { diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 234242746..a13789668 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -1,4 +1,4 @@ -/* $Id: sgiseeq.c,v 1.11 1999/10/09 00:01:24 ralf Exp $ +/* $Id: sgiseeq.c,v 1.12 1999/10/21 00:23:05 ralf Exp $ * * sgiseeq.c: Seeq8003 ethernet driver for SGI machines. * @@ -71,12 +71,12 @@ static char *sgiseeqstr = "SGI Seeq8003"; struct sgiseeq_rx_desc { struct hpc_dma_desc rdma; - unsigned long buf_vaddr; + signed int buf_vaddr; }; struct sgiseeq_tx_desc { struct hpc_dma_desc tdma; - unsigned long buf_vaddr; + signed int buf_vaddr; }; /* Warning: This structure is layed out in a certain way because @@ -87,7 +87,7 @@ struct sgiseeq_init_block { /* Note the name ;-) */ /* Ptrs to the descriptors in KSEG1 uncached space. */ struct sgiseeq_rx_desc *rx_desc; struct sgiseeq_tx_desc *tx_desc; - unsigned long _padding[30]; /* Pad out to largest cache line size. */ + unsigned int _padding[30]; /* Pad out to largest cache line size. */ struct sgiseeq_rx_desc rxvector[SEEQ_RX_BUFFERS]; struct sgiseeq_tx_desc txvector[SEEQ_TX_BUFFERS]; @@ -212,28 +212,28 @@ void sgiseeq_dump_rings(void) once++; printk("RING DUMP:\n"); for(i = 0; i < SEEQ_RX_BUFFERS; i++) { - printk("RX [%d]: @(%p) [%08lx,%08lx,%08lx] ", + printk("RX [%d]: @(%p) [%08x,%08x,%08x] ", i, (&r[i]), r[i].rdma.pbuf, r[i].rdma.cntinfo, r[i].rdma.pnext); i += 1; - printk("-- [%d]: @(%p) [%08lx,%08lx,%08lx]\n", + printk("-- [%d]: @(%p) [%08x,%08x,%08x]\n", i, (&r[i]), r[i].rdma.pbuf, r[i].rdma.cntinfo, r[i].rdma.pnext); } for(i = 0; i < SEEQ_TX_BUFFERS; i++) { - printk("TX [%d]: @(%p) [%08lx,%08lx,%08lx] ", + printk("TX [%d]: @(%p) [%08x,%08x,%08x] ", i, (&t[i]), t[i].tdma.pbuf, t[i].tdma.cntinfo, t[i].tdma.pnext); i += 1; - printk("-- [%d]: @(%p) [%08lx,%08lx,%08lx]\n", + printk("-- [%d]: @(%p) [%08x,%08x,%08x]\n", i, (&t[i]), t[i].tdma.pbuf, t[i].tdma.cntinfo, t[i].tdma.pnext); } printk("INFO: [rx_new = %d rx_old=%d] [tx_new = %d tx_old = %d]\n", gpriv->rx_new, gpriv->rx_old, gpriv->tx_new, gpriv->tx_old); - printk("RREGS: rx_cbptr[%08lx] rx_ndptr[%08lx] rx_ctrl[%08lx]\n", + printk("RREGS: rx_cbptr[%08x] rx_ndptr[%08x] rx_ctrl[%08x]\n", hregs->rx_cbptr, hregs->rx_ndptr, hregs->rx_ctrl); - printk("TREGS: tx_cbptr[%08lx] tx_ndptr[%08lx] tx_ctrl[%08lx]\n", + printk("TREGS: tx_cbptr[%08x] tx_ndptr[%08x] tx_ctrl[%08x]\n", hregs->tx_cbptr, hregs->tx_ndptr, hregs->tx_ctrl); } #endif @@ -309,7 +309,7 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp /* Service every received packet. */ for_each_rx(rd, sp) { len = (PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3); - pkt_pointer = (unsigned char *)rd->buf_vaddr; + pkt_pointer = (unsigned char *)(long)rd->buf_vaddr; pkt_status = pkt_pointer[len + 2]; if(pkt_status & SEEQ_RSTAT_FIG) { @@ -364,8 +364,7 @@ static inline void kick_tx(struct sgiseeq_tx_desc *td, */ while((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) == (HPCDMA_XIU | HPCDMA_ETXD)) - td = (struct sgiseeq_tx_desc *) - KSEG1ADDR(td->tdma.pnext); + td = (struct sgiseeq_tx_desc *)(long) KSEG1ADDR(td->tdma.pnext); if(td->tdma.cntinfo & HPCDMA_XIU) { hregs->tx_ndptr = PHYSADDR(td); hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE; @@ -562,7 +561,7 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) * entry and the HPC got to the end of the chain before we * added this new entry and restarted it. */ - memcpy((char *)td->buf_vaddr, skb->data, skblen); + memcpy((char *)(long)td->buf_vaddr, skb->data, skblen); td->tdma.cntinfo = ((len) & HPCDMA_BCNT) | (HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX); if(sp->tx_old != sp->tx_new) { @@ -733,7 +732,8 @@ int sgiseeq_probe(struct net_device *dev) /* First get the ethernet address of the onboard * interface from ARCS. - * (This is fragile; PROM doesn't like running from cache.) + * This is fragile; PROM doesn't like running from cache. + * On MIPS64 it crashes for some other, yet unknown reason. */ ep = romvec->get_evar("eaddr"); str2eaddr(onboard_eth_addr, ep); diff --git a/drivers/net/sgiseeq.h b/drivers/net/sgiseeq.h index 4f684f5a1..0b5d39c68 100644 --- a/drivers/net/sgiseeq.h +++ b/drivers/net/sgiseeq.h @@ -1,4 +1,4 @@ -/* $Id: sgiseeq.h,v 1.1 1997/06/09 08:34:32 ralf Exp $ +/* $Id: sgiseeq.h,v 1.4 1999/10/09 00:01:24 ralf Exp $ * sgiseeq.h: Defines for the Seeq8003 ethernet controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) @@ -7,27 +7,27 @@ #define _SGISEEQ_H struct sgiseeq_wregs { - volatile unsigned long multicase_high[2]; - volatile unsigned long frame_gap; - volatile unsigned long control; + volatile unsigned int multicase_high[2]; + volatile unsigned int frame_gap; + volatile unsigned int control; }; struct sgiseeq_rregs { - volatile unsigned long collision_tx[2]; - volatile unsigned long collision_all[2]; - volatile unsigned long _unused0; - volatile unsigned long rflags; + volatile unsigned int collision_tx[2]; + volatile unsigned int collision_all[2]; + volatile unsigned int _unused0; + volatile unsigned int rflags; }; struct sgiseeq_regs { union { - volatile unsigned long eth_addr[6]; - volatile unsigned long multicast_low[6]; + volatile unsigned int eth_addr[6]; + volatile unsigned int multicast_low[6]; struct sgiseeq_wregs wregs; struct sgiseeq_rregs rregs; } rw; - volatile unsigned long rstat; - volatile unsigned long tstat; + volatile unsigned int rstat; + volatile unsigned int tstat; }; /* Seeq8003 receive status register */ diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c index c11248958..cdee2d6e6 100644 --- a/drivers/net/sk_mca.c +++ b/drivers/net/sk_mca.c @@ -71,6 +71,7 @@ History: #include <linux/version.h> #include <linux/kernel.h> +#include <linux/version.h> #include <linux/sched.h> #include <linux/string.h> #include <linux/errno.h> diff --git a/drivers/net/tokenring/.cvsignore b/drivers/net/tokenring/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/drivers/net/tokenring/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/drivers/net/tokenring/Config.in b/drivers/net/tokenring/Config.in new file mode 100644 index 000000000..8b3065c8a --- /dev/null +++ b/drivers/net/tokenring/Config.in @@ -0,0 +1,15 @@ +# +# Token Ring driver configuration +# + +mainmenu_option next_comment +comment 'Token Ring driver support' + +bool 'Token Ring driver support' CONFIG_TR +if [ "$CONFIG_TR" = "y" ]; then + tristate ' IBM Tropic chipset based adapter support' CONFIG_IBMTR + tristate ' IBM Olympic chipset PCI adapter support' CONFIG_IBMOL + tristate ' SysKonnect adapter support' CONFIG_SKTR +fi + +endmenu diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile new file mode 100644 index 000000000..038c58b86 --- /dev/null +++ b/drivers/net/tokenring/Makefile @@ -0,0 +1,51 @@ +# +# Makefile for drivers/net/tokenring +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now inherited from the +# parent makefile. +# + +# +# Note : at this point, these files are compiled on all systems. +# In the future, some of these should be built conditionally. +# + +SUB_DIRS := +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) + + +L_TARGET := tr.a +L_OBJS := +M_OBJS := + +ifeq ($(CONFIG_IBMTR),y) + L_OBJS += ibmtr.o +else + ifeq ($(CONFIG_IBMTR),m) + M_OBJS += ibmtr.o + endif +endif + +ifeq ($(CONFIG_IBMOL),y) + L_OBJS += olympic.o +else + ifeq ($(CONFIG_IBMOL),m) + M_OBJS += olympic.o + endif +endif + +ifeq ($(CONFIG_SKTR),y) + L_OBJS += sktr.o +else + ifeq ($(CONFIG_SKTR),m) + M_OBJS += sktr.o + endif +endif + +include $(TOPDIR)/Rules.make + diff --git a/drivers/net/ibmtr.c b/drivers/net/tokenring/ibmtr.c index cf2514fa6..85cdfb774 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -79,6 +79,10 @@ * * Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) : * + added spinlocks for SMP sanity (10 March 1999) + * + * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting + * i.e. using functional address C0 00 00 04 00 00 to transmit and + * receive multicast packets. */ /* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value @@ -211,6 +215,7 @@ static int tok_open(struct net_device *dev); static int tok_close(struct net_device *dev); static int tok_send_packet(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats * tok_get_stats(struct net_device *dev); +static void tok_set_multicast_list(struct net_device *dev); void ibmtr_readlog(struct net_device *dev); void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev); int ibmtr_change_mtu(struct net_device *dev, int mtu); @@ -778,7 +783,7 @@ static int __init trdev_init(struct net_device *dev) dev->stop = tok_close; dev->hard_start_xmit = tok_send_packet; dev->get_stats = tok_get_stats; - dev->set_multicast_list = NULL; + dev->set_multicast_list = tok_set_multicast_list; dev->change_mtu = ibmtr_change_mtu; #ifndef MODULE @@ -790,6 +795,43 @@ static int __init trdev_init(struct net_device *dev) } +static void tok_set_multicast_list(struct net_device *dev) +{ + struct tok_info *ti=(struct tok_info *)dev->priv; + struct dev_mc_list *mclist; + unsigned char address[4]; + + int i; + + address[0] = address[1] = address[2] = address[3] = 0; + + mclist = dev->mc_list; + for (i=0; i< dev->mc_count; i++) + { + address[0] |= mclist->dmi_addr[2]; + address[1] |= mclist->dmi_addr[3]; + address[2] |= mclist->dmi_addr[4]; + address[3] |= mclist->dmi_addr[5]; + mclist = mclist->next; + } + SET_PAGE(ti->srb); + for (i=0; i<sizeof(struct srb_set_funct_addr); i++) + writeb(0, ti->srb+i); + + writeb(DIR_SET_FUNC_ADDR, + ti->srb + offsetof(struct srb_set_funct_addr, command)); + + DPRINTK("Setting functional address: "); + + for (i=0; i<4; i++) + { + writeb(address[i], + ti->srb + offsetof(struct srb_set_funct_addr, funct_address)+i); + printk("%02X ", address[i]); + } + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + printk("\n"); +} static int tok_open(struct net_device *dev) { @@ -1621,12 +1663,10 @@ static void tr_rx(struct net_device *dev) ti->tr_stats.rx_packets++; skb->protocol = tr_type_trans(skb,dev); - - if (IPv4_p){ + if (IPv4_p){ skb->csum = chksum; skb->ip_summed = 1; } - netif_rx(skb); } diff --git a/drivers/net/ibmtr.h b/drivers/net/tokenring/ibmtr.h index f51174c4f..3f3fa6aed 100644 --- a/drivers/net/ibmtr.h +++ b/drivers/net/tokenring/ibmtr.h @@ -444,6 +444,6 @@ struct srb_set_funct_addr { unsigned char reserved1; unsigned char ret_code; unsigned char reserved2[3]; - __u32 funct_address; + unsigned char funct_address[4]; }; diff --git a/drivers/net/olympic.c b/drivers/net/tokenring/olympic.c index 460480c48..460480c48 100644 --- a/drivers/net/olympic.c +++ b/drivers/net/tokenring/olympic.c diff --git a/drivers/net/olympic.h b/drivers/net/tokenring/olympic.h index d5a06423a..d5a06423a 100644 --- a/drivers/net/olympic.h +++ b/drivers/net/tokenring/olympic.h diff --git a/drivers/net/sktr.c b/drivers/net/tokenring/sktr.c index f9b877f66..81b2df4bc 100644 --- a/drivers/net/sktr.c +++ b/drivers/net/tokenring/sktr.c @@ -24,7 +24,8 @@ * * Maintainer(s): * JS Jay Schulist jschlst@samba.anu.edu.au - * CG Christoph Goos cgoos@syskonnect.de + * CG Christoph Goos cgoos@syskonnect.de + * AF Adam Fritzler mid@auk.cx * * Modification History: * 29-Aug-97 CG Created @@ -33,10 +34,14 @@ * 27-May-98 JS Formated to Linux Kernel Format * 31-May-98 JS Hacked in PCI support * 16-Jun-98 JS Modulized for multiple cards with one driver + * 21-Sep-99 CG Fixed source routing issues for 2.2 kernels + * 21-Sep-99 AF Added multicast changes recommended by + * Jochen Friedrich <jochen@nwe.de> (untested) + * Added detection of compatible Compaq PCI card * * To do: * 1. Selectable 16 Mbps or 4Mbps - * 2. Multi/Broadcast packet handling + * 2. Multi/Broadcast packet handling (might be done) * */ @@ -135,7 +140,6 @@ static void sktr_enable_interrupts(struct net_device *dev); static void sktr_exec_cmd(struct net_device *dev, unsigned short Command); static void sktr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue); /* "F" */ -static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen); /* "G" */ static struct enet_statistics *sktr_get_stats(struct net_device *dev); /* "H" */ @@ -254,10 +258,17 @@ static int __init sktr_pci_chk_card(struct net_device *dev) /* Remove I/O space marker in bit 0. */ pci_ioaddr &= ~3; - if(vendor != PCI_VENDOR_ID_SK) + if((vendor != PCI_VENDOR_ID_SK) && + (vendor != PCI_VENDOR_ID_COMPAQ)) continue; - if(device != PCI_DEVICE_ID_SK_TR) + + if((vendor == PCI_VENDOR_ID_SK) && + (device != PCI_DEVICE_ID_SK_TR)) + continue; + else if((vendor == PCI_VENDOR_ID_COMPAQ) && + (device != PCI_DEVICE_ID_COMPAQ_TOKENRING)) continue; + if(check_region(pci_ioaddr, SKTR_IO_EXTENT)) continue; request_region(pci_ioaddr, SKTR_IO_EXTENT, pci_cardname); @@ -390,6 +401,7 @@ static int __init sktr_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; struct net_local *tp; + int DeviceType = SK_PCI; int err; if(sktr_debug && version_printed++ == 0) @@ -407,6 +419,7 @@ static int __init sktr_probe1(struct net_device *dev, int ioaddr) err = sktr_isa_chk_card(dev, ioaddr); if(err < 0) return (-ENODEV); + DeviceType = SK_ISA; } /* Setup this devices private information structure */ @@ -414,6 +427,7 @@ static int __init sktr_probe1(struct net_device *dev, int ioaddr) if(tp == NULL) return (-ENOMEM); memset(tp, 0, sizeof(struct net_local)); + tp->DeviceType = DeviceType; init_waitqueue_head(&tp->wait_for_tok_int); dev->priv = tp; @@ -691,7 +705,9 @@ static void sktr_init_net_local(struct net_device *dev) skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); /* data unreachable for DMA ? then use local buffer */ - if(virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS) + if(tp->DeviceType == SK_ISA && + virt_to_bus(tp->Rpl[i].Skb->data) + + tp->MaxPacketSize > ISA_MAX_ADDRESS) { tp->Rpl[i].SkbStat = SKB_DATA_COPY; tp->Rpl[i].FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[i])); @@ -749,7 +765,7 @@ static void sktr_init_opb(struct net_local *tp) tp->ocpl.OPENOptions = 0; tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION; - tp->ocpl.OPENOptions |= PAD_ROUTING_FIELD; +/* tp->ocpl.OPENOptions |= PAD_ROUTING_FIELD; no more needed */ tp->ocpl.FullDuplex = 0; tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF; @@ -827,32 +843,6 @@ static void sktr_exec_cmd(struct net_device *dev, unsigned short Command) } /* - * Linux always gives 18 byte of source routing information in the frame header. - * But the length field can indicate shorter length. Then cut header - * appropriate. - */ -static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen) -{ - struct trh_hdr *trh = (struct trh_hdr *)buf; - int len; - - if(buf[8] & TR_RII) - { - trh->rcf &= ~SWAPB((unsigned short) TR_RCF_LONGEST_FRAME_MASK); - trh->rcf |= SWAPB((unsigned short) TR_RCF_FRAME4K); - len = (SWAPB(trh->rcf) & TR_RCF_LEN_MASK) >> 8; - if(len < 18) - { - memcpy(&buf[18-len],buf,sizeof(struct trh_hdr)-18+len); - *FrameLen -= (18 - len); - } - return (&buf[18-len]); - } - - return (buf); -} - -/* * Gets skb from system, queues it and checks if it can be sent */ static int sktr_send_packet(struct sk_buff *skb, struct net_device *dev) @@ -934,7 +924,8 @@ static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* tp->QueueSkb++; /* Is buffer reachable for Busmaster-DMA? */ - if(virt_to_bus((void*)(((long) skb->data) + skb->len)) + if(tp->DeviceType == SK_ISA && + virt_to_bus((void*)(((long) skb->data) + skb->len)) > ISA_MAX_ADDRESS) { /* Copy frame to local buffer */ @@ -942,13 +933,13 @@ static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* length = skb->len; buf = tp->LocalTxBuffers[i]; memcpy(buf, skb->data, length); - newbuf = sktr_fix_srouting(buf, &length); + newbuf = buf; } else { /* Send direct from skb->data */ length = skb->len; - newbuf = sktr_fix_srouting(skb->data, &length); + newbuf = skb->data; } /* Source address in packet? */ @@ -1486,53 +1477,65 @@ static struct enet_statistics *sktr_get_stats(struct net_device *dev) static void sktr_set_multicast_list(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; - unsigned int OpenOptions; - - OpenOptions = tp->ocpl.OPENOptions & - ~(PASS_ADAPTER_MAC_FRAMES - | PASS_ATTENTION_FRAMES - | PASS_BEACON_MAC_FRAMES - | COPY_ALL_MAC_FRAMES - | COPY_ALL_NON_MAC_FRAMES); - - if(dev->flags & IFF_PROMISC) - /* Enable promiscuous mode */ - OpenOptions |= COPY_ALL_NON_MAC_FRAMES | COPY_ALL_MAC_FRAMES; - else - { - if(dev->flags & IFF_ALLMULTI) - /* || dev->mc_count > HW_MAX_ADDRS) */ - { - /* Disable promiscuous mode, use normal mode. */ - } - else - { - if(dev->mc_count) - { - /* Walk the address list, and load the filter */ - } - } - } - - tp->ocpl.OPENOptions = OpenOptions; - sktr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS); - - return; + unsigned int OpenOptions; + + OpenOptions = tp->ocpl.OPENOptions & + ~(PASS_ADAPTER_MAC_FRAMES + | PASS_ATTENTION_FRAMES + | PASS_BEACON_MAC_FRAMES + | COPY_ALL_MAC_FRAMES + | COPY_ALL_NON_MAC_FRAMES); + + tp->ocpl.FunctAddr = 0; + + if(dev->flags & IFF_PROMISC) + /* Enable promiscuous mode */ + OpenOptions |= COPY_ALL_NON_MAC_FRAMES | + COPY_ALL_MAC_FRAMES; + else + { + if(dev->flags & IFF_ALLMULTI) + { + /* Disable promiscuous mode, use normal mode. */ + tp->ocpl.FunctAddr = 0xFFFFFFFF; + + } + else + { + int i; + struct dev_mc_list *mclist = dev->mc_list; + for (i=0; i< dev->mc_count; i++) + { + ((char *)(&tp->ocpl.FunctAddr))[0] |= + mclist->dmi_addr[2]; + ((char *)(&tp->ocpl.FunctAddr))[1] |= + mclist->dmi_addr[3]; + ((char *)(&tp->ocpl.FunctAddr))[2] |= + mclist->dmi_addr[4]; + ((char *)(&tp->ocpl.FunctAddr))[3] |= + mclist->dmi_addr[5]; + mclist = mclist->next; + } + } + sktr_exec_cmd(dev, OC_SET_FUNCT_ADDR); + } + + tp->ocpl.OPENOptions = OpenOptions; + sktr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS); + return; } /* * Wait for some time (microseconds) + * + * udelay() is a bit harsh, but using a looser timer causes + * the bring-up-diags to stall indefinitly. + * */ + static void sktr_wait(unsigned long time) { - long tmp; - - tmp = jiffies + time/(1000000/HZ); - do { - current->state = TASK_INTERRUPTIBLE; - tmp = schedule_timeout(tmp); - } while(time_after(tmp, jiffies)); - + udelay(time); return; } @@ -2451,8 +2454,6 @@ static void sktr_rcv_status_irq(struct net_device *dev) /* Drop frames sent by myself */ if(sktr_chk_frame(dev, rpl->MData)) { - printk(KERN_INFO "%s: Received my own frame\n", - dev->name); if(rpl->Skb != NULL) dev_kfree_skb(rpl->Skb); } @@ -2464,9 +2465,10 @@ static void sktr_rcv_status_irq(struct net_device *dev) printk("%s: Packet Length %04X (%d)\n", dev->name, Length, Length); - /* Indicate the received frame to system the - * adapter does the Source-Routing padding for - * us. See: OpenOptions in sktr_init_opb() + /* Indicate the received frame to system. + * The source routing padding is no more + * necessary with 2.2.x kernel. + * See: OpenOptions in sktr_init_opb() */ skb = rpl->Skb; if(rpl->SkbStat == SKB_UNAVAILABLE) @@ -2497,6 +2499,7 @@ static void sktr_rcv_status_irq(struct net_device *dev) /* Deliver frame to system */ rpl->Skb = NULL; skb_trim(skb,Length); + skb->dev = dev; skb->protocol = tr_type_trans(skb,dev); netif_rx(skb); } @@ -2529,7 +2532,8 @@ static void sktr_rcv_status_irq(struct net_device *dev) skb_put(rpl->Skb, tp->MaxPacketSize); /* Data unreachable for DMA ? then use local buffer */ - if(virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize + if(tp->DeviceType == SK_ISA && + virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS) { rpl->SkbStat = SKB_DATA_COPY; diff --git a/drivers/net/sktr.h b/drivers/net/tokenring/sktr.h index 4c2a3bf36..90b5c382f 100644 --- a/drivers/net/sktr.h +++ b/drivers/net/tokenring/sktr.h @@ -16,6 +16,9 @@ #define TR_RCF_LONGEST_FRAME_MASK 0x0070 #define TR_RCF_FRAME4K 0x0030 +#define SK_ISA 0 +#define SK_PCI 1 + /*------------------------------------------------------------------*/ /* Bit order for adapter communication with DMA */ /* -------------------------------------------------------------- */ @@ -642,7 +645,7 @@ typedef struct { * but possibly multiple TPLs for one frame) the length of the TPLs has to be * initialized in the OPL. (OPEN parameter list) */ -#define TPL_NUM 3 /* Number of Transmit Parameter Lists. +#define TPL_NUM 9 /* Number of Transmit Parameter Lists. * !! MUST BE >= 3 !! */ @@ -1063,6 +1066,8 @@ typedef struct net_local { unsigned char ScbInUse; unsigned short CMDqueue; + unsigned int DeviceType; + unsigned long AdapterOpenFlag:1; unsigned long AdapterVirtOpenFlag:1; unsigned long OpenCommandIssued:1; diff --git a/drivers/net/sktr_firmware.h b/drivers/net/tokenring/sktr_firmware.h index 25dd973d4..25dd973d4 100644 --- a/drivers/net/sktr_firmware.h +++ b/drivers/net/tokenring/sktr_firmware.h diff --git a/drivers/net/wan/.cvsignore b/drivers/net/wan/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/drivers/net/wan/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/drivers/net/wan/Config.in b/drivers/net/wan/Config.in new file mode 100644 index 000000000..503854a0f --- /dev/null +++ b/drivers/net/wan/Config.in @@ -0,0 +1,64 @@ +# +# wan devices configuration +# + +mainmenu_option next_comment +comment 'Wan interfaces' + +bool 'Wan interfaces support' CONFIG_WAN +if [ "$CONFIG_WAN" = "y" ]; then + + # There is no way to detect a comtrol sv11 - force it modular for now. + + dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m + + # The COSA/SRP driver has not been tested as non-modular yet. + + dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m + + # There is no way to detect a Sealevel board. Force it modular + + dep_tristate 'Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m + + tristate 'Frame relay DLCI support' CONFIG_DLCI + if [ "$CONFIG_DLCI" != "n" ]; then + int 'Max open DLCI' CONFIG_DLCI_COUNT 24 + int 'Max DLCI per device' CONFIG_DLCI_MAX 8 + dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI + fi + + # Wan router core. + + if [ "$CONFIG_WAN_ROUTER" != "n" ]; then + bool 'WAN router drivers' CONFIG_WAN_ROUTER_DRIVERS + if [ "$CONFIG_WAN_ROUTER_DRIVERS" = "y" ]; then + dep_tristate ' Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA $CONFIG_WAN_ROUTER_DRIVERS + if [ "$CONFIG_VENDOR_SANGOMA" != "n" ]; then + int 'Maximum number of cards' CONFIG_WANPIPE_CARDS 1 + bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25 + bool ' WANPIPE Frame Relay support' CONFIG_WANPIPE_FR + bool ' WANPIPE PPP support' CONFIG_WANPIPE_PPP + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Cyclom 2X(tm) cards (EXPERIMENTAL)' CONFIG_CYCLADES_SYNC $CONFIG_WAN_ROUTER_DRIVERS + if [ "$CONFIG_CYCLADES_SYNC" != "n" ]; then + bool ' Cyclom 2X X.25 support' CONFIG_CYCLOMX_X25 + fi + fi + fi + fi + + # X.25 network drivers + + if [ "$CONFIG_X25" != "n" ]; then + if [ "$CONFIG_LAPB" != "n" ]; then + dep_tristate 'LAPB over Ethernet driver' CONFIG_LAPBETHER $CONFIG_LAPB + dep_tristate 'X.25 async driver' CONFIG_X25_ASY $CONFIG_LAPB + fi + fi + + tristate 'SBNI12-xx support' CONFIG_SBNI +fi + +endmenu + diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile new file mode 100644 index 000000000..73060f5b9 --- /dev/null +++ b/drivers/net/wan/Makefile @@ -0,0 +1,181 @@ +# File: drivers/net/wan/Makefile +# +# Makefile for the Linux network (wan) device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now inherited from the +# parent makefile. +# + +SUB_DIRS := +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) + +L_TARGET := wan.a +L_OBJS := +M_OBJS := + +# Need these to keep track of whether the 82530 or SYNCPPP +# modules should really go in the kernel or a module. +CONFIG_85230_BUILTIN := +CONFIG_85230_MODULE := +CONFIG_SYNCPPP_BUILTIN := +CONFIG_SYNCPPP_MODULE := + +ifeq ($(CONFIG_HOSTESS_SV11),y) +L_OBJS += hostess_sv11.o +CONFIG_85230_BUILTIN = y +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_HOSTESS_SV11),m) + CONFIG_85230_MODULE = y + CONFIG_SYNCPPP_MODULE = y + M_OBJS += hostess_sv11.o + endif +endif + +ifeq ($(CONFIG_SEALEVEL_4021),y) +L_OBJS += sealevel.o +CONFIG_85230_BUILTIN = y +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_SEALEVEL_4021),m) + CONFIG_85230_MODULE = y + CONFIG_SYNCPPP_MODULE = y + M_OBJS += sealevel.o + endif +endif + +ifeq ($(CONFIG_COSA),y) +L_OBJS += cosa.o +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_COSA),m) + CONFIG_SYNCPPP_MODULE = y + M_OBJS += cosa.o + endif +endif + +# If anything built-in uses syncppp, then build it into the kernel also. +# If not, but a module uses it, build as a module. + +ifdef CONFIG_SYNCPPP_BUILTIN +LX_OBJS += syncppp.o +else + ifdef CONFIG_SYNCPPP_MODULE + MX_OBJS += syncppp.o + endif +endif + +# If anything built-in uses Z85230, then build it into the kernel also. +# If not, but a module uses it, build as a module. + +ifdef CONFIG_85230_BUILTIN +LX_OBJS += z85230.o +else + ifdef CONFIG_85230_MODULE + MX_OBJS += z85230.o + endif +endif + +ifeq ($(CONFIG_DLCI),y) +L_OBJS += dlci.o +else + ifeq ($(CONFIG_DLCI),m) + M_OBJS += dlci.o + endif +endif + +ifeq ($(CONFIG_SDLA),y) + L_OBJS += sdla.o +else + ifeq ($(CONFIG_SDLA),m) + M_OBJS += sdla.o +endif + +ifeq ($(CONFIG_VENDOR_SANGOMA),y) + LX_OBJS += sdladrv.o + L_OBJS += sdlamain.o + ifeq ($(CONFIG_WANPIPE_X25),y) + L_OBJS += sdla_x25.o + endif + ifeq ($(CONFIG_WANPIPE_FR),y) + L_OBJS += sdla_fr.o + endif + ifeq ($(CONFIG_WANPIPE_PPP),y) + L_OBJS += sdla_ppp.o + endif +endif + +endif + +ifeq ($(CONFIG_VENDOR_SANGOMA),m) + MX_OBJS += sdladrv.o + M_OBJS += wanpipe.o + WANPIPE_OBJS = sdlamain.o + ifeq ($(CONFIG_WANPIPE_X25),y) + WANPIPE_OBJS += sdla_x25.o + endif + ifeq ($(CONFIG_WANPIPE_FR),y) + WANPIPE_OBJS += sdla_fr.o + endif + ifeq ($(CONFIG_WANPIPE_PPP),y) + WANPIPE_OBJS += sdla_ppp.o + endif +endif + +ifeq ($(CONFIG_CYCLADES_SYNC),y) + LX_OBJS += cycx_drv.o + L_OBJS += cycx_main.o + ifeq ($(CONFIG_CYCLOMX_X25),y) + L_OBJS += cycx_x25.o + endif +endif + +ifeq ($(CONFIG_CYCLADES_SYNC),m) + MX_OBJS += cycx_drv.o + M_OBJS += cyclomx.o + CYCLOMX_OBJS = cycx_main.o + ifeq ($(CONFIG_CYCLOMX_X25),y) + CYCLOMX_OBJS += cycx_x25.o + endif +endif + +ifeq ($(CONFIG_X25_ASY),y) +L_OBJS += x25_asy.o +else + ifeq ($(CONFIG_X25_ASY),m) + M_OBJS += x25_asy.o + endif +endif + +ifeq ($(CONFIG_LAPBETHER),y) +L_OBJS += lapbether.o +else + ifeq ($(CONFIG_LAPBETHER),m) + M_OBJS += lapbether.o + endif +endif + +ifeq ($(CONFIG_SBNI),y) +L_OBJS += sbni.o +else + ifeq ($(CONFIG_SBNI),m) + M_OBJS += sbni.o + endif +endif + +include $(TOPDIR)/Rules.make + +clean: + rm -f core *.o *.a *.s + +wanpipe.o: $(WANPIPE_OBJS) + ld -r -o $@ $(WANPIPE_OBJS) + +cyclomx.o: $(CYCLOMX_OBJS) + ld -r -o $@ $(CYCLOMX_OBJS) + diff --git a/drivers/net/cosa.c b/drivers/net/wan/cosa.c index 863cd4b59..863cd4b59 100644 --- a/drivers/net/cosa.c +++ b/drivers/net/wan/cosa.c diff --git a/drivers/net/cosa.h b/drivers/net/wan/cosa.h index 7b5a39018..7b5a39018 100644 --- a/drivers/net/cosa.h +++ b/drivers/net/wan/cosa.h diff --git a/drivers/net/cycx_drv.c b/drivers/net/wan/cycx_drv.c index 1629bdcf0..1629bdcf0 100644 --- a/drivers/net/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c diff --git a/drivers/net/cycx_main.c b/drivers/net/wan/cycx_main.c index 52a2abd04..52a2abd04 100644 --- a/drivers/net/cycx_main.c +++ b/drivers/net/wan/cycx_main.c diff --git a/drivers/net/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 7e79943c0..7e79943c0 100644 --- a/drivers/net/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c diff --git a/drivers/net/dlci.c b/drivers/net/wan/dlci.c index a8c52f0d6..a8c52f0d6 100644 --- a/drivers/net/dlci.c +++ b/drivers/net/wan/dlci.c diff --git a/drivers/net/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 7b24901ce..ba4e49c83 100644 --- a/drivers/net/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -320,7 +320,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) for(i=0;i<999;i++) { sprintf(sv->name,"hdlc%d", i); - if(dev_get(sv->name)==NULL) + if(dev_get(sv->name)==0) { struct net_device *d=dev->chanA.netdevice; diff --git a/drivers/net/lapbether.c b/drivers/net/wan/lapbether.c index a4564afcb..a4564afcb 100644 --- a/drivers/net/lapbether.c +++ b/drivers/net/wan/lapbether.c diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c new file mode 100644 index 000000000..9d5fba082 --- /dev/null +++ b/drivers/net/wan/sbni.c @@ -0,0 +1,1533 @@ +/* + * Driver for Granch SBNI-12 leased line network adapters. + * + * Copyright 1997 - 1999, Granch ltd. + * Written 1999 by Yaroslav Polyakov (xenon@granch.ru). + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + * + * // Whole developers team: + * // Yaroslav Polyakov (xenon@granch.ru) + * // - main developer of this version + * // Alexey Zverev (zverev@granch.ru) + * // - previous SBNI driver for linux + * // Alexey Chirkov (chirkov@granch.ru) + * // - all the hardware work and consulting + * // Max Khon (max@iclub.nsu.ru) + * // - first SBNI driver for linux + * // -------------------------------------------- + * // also I thank: + * // Max Krasnyansky (max@uznet.net) + * // - for bug hunting and many ideas + * // Alan Cox (Alan.Cox@linux.org) + * // - for consulting in some hardcore questions + * // Donald Becker (becker@cesdis.gsfc.nasa.gov) + * // - for pretty nice skeleton + * + * More info and useful utilities to work w/ SBNI you can find at + * http://www.granch.ru. + * + * 3.0.0 = Initial Revision, Yaroslav Polyakov (24 Feb 1999) + * - added pre-calculation for CRC, fixed bug with "len-2" frames, + * - removed outbound fragmentation (MTU=1000), written CRC-calculation + * - on asm, added work with hard_headers and now we have our own cache + * - for them, optionally supported word-interchange on some chipsets, + * - something else I cant remember ;) + * + * 3.0.1 = just fixed some bugs (14 apr 1999). + * - fixed statistical tx bug + * - fixed wrong creation dates (1998 -> 1999) in driver source code ;) + * - fixed source address bug. + * - fixed permanent nirvana bug + * + * 3.1.0 = (Katyusha) (26 apr 1999) + * - Added balancing feature + * + * 3.1.1 = (Medea) (5 aug 1999) + * - Fixed mac.raw bug + * - Thanks to tolix@olviko.ru and + * - to Barnaul Brewery, producers of my favorite beer "Medea". + * + * + */ + + +#undef GOODBUS16 +#define CRCASM +#define KATYUSHA + +#include <linux/version.h> + +#if LINUX_VERSION_CODE >=0x020200 +#define v22 +#endif + + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/ptrace.h> +#include <linux/fcntl.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/malloc.h> +#include <linux/string.h> +#include <linux/errno.h> + +#include <asm/io.h> +#include <asm/types.h> +#include <asm/byteorder.h> + + +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/timer.h> +#include <linux/config.h> /* for CONFIG_INET. do we need this?*/ + +#include <net/arp.h> + + + +#ifdef v22 +#include <asm/uaccess.h> +#include <linux/init.h> +#endif + +#include "sbni.h" + + +static const char *version = +"sbni.c: ver. 3.1.1 Medea 5 Aug 1999 Yaroslav Polyakov (xenon@granch.ru)\n"; + +int sbni_probe(struct net_device *dev); +static int sbni_probe1(struct net_device *dev, int ioaddr); +static int sbni_open(struct net_device *dev); +static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void sbni_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static int sbni_close(struct net_device *dev); +static void sbni_drop_tx_queue(struct net_device *dev); +static struct enet_statistics *sbni_get_stats(struct net_device *dev); +void card_start(struct net_device *dev); +static inline unsigned short sbni_recv(struct net_device *dev); +void change_level(struct net_device *dev); +static inline void sbni_xmit(struct net_device *dev); +static inline void sbni_get_packet(struct net_device* dev); +static void sbni_watchdog(unsigned long arg); +static void set_multicast_list(struct net_device *dev); +static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int sbni_set_mac_address(struct net_device *dev, void *addr); +unsigned long calc_crc(char *mem, int len, unsigned initial); +void sbni_nirvana(struct net_device *dev); +static int sbni_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, + void *daddr, void *saddr, unsigned len); + +static int sbni_rebuild_header(struct sk_buff *skb); +static int sbni_header_cache(struct neighbour *neigh, struct hh_cache *hh); + +static inline void sbni_outs(int port, void *data, int len); +static inline void sbni_ins(int port, void *data, int len); + + + +#define SIZE_OF_TIMEOUT_RXL_TAB 4 +static u_char timeout_rxl_tab[] = { + 0x03, 0x05, 0x08, 0x0b +}; + +static u_char rxl_tab[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, + 0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f +}; + +/* A zero-terminated list of I/O addresses to be probed */ +static unsigned int netcard_portlist[] = { + 0x210, 0x2c0, 0x2d0, 0x2f0, 0x220, 0x230, 0x240, 0x250, + 0x260, 0x290, 0x2a0, 0x2b0, 0x224, 0x234, 0x244, 0x254, + 0x264, 0x294, 0x2a4, 0x2b4, 0}; + +static unsigned char magic_reply[] = { + 0x5a,0x06,0x30,0x00,0x00,0x50,0x65,0x44,0x20 +}; + +static int def_baud = DEF_RATE; +static int def_rxl = DEF_RXL_DELTA; +static long def_mac = 0; + + +/* + * CRC-32 stuff + */ + +#define CRC32(c,crc) (crc32tab[((size_t)(crc) ^ (c)) & 0xff] ^ (((crc) >> 8) & 0x00FFFFFF)) +/* CRC generator 0xEDB88320 */ +/* CRC remainder 0x2144DF1C */ +/* CRC initial value 0x00000000 */ +#define CRC32_REMAINDER 0x2144DF1C +#define CRC32_INITIAL 0x00000000 + +static unsigned long crc32tab[] = { + 0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37, + 0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E, + 0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605, + 0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C, + 0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53, + 0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A, + 0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661, + 0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278, + 0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF, + 0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6, + 0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD, + 0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4, + 0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B, + 0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82, + 0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9, + 0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0, + 0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7, + 0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE, + 0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795, + 0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C, + 0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3, + 0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA, + 0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1, + 0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8, + 0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F, + 0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76, + 0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D, + 0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344, + 0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B, + 0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12, + 0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739, + 0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320, + 0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17, + 0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E, + 0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525, + 0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C, + 0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73, + 0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A, + 0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541, + 0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158, + 0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF, + 0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6, + 0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED, + 0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4, + 0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB, + 0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2, + 0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589, + 0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190, + 0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87, + 0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E, + 0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5, + 0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC, + 0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3, + 0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA, + 0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1, + 0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8, + 0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F, + 0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856, + 0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D, + 0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064, + 0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B, + 0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832, + 0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419, + 0x660951BA, 0x110E612C, 0x88073096, 0xFF000000 +}; + +static inline void sbni_outs(int port, void *data, int len) +{ +#ifdef GOODBUS16 + outsw(port,data,len/2); + if(len & 1) + outb(((char*)data)[len - 1],port); +#else + outsb(port,data,len); +#endif +} + +static inline void sbni_ins(int port, void *data, int len) +{ +#ifdef GOODBUS16 + insw(port,data,len/2); + if(len & 1) + ((char*)data)[len - 1] = inb(port); +#else + insb(port,data,len); +#endif +} + + +static int sbni_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, + void *daddr, void *saddr, unsigned len) +{ + struct sbni_hard_header *hh = (struct sbni_hard_header *) + skb_push(skb, sizeof(struct sbni_hard_header)); + + + if(type!=ETH_P_802_3) + hh->h_proto = htons(type); + else + hh->h_proto = htons(len); + + if(saddr) + memcpy(hh->h_source,saddr,dev->addr_len); + else + memcpy(hh->h_source,dev->dev_addr,dev->addr_len); + + if(daddr) + { + memcpy(hh->h_dest,daddr,dev->addr_len); + return dev->hard_header_len; + } + return -dev->hard_header_len; +} + + +int sbni_header_cache(struct neighbour *neigh, struct hh_cache *hh) +{ + unsigned short type = hh->hh_type; + struct sbni_hard_header *sbni = (struct sbni_hard_header*) + (((u8*)hh->hh_data) - 8); + struct net_device *dev = neigh->dev; + + + if (type == __constant_htons(ETH_P_802_3)) + return -1; + + sbni->h_proto = type; + memcpy(sbni->h_source, dev->dev_addr, dev->addr_len); + memcpy(sbni->h_dest, neigh->ha, dev->addr_len); + return 0; +} + +static int sbni_rebuild_header(struct sk_buff *skb) +{ + struct sbni_hard_header *hh = (struct sbni_hard_header *)skb; + /* + * Only ARP/IP is currently supported + */ + + /* + * Try to get ARP to resolve the header. + */ + +#ifdef CONFIG_INET + return arp_find((unsigned char*)hh->h_dest, skb)? 1 : 0; +#else + return 0; +#endif +} + +static void sbni_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) +{ + memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); +} + + + +#ifdef HAVE_DEVLIST +struct netdev_entry sbni_drv = { + "sbni", sbni_probe1, SBNI_IO_EXTENT, netcard_portlist +}; + +#else + +int __init sbni_probe(struct net_device *dev) +{ + int i; + int base_addr = dev ? dev->base_addr : 0; + + DP( printk("%s: sbni_probe\n", dev->name); ) + + if(base_addr > 0x1ff) /* Check a single specified location. */ + return sbni_probe1(dev, base_addr); + else if(base_addr != 0) /* Don't probe at all. */ + return ENXIO; + for(i = 0; (base_addr = netcard_portlist[i]); i++) + { + if(!check_region(base_addr, SBNI_IO_EXTENT) && base_addr != 1) + { + /* Lock this address, or later we'll try it again */ + netcard_portlist[i] = 1; + if(sbni_probe1(dev, base_addr) == 0) + return 0; + } + } + return ENODEV; +} + +#endif /* have devlist*/ + +/* + * The actual probe. + */ + +/* + Valid combinations in CSR0 (for probing): + + VALID_DECODER 0000,0011,1011,1010 + + ; 0 ; - + TR_REQ ; 1 ; + + TR_RDY ; 2 ; - + TR_RDY TR_REQ ; 3 ; + + BU_EMP ; 4 ; + + BU_EMP TR_REQ ; 5 ; + + BU_EMP TR_RDY ; 6 ; - + BU_EMP TR_RDY TR_REQ ; 7 ; + + RC_RDY ; 8 ; + + RC_RDY TR_REQ ; 9 ; + + RC_RDY TR_RDY ; 10 ; - + RC_RDY TR_RDY TR_REQ ; 11 ; - + RC_RDY BU_EMP ; 12 ; - + RC_RDY BU_EMP TR_REQ ; 13 ; - + RC_RDY BU_EMP TR_RDY ; 14 ; - + RC_RDY BU_EMP TR_RDY TR_REQ ; 15 ; - +*/ +#define VALID_DECODER (2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200) + +static int __init sbni_probe1(struct net_device *dev, int ioaddr) + +{ + int autoirq = 0; + int bad_card = 0; + unsigned char csr0; + struct net_local* lp; + static int version_printed = 0; + + DP( printk("%s: sbni_probe1 ioaddr=%d\n", dev->name, ioaddr); ) + + if(check_region(ioaddr, SBNI_IO_EXTENT) < 0) + return -ENODEV; + if(version_printed++ == 0) + printk(version); + + /* check for valid combination in CSR0 */ + csr0 = inb(ioaddr + CSR0); + if(csr0 == 0xff || csr0 == 0) + bad_card = 1; + else + { + csr0 &= ~EN_INT; + if(csr0 & BU_EMP) + csr0 |= EN_INT; + if((VALID_DECODER & (1 << (csr0 >> 4))) == 0) + bad_card = 1; + } + + if(bad_card) + return ENODEV; + else + outb(0, ioaddr + CSR0); + if(dev->irq < 2) + { + DP( printk("%s: autoprobing\n", dev->name); ); + autoirq_setup(5); + outb(EN_INT | TR_REQ, ioaddr + CSR0); + outb(PR_RES, ioaddr + CSR1); + autoirq = autoirq_report(5); + + if(autoirq == 0) + { + printk("sbni probe at %#x failed to detect IRQ line\n", ioaddr); + return EAGAIN; + } + } + /* clear FIFO buffer */ + outb(0, ioaddr + CSR0); + + if(autoirq) + dev->irq = autoirq; + + { + int irqval=request_irq(dev->irq, sbni_interrupt, 0, dev->name, dev); + if (irqval) + { + printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); + return EAGAIN; + } + } + + /* + * Initialize the device structure. + */ + + dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); + if(dev->priv == NULL) + { + DP( printk("%s: cannot allocate memory\n", dev->name); ) + return -ENOMEM; + } + + memset(dev->priv, 0, sizeof(struct net_local)); + dev->base_addr = ioaddr; + request_region(ioaddr, SBNI_IO_EXTENT, "sbni"); + + /* + * generate Ethernet address (0x00ff01xxxxxx) + */ + + *(u16*)dev->dev_addr = htons(0x00ff); + *(u32*)(dev->dev_addr+2) = htonl(((def_mac ? def_mac : (u32) dev->priv) & 0x00ffffff) | 0x01000000); + + lp = dev->priv; + if(def_rxl < 0) + { + /* autodetect receive level */ + lp->rxl_curr = 0xf; + lp->rxl_delta = -1; + } else { + /* fixed receive level */ + lp->rxl_curr = def_rxl & 0xf; + lp->rxl_delta = 0; + } + lp->csr1.rxl = rxl_tab[lp->rxl_curr]; + lp->csr1.rate = def_baud & 3; + lp->frame_len = DEF_FRAME_LEN; + printk("%s: sbni adapter at %#lx, using %sIRQ %d, MAC: 00:ff:01:%x:%x:%x\n", + dev->name, dev->base_addr, autoirq ? "auto":"assigned ", dev->irq, + *(unsigned char*)(dev->dev_addr+3), + *(unsigned char*)(dev->dev_addr+4), + *(unsigned char*)(dev->dev_addr+5) + ); + + printk("%s: receive level: ", dev->name); + if(lp->rxl_delta == 0) + printk ("%#1x (fixed)", lp->rxl_curr); + else + printk ("autodetect"); + printk(", baud rate: %u\n", (unsigned)lp->csr1.rate); + + /* + * The SBNI-specific entries in the device structure. + */ + dev->open = &sbni_open; + dev->hard_start_xmit = &sbni_start_xmit; + dev->stop = &sbni_close; + dev->get_stats = &sbni_get_stats; + dev->set_multicast_list = &set_multicast_list; + dev->set_mac_address = &sbni_set_mac_address; + dev->do_ioctl = &sbni_ioctl; + + /* + * Setup the generic properties + */ + + ether_setup(dev); + + dev->hard_header = sbni_header; + dev->hard_header_len = sizeof(struct sbni_hard_header); + dev->rebuild_header=sbni_rebuild_header; + dev->mtu = DEF_FRAME_LEN; + + dev->hard_header_cache = sbni_header_cache; + dev->header_cache_update = sbni_header_cache_update; + + lp->m=dev; + lp->me=dev; + lp->next_lp=NULL; + + return 0; +} + +/* + * Open/initialize the board. + */ + +static int sbni_open(struct net_device *dev) +{ + struct net_local* lp = (struct net_local*)dev->priv; + struct timer_list* watchdog = &lp->watchdog; + + + DP( printk("%s: sbni_open\n", dev->name); ) + + cli(); + lp->currframe = NULL; + + card_start(dev); + dev->start = 1; + /* set timer watchdog */ + init_timer(watchdog); + watchdog->expires = jiffies + SBNI_TIMEOUT; + watchdog->data = (unsigned long)dev; + watchdog->function = sbni_watchdog; + add_timer(watchdog); + DP( printk("%s: sbni timer watchdog initialized\n", dev->name); ); + + sti(); + + MOD_INC_USE_COUNT; + return 0; +} + +static int sbni_close(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + struct net_local* lp = (struct net_local*) dev->priv; + struct timer_list* watchdog = &lp->watchdog; + + + DP( printk("%s: sbni_close\n", dev->name); ) + + cli(); + + sbni_drop_tx_queue(dev); + + dev->tbusy = 1; + dev->start = 0; + + del_timer(watchdog); + + outb(0, ioaddr + CSR0); + sti(); + + MOD_DEC_USE_COUNT; + return 0; +} + +static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + struct sbni_hard_header *hh=(struct sbni_hard_header *)skb->data; + +#ifdef KATYUSHA + struct net_local *nl; + int stop; +#endif + + DP( printk("%s: sbni_start_xmit In \n", dev->name); ); + + + if(lp->me != dev) + panic("sbni: lp->me != dev !!!\nMail to developer (xenon@granch.ru) if you noticed this error\n"); + + if(dev->interrupt) + { + DP( printk("sbni_xmit_start: interrupt\n"); ) + /* May be unloading, don't stamp on */ + return 1; /* the packet buffer this time */ + } + + hh->number = 1; + hh->reserv = 0; + + hh->packetlen = (skb->len - sizeof (unsigned short) - + (sizeof(struct sbni_hard_header) - SBNI_HH_SZ)) + | PACKET_SEND_OK | PACKET_FIRST_FRAME; + + /* we should use hairy method to calculate crc because of extra bytes are + livin between hard header and data*/ + hh->crc = calc_crc((void*)&hh->packetlen, SBNI_HH_SZ - sizeof(unsigned), CRC32_INITIAL); + hh->crc = calc_crc(skb->data + sizeof(struct sbni_hard_header), + skb->len - sizeof(struct sbni_hard_header), + hh->crc); + +#ifdef KATYUSHA + /* looking for first idle device */ + for (stop=0,nl=lp; nl && !stop; nl=nl->next_lp) + { + if((!nl->currframe) && (nl->carrier)) /* if idle */ + { + skb->dev = lp->me; + nl->currframe = skb; + /* set request for transmit */ + outb(inb(nl->me->base_addr + CSR0) | TR_REQ, + nl->me->base_addr + CSR0); + stop=1; + } + } + + if(!stop) /* we havent found any idle.*/ + { + skb_queue_tail(&lp->queue,skb); + outb(inb(dev->base_addr + CSR0) | TR_REQ, dev->base_addr + CSR0); + + } +#else + if (lp->currframe || 1) + { + skb_queue_tail(&lp->queue,skb); + + } + else + { + lp->currframe = skb; + } + /* set request for transmit */ + outb(inb(dev->base_addr + CSR0) | TR_REQ, dev->base_addr + CSR0); +#endif + return 0; +} + +void card_start(struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + + DP( printk("%s: card_start\n",dev->name); ) + lp->wait_frame_number = 0; + lp->inppos = lp->outpos = 0; + lp->eth_trans_buffer_len = 0; + lp->tr_err = TR_ERROR_COUNT; + lp->last_receive_OK = FALSE; + lp->tr_resend = FALSE; + lp->timer_ticks = CHANGE_LEVEL_START_TICKS; + lp->timeout_rxl = 0; + + lp->waitack=0; + skb_queue_head_init(&lp->queue); + sbni_drop_tx_queue(dev); + dev->tbusy = 0; + + dev->interrupt = 0; + /* Reset the card and set start parameters */ + outb(PR_RES | *(char*)&lp->csr1, dev->base_addr + CSR1); + outb(EN_INT, dev->base_addr + CSR0); +} + +void sbni_nirvana(struct net_device *dev) +{ + sbni_outs(dev->base_addr+DAT,magic_reply,9); +} + +static inline unsigned short sbni_recv(struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + unsigned long crc; + unsigned short packetlen = 0; + unsigned short packetinf, packetfirst, receiveframeresend; + unsigned char current_frame; + unsigned int i, j; + unsigned char delme,rcv_res=RCV_WR; + + lp->in_stats.all_rx_number++; + + if((delme=inb(dev->base_addr + DAT)) == SBNI_SIG) + { + crc = CRC32_INITIAL; + *(((unsigned char *)&packetlen) + 0) = inb(dev->base_addr + DAT); + crc = CRC32(*(((unsigned char *)&packetlen) + 0), crc); + *(((unsigned char *)&packetlen) + 1) = inb(dev->base_addr + DAT); + crc = CRC32(*(((unsigned char *)&packetlen) + 1), crc); + packetinf = packetlen & PACKET_INF_MASK; + packetfirst = packetlen & PACKET_FIRST_FRAME; + receiveframeresend = packetlen & RECEIVE_FRAME_RESEND; + packetlen = packetlen & PACKET_LEN_MASK; + + + if((packetlen <= SB_MAX_BUFFER_ARRAY - 3) && (packetlen >= 6)) + { + /* read frame number */ + current_frame = inb(dev->base_addr + DAT); + crc = CRC32(current_frame, crc); + /* read HandShake counter */ + lp->HSCounter = inb(dev->base_addr + DAT); + crc = CRC32(lp->HSCounter, crc); + packetlen -= 2; + + sbni_ins(dev->base_addr + DAT, lp->eth_rcv_buffer + lp->inppos, packetlen); + + for(i = lp->inppos; i < (packetlen + lp->inppos); i++) + { + crc = CRC32(lp->eth_rcv_buffer[i], crc); + } + + if(crc == CRC32_REMAINDER) + { + if(packetlen > 4) + rcv_res=RCV_OK; + else if(packetlen == 4) + rcv_res=RCV_NO; + + if(lp->waitack && packetinf == PACKET_RESEND) + lp->in_stats.resend_tx_number++; + + + switch(packetinf) + { + case PACKET_SEND_OK: + { + lp->tr_err = TR_ERROR_COUNT; + lp->tr_resend = FALSE; + /* if(lp->trans_frame_number){ */ + lp->outpos += lp->realframelen; + + /* SendComplete + * not supported + */ + DP( printk("%s: sbni_recv SendComplete\n",dev->name); ); + /* + * We sucessfully sent current packet + */ + + if(lp->waitack) + { + dev_kfree_skb(lp->currframe); + lp->stats.tx_packets++; +#ifdef KATYUSHA + lp->currframe=skb_dequeue(&(((struct net_local*) (lp->m->priv))->queue)); +#else + lp->currframe=skb_dequeue(&lp->queue); +#endif + lp->in_stats.all_tx_number++; + lp->waitack=0; + } + + /* + * reset output active flags + */ + dev->tbusy = 0; + mark_bh(NET_BH); + /*} if */ + } + case PACKET_RESEND: + { + if(lp->tr_err) /**/ + lp->tr_err--; + if(lp->ok_curr < 0xffffffff) + lp->ok_curr++; + if(packetlen > 4 && !(lp->last_receive_OK && receiveframeresend)) + { + if(packetfirst) + { + if(lp->wait_frame_number) + { + for(i = lp->inppos, j = 0; + i < (lp->inppos + packetlen - 4); + i++, j++) + lp->eth_rcv_buffer[j] = lp->eth_rcv_buffer[i]; + } + lp->wait_frame_number = current_frame; + lp->inppos = 0; + } + if(current_frame == lp->wait_frame_number) + { + lp->inppos += (packetlen - 4); + if(lp->wait_frame_number == 1) + { + sbni_get_packet(dev); + lp->inppos = 0; + } + lp->wait_frame_number--; + } + } + lp->last_receive_OK = TRUE; + break; + } + default: + break; + } + } + else + { + DP(printk("%s: bad CRC32\n",dev->name)); + change_level(dev); + } + } + else + { + DP(printk("%s: bad len\n ",dev->name)); + change_level(dev); + lp->stats.rx_over_errors++; + } + } + else + { + DP(printk("%s: bad sig\n",dev->name)); + change_level(dev); + } + outb(inb(dev->base_addr + CSR0) ^ CT_ZER, dev->base_addr + CSR0); + return (rcv_res); +} + +void change_level(struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + + lp->in_stats.bad_rx_number++; + lp->stats.tx_errors++; + if(lp->rxl_delta == 0) + return; + /* + * set new rxl_delta value + */ + if(lp->rxl_curr == 0) + lp->rxl_delta = 1; + else if(lp->rxl_curr == 0xf) + lp->rxl_delta = -1; + else if(lp->ok_curr < lp->ok_prev) + lp->rxl_delta = -lp->rxl_delta; + /* + * set new rxl_curr value + */ + lp->csr1.rxl = rxl_tab[lp->rxl_curr += lp->rxl_delta]; + outb(*(char*)&lp->csr1, dev->base_addr + CSR1); + + + /* + * update ok_prev/ok_curr counters + */ + lp->ok_prev = lp->ok_curr; + lp->ok_curr = 0; + + DP( printk("%s: receive error, rxl_curr = %d, rxl_delta = %d\n",\ + dev->name,lp->rxl_curr, lp->rxl_delta); ) + +} + +static inline void sbni_xmit(struct net_device *dev) +{ + struct net_local* lp = (struct net_local *)dev->priv; + struct sk_buff *skb; + + skb=lp->currframe; + + DP( printk("%s: sbni_xmit CSR0=%02x\n",dev->name, (unsigned char)inb(dev->base_addr + CSR0)); ); + + /* push signature*/ + outb(SBNI_SIG, dev->base_addr + DAT); + + /* push frame w/o crc [HAiRY]*/ + sbni_outs(dev->base_addr + DAT, + &((struct sbni_hard_header *)(skb->data))->packetlen, + SBNI_HH_SZ - sizeof(unsigned)); + + sbni_outs(dev->base_addr + DAT, + skb->data + sizeof(struct sbni_hard_header), + skb->len - sizeof(struct sbni_hard_header)); /* успеем еще */ + + /* push crc */ + sbni_outs(dev->base_addr + DAT, skb->data, sizeof(unsigned)); + + lp->waitack=1; +} + +/* + * The typical workload of the driver: + * Handle the ether interface interrupts. + */ +static void sbni_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct net_local* lp; + u_char csr0; + unsigned short rcv_res = RCV_NO; + + + if(dev == NULL || dev->irq != irq) + { + printk("sbni: irq %d for unknown device\n", irq); + return; + } + + if(dev->interrupt) + { + printk("%s: Reentering the interrupt driver!\n", dev->name); + return; + } + dev->interrupt = 1; + + csr0 = inb(dev->base_addr + CSR0); + DP( printk("%s: entering interrupt handler, CSR0 = %02x\n", dev->name, csr0); ) + + lp=dev->priv; + + if(!lp->carrier) + lp->carrier=1; + + /* + * Disable adapter interrupts + */ + outb((csr0 & ~EN_INT) | TR_REQ, dev->base_addr + CSR0); + lp->timer_ticks = CHANGE_LEVEL_START_TICKS; + csr0 = inb(dev->base_addr + CSR0); + + if(csr0 & (TR_RDY | RC_RDY)) + { + if(csr0 & RC_RDY) + rcv_res = sbni_recv(dev); + + if((lp->currframe) && (rcv_res != RCV_WR)) + sbni_xmit(dev); + else if (rcv_res == RCV_OK) + sbni_nirvana(dev); + + csr0 = inb(dev->base_addr + CSR0); + DP( printk("%s: CSR0 = %02x\n",dev->name, (u_int)csr0); ); + } + + + DP( printk("%s: leaving interrupt handler, CSR0 = %02x\n",dev->name, csr0 | EN_INT); ); + + /* here we should send pong */ + outb(inb(dev->base_addr+CSR0) & ~TR_REQ, dev->base_addr + CSR0); + if(lp->currframe) + outb(inb(dev->base_addr+CSR0) | TR_REQ, dev->base_addr + CSR0); + else + csr0 = inb(dev->base_addr + CSR0); + + /* + * Enable adapter interrupts + */ + + outb(csr0 | EN_INT, dev->base_addr + CSR0); + dev->interrupt = 0; +} + +static struct enet_statistics *sbni_get_stats(struct net_device *dev) +{ + struct net_local *lp = (struct net_local *)dev->priv; + return &lp->stats; +} + +static inline void sbni_get_packet(struct net_device* dev) +{ + struct net_local* lp = (struct net_local*)dev->priv; + struct sk_buff* skb; + unsigned char *rawp; + + + + skb = dev_alloc_skb(lp->inppos - ETH_HLEN + sizeof(struct sbni_hard_header)); + + if(skb == NULL) + { + DP( printk("%s: Memory squeeze, dropping packet.\n", dev->name); ) + lp->stats.rx_dropped++; + return; + } else { +#ifdef KATYUSHA + skb->dev = lp->m; +#else + skb->dev = dev; +#endif + memcpy((unsigned char*)skb_put(skb, lp->inppos + 8)+8, + lp->eth_rcv_buffer, + lp->inppos); + + + skb->mac.raw = skb->data + 8; + + if((*(char*)lp->eth_rcv_buffer) & 1) + { + if(memcmp(lp->eth_rcv_buffer,dev->broadcast, ETH_ALEN)==0) + skb->pkt_type=PACKET_BROADCAST; + else + skb->pkt_type=PACKET_MULTICAST; + } + else if(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) + { + if(memcmp(lp->eth_rcv_buffer,dev->dev_addr, ETH_ALEN)) + skb->pkt_type=PACKET_OTHERHOST; + } + + if( htons(*((unsigned short*)(&lp->eth_rcv_buffer[2*ETH_ALEN]))) >= 1536) + skb->protocol = *((unsigned short*)(&lp->eth_rcv_buffer[2*ETH_ALEN])); + else + { + rawp = (unsigned char*)(&lp->eth_rcv_buffer[2*ETH_ALEN]); + if (*(unsigned short *)rawp == 0xFFFF) + skb->protocol=htons(ETH_P_802_3); + else + skb->protocol=htons(ETH_P_802_2); + } + + + skb_pull(skb,SBNI_HH_SZ); + + netif_rx(skb); + lp->stats.rx_packets++; + } + return; +} + +static void sbni_watchdog(unsigned long arg) +{ + struct net_device* dev = (struct net_device*)arg; + struct net_local* lp = (struct net_local *)dev->priv; + u_char csr0; + + + + DP( printk("%s: watchdog start\n",dev->name); ) + /* + * if no pong received and transmission is not in progress + * then assume error + */ + cli(); + csr0 = inb(dev->base_addr + CSR0); + if(csr0 & (RC_CHK | TR_REQ)) + { + if(lp->timer_ticks) + { + if(csr0 & (RC_RDY | BU_EMP)) + { + lp->timer_ticks--; + } + } + else + { + if(lp->rxl_delta) + { + lp->ok_prev = lp->ok_curr; + lp->ok_curr = 0; + lp->rxl_curr = timeout_rxl_tab[lp->timeout_rxl]; + lp->timeout_rxl++; + if(lp->timeout_rxl > SIZE_OF_TIMEOUT_RXL_TAB - 1) + lp->timeout_rxl = 0; + lp->csr1.rxl = rxl_tab[lp->rxl_curr]; + /* + * update ok_prev/ok_curr counters + */ + lp->ok_prev = lp->ok_curr; + lp->ok_curr = 0; + } + if(lp->tr_err) + lp->tr_err--; + else + { + /* Drop the queue of tx packets */ + sbni_drop_tx_queue(dev); + lp->carrier=0; + } + + /* + * send pong + */ + + csr0 = inb(dev->base_addr + CSR0); + outb(csr0 & ~TR_REQ, dev->base_addr + CSR0); + outb(*(char*)(&lp->csr1) | PR_RES, dev->base_addr + CSR1); + lp->in_stats.timeout_number++; + } + } + sti(); + outb(csr0 | RC_CHK, dev->base_addr + CSR0); + if(dev->start) + { + struct timer_list* watchdog = &lp->watchdog; + init_timer(watchdog); + watchdog->expires = jiffies + SBNI_TIMEOUT; + watchdog->data = arg; + watchdog->function = sbni_watchdog; + add_timer(watchdog); + } +} + +static void sbni_drop_tx_queue(struct net_device *dev) +{ + struct net_local* lp = (struct net_local *)dev->priv,*nl; + struct sk_buff *tmp; + + /* first of all, we should try to gift our packets to another interface */ + + nl=(struct net_local *)lp->m->priv; + if(nl==lp) + nl=lp->next_lp; + + if(nl) + { + /* we found device*/ + if(lp->currframe) + { + if(!nl->currframe) + { + nl->currframe=lp->currframe; + } + else + { + skb_queue_head(&((struct net_local*)(lp->m->priv))->queue,lp->currframe); + } + } + lp->currframe=NULL; + + if(!nl->currframe) + nl->currframe=skb_dequeue(&(((struct net_local*)(lp->m->priv))->queue)); + + /* set request for transmit */ + outb(inb(nl->me->base_addr + CSR0) | TR_REQ, nl->me->base_addr + CSR0); + + } + else + { + /* *sigh*, we should forget this packets */ + nl=lp->m->priv; + + while((tmp = skb_dequeue(&nl->queue)) != NULL) + { + dev_kfree_skb(tmp); + lp->stats.tx_packets++; + } + + if (lp->currframe) + { + dev_kfree_skb(lp->currframe); + lp->currframe = NULL; + lp->stats.tx_packets++; + } + } + lp->waitack=0; + dev->tbusy = 0; + + mark_bh(NET_BH); + DP( printk("%s: queue dropping stoped\n",dev->name); ); +} + +/* + * Set or clear the multicast filter for this adaptor. + * num_addrs == -1 Promiscuous mode, receive all packets + * num_addrs == 0 Normal mode, clear multicast list + * num_addrs > 0 Multicast mode, receive normal and MC packets, + * and do best-effort filtering. + */ + +static void set_multicast_list(struct net_device *dev) +{ + /* + * always enabled promiscuous mode. + */ + return; +} + +static int sbni_set_mac_address(struct net_device *dev, void *addr) +{ + /* struct net_local *lp = (struct net_local *)dev->priv; */ + struct sockaddr *saddr = addr; + + if(dev->start) + { + /* Only possible while card isn't started */ + return -EBUSY; + } + memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len); + return (0); +} + +static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct net_local* lp = (struct net_local *)dev->priv,*tlp; + struct net_device *slave; + int error = 0; + char tmpstr[6]; + + + switch(cmd) + { + case SIOCDEVGETINSTATS: + { + struct sbni_in_stats *in_stats = (struct sbni_in_stats *)ifr->ifr_data; + DP( printk("%s: SIOCDEVGETINSTATS %08x\n",dev->name,(unsigned)in_stats);) + if(copy_to_user((void *)in_stats, (void *)(&(lp->in_stats)), sizeof(struct sbni_in_stats))) + return -EFAULT; + break; + } + case SIOCDEVRESINSTATS: + { + DP( printk("%s: SIOCDEVRESINSTATS\n",dev->name); ) + lp->in_stats.all_rx_number = 0; + lp->in_stats.bad_rx_number = 0; + lp->in_stats.timeout_number = 0; + lp->in_stats.all_tx_number = 0; + lp->in_stats.resend_tx_number = 0; + break; + } + case SIOCDEVGHWSTATE: + { + struct sbni_flags flags; + flags.rxl = lp->rxl_curr; + flags.rate = lp->csr1.rate; + flags.fixed_rxl = (lp->rxl_delta == 0); + flags.fixed_rate = 1; + ifr->ifr_data = *(caddr_t*)&flags; + DP( printk("%s: get flags (0x%02x)\n",dev->name, (unsigned char)ifr->ifr_data); ) + break; + } + case SIOCDEVSHWSTATE: + { + struct sbni_flags flags; + DP( printk("%s: SIOCDEVSHWSTATE flags=0x%02x\n",dev->name, (unsigned char)ifr->ifr_data); ) + /* root only */ + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + flags = *(struct sbni_flags*)&ifr->ifr_data; + if(flags.fixed_rxl) + { + lp->rxl_delta = 0; + lp->rxl_curr = flags.rxl; + } + else + { + lp->rxl_delta = DEF_RXL_DELTA; + lp->rxl_curr = DEF_RXL; + } + lp->csr1.rxl = rxl_tab[lp->rxl_curr]; + if(flags.fixed_rate) + lp->csr1.rate = flags.rate; + else + lp->csr1.rate = DEF_RATE; + /* + * Don't be afraid... + */ + outb(*(char*)(&lp->csr1) | PR_RES, dev->base_addr + CSR1); + + DP( printk("%s: set flags (0x%02x)\n receive level: %u, baud rate: %u\n",\ + dev->name, (unsigned char)ifr->ifr_data, (unsigned)lp->rxl_curr, (unsigned)lp->csr1.rate); ) + break; + } + + case SIOCDEVENSLAVE: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + if(copy_from_user( tmpstr, ifr->ifr_data, 6)) + return -EFAULT; + slave=dev_get(tmpstr); + if(!(slave && slave->flags & IFF_UP && dev->flags & IFF_UP)) + { + printk("%s: Both devices should be UP to enslave!\n",dev->name); + return -EINVAL; + } + + if(slave) + { + if(!((dev->flags & IFF_SLAVE) || (slave->flags & IFF_SLAVE))) + { + /* drop queue*/ + sbni_drop_tx_queue(slave); + slave->flags |= IFF_SLAVE; + ((struct net_local *)(slave->priv))->m=dev; + while(lp->next_lp) //tail it after last slave + lp=lp->next_lp; + lp->next_lp=slave->priv; + lp=(struct net_local *)dev->priv; + dev->flags |= IFF_MASTER; + } + else + { + printk("%s: one of devices is already slave!\n",dev->name); + return -EBUSY; + } + } + else + { + printk("%s: can't find device %s to enslave\n",dev->name,ifr->ifr_data); + return -ENOENT; + } + break; + + case SIOCDEVEMANSIPATE: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if(dev->flags & IFF_SLAVE) + { + dev->flags &= ~IFF_SLAVE; + /* exclude us from masters slavelist*/ + for(tlp=lp->m->priv;tlp->next_lp!=lp && tlp->next_lp;tlp=tlp->next_lp); + if(tlp->next_lp) + { + tlp->next_lp = lp->next_lp; + if(!((struct net_local *)lp->m->priv)->next_lp) + { + lp->m->flags &= ~IFF_MASTER; + } + lp->next_lp=NULL; + lp->m=dev; + } + else + { + printk("%s: Ooops. drivers structure is mangled!\n",dev->name); + return -EIO; + } + } + else + { + printk("%s: isn't slave device!\n",dev->name); + return -EINVAL; + } + break; + + default: + DP( printk("%s: invalid ioctl: 0x%x\n",dev->name, cmd); ) + error = -EINVAL; + } + return (error); +} + + + +#ifdef CRCASM + +unsigned long calc_crc(char *mem, int len, unsigned initial) +{ + + __asm__ ( + "xorl %%eax,%%eax\n\t" + "1:\n\t" + "lodsb\n\t" + "xorb %%dl,%%al\n\t" + "shrl $8,%%edx\n\t" + "xorl (%%edi,%%eax,4),%%edx\n\t" + "loop 1b\n\t" + "movl %%edx,%%eax" + : + : "S" (mem), "D" (&crc32tab[0]), "c" (len), "d" (initial) + : "eax", "edx", "ecx" + ); + /* return crc; */ +} + +#else + +unsigned long calc_crc(char *mem, int len, unsigned initial) +{ + unsigned crc; + crc = initial; + + for(;len;mem++,len--) + { + crc = CRC32(*mem, crc); + } + return(crc); +} +#endif /* CRCASM */ +#ifdef MODULE + +static int io[SBNI_MAX_NUM_CARDS] = { 0 }; +static int irq[SBNI_MAX_NUM_CARDS] = { 0 }; +static int rxl[SBNI_MAX_NUM_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +static int baud[SBNI_MAX_NUM_CARDS] = { 0 }; +static long mac[SBNI_MAX_NUM_CARDS] = { 0 }; + +#ifdef v22 +MODULE_PARM(io, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(rxl, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(baud, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(mac, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +#endif + + +static int sbniautodetect = -1; + +static struct net_device dev_sbni[SBNI_MAX_NUM_CARDS] = { + { + "sbni0", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni1", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni2", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni3", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni4", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni5", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni6", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni7", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + } +}; + +int init_module(void) +{ + int devices = 0; + int installed = 0; + int i; + + /* My simple plug for this huge init_module. "XenON */ + + if(sbniautodetect != -1) + { + /* Autodetect mode */ + printk("sbni: Autodetect mode (not recommended!) ...\n"); + if(!sbniautodetect) + sbniautodetect=SBNI_MAX_NUM_CARDS; + printk("Trying to find %d SBNI cards...\n", sbniautodetect); + if(sbniautodetect > SBNI_MAX_NUM_CARDS) + { + sbniautodetect = SBNI_MAX_NUM_CARDS; + printk("sbni: You want to detect too many cards. Truncated to %d\n", SBNI_MAX_NUM_CARDS); + } + for(i = 0; i < sbniautodetect; i++) + { + if(!register_netdev(&dev_sbni[i])) + installed++; + } + if(installed) + return 0; + else + return -EIO; + } + + /* Manual mode */ + for(i = 0; i < SBNI_MAX_NUM_CARDS; i++) + { + if((io[i] != 0) || (irq[i] != 0)) + devices++; + } + for(i = 0; i < devices; i++) + { + dev_sbni[i].irq = irq[i]; + dev_sbni[i].base_addr = io[i]; + def_rxl = rxl[i]; + def_baud = baud[i]; + def_mac = mac[i]; + if(register_netdev(&dev_sbni[i])) + printk("sbni: card not found!\n"); + else + installed++; + } + if(installed) + return 0; + else + return -EIO; +} + +void cleanup_module(void) +{ + int i; + for(i = 0; i < 4; i++) + { + if(dev_sbni[i].priv) + { + free_irq(dev_sbni[i].irq, &dev_sbni[i]); + release_region(dev_sbni[i].base_addr, SBNI_IO_EXTENT); + unregister_netdev(&dev_sbni[i]); + kfree(dev_sbni[i].priv); + dev_sbni[i].priv = NULL; + } + } +} +#endif /* MODULE */ diff --git a/drivers/net/wan/sbni.h b/drivers/net/wan/sbni.h new file mode 100644 index 000000000..2e34d8d34 --- /dev/null +++ b/drivers/net/wan/sbni.h @@ -0,0 +1,194 @@ +/* + * sbni.h - header file for sbni linux device driver + * + * Copyright (C) 1999 Granch ltd., Yaroslav Polyakov (xenon@granch.ru). + * + */ + +/* + * SBNI12 definitions + * + * Revision 2.0.0 1997/08/27 + * Initial revision + * + * Revision 2.1.0 1999/04/26 + * dev_priv structure changed to support balancing and some other features. + * + */ + +#ifndef __SBNI_H +#define __SBNI_H + +#define SBNI_DEBUG 0 + +#if SBNI_DEBUG +#define DP( A ) A +#else +#define DP( A ) +#endif + +typedef unsigned char BOOLEAN; + +#define TRUE 1 +#define FALSE 0 + +#define SBNI_IO_EXTENT 0x4 +#define SB_MAX_BUFFER_ARRAY 1023 + +#define CSR0 0 +#define CSR1 1 + +#define DAT 2 + +/* CSR0 mapping */ +#define BU_EMP (1 << 1) /* r z */ +#define RC_CHK (1 << 2) /* rw */ +#define CT_ZER (1 << 3) /* w */ +#define TR_REQ (1 << 4) /* rwz* */ + +#define TR_RDY (1 << 5) /* r z */ +#define EN_INT (1 << 6) /* rwz* */ +#define RC_RDY (1 << 7) /* r z */ + +/* CSR1 mapping */ +#define PR_RES (1 << 7) /* w */ + +struct sbni_csr1 { + unsigned rxl:5; + unsigned rate:2; + unsigned:1; +}; + +#define DEF_RXL_DELTA -1 +#define DEF_RXL 0xf +#define DEF_RATE 0 +#define DEF_FRAME_LEN (1023 - 14 - 9) + +#ifdef MODULE + +#define SBNI_MAX_NUM_CARDS 8 +#define SBNI_MAX_SLAVES 8 + + +#endif /* MODULE */ + +#define SBNI_SIG 0x5a + +#define SB_ETHER_MIN_LEN 60 + +#define SB_FILLING_CHAR (unsigned char)0x00 +#define TR_ERROR_COUNT 32 +#define CHANGE_LEVEL_START_TICKS 4 +#define SBNI_INTERNAL_QUEUE_SIZE 10 /* 100 ? */ + +#define PACKET_FIRST_FRAME (unsigned short)0x8000 +#define RECEIVE_FRAME_RESEND (unsigned short)0x0800 +#define PACKET_RESEND 0x4000 +#define PACKET_SEND_OK 0x3000 +#define PACKET_LEN_MASK (unsigned short)0x03ff +#define PACKET_INF_MASK (unsigned short)0x7000 + +#define ETHER_ADDR_LEN 6 + +#define SBNI_TIMEOUT HZ/10 /* ticks to wait for pong or packet */ + /* sbni watchdog called SBNI_HZ times per sec. */ + +struct sbni_in_stats { + unsigned int all_rx_number; + unsigned int bad_rx_number; + unsigned int timeout_number; + unsigned int all_tx_number; + unsigned int resend_tx_number; +}; + + +/* + * Board-specific info in dev->priv. + */ +struct net_local { + struct enet_statistics stats; + + struct timer_list watchdog; + unsigned int realframelen; /* the current size of the SB-frame */ + unsigned int eth_trans_buffer_len; /* tx buffer length */ + unsigned int outpos; + unsigned int inppos; + unsigned int frame_len; /* The set SB-frame size */ + unsigned int tr_err; + unsigned int timer_ticks; + BOOLEAN last_receive_OK; + BOOLEAN tr_resend; + + unsigned char wait_frame_number; + unsigned char eth_trans_buffer[1520]; /* tx buffer */ + unsigned char HSCounter; /* Reserved field */ + unsigned char eth_rcv_buffer[2600]; /* rx buffer */ + struct sbni_csr1 csr1; + /* Internal Statistics */ + struct sbni_in_stats in_stats; + + int rxl_curr; /* current receive level value [0..0xf] */ + int rxl_delta; /* receive level delta (+1, -1) + rxl_delta == 0 - receive level + autodetection + disabled */ + unsigned int ok_curr; /* current ok frames received */ + unsigned int ok_prev; /* previous ok frames received */ + unsigned int timeout_rxl; + + struct sk_buff_head queue; + struct sk_buff *currframe; + BOOLEAN waitack; + + struct net_device *m; /* master */ + struct net_device *me; /* me */ + struct net_local *next_lp; /* next lp */ + + int carrier; + + +}; + + +struct sbni_hard_header { + + /* internal sbni stuff */ + unsigned int crc; /* 4 */ + unsigned short packetlen; /* 2 */ + unsigned char number; /* 1 */ + unsigned char reserv; /* 1 */ + + /* 8 */ + + /* ethernet stuff */ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ + /* +14 */ + /* 22 */ + +}; + +#define SBNI_HH_SZ 22 + +struct sbni_flags { + unsigned rxl:4; + unsigned rate:2; + unsigned fixed_rxl:1; + unsigned fixed_rate:1; +}; + +#define RCV_NO 0 +#define RCV_OK 1 +#define RCV_WR 2 + + +#define SIOCDEVGETINSTATS SIOCDEVPRIVATE +#define SIOCDEVRESINSTATS SIOCDEVPRIVATE+1 +#define SIOCDEVGHWSTATE SIOCDEVPRIVATE+2 +#define SIOCDEVSHWSTATE SIOCDEVPRIVATE+3 +#define SIOCDEVENSLAVE SIOCDEVPRIVATE+4 +#define SIOCDEVEMANSIPATE SIOCDEVPRIVATE+5 + + +#endif /* __SBNI_H */ diff --git a/drivers/net/sdla.c b/drivers/net/wan/sdla.c index 9b5152366..9b5152366 100644 --- a/drivers/net/sdla.c +++ b/drivers/net/wan/sdla.c diff --git a/drivers/net/sdla_fr.c b/drivers/net/wan/sdla_fr.c index 6b2201a81..6b2201a81 100644 --- a/drivers/net/sdla_fr.c +++ b/drivers/net/wan/sdla_fr.c diff --git a/drivers/net/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c index d35ac7c18..d35ac7c18 100644 --- a/drivers/net/sdla_ppp.c +++ b/drivers/net/wan/sdla_ppp.c diff --git a/drivers/net/sdla_x25.c b/drivers/net/wan/sdla_x25.c index 270c5a59f..270c5a59f 100644 --- a/drivers/net/sdla_x25.c +++ b/drivers/net/wan/sdla_x25.c diff --git a/drivers/net/sdladrv.c b/drivers/net/wan/sdladrv.c index 7182dff42..5e1f6b99e 100644 --- a/drivers/net/sdladrv.c +++ b/drivers/net/wan/sdladrv.c @@ -5,6 +5,7 @@ * used by all Sangoma drivers. * * Author: Gene Kozin <genek@compuserve.com> +* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> * * Copyright: (c) 1995-1996 Sangoma Technologies Inc. * diff --git a/drivers/net/sdlamain.c b/drivers/net/wan/sdlamain.c index ca98eeff9..23b811fc9 100644 --- a/drivers/net/sdlamain.c +++ b/drivers/net/wan/sdlamain.c @@ -3,6 +3,7 @@ * * Author: Gene Kozin <genek@compuserve.com> * Jaspreet Singh <jaspreet@sangoma.com> +* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> * * Copyright: (c) 1995-1997 Sangoma Technologies Inc. * diff --git a/drivers/net/sealevel.c b/drivers/net/wan/sealevel.c index 1dc146711..5cbbff8c9 100644 --- a/drivers/net/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -340,7 +340,7 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i for(i=0;i<999;i++) { sprintf(sv->name,"hdlc%d", i); - if(dev_get(sv->name)==NULL) + if(dev_get(sv->name)==0) { struct net_device *d=sv->chan->netdevice; diff --git a/drivers/net/syncppp.c b/drivers/net/wan/syncppp.c index eee3fceb8..eee3fceb8 100644 --- a/drivers/net/syncppp.c +++ b/drivers/net/wan/syncppp.c diff --git a/drivers/net/syncppp.h b/drivers/net/wan/syncppp.h index c03c720ca..c03c720ca 100644 --- a/drivers/net/syncppp.h +++ b/drivers/net/wan/syncppp.h diff --git a/drivers/net/x25_asy.c b/drivers/net/wan/x25_asy.c index 49d041abc..49d041abc 100644 --- a/drivers/net/x25_asy.c +++ b/drivers/net/wan/x25_asy.c diff --git a/drivers/net/x25_asy.h b/drivers/net/wan/x25_asy.h index 5abeceb20..5abeceb20 100644 --- a/drivers/net/x25_asy.h +++ b/drivers/net/wan/x25_asy.h diff --git a/drivers/net/z85230.c b/drivers/net/wan/z85230.c index a802170ce..a802170ce 100644 --- a/drivers/net/z85230.c +++ b/drivers/net/wan/z85230.c diff --git a/drivers/net/z85230.h b/drivers/net/wan/z85230.h index 0b4b48748..0b4b48748 100644 --- a/drivers/net/z85230.h +++ b/drivers/net/wan/z85230.h |