home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / network / drivers / wdsetup_.z / wdsetup_ / wdsetup-0.6 / wdsetup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-05  |  71.2 KB  |  2,302 lines

  1. /* wdsetup.c: A WD and SMC ethernet card configurer for linux. */
  2. /*
  3.     Written 1993 by Gregg Weber. This is alpha test code.
  4.     This is an extension to the Linux operating system, and is covered by
  5.     same Gnu Public License that covers that work.
  6.  
  7.     version 0.3 3-mar-1993 gw added command line configuration stuff 
  8.     version 0.4 15-mar-1993 gw added twisted pair support 
  9.     version 0.5 19-mar-1993 gw fixed bug in wrongly id 8003 board with
  10.     interface chip as 8013.
  11.     version 0.6 28-april-1992 gw updated based on new lmgetcnfg code from SMC
  12. */
  13.     
  14. #include <unistd.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17.  
  18. #define wdsetup_version "0.6a"
  19. #define PERM_OFF 0
  20. #define PERM_ON 1
  21. #define WD_JUMPERS 6
  22.  
  23. #undef FACTORY_INIT
  24.  
  25. unsigned char eedata[8];
  26. int verbose;
  27. unsigned char ConfigZero[8];
  28. int cnfg_val;
  29. static unsigned char irqlist[8] = {9,3,5,7,10,11,15,4};
  30.  
  31.  
  32. /*--------------- General Equates -----------------*/
  33. #define CHECKSUM    0x0ff
  34. #define RECALL_DATA    0
  35. #define RECALL_LANADDR    1
  36.  
  37. /******************************
  38.  Adapter Structure Definition
  39. ******************************/
  40.  
  41. typedef struct
  42. {  
  43.   int    adapter_num;        /* logical adapter no. */
  44.   int    pc_bus;            /* Bus type */
  45.   int    io_base;        /* I/O base address */
  46.   char    adapter_name[12];
  47.   int    irq_value;           /* IRQ line used by hardware */
  48.   int    rom_size;        /* num of 1024 byte blocks */
  49.   int    rom_base;        /* physical address of ROM */
  50.   int    rom_access;        /* seg:off value to access ROM */
  51.   int    ram_size;        /* num of 1024 byte blocks */
  52.   int    ram_base;        /* physical address of RAM */
  53.   int    ram_access;        /* seg:off value to access RAM */
  54.   int    ram_usable;        /* num of 1024 byte blocks (window size) */
  55.   int    io_base_new;        /* new base I/O Addr (for PutCnfg) */
  56.   char    node_address[6];     /* network address */
  57.   int    max_packet_size;    /* max pkt size hardware supports */
  58.   int    num_of_tx_buffs;    /* TX buffs available in hardware */
  59.   int    media_type;        /* BNC, AUI, UTP_4, etc. */
  60.   int    adapter_bus;
  61.   int    pos_id;            /* Adapter POS ID (MCA only) */
  62.   int    adapter_flags;
  63.   int    slot_num;        /* Micro Channel slot number */
  64.  
  65. /* -----------------...Local vars for each adapter...----------------------*/
  66.  
  67.   int    bic_type;
  68.   int    nic_type;
  69.   int    board_id;        /* WDM defined Board ID */
  70.   int    extra_info;        /* WDM defined Extra Board Info */
  71.   int    full_bid;        /* 32 bit board info */
  72.   int    mode_bits;        /* mode bits for adapter */
  73.   int    status_bits;
  74.   int    config_mode;        /*  1=store config in EEROM */
  75.   int    page_offset_mask;
  76.   int    clone;            /* 1=card is a clone */
  77. } CNFG_Adapter;
  78.  
  79.  
  80. /**************
  81.  Return Codes
  82. **************/
  83.  
  84. #define SUCCESS            0x0000    /* this code is defined by NDIS spec */
  85. #define ADAPTER_AND_CONFIG    0x0001
  86. #define ADAPTER_NO_CONFIG    0x0002
  87. #define UNKNOWN_ADAPTER        0x0086
  88. #define CONFIG_ERROR        0x0087
  89. #define CONFIG_WARNING        0x0088
  90. #define NO_FIXED_CNFG        0x0089
  91. #define EEROM_CKSUM_ERROR    0x008A
  92. #define ADAPTER_NOT_FOUND    0x0ffff
  93. #define ILLEGAL_FUNCTION    INVALID_FUNCTION
  94.  
  95. /*
  96.  Bit-Mapped codes returned in cnfg_val if return code from LM_GET_CONFIG is
  97.  CONFIG_ERROR or CONFIG_WARNING:
  98. */
  99.  
  100. /* Errors */
  101. #define IO_BASE_INVALID        0x0001
  102. #define IO_BASE_RANGE        0x0002
  103. #define IRQ_INVALID        0x0004
  104. #define IRQ_RANGE        0x0008
  105. #define RAM_BASE_INVALID    0x0010
  106. #define RAM_BASE_RANGE        0x0020
  107. #define RAM_SIZE_RANGE        0x0040
  108.  
  109. /* Warnings */
  110. #define IRQ_MISMATCH        0x0080
  111. #define RAM_BASE_MISMATCH    0x0100
  112. #define RAM_SIZE_MISMATCH    0x0200
  113.  
  114.  
  115. /*
  116.  Definitions for the field BUS_TYPE
  117. */
  118. #define AT_BUS            0x00
  119. #define MCA_BUS            0x01
  120. #define EISA_BUS        0x02
  121. #define PCMCIA_BUS        0x03
  122.  
  123. /**********************
  124.  MODE BIT DEFINITIONS
  125. **********************/
  126.  
  127. #define INTERRUPT_STATUS_BIT    0x8000    /* PC Interrupt Line: 0=Not Enabled */
  128. #define BOOT_STATUS_MASK    0x6000    /* Mask to isolate BOOT_STATUS */
  129. #define BOOT_INHIBIT        0x0000    /* BOOT_STATUS is 'inhibited' */
  130. #define BOOT_TYPE_1        0x2000    /* Unused BOOT_STATUS value */
  131. #define BOOT_TYPE_2        0x4000    /* Unused BOOT_STATUS value */
  132. #define BOOT_TYPE_3        0x6000    /* Unused BOOT_STATUS value */
  133. #define ZERO_WAIT_STATE_MASK    0x1800    /* Mask to isolate Wait State flags */
  134. #define ZERO_WAIT_STATE_8_BIT    0x1000    /* 0=Disabled (Inserts Wait States) */
  135. #define ZERO_WAIT_STATE_16_BIT    0x0800    /* 0=Disabled (Inserts Wait States) */
  136. #define BNC_INTERFACE        0x0400    /* net defs for adv. feature adapters*/
  137. #define AUI_INTERFACE        0x0300    
  138. #define AUI_10BT_INTERFACE    0x0200    
  139. #define STARLAN_10_INTERFACE    0x0100    
  140. #define INTERFACE_TYPE_MASK    0x0700    /* Mask value for interface type */
  141.  
  142. /****************************************************************************
  143.  Definitions for the field:
  144.  media_type
  145.  TP = Twisted Pair
  146.  STP = Shielded twisted pair
  147.  UTP = Unshielded twisted pair
  148. *****************************************************************************/
  149. #define CNFG_MEDIA_TYPE_MASK    0x03    /* bits 0-1 */
  150.  
  151. #define MEDIA_S10        0x00000    /* Ethernet adapter, TP. */
  152. #define MEDIA_AUI_UTP        0x00001    /* Ethernet adapter, AUI/UTP media. */
  153. #define MEDIA_BNC        0x00002    /* Ethernet adapter, BNC media. */
  154. #define MEDIA_AUI        0x00003    /* Ethernet adapter, AUI media. */
  155. #define MEDIA_STP_16        0x00004    /* TokenRing adap, 16Mbit STP. */
  156. #define MEDIA_STP_4        0x00005    /* TokenRing adap, 4Mbit STP. */
  157. #define MEDIA_UTP_16        0x00006    /* TokenRing adap, 16Mbit UTP. */
  158. #define MEDIA_UTP_4        0x00007    /* TokenRing adap, 4Mbit UTP. */
  159. #define MEDIA_UNKNOWN        0x0FFFF    /* Unknown adapter/media type */
  160.  
  161. /****************************************************************************
  162.  Definitions for the field:
  163.  bic_type (Bus interface chip type)
  164. */
  165. #define BIC_NO_CHIP        0x00000    /* Bus interface chip not implemented */
  166. #define BIC_583_CHIP        0x00001    /* 83C583 bus interface chip */
  167. #define BIC_584_CHIP        0x00002    /* 83C584 bus interface chip */
  168. #define BIC_585_CHIP        0x00003    /* 83C585 bus interface chip */
  169. #define BIC_593_CHIP        0x00004    /* 83C593 bus interface chip */
  170. #define BIC_594_CHIP        0x00005    /* 83C594 bus interface chip */
  171. #define BIC_564_CHIP        0x00006    /* PCMCIA bus interface chip */
  172. #define BIC_790_CHIP        0x00007    /* 83C790 bus i-face/Ethernet NIC chip */
  173.  
  174. /****************************************************************************
  175.  Definitions for the field:
  176.  nic_type (Bus interface chip type)
  177. */
  178. #define NIC_UNK_CHIP        0x00000    /* Unknown NIC chip */
  179. #define NIC_8390_CHIP        0x00001    /* DP8390 Ethernet NIC */
  180. #define NIC_690_CHIP        0x00002    /* 83C690 Ethernet NIC */
  181. #define NIC_825_CHIP        0x00003    /* 83C825 Token Ring NIC */
  182. /* #define NIC_???_CHIP        0x00004     Not used */
  183. /* #define NIC_???_CHIP        0x00005     Not used */
  184. /* #define NIC_???_CHIP        0x00006     Not used */
  185. #define NIC_790_CHIP        0x00007    /* 83C790 bus i-face/Ethernet NIC chip */
  186.  
  187. /****************************************************************************
  188.  Definitions for the field:
  189.  adapter_type    The adapter_type field describes the adapter/bus
  190.         configuration.
  191. */
  192. #define BUS_UNK_TYPE        0x00000
  193. #define BUS_ISA16_TYPE        0x00001    /* 16 bit adap in 16 bit (E)ISA slot */
  194. #define BUS_ISA8_TYPE        0x00002    /* 8/16b adap in 8 bit XT/(E)ISA slot */
  195. #define BUS_MCA_TYPE        0x00003    /* Micro Channel adapter */
  196. #define BUS_EISA32M_TYPE    0x00004    /* EISA 32 bit bus master adapter */
  197. #define BUS_EISA32S_TYPE    0x00005    /* EISA 32 bit bus slave adapter */
  198. #define BUS_PCMCIA_TYPE        0x00006    /* PCMCIA Bus */
  199.  
  200.        
  201. /*******************************************
  202.  config_mode defs
  203. *******************************************/
  204.  
  205. #define STORE_EEROM        0x00001    /* Store config in EEROM. */
  206. #define STORE_REGS        0x00002    /* Store config in register set. */
  207.  
  208. /* Adapter POS ID's */
  209.  
  210. #define CNFG_ID_8003E               0x6fc0
  211. #define CNFG_ID_8003S               0x6fc1
  212. #define CNFG_ID_8003W               0x6fc2
  213. #define CNFG_ID_8115TRA               0x6ec6        /* Token Ring MCA */ 
  214. #define CNFG_ID_8013E               0x61C8
  215. #define CNFG_ID_8013W               0x61C9
  216. #define CNFG_ID_BISTRO03E          0x0EFE5
  217. #define CNFG_ID_BISTRO13E          0x0EFD5
  218. #define CNFG_ID_BISTRO13W          0x0EFD4
  219.  
  220. /* 583 & 584 registers, needed for getinfo */
  221.  
  222. #define CNFG_MSR_583               0
  223. #define CNFG_ICR_583               1
  224. #define CNFG_IAR_583               2
  225. #define CNFG_BIO_583               3
  226. #define CNFG_EAR_583            3
  227. #define CNFG_IRR_583               4
  228. #define CNFG_LAAR_584               5
  229. #define CNFG_GP2               7
  230. #define CNFG_LAAR_MASK               0x01F
  231. #define CNFG_LAAR_ZWS               0x020
  232. #define CNFG_LAAR_L16E               0x040
  233. #define CNFG_ICR_IR2_584           0x04
  234. #define CNFG_ICR_MASK           0x08
  235. #define CNFG_ICR_MSZ            0x08
  236. #define CNFG_ICR_RLA            0x010
  237. #define CNFG_ICR_STO            0x080
  238. #define CNFG_IRR_IRQS               0x060
  239. #define CNFG_IRR_IEN               0x080
  240. #define CNFG_IRR_ZWS               0x01
  241. #define CNFG_GP2_BOOT_NIBBLE       0x0F
  242. #define CNFG_IRR_OUT2           0x04
  243. #define CNFG_IRR_OUT1           0x02
  244.  
  245. #define CNFG_SIZE_8kb               8
  246. #define CNFG_SIZE_16kb               16
  247. #define CNFG_SIZE_32kb               32
  248. #define CNFG_SIZE_64kb               64
  249.  
  250. #define ROM_DISABLE               0
  251.  
  252. #define CNFG_SLOT_ENABLE_BIT       0x08
  253.  
  254. #define CNFG_POS_CONTROL_REG       0x096
  255. #define CNFG_POS_REG0               0x100
  256. #define CNFG_POS_REG1               0x101
  257. #define CNFG_POS_REG2               0x102
  258. #define CNFG_POS_REG3               0x103
  259. #define CNFG_POS_REG4               0x104
  260. #define CNFG_POS_REG5               0x105
  261.  
  262. #define CNFG_ADAPTER_TYPE_MASK     0x00e
  263. /*****************************************************************************
  264. *    General register definitions for identifying board types
  265. ******************************************************************************/
  266. #define REG_IJR          0x06
  267. #define LAR0          0x08    /*LAN address ROM registers */
  268. #define LAR1          0x09
  269. #define LAR2          0x0A
  270. #define LAR3          0x0B
  271. #define LAR4          0x0C
  272. #define LAR5          0x0D
  273.  
  274. #define BID_BOARD_ID_BYTE          0x0E
  275. #define BID_CHCKSM_BYTE               0x0F
  276. #define REG_CKSM    0x0F
  277.  
  278. #define BID_LAR_OFFSET     0x08    /*offset for aliasing check */
  279.  
  280. /******************************************************************************
  281. *    General definitions
  282. ******************************************************************************/
  283. #define BID_MSZ_583_BIT               0x08
  284. #define BID_SIXTEEN_BIT_BIT        0x01
  285.  
  286. /******************************************************************************
  287. *    Mask for extracting the board revision number
  288. ******************************************************************************/
  289. #define BID_BOARD_REV_MASK         0x1E
  290.  
  291. /*****************************************************************************
  292. *    Definitions for board rev numbers greater that 1
  293. ******************************************************************************/
  294. #define BID_MEDIA_TYPE_BIT         0x01
  295. #define BID_SOFT_CONFIG_BIT        0x20
  296. #define BID_RAM_SIZE_BIT           0x40
  297. #define BID_BUS_TYPE_BIT           0x80
  298.  
  299. /*****************************************************************************
  300. *    Defs for identifying the 690
  301. ******************************************************************************/
  302. #define BID_CR               0x10        /* Command Register */
  303. #define BID_TXP               0x04        /* Transmit Packet Command */
  304. #define BID_TCR_DIFF       0x0D        /* Transmit Configuration Register */
  305. #define BID_TCR_VAL        0x18        /* Value to Test 8390 or 690 */
  306. #define BID_PS0               0x00        /* Register Page Select 0 */
  307. #define BID_PS1               0x40        /* Register Page Select 1 */
  308. #define BID_PS2               0x80        /* Register Page Select 2 */
  309. #define BID_PS_MASK        0x3F        /* For Masking Off Page Select Bits */
  310.  
  311. /*****************************************************************************
  312. *    Defs for manipulating the 584
  313. ******************************************************************************/
  314. #define BID_EEPROM_0                   0x08
  315. #define BID_EEPROM_1                   0x09
  316. #define BID_EEPROM_2                   0x0A
  317. #define BID_EEPROM_3                   0x0B
  318. #define BID_EEPROM_4                   0x0C
  319. #define BID_EEPROM_5                   0x0D
  320. #define BID_EEPROM_6                   0x0E
  321. #define BID_EEPROM_7                   0x0F
  322.  
  323. #define BID_OTHER_BIT                   0x02
  324. #define BID_ICR_MASK                   0x0C
  325. #define BID_EAR_MASK                   0x0F
  326. #define BID_ENGR_PAGE                   0x0A0
  327. #define BID_RLA                       0x10
  328. #define BID_EA6                       0x80
  329. #define BID_RECALL_DONE_MASK               0x010
  330. #define BID_EEPROM_OVERRIDE               0xFFD0FFB0
  331. #define BID_BID_EEPROM_OVERRIDE               0x0FFB0
  332. #define BID_EXTRA_EEPROM_OVERRIDE          0x0FFD0
  333. #define BID_EEPROM_MEDIA_MASK               0x07
  334. #define BID_STARLAN_TYPE               0x00
  335. #define BID_ETHERNET_TYPE               0x01
  336. #define BID_TP_TYPE                   0x02
  337. #define BID_EW_TYPE                   0x03
  338. #define BID_EEPROM_IRQ_MASK               0x18
  339. #define BID_PRIMARY_IRQ                   0x00
  340. #define BID_ALTERNATE_IRQ_1               0x08
  341. #define BID_ALTERNATE_IRQ_2               0x10
  342. #define BID_ALTERNATE_IRQ_3               0x18
  343. #define BID_EEPROM_RAM_SIZE_MASK           0x0E0
  344. #define BID_EEPROM_RAM_SIZE_RES1           0x00
  345. #define BID_EEPROM_RAM_SIZE_RES2           0x20
  346. #define BID_EEPROM_RAM_SIZE_8K               0x40
  347. #define BID_EEPROM_RAM_SIZE_16K               0x60
  348. #define BID_EEPROM_RAM_SIZE_32K               0x80
  349. #define BID_EEPROM_RAM_SIZE_64K               0x0A0
  350. #define BID_EEPROM_RAM_SIZE_RES3           0x0C0
  351. #define BID_EEPROM_RAM_SIZE_RES4           0x0E0
  352. #define BID_EEPROM_BUS_TYPE_MASK           0x07
  353. #define BID_EEPROM_BUS_TYPE_AT               0x00
  354. #define BID_EEPROM_BUS_TYPE_MCA               0x01
  355. #define BID_EEPROM_BUS_TYPE_EISA           0x02
  356. #define BID_EEPROM_BUS_SIZE_MASK           0x18
  357. #define BID_EEPROM_BUS_SIZE_8BIT           0x00
  358. #define BID_EEPROM_BUS_SIZE_16BIT          0x08
  359. #define BID_EEPROM_BUS_SIZE_32BIT          0x10
  360. #define BID_EEPROM_BUS_SIZE_64BIT          0x18
  361. #define BID_EEPROM_RAM_PAGING               0x40
  362. #define BID_EEPROM_ROM_PAGING               0x80
  363. #define BID_EEPROM_PAGING_MASK               0x0C0
  364.  
  365. #define OFFSET_585_ENGR_DATA               0x00A
  366. #define OFFSET_585_LAN_ADDR               0x006
  367. /*****************************************************************************
  368. *    Defs for local variables
  369. ******************************************************************************/
  370. #define BID_LOCAL_BID               2
  371. #define BID_LOCAL_EXTRA               4
  372. #define BID_LOCAL_CR               2
  373. #define BID_LOCAL_TCR               4
  374.  
  375. /* board_id stuff */
  376. #define STARLAN_MEDIA               0x0001        /* StarLAN */
  377. #define ETHERNET_MEDIA               0x0002        /* Ethernet */
  378. #define TWISTED_PAIR_MEDIA         0x0003        /* Twisted Pair */
  379. #define EW_MEDIA               0x0004        /* Ethernet and Twisted Pair */
  380. #define TOKEN_MEDIA               0x0005        /* Token Ring Media */
  381. #define MICROCHANNEL               0x0008        /* MicroChannel Adapter */
  382. #define INTERFACE_CHIP               0x0010        /* Soft Config Adapter */
  383. #define ADVANCED_FEATURES          0x0020    /* Adv. netw. interface features */
  384. #define BOARD_16BIT               0x0040        /* 16 bit capability */
  385. #define PAGED_RAM               0x0080        /* Adapter has paged RAM */
  386. #define PAGED_ROM               0x0100        /* Adapter has paged ROM */
  387. #define MEDIA_MASK               0x0007        /* Isolates Media Type */
  388. #define PCM_ADAPTER               0x0200        /* PCMCIA Adapter */
  389.  
  390. #define RAM_SIZE_UNKNOWN           0x00000000    /* Unknown RAM size */
  391. #define RAM_SIZE_RESERVED_1        0x00010000    /* Reserved RAM size */
  392. #define RAM_SIZE_8K               0x00020000    /* 8k RAM */
  393. #define RAM_SIZE_16K               0x00030000    /* 16k RAM */
  394. #define RAM_SIZE_32K               0x00040000    /* 32k RAM */
  395. #define RAM_SIZE_64K               0x00050000    /* 64k RAM */
  396. #define RAM_SIZE_RESERVED_6        0x00060000    /* Reserved RAM size */
  397. #define RAM_SIZE_RESERVED_7        0x00070000    /* Reserved RAM size */
  398. #define SLOT_16BIT               0x00080000    /* 16 bit board-16 bit slot */
  399. #define NIC_690_BIT               0x00100000    /* NIC is 690 */
  400. #define ALTERNATE_IRQ_BIT          0x00200000    /* Alternate IRQ is used */
  401. #define INTERFACE_5X3_CHIP         0x00000000    /* 0000 = 583 or 593 chips */
  402. #define INTERFACE_584_CHIP         0x00400000    /* 0001 = 584 chip */
  403. #define INTERFACE_594_CHIP         0x00800000    /* 0010 = 594 chip */
  404. #define INTERFACE_585_CHIP         0x01000000    /* 0100 = 585/790 chip */
  405. #define RAM_SIZE_MASK               0x00070000    /* Isolates RAM Size */
  406. #define INTERFACE_CHIP_MASK        0x03C00000    /* Isolates Intfc Chip Type */
  407. #define NIC_825_BIT               0x04000000    /* TRC 83C825 NIC */
  408. #define NIC_790_BIT               0x08000000    /* NIC is 83C790 Ethernet */
  409. #define STATIC_ID_MASK        0x0000ffff
  410. /*****************************************************************************
  411. *    Full board type definitions
  412. ******************************************************************************/
  413.  
  414. #define WD8003E               ETHERNET_MEDIA
  415. #define WD8003EBT          WD8003E
  416. #define WD8003S               STARLAN_MEDIA
  417. #define WD8003SH           WD8003S
  418. #define WD8003WT           TWISTED_PAIR_MEDIA
  419. #define WD8003W               (TWISTED_PAIR_MEDIA | INTERFACE_CHIP)
  420. #define WD8003EB           (ETHERNET_MEDIA | INTERFACE_CHIP)
  421. #define WD8003EP           WD8003EB    /* with INTERFACE_584_CHIP */
  422. #define WD8003EW           (EW_MEDIA | INTERFACE_CHIP)
  423. #define WD8003ETA          (ETHERNET_MEDIA | MICROCHANNEL)
  424. #define WD8003STA          (STARLAN_MEDIA | MICROCHANNEL)
  425. #define WD8003EA           (ETHERNET_MEDIA | MICROCHANNEL | INTERFACE_CHIP)
  426. #define WD8013EPA          WD8003EA    /* with INTERFACE_594_CHIP */
  427. #define WD8003SHA          (STARLAN_MEDIA | MICROCHANNEL | INTERFACE_CHIP)
  428. #define WD8003WA           (TWISTED_PAIR_MEDIA | MICROCHANNEL | INTERFACE_CHIP)
  429. #define WD8013WPA          WD8003WA    /* with INTERFACE_594_CHIP */
  430. #define WD8013EBT          (ETHERNET_MEDIA | BOARD_16BIT)
  431. #define WD8013EB           (ETHERNET_MEDIA | BOARD_16BIT | INTERFACE_CHIP)
  432. #define WD8013W               (TWISTED_PAIR_MEDIA | BOARD_16BIT | INTERFACE_CHIP)
  433. #define WD8013EW           (EW_MEDIA | BOARD_16BIT | INTERFACE_CHIP)
  434. #define WD8013EWC          (WD8013EW | ADVANCED_FEATURES)
  435. #define WD8013WC           (WD8013W | ADVANCED_FEATURES)
  436. #define WD8013EPC          (WD8013EB | ADVANCED_FEATURES)
  437. #define WD8003WC           (WD8003W | ADVANCED_FEATURES)
  438. #define WD8003EPC          (WD8003EP | ADVANCED_FEATURES)
  439. #define WD8115TA           (TOKEN_MEDIA | MICROCHANNEL | INTERFACE_CHIP | PAGED_RAM)
  440. #define WD8115T               (TOKEN_MEDIA | INTERFACE_CHIP | BOARD_16BIT | PAGED_RAM)
  441. #define WD8203W               (WD8003WC | PAGED_ROM)
  442. #define WD8203EP           (WD8003EPC | PAGED_ROM)
  443. #define WD8216T               (WD8013WC | PAGED_ROM | PAGED_RAM)
  444. #define WD8216                (WD8013EPC | PAGED_ROM | PAGED_RAM)
  445. #define WD8216C               (WD8013EWC | PAGED_ROM | PAGED_RAM)
  446. #define PCM10BT               (TWISTED_PAIR_MEDIA | PCM_ADAPTER | PAGED_RAM | ADVANCED_FEATURES)
  447.  
  448. /* Defs for PCM adapters */
  449. #define REG_PCM_RESETDRV           0x002
  450. #define REG_PCM_GEN_CTRL           0x003
  451. #define GEN_CTRL_INTR               0x010
  452. #define GEN_CTRL_IO_CARD           0x020
  453. #define GEN_CTRL_RST               0x040
  454.  
  455.  
  456. #define REG_PCM_IO_START_LO        0x008
  457. #define REG_PCM_IO_START_HI        0x009
  458. #define REG_PCM_IO_STOP_LO         0x00A
  459. #define REG_PCM_IO_STOP_HI         0x00B
  460.  
  461. #define REG_PCM_MEM_START_LO       0x010
  462. #define REG_PCM_MEM_START_HI       0x011
  463. #define REG_PCM_MEM_STOP_LO        0x012
  464. #define REG_PCM_MEM_STOP_HI        0x013
  465.  
  466. #define REG_PCM_MEM_OFST_LO        0x014
  467. #define REG_PCM_MEM_OFST_HI        0x015
  468. #define MEM_ADD17               0x020    /* Memory Addr bit 17 aligned at 12. */
  469.  
  470. #define REG_PCM_WIN_ENABLE         0x006
  471. #define PCM_MEMWIN_EN0               0x001
  472. #define PCM_MEMWIN_EN1               0x002
  473. #define PCM_MEMWIN_EN2               0x004
  474. #define PCM_MEMWIN_EN3               0x008
  475. #define PCM_MEMWIN_EN4               0x010
  476.  
  477. #define PCM_IOWIN_EN0               0x040
  478. #define PCM_IOWIN_EN1               0x080
  479.  
  480. #define PCM_MEM_16BIT               0x080
  481. #define PCM_MEM_WAIT_STATE         0x040
  482.  
  483.  
  484.  
  485. #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
  486.  
  487. #ifdef REALLY_SLOW_IO
  488. #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
  489. #else
  490. #define SLOW_DOWN_IO __SLOW_DOWN_IO
  491. #endif
  492.  
  493. inline void outb(char value, unsigned short port)
  494. {
  495. __asm__ __volatile__ ("outb %%al,%%dx"
  496.         ::"a" ((char) value),"d" ((unsigned short) port));
  497. }
  498.  
  499. inline unsigned int inb(unsigned short port)
  500. {
  501.     unsigned int _v;
  502. __asm__ __volatile__ ("inb %%dx,%%al"
  503.         :"=a" (_v):"d" ((unsigned short) port),"0" (0));
  504.     return _v;
  505. }
  506.  
  507. inline void outb_p(char value, unsigned short port)
  508. {
  509. __asm__ __volatile__ ("outb %%al,%%dx"
  510.         ::"a" ((char) value),"d" ((unsigned short) port));
  511.     SLOW_DOWN_IO;
  512. }
  513.  
  514. inline unsigned int inb_p(unsigned short port)
  515. {
  516.     unsigned int _v;
  517. __asm__ __volatile__ ("inb %%dx,%%al"
  518.         :"=a" (_v):"d" ((unsigned short) port),"0" (0));
  519.     SLOW_DOWN_IO;
  520.     return _v;
  521. }
  522.  
  523. void SelectOtherRegister(int ioaddr)
  524. {
  525.   outb_p((inb_p(ioaddr + CNFG_ICR_583) & 4) | 2,ioaddr + CNFG_ICR_583);
  526. }
  527.  
  528. void RecallEERomData(int ioaddr, int flag)
  529. {
  530.   int temp;
  531.   temp = (inb_p(ioaddr + CNFG_ICR_583) & 4) + 0x10;
  532.   if (flag != RECALL_LANADDR) temp |= 2; /* set other bit if recall data */
  533.   outb_p(temp, ioaddr + CNFG_ICR_583);
  534.   while (inb_p(ioaddr + CNFG_ICR_583) & 0x10); /* wait for recall to complete */
  535. }
  536.  
  537. int SumEERomData(int ioaddr, int page, int nbytes)
  538. {
  539.   int i,temp;
  540.   unsigned char cksum;
  541.   cksum = 0;
  542.   SelectOtherRegister(ioaddr);
  543.   outb_p((inb_p(ioaddr + CNFG_BIO_583) & 0xf) | (page << 4),ioaddr + CNFG_BIO_583);
  544.   RecallEERomData(ioaddr, RECALL_DATA);
  545.   for (i = 0; i < nbytes; i++) {
  546.     temp = inb_p(ioaddr + LAR0 + i);
  547.     cksum += temp;
  548.     if (verbose >= 5)
  549.       printf("sumeeromdata page %d byte= %x\n",page, temp);
  550.   }
  551.   RecallEERomData(ioaddr, RECALL_LANADDR);
  552.   return((int) cksum);
  553. }
  554.  
  555. int Read584Checksum(int ioaddr)
  556. {
  557.   int eepage;
  558.   unsigned char cksum,cksumpage;
  559.   cksum = 0;
  560.   for (eepage = 0; eepage <= 15; eepage++)
  561.     {
  562.       cksumpage = SumEERomData(ioaddr, eepage, 8);
  563.       if (verbose >= 4) printf("read584checksum page %d cksum= %x\n",
  564.                     eepage, (int) cksumpage);
  565.       cksum += cksumpage;
  566.     }
  567.   if (verbose >= 3) printf("read584checksum final cksum= %x\n",(int) cksum);
  568.   return((cksum == CHECKSUM) ? SUCCESS : EEROM_CKSUM_ERROR);
  569. }
  570.  
  571. void SaveConfigZero(int ioaddr)
  572. {
  573.   int i;
  574.   SelectOtherRegister(ioaddr);
  575.   outb_p(inb_p(ioaddr + CNFG_EAR_583) & 0xf, ioaddr + CNFG_EAR_583); /* page 0 */
  576.   RecallEERomData(ioaddr, RECALL_DATA);
  577.   for (i = 0; i < 8; i++) ConfigZero[i] =
  578.     (unsigned char) inb_p(ioaddr + LAR0 + i);
  579. }
  580.  
  581. void StoreEERomData(int ioaddr)
  582. {
  583.   outb_p((inb_p(ioaddr + CNFG_ICR_583) & 4) | 0x82, ioaddr + CNFG_ICR_583);
  584.   while (inb_p(ioaddr + CNFG_ICR_583) & 0x80); /* wait for store to complete */
  585. }
  586.  
  587. void WriteCheckSumByte(int ioaddr, int value)
  588. {
  589.   int i;
  590.   SaveConfigZero(ioaddr);
  591.   SelectOtherRegister(ioaddr);
  592.   outb_p(inb_p(ioaddr + CNFG_EAR_583) | 0xf0, ioaddr + CNFG_EAR_583); /* page 16 */
  593.   RecallEERomData(ioaddr, RECALL_DATA);
  594.   outb_p(value, ioaddr + REG_CKSM);
  595.   StoreEERomData(ioaddr);
  596.   /* restore config 0, since it was corrupted by the above store */
  597.   for (i = 0; i < 8; i++) outb_p(ConfigZero[i], ioaddr + LAR0 + i);
  598.   outb_p(inb_p(ioaddr + CNFG_EAR_583) & 0xf, ioaddr + CNFG_EAR_583); /* page 0 */
  599.   StoreEERomData(ioaddr);
  600.   /* recall the lan address */
  601.   RecallEERomData(ioaddr, RECALL_LANADDR);
  602. }
  603.  
  604. int Write584Checksum(int ioaddr)
  605. {
  606.   int page;
  607.   unsigned char cksum,cksumpage;
  608.   cksum = 0;
  609.   for (page = 0; page <= 14; page++)
  610.     {
  611.       cksumpage = SumEERomData(ioaddr, page, 8);
  612.       cksum += cksumpage;
  613.       if (verbose >= 4)
  614.     printf("wr584checksum page %d, cksumpage= %x\n",page, (int) cksumpage);
  615.     }
  616.   cksumpage = SumEERomData(ioaddr, 15, 7);
  617.   if (verbose >= 4)
  618.     printf("write584ckecksum page %d cksumpage= %x\n",page,(int) cksumpage);
  619.   cksum += cksumpage;
  620.   cksum = CHECKSUM - cksum;
  621.   if (verbose >= 3)
  622.     printf("write584checksum final cksum= %x\n",(int) cksum);
  623.   WriteCheckSumByte(ioaddr, cksum);
  624.   return(SUCCESS);
  625. }
  626.  
  627. /* getcnfg.c: this program gets config info from WD and SMC ether cards */
  628. /*
  629.     Written 1993 by Gregg Weber. This is alpha test code.
  630.     This is a extension to the Linux operating system, and is covered by
  631.     same Gnu Public License that covers that work.
  632.  
  633.     version 0.1 29-jan-93
  634.     re-written for Linux in C, and Microchannel stuff removed
  635.     by Gregg Weber
  636.  
  637.     version 0.2 31-jan-93
  638.     added check for nic chip type
  639.  
  640.     version 0.3 19-mar-93
  641.     fixed bug in get_board_id , wrongly identified 8003 as 8013 sometimes
  642.     on boards with interface chips
  643.  
  644.     version 0.6 28-april-1993 gw
  645.     updated based on new information from SMC
  646. */
  647.  
  648. int check_for_585(int ioaddr)
  649. {
  650.   /* TODO */
  651.   return(0);
  652. }
  653.  
  654. int bid_check_bic_type(int ioaddr)
  655. {
  656.  check_for_585(ioaddr);
  657.  return(0);
  658. }
  659.  
  660. /************************************************************************
  661.   this determines if the nic chip is a 690 or 8390.
  662. *************************************************************************/
  663. int bid_check_for_690(int ioaddr)
  664. {
  665.   int i,oldcr,enhval,enhval2;
  666.   int is690 = 0;
  667.   oldcr = inb_p(ioaddr + 0x10) & 0xfb; /* get command register, mask txp */
  668.   outb_p((oldcr & 0x3f) | 0x80,ioaddr + 0x10); /* select page 2 */
  669.   enhval = inb_p(ioaddr + 0x17); /* get enh */
  670.   outb_p(enhval + 0x18,ioaddr + 0x17); /* write 0x18 to enh */
  671.   i = inb_p(ioaddr + 0x10); /* put something else on bus */
  672.   enhval2 = inb_p(ioaddr + 0x17) & 0x18; /* get new enh */
  673.   if (enhval2 == 0x18) is690 = 1;
  674.   /* restore stuff */
  675.   outb_p(enhval,ioaddr + 0x17); /* restore enh */
  676.   outb_p(oldcr,ioaddr + 0x10); /* restore cr */
  677.   return(is690);
  678. }
  679.  
  680. int bid_get_board_rev_number(int ioaddr)
  681. {
  682.  return((inb_p(ioaddr + BID_BOARD_ID_BYTE) & BID_BOARD_REV_MASK) >> 1);
  683. }
  684.  
  685. int bid_check_aliasing(int ioaddr)
  686. {
  687.   int i;
  688.   /* see if there is register aliasing */
  689.   /* only check regs 1,2,3,4,7 - some ASICs don't have regs 5 and 6
  690.    and register 0 is never aliased */
  691.   for (i = 1; i <= 4; i++) {
  692.     if (inb_p(ioaddr+i) != inb_p(ioaddr+i+8)) {
  693.       return(0);
  694.     }
  695.   }
  696.   if (inb_p(ioaddr+7) != inb_p(ioaddr+7+8)) return(0);
  697.   return (1);  
  698. }
  699.  
  700. int bid_interface_chip(int ioaddr)
  701. {
  702.   int temp7,temp2;
  703.   /* see if there is an interface chip */
  704.   temp7 = inb_p(ioaddr+CNFG_GP2); /* save reg just in case */
  705.   /* see if we can write and read some values in gp2 register */
  706.   outb_p(0x35,ioaddr+CNFG_GP2); /* write something */
  707.   temp2 = inb_p(ioaddr); /* put something else on bus */
  708.   if (inb_p(ioaddr+CNFG_GP2) == 0x35) {
  709.     outb_p(0x3a,ioaddr+CNFG_GP2); /* try another value */
  710.     temp2 = inb_p(ioaddr); /* put something else on bus */
  711.     if (inb_p(ioaddr+CNFG_GP2) == 0x3a) {
  712.       outb_p(temp7,ioaddr+CNFG_GP2); /* restore reg just in case */
  713.       return(1);
  714.     }
  715.   }
  716.   return(check_for_585(ioaddr)); /* returns true if 585/790 is present */
  717. }
  718.  
  719. /* is board 16 bit? */
  720. int bid_board_16bit(int ioaddr)
  721. {
  722.   int temp7,temp1,temp2;
  723.   temp7 = inb_p(ioaddr+CNFG_ICR_583); /* save value */
  724.   /* flip the bit */
  725.   temp1 = temp7 ^ BID_SIXTEEN_BIT_BIT;
  726.   outb_p(temp1,ioaddr+CNFG_ICR_583); /* try to flip the 16-bit bit */
  727.   temp2 = inb_p(ioaddr); /* put something else on bus */
  728.   temp2 = inb_p(ioaddr+CNFG_ICR_583); /* read it back */
  729.   temp1 = temp7 & BID_SIXTEEN_BIT_BIT; /* original state of bit */
  730.   temp2 &= BID_SIXTEEN_BIT_BIT; /* current state of bit */
  731.   if (temp1 == temp2) {
  732.     /* new value didn't stick, so its 16 bit board */
  733.     outb_p(temp7 & 0xfe,ioaddr+CNFG_ICR_583); /* restore it and clear bit 0 */
  734.     return(1);
  735.   }
  736.   outb_p(temp7, ioaddr+CNFG_ICR_583); /* restore it just in case */
  737.   return(0);
  738. }
  739.  
  740. /* is 16 bit board in 16 bit slot? */
  741. int bid_slot_16bit(int ioaddr)
  742. {
  743.   int temp1;
  744.   if (check_for_585(ioaddr)) {
  745.     return(0);
  746. /* TODO   return((inb_p(ioaddr+REG_HWR) & HWR_HOST16) != 0); */
  747.   }
  748.   else {
  749.     temp1 = inb_p(ioaddr+CNFG_ICR_583) & 0xc;
  750.     outb_p(temp1,ioaddr+CNFG_ICR_583);
  751.     return((inb_p(ioaddr+CNFG_ICR_583) & BID_SIXTEEN_BIT_BIT) != 0);
  752.   }
  753. }
  754.  
  755. int bid_get_base_info(int ioaddr)
  756. {
  757.   int temp = 0;
  758.   if (!bid_check_aliasing(ioaddr)) {
  759.     /* no aliasing, check for interface chip */
  760.     if (bid_interface_chip(ioaddr)) return(INTERFACE_CHIP);
  761.     /* no interface chip, check 16 bit */
  762.     if (bid_board_16bit(ioaddr)) {
  763.       temp |= BOARD_16BIT;
  764.       if (bid_slot_16bit) temp |= SLOT_16BIT;
  765.     }
  766.   }
  767.   return(temp);
  768. }
  769.  
  770. /* find the media type */
  771. int bid_get_media_type(int ioaddr,int board_rev)
  772. {
  773.   if ((inb_p(ioaddr+BID_BOARD_ID_BYTE) & BID_MEDIA_TYPE_BIT) != 0)
  774.     return(ETHERNET_MEDIA);
  775.   else {
  776.     if (board_rev == 1) return(STARLAN_MEDIA);
  777.     else return(TWISTED_PAIR_MEDIA);
  778.   }
  779. }
  780.  
  781. /* get board id byte info */
  782. int bid_get_id_byte_info(int ioaddr, int board_id)
  783. {
  784.   int temp7;
  785.   temp7 = inb_p(ioaddr+BID_BOARD_ID_BYTE);
  786.   /* check for soft config bit */
  787.   if ((temp7 & BID_SOFT_CONFIG_BIT) != 0) {
  788.     temp7 = board_id & STATIC_ID_MASK;
  789.     if ((temp7 == WD8003EB) || (temp7 == WD8003W))
  790.       return(ALTERNATE_IRQ_BIT);
  791.   }
  792.   return(0);
  793. }
  794.  
  795. void bid_wait_for_recall(int ioaddr)
  796. {
  797.   while (inb_p(ioaddr+1) & 0x10); /* wait for recall */
  798. }
  799.  
  800. void bid_recall_engr_eeprom(int ioaddr)
  801. {
  802.   if (check_for_585(ioaddr)) {
  803. /* TODO */
  804.   }
  805.   else {
  806.     outb_p((inb_p(ioaddr+1) & 0xc) | 2,ioaddr+1); /* set other bit */
  807.     outb_p((inb_p(ioaddr+3) & 0xf) | 0xa0,ioaddr+3); /* set engr page */
  808.     outb_p((inb_p(ioaddr+1) & 0xc) | 0x12,ioaddr+1); /* set rla, other bit */
  809.   }
  810.   bid_wait_for_recall(ioaddr);
  811. }
  812.  
  813. /* get eeprom info */
  814. int bid_get_eeprom_info(int ioaddr)
  815. {
  816.   int temp_id,temp7;
  817.   temp_id = 0;
  818.   /* first recall the reserved engineering bytes from eeprom */
  819.   bid_recall_engr_eeprom(ioaddr);
  820.   temp7 = inb_p(ioaddr+BID_EEPROM_1);
  821.   if ((temp7 & BID_EEPROM_BUS_TYPE_MASK) == BID_EEPROM_BUS_TYPE_MCA)
  822.     temp_id |= MICROCHANNEL;
  823.   if ((temp7 & BID_EEPROM_PAGING_MASK) != 0) {
  824.     if ((temp7 & BID_EEPROM_RAM_PAGING) != 0)
  825.       temp_id |= PAGED_RAM;
  826.     if ((temp7 & BID_EEPROM_ROM_PAGING) != 0)
  827.       temp_id |= PAGED_ROM;
  828.   }
  829.   if ((temp7 & BID_EEPROM_BUS_SIZE_MASK) == BID_EEPROM_BUS_SIZE_16BIT) {
  830.     temp_id |= BOARD_16BIT;
  831.     /* is 16 bit board in 16 bit slot? */
  832.     if (bid_slot_16bit(ioaddr)) temp_id |= SLOT_16BIT;
  833.   }
  834.   temp7 = inb_p(ioaddr+BID_EEPROM_0);
  835.   switch(temp7 & BID_EEPROM_MEDIA_MASK) {
  836.   case BID_STARLAN_TYPE: temp_id |= STARLAN_MEDIA;
  837.     break;
  838.   case BID_TP_TYPE: temp_id |= TWISTED_PAIR_MEDIA;
  839.     break;
  840.   case BID_EW_TYPE: temp_id |= EW_MEDIA;
  841.     break;
  842.   default: temp_id |= ETHERNET_MEDIA;
  843.     break;
  844.   }
  845.   if ((temp7 & 0x18) == 8) temp_id |= ALTERNATE_IRQ_BIT;
  846.   switch(temp7 & 0xe0) {
  847.   case 0x40: temp_id |= RAM_SIZE_8K;
  848.     break;
  849.   case 0x60: if ((temp_id & BOARD_16BIT) && !(temp_id & SLOT_16BIT))
  850.     temp_id |= RAM_SIZE_8K;
  851.   else temp_id |= RAM_SIZE_16K;
  852.     break;
  853.   case 0x80: temp_id |= RAM_SIZE_32K;
  854.     break;
  855.   case 0xa0: if ((temp_id & BOARD_16BIT) && !(temp_id & SLOT_16BIT))
  856.     temp_id |= RAM_SIZE_32K;
  857.   else temp_id |= RAM_SIZE_64K;
  858.     break;
  859.   default: temp_id |= RAM_SIZE_UNKNOWN;
  860.     break;
  861.   }
  862.   /* now recall the lan address from eeprom */
  863.   outb_p((inb_p(ioaddr+1) & 0xc) | 2,ioaddr+1); /* set other bit */
  864.   outb_p((inb_p(ioaddr+3) & 0xf) | 0x80,ioaddr+3); /* set page */
  865.   outb_p((inb_p(ioaddr+1) & 0xc) | 0x10,ioaddr+1); /* set rla */
  866.   while (inb_p(ioaddr+1) & 0x10); /* wait for recall */
  867.   return(temp_id);
  868. }
  869.  
  870. /* get ram size */
  871. int bid_get_ram_size(int ioaddr, int board_rev, int board_id)
  872. {
  873.   int temp1,temp2,temp_id;
  874.   temp_id = 0;
  875.   if (board_rev >= 2) {
  876.     temp1 = inb_p(ioaddr+0xe); /* get hardware id byte */
  877.     temp2 = board_id & STATIC_ID_MASK; /* get board type */
  878.     if ((temp2 == WD8003E) || (temp2 == WD8003S) ||
  879.     (temp2 == WD8003WT) || (temp2 == WD8003W) ||
  880.     (temp2 == WD8003EB)) {
  881.       /* hardware ram size bit determines 8K or 32K */
  882.       temp_id |= (temp1 & 0x40) ? RAM_SIZE_32K : RAM_SIZE_8K;
  883.     }
  884.     else {
  885.       if (temp2 == WD8013EBT) {
  886.     if (board_id & SLOT_16BIT) {
  887.       /* hardware ram size bit determines 16K or 64K */
  888.       temp_id |= (temp1 & 0x40) ? RAM_SIZE_64K : RAM_SIZE_16K;
  889.     }
  890.     else {
  891.       /* hardware ram size bit determines 8K or 32K */
  892.       temp_id |= (temp1 & 0x40) ? RAM_SIZE_32K : RAM_SIZE_8K;
  893.     }
  894.       }
  895.       else temp_id |= RAM_SIZE_UNKNOWN;
  896.     }
  897.   }
  898.   else {
  899.     /* old rev boards */
  900.     if (board_id & BOARD_16BIT) {
  901.       if (board_id & SLOT_16BIT) temp_id |= RAM_SIZE_16K;
  902.       else temp_id |= RAM_SIZE_8K;
  903.     }
  904.     else {
  905.       if (board_id & INTERFACE_CHIP) {
  906.     /* look at memory size bit in register 1 */
  907.     temp_id |= (inb_p(ioaddr+1) & 8) ? RAM_SIZE_32K : RAM_SIZE_8K;
  908.       }
  909.       /* can't determine ram size */
  910.       else temp_id |= RAM_SIZE_UNKNOWN;
  911.     }
  912.   }
  913.   return(temp_id);
  914. }
  915.  
  916. /*
  917.     get board id information.
  918.  
  919.     returns 0 if bad board
  920.     else returns 32 bit word with bits encoding information about
  921.     the board. See getcnfg.h for definitions of bits.
  922. */
  923. unsigned long lm_gc_get_bid(int ioaddr)
  924. {
  925.   unsigned long board_id = 0;
  926.   int board_rev;
  927.   unsigned char temp1;
  928.   /* rev number = 0 means board is broken */
  929.   board_rev = bid_get_board_rev_number(ioaddr);
  930.   if (board_rev == 0) return(0);
  931.   board_id |= bid_get_base_info(ioaddr);
  932.   board_id |= bid_get_media_type(ioaddr,board_rev);
  933.   if (board_rev >= 2) {
  934.     board_id |= bid_get_id_byte_info(ioaddr,board_id);
  935.     if (board_rev >= 3) {
  936.       board_id &= BID_EEPROM_OVERRIDE;
  937.       board_id |=
  938.     check_for_585(ioaddr) ? INTERFACE_585_CHIP : INTERFACE_584_CHIP;
  939.       board_id |= bid_get_eeprom_info(ioaddr);
  940.     }
  941.     else {
  942.       board_id |= bid_get_ram_size(ioaddr, board_rev, board_id);
  943.     }
  944.   }
  945.   else {
  946.     board_id |= bid_get_ram_size(ioaddr, board_rev, board_id);
  947.   }
  948.   if (board_rev >= 4) {
  949.     board_id |= ADVANCED_FEATURES;
  950.     temp1 = bid_check_bic_type(ioaddr);
  951.     if (temp1) {
  952.       board_id &= ~INTERFACE_CHIP_MASK;
  953.       board_id |= temp1;
  954.     }
  955.     else {
  956.       if (bid_check_for_690(ioaddr)) board_id |= NIC_690_BIT; /*check for 690*/
  957.     }
  958.   }
  959.   else {
  960.     if (bid_check_for_690(ioaddr)) board_id |= NIC_690_BIT; /*check for 690*/
  961.   }
  962.   return(board_id);
  963. }
  964.  
  965. /* check if board is there via checksum */
  966. /* return 0 if no board there,
  967.    return 1 if board there */
  968. int lm_gc_is_board_there(int ioaddr)
  969. {
  970.   int i;
  971.   unsigned char csum = 0;
  972.   if (ioaddr & 0x1f) return(0); /* check for illegal io address */
  973.   for (i = 0; i< 8; i++) csum += inb_p(ioaddr + 8 + i);
  974.   return(csum == 0xff); /* if bad checksum report no board */
  975. }
  976.  
  977. /* test for clone */
  978. int lm_verify_nadd(int ioaddr)
  979. {
  980.  if ((inb_p(ioaddr + LAR0) == 0) &&(inb_p(ioaddr + LAR1) == 0) &&
  981.      (inb_p(ioaddr + LAR2) == 0xc0)) return(0);
  982.  return(1);
  983. }
  984.  
  985. /*
  986.    get lots of configuration information about any western digital
  987.    or SMC ethernet card.
  988.  
  989.    gets the following info:
  990.    board id
  991.    media type - starlan or ethernet or twisted pair
  992.    interface chip type - none or 583 or 584 or 593 or 594
  993.    NIC chip type - 8390 or 690
  994.    8/16 bit board
  995.    8/16 bit slot
  996.    base address of ram
  997.    size of ram
  998.    interrupt line used
  999.    base address of rom
  1000.    size of rom
  1001.  
  1002.    also returns the following values:
  1003.  
  1004. */
  1005.  
  1006. int lm_get_at_config(CNFG_Adapter *cfg_info)
  1007. {
  1008.   unsigned long board_id,temp1;
  1009.   unsigned short base_addr;
  1010.   int irnum,i,rbase1;
  1011.   int ram_size,intf_chip,irq_value;
  1012.  
  1013.   cnfg_val = 0;
  1014.   base_addr = cfg_info->io_base;
  1015.   if (!lm_gc_is_board_there(base_addr)) return(ADAPTER_NOT_FOUND);
  1016.   board_id = lm_gc_get_bid(base_addr);
  1017.   cfg_info->board_id = board_id & STATIC_ID_MASK;
  1018.   cfg_info->full_bid = board_id;
  1019.   /* copy ram size from board_id to the config structure */
  1020.   temp1 = board_id & RAM_SIZE_MASK; /* get ram size bits */
  1021.   if ((temp1 >= RAM_SIZE_8K) && (temp1 <= RAM_SIZE_64K)) {
  1022.     ram_size = CNFG_SIZE_8kb << ((temp1 >> 16) - 2);
  1023.     if (cfg_info->ram_size != ram_size) cnfg_val |= RAM_SIZE_MISMATCH;
  1024.     cfg_info->ram_size = ram_size;
  1025.     if ((board_id & PAGED_RAM) != 0) ram_size = CNFG_SIZE_16kb;
  1026.     if (cfg_info->ram_usable != ram_size) cnfg_val |= RAM_SIZE_MISMATCH;
  1027.     cfg_info->ram_usable = ram_size;
  1028.   }
  1029.   if (!(board_id & INTERFACE_CHIP)) {
  1030.     cfg_info->mode_bits |= INTERRUPT_STATUS_BIT;
  1031.     cfg_info->media_type = MEDIA_UNKNOWN;
  1032.     cfg_info->bic_type = BIC_NO_CHIP;
  1033.     cfg_info->clone = lm_verify_nadd(base_addr);
  1034.     return(ADAPTER_NO_CONFIG); /* no interface chip */
  1035.   }
  1036.   intf_chip = board_id & INTERFACE_CHIP_MASK;
  1037.   switch(intf_chip) {
  1038.   case INTERFACE_5X3_CHIP:
  1039.     cfg_info->bic_type = BIC_583_CHIP;
  1040.     break;
  1041.   case INTERFACE_585_CHIP:
  1042.     cfg_info->bic_type = BIC_585_CHIP;
  1043.     break;
  1044.   default:
  1045.     cfg_info->bic_type = BIC_584_CHIP;
  1046.     break;
  1047.   }
  1048.   /*************************************************
  1049.                  get interrupt line
  1050.   ***************************************************/
  1051.   irnum = 0;
  1052.   switch(intf_chip) {
  1053.   case INTERFACE_585_CHIP:
  1054.     /* TODO */
  1055.     break;
  1056.   case INTERFACE_584_CHIP:
  1057.     irnum = inb_p(base_addr + 1) & 4; 
  1058.   default:
  1059.     irnum += (inb_p(base_addr + 4) & 0x60) >> 5;
  1060.     if ((irnum == 2) && !(board_id & ALTERNATE_IRQ_BIT))
  1061.       irq_value = 4;
  1062.     else irq_value = irqlist[irnum];
  1063.     break;
  1064.   }
  1065.   if (cfg_info->irq_value != irq_value) cnfg_val |= IRQ_MISMATCH;
  1066.   cfg_info->irq_value = irq_value;
  1067.   /* get irq status */
  1068.   cfg_info->mode_bits &= ~INTERRUPT_STATUS_BIT;
  1069.   switch(intf_chip) {
  1070.   case INTERFACE_585_CHIP:
  1071.     /* TODO */
  1072.     break;
  1073.   default:
  1074.     if ((inb_p(base_addr + CNFG_IRR_583) & 0x80) != 0)
  1075.       cfg_info->mode_bits |= INTERRUPT_STATUS_BIT;
  1076.     break;
  1077.   }
  1078.   /******************************************************
  1079.                    get ram base
  1080.   *******************************************************/
  1081.   rbase1 = inb_p(base_addr) & 0x3f;
  1082.   if ((board_id & INTERFACE_CHIP_MASK) != INTERFACE_5X3_CHIP) {
  1083.     temp1 =
  1084.       (inb_p(base_addr + 5) & 0x1f) << 19 | (rbase1 << 13);
  1085.   }
  1086.   else temp1 = (rbase1 | 0x40) << 13;
  1087.   if (cfg_info->ram_base != temp1) cnfg_val |= RAM_BASE_MISMATCH;
  1088.   cfg_info->ram_base = temp1;
  1089.   /*****************************************************
  1090.                      get rom base
  1091.   ******************************************************/
  1092.   cfg_info->rom_base = ((inb_p(base_addr + CNFG_BIO_583) & 0x3e) | 0x40) << 13;
  1093.   /*****************************************************
  1094.                    get rom size (in Kb)
  1095.   ******************************************************/
  1096.   cfg_info->rom_size = (inb_p(base_addr + CNFG_BIO_583) & 0xc0) >> 2;
  1097.   /*****************************************************
  1098.                     get boot status
  1099.   ******************************************************/
  1100.   cfg_info->mode_bits &= ~BOOT_STATUS_MASK;
  1101.   if ((inb_p(base_addr + CNFG_GP2) & CNFG_GP2_BOOT_NIBBLE) == 0)
  1102.     cfg_info->mode_bits |= BOOT_TYPE_1;
  1103.   /*****************************************************
  1104.                   get zero wait state
  1105.   ******************************************************/
  1106.   cfg_info->mode_bits &= ~ZERO_WAIT_STATE_MASK;
  1107.   if ((inb_p(base_addr + CNFG_IRR_583) & 1) != 0)
  1108.     cfg_info->mode_bits |= ZERO_WAIT_STATE_8_BIT;
  1109.   if (board_id & BOARD_16BIT) {
  1110.     if (inb_p(base_addr + CNFG_LAAR_584) & 0x20)
  1111.       cfg_info->mode_bits |= ZERO_WAIT_STATE_16_BIT;
  1112.   }
  1113.   /*****************************************************
  1114.                  get advanced features
  1115.   ******************************************************/
  1116.   cfg_info->mode_bits &= ~INTERFACE_TYPE_MASK;
  1117.   temp1 = inb_p(base_addr + CNFG_IRR_583);
  1118.   if (board_id & ADVANCED_FEATURES) {
  1119.     if (temp1 & 0x02) {
  1120.       if (temp1 & 0x04) {
  1121.     cfg_info->mode_bits |= BNC_INTERFACE;
  1122.     cfg_info->media_type = MEDIA_BNC;
  1123.       }
  1124.       else {
  1125.     if ((board_id & MEDIA_MASK) == ETHERNET_MEDIA) {
  1126.       cfg_info->mode_bits |= AUI_INTERFACE;
  1127.       cfg_info->media_type = MEDIA_AUI;
  1128.     }
  1129.     else {
  1130.       cfg_info->mode_bits |= AUI_10BT_INTERFACE;
  1131.       cfg_info->media_type = MEDIA_AUI_UTP;
  1132.     }
  1133.       }
  1134.     }
  1135.     else {
  1136.       cfg_info->mode_bits |= STARLAN_10_INTERFACE;
  1137.       cfg_info->media_type = MEDIA_S10;
  1138.     }
  1139.   }
  1140.   else {
  1141.     if (temp1 & 0x02) {
  1142.       cfg_info->mode_bits |= STARLAN_10_INTERFACE;
  1143.       cfg_info->media_type = MEDIA_S10;
  1144.     }
  1145.     else {
  1146.       cfg_info->media_type = MEDIA_UNKNOWN;
  1147.     }
  1148.   }
  1149.   /***************************************************
  1150.                 get adapter type
  1151.   ****************************************************/
  1152.  cfg_info->adapter_bus =
  1153.    (board_id & SLOT_16BIT) ? BUS_ISA16_TYPE : BUS_ISA8_TYPE;
  1154.   /***************************************************
  1155.                      checksum
  1156.   ****************************************************/
  1157.   if (cfg_info->bic_type == BIC_584_CHIP) {
  1158.     if ((i = Read584Checksum(base_addr)) != SUCCESS) return(i);
  1159.   }
  1160.   if (cnfg_val) return(CONFIG_WARNING);
  1161.   else return(ADAPTER_AND_CONFIG);
  1162. }
  1163.  
  1164. /* get name of board type */
  1165. void GetAdapterName(CNFG_Adapter *cfg_info)
  1166. {
  1167.  switch(cfg_info->board_id) {
  1168.  case WD8003E: strcpy(cfg_info->adapter_name,"8003 Family");
  1169.    break;
  1170.  case WD8003WT: strcpy(cfg_info->adapter_name,"WD8003WT");
  1171.    break;
  1172.  case WD8003W: strcpy(cfg_info->adapter_name,"WD8003W");
  1173.    break;
  1174.  case WD8003EB:
  1175.    if ((cfg_info->full_bid & INTERFACE_CHIP_MASK) == INTERFACE_584_CHIP)
  1176.      strcpy(cfg_info->adapter_name,"WD8003EP");
  1177.    else
  1178.      strcpy(cfg_info->adapter_name,"WD8003EB");
  1179.    break;
  1180.  case WD8003EW: strcpy(cfg_info->adapter_name,"WD8003EW");
  1181.    break;
  1182.  case WD8003ETA: strcpy(cfg_info->adapter_name,"WD8003ETA");
  1183.    break;
  1184.  case WD8003EA:
  1185.    if ((cfg_info->full_bid & INTERFACE_CHIP_MASK) == INTERFACE_594_CHIP)
  1186.      strcpy(cfg_info->adapter_name,"WD8003EPA");
  1187.    else
  1188.      strcpy(cfg_info->adapter_name,"WD8003EA");
  1189.    break;
  1190.  case WD8003WA:
  1191.    if ((cfg_info->full_bid & INTERFACE_CHIP_MASK) == INTERFACE_594_CHIP)
  1192.      strcpy(cfg_info->adapter_name,"WD8003WPA");
  1193.    else
  1194.      strcpy(cfg_info->adapter_name,"WD8003WA");
  1195.    break;
  1196.  case WD8013EBT: strcpy(cfg_info->adapter_name,"WD8013EBT");
  1197.    break;
  1198.  case WD8013EB:  strcpy(cfg_info->adapter_name,"WD8013EB");
  1199.    break;
  1200.  case WD8013W: strcpy(cfg_info->adapter_name,"WD8013W");
  1201.    break;
  1202.  case WD8013EW: strcpy(cfg_info->adapter_name,"WD8013EW");
  1203.    break;
  1204.  case WD8013EWC: strcpy(cfg_info->adapter_name,"WD8013EWC");
  1205.    break;
  1206.  case WD8013WC: strcpy(cfg_info->adapter_name,"WD8013WC");
  1207.    break;
  1208.  case WD8013EPC: strcpy(cfg_info->adapter_name,"WD8013EPC");
  1209.    break;
  1210.  case WD8003EPC: strcpy(cfg_info->adapter_name,"WD8003EPC");
  1211.    break;
  1212.  case WD8115T: strcpy(cfg_info->adapter_name,"WD8115T");
  1213.    break;
  1214.  case WD8115TA: strcpy(cfg_info->adapter_name,"WD8115TA");
  1215.    break;
  1216.  case WD8003WC: strcpy(cfg_info->adapter_name,"WD8003WC");
  1217.    break;
  1218.  case PCM10BT: strcpy(cfg_info->adapter_name,"PCM10BT");
  1219.    break;
  1220.  case WD8203EP: strcpy(cfg_info->adapter_name,"WD8203EP");
  1221.    break;
  1222.  case WD8203W: strcpy(cfg_info->adapter_name,"WD8203W");
  1223.    break;
  1224.  case WD8216: strcpy(cfg_info->adapter_name,"WD8216");
  1225.    break;
  1226.  case WD8216T: strcpy(cfg_info->adapter_name,"WD8216T");
  1227.    break;
  1228.  case WD8216C: strcpy(cfg_info->adapter_name,"WD8216C");
  1229.    break;
  1230.  default: sprintf(cfg_info->adapter_name,"??%x",cfg_info->board_id);
  1231.    break;
  1232.  }
  1233. }
  1234.  
  1235. int VerifyParams(CNFG_Adapter *cfg_info)
  1236. {
  1237.   int intf_chip;
  1238.  
  1239.   cnfg_val = 0;
  1240.   intf_chip = cfg_info->full_bid & INTERFACE_CHIP_MASK;
  1241.   switch(cfg_info->irq_value) {
  1242.   case 3:
  1243.     break;
  1244.   case 4:
  1245.     if ((cfg_info->full_bid & ALTERNATE_IRQ_BIT) &&
  1246.           (intf_chip == INTERFACE_5X3_CHIP))
  1247.     cnfg_val |= IRQ_INVALID;
  1248.     break;
  1249.   case 5:
  1250.     if (!(cfg_info->full_bid & ALTERNATE_IRQ_BIT) &&
  1251.           (cfg_info->full_bid & INTERFACE_CHIP))
  1252.     cnfg_val |= IRQ_INVALID;
  1253.     break;
  1254.   case 7:
  1255.     break;
  1256.   case 9:
  1257.   case 10:
  1258.   case 11:
  1259.     if (!(cfg_info->full_bid & BOARD_16BIT)) cnfg_val |= IRQ_RANGE;
  1260.     else if (!(cfg_info->full_bid & SLOT_16BIT)) cnfg_val |= IRQ_INVALID;
  1261.     break;
  1262.   case 15:
  1263.     break;
  1264.   default:
  1265.     cnfg_val |= IRQ_RANGE;
  1266.     break;
  1267.   }
  1268.   switch(cfg_info->ram_usable) {
  1269.   case 8:
  1270.   case 16:
  1271.   case 32:
  1272.     break;
  1273.   default:
  1274.   cnfg_val |= RAM_SIZE_RANGE;
  1275.   }
  1276.   if (cfg_info->ram_base < 0x80000) cnfg_val |= RAM_BASE_RANGE;
  1277.   if (cfg_info->full_bid & SLOT_16BIT) {
  1278.     if (cfg_info->ram_base >= 0x1000000) cnfg_val |= RAM_BASE_RANGE;
  1279.   }
  1280.   else if (cfg_info->ram_base >= 0x100000) cnfg_val |= RAM_BASE_RANGE;
  1281.   if ((cfg_info->io_base < 0x200) || (cfg_info->io_base > 0x3e0)) {
  1282.     cnfg_val |= IO_BASE_RANGE;
  1283.   }
  1284.   else if (cfg_info->io_base & 0x1f) cnfg_val |= IO_BASE_INVALID;
  1285.   return((cnfg_val == 0) ? SUCCESS : CONFIG_ERROR);
  1286. }
  1287.  
  1288. int LM_GetCnfg(CNFG_Adapter *cfg_info)
  1289. {
  1290.  int retval,retval2,temp;
  1291.  retval = lm_get_at_config(cfg_info);
  1292.  if (verbose > 2)
  1293.    printf("lm_get_at_config returned %x, cnfg_val=%x\n",retval,cnfg_val);
  1294.  if (retval == ADAPTER_NOT_FOUND) return(retval);
  1295.  if (retval != EEROM_CKSUM_ERROR) {
  1296.    temp = cnfg_val;
  1297.    retval2 = VerifyParams(cfg_info);
  1298.    if (verbose > 2)
  1299.      printf("verifyparams returned %x, cnfg_val=%x\n",retval2,cnfg_val);
  1300.    if (retval2 != SUCCESS) {
  1301.      cnfg_val |= temp; /* combine flags */
  1302.      retval = retval2;
  1303.    }
  1304.    else cnfg_val = temp; /* restore cnfg_val */
  1305.  }
  1306.  GetAdapterName(cfg_info);
  1307.  cfg_info->nic_type = NIC_8390_CHIP;
  1308.  if (cfg_info->full_bid & NIC_690_BIT) cfg_info->nic_type = NIC_690_CHIP;
  1309.  if (cfg_info->full_bid & NIC_790_BIT) cfg_info->nic_type = NIC_790_CHIP;
  1310.  if (cfg_info->full_bid & NIC_825_BIT) cfg_info->nic_type = NIC_825_CHIP;
  1311.  return(retval);
  1312. }
  1313.  
  1314. /* returns 1 if config is soft/soft, 0 otherwise */
  1315. int GetJumperStatus(int ioaddr)
  1316. {
  1317.   return((~(inb_p(ioaddr + REG_IJR)) & 7) == 0);
  1318. }
  1319.  
  1320. void RecallConfigZero(int ioaddr)
  1321. {
  1322.   SelectOtherRegister(ioaddr);
  1323.   outb_p(inb_p(ioaddr + CNFG_EAR_583) & 0xf,ioaddr + CNFG_EAR_583); /* select page 0 */
  1324.   RecallEERomData(ioaddr, RECALL_DATA);
  1325. }
  1326.  
  1327. void RecallLanAddress(int ioaddr)
  1328. {
  1329.   RecallEERomData(ioaddr, RECALL_LANADDR);
  1330. }
  1331.  
  1332. int LM_Get_SoftCnfg(CNFG_Adapter *cfg_info)
  1333. {
  1334.   int ioaddr,irnum,irq_value,temp,rbase1;
  1335.   if ((cfg_info->full_bid & INTERFACE_CHIP_MASK) == INTERFACE_5X3_CHIP)
  1336.     return(NO_FIXED_CNFG);
  1337.   ioaddr = cfg_info->io_base;
  1338.   if (GetJumperStatus(ioaddr)) return(NO_FIXED_CNFG);
  1339.   RecallConfigZero(ioaddr);
  1340. /*******************************************************************
  1341.                 interrupt line
  1342.  *******************************************************************/
  1343.   if (!(inb_p(ioaddr + LAR0 + CNFG_IRR_583) & 0x80)) {
  1344.     cfg_info->irq_value = 0;
  1345.   }
  1346.   else {
  1347.     irnum = inb_p(ioaddr + LAR0 + 1) & 4; 
  1348.     irnum += (inb_p(ioaddr + LAR0 + 4) & 0x60) >> 5;
  1349.     if ((irnum == 2) && !(cfg_info->full_bid & ALTERNATE_IRQ_BIT))
  1350.       irq_value = 4;
  1351.     else irq_value = irqlist[irnum];
  1352.     cfg_info->irq_value = irq_value;
  1353.   }
  1354. /*******************************************************************
  1355.                 io address
  1356.  *******************************************************************/
  1357.   temp = inb_p(ioaddr + LAR0 + CNFG_IAR_583);
  1358.   cfg_info->io_base = ((temp & 0xe0) << 8) + ((temp & 0x1f) << 5);
  1359. /*******************************************************************
  1360.                 ram base
  1361.  *******************************************************************/
  1362.   rbase1 = inb_p(ioaddr + LAR0) & 0x3f;
  1363.   cfg_info->ram_base =
  1364.     (inb_p(ioaddr + LAR0 + 5) & 0x1f) << 19 | (rbase1 << 13);
  1365. /*******************************************************************
  1366.                 rom base and size
  1367.  *******************************************************************/
  1368.   cfg_info->rom_base = ((inb_p(ioaddr + LAR0 + CNFG_BIO_583) & 0x3e) | 0x40) << 13;
  1369.   cfg_info->rom_size = (inb_p(ioaddr + LAR0 + CNFG_BIO_583) & 0xc0) >> 2;
  1370. /*******************************************************************
  1371.                 recall lan address
  1372.  *******************************************************************/
  1373.  RecallLanAddress(ioaddr);
  1374.  return(SUCCESS);
  1375. }
  1376.  
  1377. void lm_pc_58x_io(CNFG_Adapter *cfg_info,int ioaddr)
  1378. {
  1379.   int temp;
  1380.   temp = cfg_info->io_base_new;
  1381.   temp = ((temp & 0x3e0) >> 5) + ((temp & 0xe000) >> 8);
  1382.   outb_p(temp, ioaddr + CNFG_IAR_583);
  1383.   if (cfg_info->config_mode & STORE_REGS) {
  1384.     cfg_info->io_base = cfg_info->io_base_new;
  1385.   }
  1386. }
  1387.  
  1388. void lm_pc_58x_irq(CNFG_Adapter *cfg_info,int ioaddr)
  1389. {
  1390.   int if583,icrval,irrval;
  1391.   if583 = (cfg_info->full_bid & INTERFACE_CHIP_MASK) == INTERFACE_5X3_CHIP;
  1392.   switch(cfg_info->irq_value) {
  1393.   case 3:
  1394.     icrval = 0;
  1395.     irrval = 0x20;
  1396.     break;
  1397.   case 4:
  1398.     if (cfg_info->full_bid & ALTERNATE_IRQ_BIT) {
  1399.       icrval = 4;
  1400.       irrval = 0x60;
  1401.     }
  1402.     else {
  1403.       icrval = 0;
  1404.       irrval = 0x40;
  1405.     }
  1406.     break;
  1407.   case 5:
  1408.     icrval = 0;
  1409.     irrval = 0x40;
  1410.     break;
  1411.   case 7:
  1412.     icrval = 0;
  1413.     irrval = 0x60;
  1414.     break;
  1415.   case 8:
  1416.     icrval = 0;
  1417.     irrval = 0x20;
  1418.     break;
  1419.   case 9:
  1420.     icrval = 0;
  1421.     irrval = 0;
  1422.     break;
  1423.   case 10:
  1424.     icrval = 4;
  1425.     irrval = 0;
  1426.     break;
  1427.   case 11:
  1428.     icrval = 4;
  1429.     irrval = 0x20;
  1430.     break;
  1431.   case 15:
  1432.     icrval = 4;
  1433.     irrval = 0x40;
  1434.     break;
  1435.   default:
  1436.     break;
  1437.   }
  1438.   if (!if583) {
  1439.     icrval |= (inb_p(ioaddr + CNFG_ICR_583) & CNFG_ICR_MASK);
  1440.     outb_p(icrval, ioaddr + CNFG_ICR_583);
  1441.   }
  1442.   irrval |= (inb_p(ioaddr + CNFG_IRR_583) & 0x9f);
  1443.   outb_p(irrval, ioaddr + CNFG_IRR_583);
  1444. }
  1445.  
  1446. void lm_pc_58x_irq_status(CNFG_Adapter *cfg_info, int ioaddr)
  1447. {
  1448.   int temp;
  1449.   temp = inb_p(ioaddr + CNFG_IRR_583) & ~CNFG_IRR_IEN;
  1450.   if (cfg_info->mode_bits & INTERRUPT_STATUS_BIT) temp |= CNFG_IRR_IEN;
  1451.   outb_p(temp, ioaddr + CNFG_IRR_583);
  1452. }
  1453.  
  1454. void lm_pc_58x_boot_status(CNFG_Adapter *cfg_info, int ioaddr)
  1455. {
  1456.   int temp;
  1457.   temp = inb_p(ioaddr + CNFG_GP2) & ~CNFG_GP2_BOOT_NIBBLE;
  1458.   if (!(cfg_info->mode_bits & BOOT_STATUS_MASK)) temp |= 1;
  1459.   outb_p(temp, ioaddr + CNFG_GP2);
  1460. }
  1461.  
  1462. void lm_pc_58x_zero_wait_state(CNFG_Adapter *cfg_info, int ioaddr)
  1463. {
  1464.   int temp;
  1465.   temp = inb_p(ioaddr + CNFG_IRR_583) & ~CNFG_IRR_ZWS;
  1466.   if (cfg_info->mode_bits & ZERO_WAIT_STATE_8_BIT) temp |= CNFG_IRR_ZWS;
  1467.   outb_p(temp, ioaddr + CNFG_IRR_583);
  1468.   if (cfg_info->full_bid & BOARD_16BIT) {
  1469.     temp = inb_p(ioaddr + CNFG_LAAR_584) & ~CNFG_LAAR_ZWS;
  1470.     if (cfg_info->mode_bits & ZERO_WAIT_STATE_16_BIT) temp |= CNFG_LAAR_ZWS;
  1471.     outb_p(temp, ioaddr + CNFG_LAAR_584);
  1472.   }
  1473. }
  1474.  
  1475. void lm_pc_58x_net_interface(CNFG_Adapter *cfg_info, int ioaddr)
  1476. {
  1477.   int temp,net_int;
  1478.   temp = inb_p(ioaddr + CNFG_IRR_583) & 0xf9;
  1479.   net_int = cfg_info->mode_bits & INTERFACE_TYPE_MASK;
  1480.   switch(net_int) {
  1481.   case BNC_INTERFACE:
  1482.     temp |= 6;
  1483.     break;
  1484.   case AUI_INTERFACE:
  1485.     temp |= 2;
  1486.     break;
  1487.   case AUI_10BT_INTERFACE:
  1488.     temp |= 4;
  1489.     break;
  1490.   }
  1491.   /* if not advanced feature adapter, invert link integrity test bit */
  1492.   if (!(cfg_info->full_bid & ADVANCED_FEATURES)) temp ^= 2;
  1493.   outb_p(temp, ioaddr + CNFG_IRR_583);
  1494. }
  1495.  
  1496. void lm_pc_58x_ram_base(CNFG_Adapter *cfg_info, int ioaddr)
  1497. {
  1498.   int temp;
  1499.   if (!((cfg_info->full_bid & INTERFACE_CHIP_MASK) == INTERFACE_5X3_CHIP)) {
  1500.     temp = (cfg_info->ram_base & 0xf80000) >> 19;
  1501.     temp |= inb_p(ioaddr + CNFG_LAAR_584) & CNFG_LAAR_MASK;
  1502.     if (!(cfg_info->full_bid & BOARD_16BIT)) temp = 1;
  1503.     outb_p(temp,ioaddr + CNFG_LAAR_584);
  1504.   }
  1505.   temp = (cfg_info->ram_base & 0x07e000) >> 13;
  1506.   outb_p(temp,ioaddr);
  1507. }
  1508.  
  1509. void lm_pc_58x_ram_size(CNFG_Adapter *cfg_info, int ioaddr)
  1510. {
  1511.   int temp;
  1512.   temp = inb_p(ioaddr + CNFG_ICR_583) & ~CNFG_ICR_MSZ;
  1513.   if ((cfg_info->ram_size != CNFG_SIZE_8kb) &&
  1514.       (cfg_info->ram_size != CNFG_SIZE_16kb)) temp |= CNFG_ICR_MSZ;
  1515.   outb_p(temp, ioaddr + CNFG_ICR_583);
  1516. }
  1517.  
  1518. void lm_pc_58x_rom_base(CNFG_Adapter *cfg_info, int ioaddr)
  1519. {
  1520.   int temp;
  1521.   temp = (cfg_info->rom_base & 0x7c000) >> 13;
  1522.   temp |= inb_p(ioaddr + CNFG_BIO_583) & 0x0c0;
  1523.   temp &= 0xfe;
  1524.   outb_p(temp, ioaddr + CNFG_BIO_583);
  1525. }
  1526.  
  1527. void lm_pc_58x_rom_size(CNFG_Adapter *cfg_info, int ioaddr)
  1528. {
  1529.   int temp;
  1530.   switch(cfg_info->rom_size) {
  1531.   case CNFG_SIZE_64kb:
  1532.     temp = 0xc0;
  1533.     break;
  1534.   case CNFG_SIZE_32kb:
  1535.     temp = 0x80;
  1536.     break;
  1537.   case CNFG_SIZE_16kb:
  1538.     temp = 0x40;
  1539.     break;
  1540.   default:
  1541.     temp = 0;
  1542.     break;
  1543.   }
  1544.   temp |= inb_p(ioaddr + CNFG_BIO_583) & 0x3e;
  1545.   outb_p(temp, ioaddr + CNFG_BIO_583);
  1546. }
  1547.  
  1548.  
  1549. /******************************************************
  1550.              store 584 eeprom stuff
  1551.  ******************************************************
  1552.  
  1553.         ROM    IRQ-IO-RAM    EEROM PG.
  1554.         ==========    ========
  1555.         soft    soft          0
  1556.         D800    soft        1
  1557.         soft    3-280-D000    2
  1558.         D800    3-280-D000    3
  1559.         soft    5-300-CC00    4
  1560.         D800    5-300-CC00    5
  1561.         (Hardware Initialized)    6
  1562.         D800    7-280-D000    7
  1563. only soft configs are changed.
  1564.  *********************************************************/
  1565.  
  1566. void lm_pc_584_store(CNFG_Adapter *cfg_info)
  1567. {
  1568.   int page,iobase,iobasefake,temp;
  1569. #ifdef FACTORY_INIT
  1570.   int saverombase,saverambase,saveirq,saveiobase,saveiobasenew;
  1571. #endif
  1572.   if (verbose > 2) printf("lm_pc_584_store\n");
  1573.   for (page = 7; page >= 0; page--) {
  1574.     /* recall eeprom into lan address regs */
  1575.     iobase = cfg_info->io_base;
  1576.     temp = inb_p(iobase + CNFG_ICR_583) & CNFG_ICR_IR2_584;
  1577.     temp |= BID_OTHER_BIT;
  1578.     outb_p(temp,iobase + CNFG_ICR_583);
  1579.     temp = inb_p(iobase + CNFG_EAR_583);
  1580.     temp &= 0xf;
  1581.     temp |= page << 4;
  1582.     outb_p(temp, iobase + CNFG_EAR_583);
  1583.     temp = inb_p(iobase + CNFG_ICR_583) & 0x0e;
  1584.     temp |= CNFG_ICR_RLA; /* set RLA bit */
  1585.     outb_p(temp, iobase + CNFG_ICR_583); /* do the recall */
  1586.     while (inb_p(iobase + CNFG_ICR_583) & CNFG_ICR_RLA); /* wait for recall */
  1587.     iobasefake = iobase + LAR0; /* point to lan address regs */
  1588. /* this is only needed if someone wiped out the factory settings */
  1589. #ifdef FACTORY_INIT
  1590.     /* these bits should be 0 */
  1591.     outb_p(inb_p(iobasefake + 1) & 0xf, iobasefake + 1);
  1592.     saverombase = cfg_info->rom_base;
  1593.     saverambase = cfg_info->ram_base;
  1594.     saveirq = cfg_info->irq_value;
  1595.     saveiobase = cfg_info->io_base;
  1596.     saveiobasenew = cfg_info->io_base_new;
  1597.     switch(page) {
  1598.     case 0:
  1599.       break;
  1600.     case 1:
  1601.       cfg_info->rom_base = 0xd8000;
  1602.       lm_pc_58x_rom_base(cfg_info,iobasefake);
  1603.       break;
  1604.     case 2:
  1605.       cfg_info->irq_value = 3;
  1606.       lm_pc_58x_irq(cfg_info,iobasefake);
  1607.       cfg_info->ram_base = 0x0d0000;
  1608.       lm_pc_58x_ram_base(cfg_info,iobasefake);
  1609.       cfg_info->io_base_new = 0x280;
  1610.       lm_pc_58x_io(cfg_info,iobasefake);
  1611.       break;
  1612.     case 3:
  1613.       cfg_info->rom_base = 0xd8000;
  1614.       lm_pc_58x_rom_base(cfg_info,iobasefake);
  1615.       cfg_info->irq_value = 3;
  1616.       lm_pc_58x_irq(cfg_info,iobasefake);
  1617.       cfg_info->ram_base = 0x0d0000;
  1618.       lm_pc_58x_ram_base(cfg_info,iobasefake);
  1619.       cfg_info->io_base_new = 0x280;
  1620.       lm_pc_58x_io(cfg_info,iobasefake);
  1621.       break;
  1622.     case 4:
  1623.       cfg_info->irq_value = 5;
  1624.       lm_pc_58x_irq(cfg_info,iobasefake);
  1625.       cfg_info->ram_base = 0x0cc000;
  1626.       lm_pc_58x_ram_base(cfg_info,iobasefake);
  1627.       cfg_info->io_base_new = 0x300;
  1628.       lm_pc_58x_io(cfg_info,iobasefake);
  1629.       break;
  1630.     case 5:
  1631.       cfg_info->rom_base = 0xd8000;
  1632.       lm_pc_58x_rom_base(cfg_info,iobasefake);
  1633.       cfg_info->irq_value = 5;
  1634.       lm_pc_58x_irq(cfg_info,iobasefake);
  1635.       cfg_info->ram_base = 0x0cc000;
  1636.       lm_pc_58x_ram_base(cfg_info,iobasefake);
  1637.       cfg_info->io_base_new = 0x300;
  1638.       lm_pc_58x_io(cfg_info,iobasefake);
  1639.       break;
  1640.     case 6:
  1641.       cfg_info->rom_base = 0xd8000;
  1642.       lm_pc_58x_rom_base(cfg_info,iobasefake);
  1643.       cfg_info->irq_value = 9;
  1644.       lm_pc_58x_irq(cfg_info,iobasefake);
  1645.       cfg_info->ram_base = 0x0d0000;
  1646.       lm_pc_58x_ram_base(cfg_info,iobasefake);
  1647.       cfg_info->io_base_new = 0x280;
  1648.       lm_pc_58x_io(cfg_info,iobasefake);
  1649.       break;
  1650.     case 7:
  1651.       cfg_info->rom_base = 0xd8000;
  1652.       lm_pc_58x_rom_base(cfg_info,iobasefake);
  1653.       cfg_info->irq_value = 7;
  1654.       lm_pc_58x_irq(cfg_info,iobasefake);
  1655.       cfg_info->ram_base = 0x0d0000;
  1656.       lm_pc_58x_ram_base(cfg_info,iobasefake);
  1657.       cfg_info->io_base_new = 0x280;
  1658.       lm_pc_58x_io(cfg_info,iobasefake);
  1659.       break;
  1660.     }
  1661.     cfg_info->rom_base = saverombase;
  1662.     cfg_info->ram_base = saverambase;
  1663.     cfg_info->io_base_new = saveiobasenew;
  1664.     cfg_info->io_base = saveiobase;
  1665.     outb_p(0, iobasefake + 7);
  1666.     if (page > 0) outb_p(0, iobasefake + 6);
  1667. #endif  
  1668.     if (page <= 1) {
  1669.       lm_pc_58x_irq(cfg_info,iobasefake);
  1670.       lm_pc_58x_irq_status(cfg_info,iobasefake);
  1671.       lm_pc_58x_ram_base(cfg_info,iobasefake);
  1672.       lm_pc_58x_ram_size(cfg_info,iobasefake);
  1673.     }
  1674.     if ((page == 0) || (page == 2) ||(page == 4)) {
  1675.       lm_pc_58x_rom_base(cfg_info,iobasefake);
  1676.       lm_pc_58x_rom_size(cfg_info,iobasefake);
  1677.     }
  1678.     if (page <= 1) {
  1679.       lm_pc_58x_io(cfg_info,iobasefake);
  1680.     }
  1681.     lm_pc_58x_boot_status(cfg_info,iobasefake);
  1682.     lm_pc_58x_zero_wait_state(cfg_info,iobasefake);
  1683.     lm_pc_58x_net_interface(cfg_info,iobasefake);
  1684.     temp = inb_p(iobase + CNFG_ICR_583) & CNFG_ICR_IR2_584;
  1685.     temp |= BID_OTHER_BIT | CNFG_ICR_STO;
  1686.     outb_p(temp,iobase + CNFG_ICR_583); /* store it */
  1687.     while (inb_p(iobase + CNFG_ICR_583) & CNFG_ICR_STO); /* wait for store */
  1688.   }
  1689.   /* now recall the lan address */
  1690.   temp = inb_p(iobase + CNFG_ICR_583) & CNFG_ICR_IR2_584;
  1691.   outb_p(temp,iobase + CNFG_ICR_583); /* restore bio register */
  1692.   temp |= CNFG_ICR_RLA;
  1693.   outb_p(temp,iobase + CNFG_ICR_583); /* recall lan address */
  1694.   while (inb_p(iobase + CNFG_ICR_583) & CNFG_ICR_RLA); /* wait for recall */
  1695.   if ((cfg_info->full_bid & INTERFACE_CHIP_MASK) == INTERFACE_584_CHIP) {
  1696.     Write584Checksum(iobase);
  1697.   }
  1698. }
  1699.  
  1700. void Write584Config(CNFG_Adapter *cfg_info)
  1701. {
  1702.   int iobase;
  1703.   iobase = cfg_info->io_base;
  1704.   lm_pc_58x_irq(cfg_info, iobase);
  1705.   lm_pc_58x_irq_status(cfg_info, iobase);
  1706.   lm_pc_58x_ram_base(cfg_info, iobase);
  1707.   lm_pc_58x_ram_size(cfg_info, iobase);
  1708.   lm_pc_58x_rom_base(cfg_info, iobase);
  1709.   lm_pc_58x_rom_size(cfg_info, iobase);
  1710.   lm_pc_58x_boot_status(cfg_info, iobase);
  1711.   lm_pc_58x_zero_wait_state(cfg_info, iobase);
  1712.   lm_pc_58x_net_interface(cfg_info, iobase);
  1713.   lm_pc_58x_io(cfg_info, iobase);
  1714. }
  1715.  
  1716. /*
  1717.   returns:
  1718.   1 - no interface chip
  1719.   0 - no board there
  1720. */
  1721. int LM_PutCnfg(CNFG_Adapter *cfg_info)
  1722. {
  1723.   int iobase,board_id,intf_chip;
  1724.   iobase = cfg_info->io_base;
  1725.   if (!lm_gc_is_board_there(iobase)) return(0xffff);
  1726.   board_id = cfg_info->full_bid;
  1727.   if (!(board_id & INTERFACE_CHIP)) return(1);
  1728.   if (cfg_info->config_mode & STORE_REGS) {
  1729.     Write584Config(cfg_info);
  1730.     iobase = cfg_info->io_base; /* in case it has changed! */
  1731.   }
  1732.   if (cfg_info->config_mode & STORE_EEROM) {
  1733.     intf_chip = board_id & INTERFACE_CHIP_MASK;
  1734.     if (intf_chip != INTERFACE_5X3_CHIP) {
  1735.       if (intf_chip != INTERFACE_584_CHIP) {
  1736.     /* must be 585 chip, punt for now */
  1737.     return(0xffff);
  1738.       }
  1739.       /* 584 chip handled here */
  1740.       lm_pc_584_store(cfg_info);
  1741.     }
  1742.     else {
  1743.       /* 583 chip handled here */
  1744.       /* do a store into eerom */
  1745.       outb_p((inb_p(iobase + CNFG_ICR_583) & 0xf) | 0x80,
  1746.          iobase + CNFG_ICR_583);
  1747.       /* wait for it to complete */
  1748.       while (inb_p(iobase + CNFG_ICR_583) & 0x80);
  1749.     }
  1750.   }
  1751.   return(0);
  1752. }
  1753.  
  1754.  
  1755. void show_eeprom(int ioaddr, int flag583)
  1756. {
  1757.  int page,i;
  1758.  if (flag583) {
  1759.    printf("eeprom  ");
  1760.    SelectOtherRegister(ioaddr);
  1761.    outb_p((inb_p(ioaddr + CNFG_BIO_583) & 0xf), ioaddr + CNFG_BIO_583);
  1762.    RecallEERomData(ioaddr, RECALL_DATA);
  1763.    for (i = 0; i < 8; i++) {
  1764.      printf("%02x ",inb_p(ioaddr + 8 + i));
  1765.    }
  1766.    printf("\n");
  1767.  }
  1768.  else {
  1769.    for (page = 0; page < 16; page++) {
  1770.      printf("eeprom page %02d  ",page);
  1771.      SelectOtherRegister(ioaddr);
  1772.      outb_p((inb_p(ioaddr + CNFG_BIO_583) & 0xf) | (page << 4),ioaddr + CNFG_BIO_583);
  1773.      RecallEERomData(ioaddr, RECALL_DATA);
  1774.      for (i = 0; i < 8; i++) {
  1775.        printf("%02x ",inb_p(ioaddr + 8 + i));
  1776.      }
  1777.      printf("\n");
  1778.    }
  1779.  }
  1780.  /* restore lan address */
  1781.  RecallEERomData(ioaddr, RECALL_LANADDR);
  1782. }
  1783.  
  1784. void show_regs(int ioaddr)
  1785. {
  1786.   int i,page,csav;
  1787.   unsigned int reg;
  1788.  
  1789.   printf("ASIC regs: ");
  1790.   for (i = 0; i < 0x10; i++) {
  1791.     reg = inb_p(ioaddr + i);
  1792.     printf("%02x ",reg);
  1793.   }
  1794.   printf("\n");
  1795.   csav = inb_p(ioaddr + 0x10) & 0xc0;
  1796.   for (page = 0; page < 4; page++) {
  1797.     outb(page<<6,ioaddr + 0x10); /* set page */
  1798.     printf("NIC page %d ",page);
  1799.     for (i = 0; i < 0x10; i++) {
  1800.       reg = inb_p(ioaddr + 0x10 + i);
  1801.       printf("%02x ",reg);
  1802.     }
  1803.     printf("\n");
  1804.   }
  1805.   outb_p(csav, ioaddr + 0x10);
  1806. }
  1807.  
  1808. void test_status(int status)
  1809. {
  1810.   switch(status) {
  1811.   case ADAPTER_NOT_FOUND:
  1812.     printf("no card found\n");
  1813.     exit(-1);
  1814.     break;
  1815.   case ADAPTER_AND_CONFIG:
  1816.     /* this is ok */
  1817.     break;
  1818.   case ADAPTER_NO_CONFIG:
  1819.     printf("Your card is not software configurable.\n");
  1820.     printf("The only way to configure it is to remove the card and set\n");
  1821.     printf("the jumpers. See your manual for more information.\n");
  1822.     exit(-1);
  1823.     break;
  1824.   case CONFIG_ERROR:
  1825.     printf("configuration error: %x\n",cnfg_val);
  1826.     exit(-1);
  1827.     break;
  1828.   case CONFIG_WARNING:
  1829.     /* this is the expected result */
  1830.     break;
  1831.   case EEROM_CKSUM_ERROR:
  1832.     printf("Warning - eerom checksum error.\n");
  1833.     break;
  1834.   default:
  1835.     printf("unknown return value from lm_getcnfg.\n");
  1836.     exit(-1);
  1837.   }
  1838. }
  1839.  
  1840. int main(int argc, char *argv[])
  1841. {
  1842.  unsigned char response[80];
  1843.  unsigned int iobase;
  1844.  int i,newval,itsok,jumpers;
  1845.  CNFG_Adapter smc_card_info,soft_cnfg_info;
  1846.  int argok,cmd_eeprom,cmd_regs,onepage;
  1847.  int numfound,status,fixed_cnfg;
  1848.  int found_addr[20];
  1849.  int media,net_interface,zerows;
  1850.  int do_set_port,do_set_rambase,do_set_irq,do_set_net_interface;
  1851.  int set_port,set_rambase,set_irq,set_net_interface;
  1852.  
  1853.  iobase = 0;
  1854.  verbose = 0;
  1855.  do_set_port = do_set_rambase = do_set_irq = do_set_net_interface = 0;
  1856.  smc_card_info.adapter_num = 0;
  1857.  smc_card_info.pc_bus = 0;
  1858.  smc_card_info.io_base = 0;
  1859.  smc_card_info.adapter_name[0] = '\0';
  1860.  smc_card_info.irq_value = 0;
  1861.  smc_card_info.rom_size = 0;
  1862.  smc_card_info.rom_base = 0;
  1863.  smc_card_info.rom_access = 0;
  1864.  smc_card_info.ram_size = 0;
  1865.  smc_card_info.ram_base = 0;
  1866.  smc_card_info.ram_access = 0;
  1867.  smc_card_info.ram_usable = 0;
  1868.  smc_card_info.io_base_new = 0;
  1869.  smc_card_info.node_address[0] = 0;
  1870.  smc_card_info.max_packet_size = 0;
  1871.  smc_card_info.num_of_tx_buffs = 0;
  1872.  smc_card_info.media_type = 0;
  1873.  smc_card_info.adapter_bus = 0;
  1874.  smc_card_info.pos_id = 0;
  1875.  smc_card_info.adapter_flags = 0;
  1876.  smc_card_info.slot_num = 0;
  1877.  smc_card_info.bic_type = 0;
  1878.  smc_card_info.nic_type = 0;
  1879.  smc_card_info.board_id = 0;
  1880.  smc_card_info.extra_info = 0;
  1881.  smc_card_info.full_bid = 0;
  1882.  smc_card_info.mode_bits = 0;
  1883.  smc_card_info.status_bits = 0;
  1884.  smc_card_info.config_mode = 0;
  1885.  smc_card_info.page_offset_mask = 0;
  1886.  smc_card_info.clone = 0;
  1887.  soft_cnfg_info = smc_card_info;
  1888.  if (argc > 1)
  1889.  for (i = 1; i < argc; i++) {
  1890.    argok = 0;
  1891.    if (((strcmp(argv[i],"-v") == 0) || (strcmp(argv[i],"--verbose") == 0))
  1892.        && (argc > (i + 1))) {
  1893.      if (sscanf(argv[++i],"%d",&newval) == 1) {
  1894.        verbose = newval;
  1895.        argok = 1;
  1896.      }
  1897.      goto next_arg;
  1898.    }
  1899.    if (((strcmp(argv[i],"-p") == 0) || (strcmp(argv[i],"--newaddr") == 0))
  1900.        && (argc > (i + 1))) {
  1901.      if (sscanf(argv[++i],"%x",&newval) == 1) {
  1902.        if ((newval & 0xe3e0) == newval) {
  1903.      do_set_port = 1;
  1904.      set_port = newval;
  1905.      argok = 1;
  1906.        }
  1907.      }
  1908.      goto next_arg;
  1909.    }
  1910.    if (((strcmp(argv[i],"-b") == 0) || (strcmp(argv[i],"--ramstart") == 0))
  1911.        && (argc > (i + 1))) {
  1912.      if (sscanf(argv[++i],"%x",&newval) == 1) {
  1913.        do_set_rambase = 1;
  1914.        set_rambase = newval;
  1915.        argok = 1;
  1916.      }
  1917.      goto next_arg;
  1918.    }
  1919.    if (((strcmp(argv[i],"-i") == 0) || (strcmp(argv[i],"--irq") == 0))
  1920.        && (argc > (i + 1))) {
  1921.      if (sscanf(argv[++i],"%u",&newval) == 1) {
  1922.        do_set_irq = 1;
  1923.        set_irq = newval;
  1924.        argok = 1;
  1925.      }
  1926.      goto next_arg;
  1927.    }
  1928.    if (((strcmp(argv[i],"-m") == 0) || (strcmp(argv[i],"--media") == 0))
  1929.        && (argc > (i + 1))) {
  1930.      i++;
  1931.      if (strcmp(argv[i],"aui") == 0) {
  1932.        do_set_net_interface = 1;
  1933.        set_net_interface = AUI_INTERFACE;
  1934.        argok = 1;
  1935.      }
  1936.      if (strcmp(argv[i],"bnc") == 0) {
  1937.        do_set_net_interface = 1;
  1938.        set_net_interface = BNC_INTERFACE;
  1939.        argok = 1;
  1940.      }
  1941.      if (strcmp(argv[i],"twp") == 0) {
  1942.        do_set_net_interface = 1;
  1943.        set_net_interface = AUI_10BT_INTERFACE;
  1944.        argok = 1;
  1945.      }
  1946.      goto next_arg;
  1947.    }
  1948.    if (strcmp(argv[i],"-e") == 0) {
  1949.      cmd_eeprom = argok = 1;
  1950.      goto next_arg;
  1951.    }
  1952.    if (strcmp(argv[i],"-r") == 0) {
  1953.      cmd_regs = argok = 1;
  1954.      goto next_arg;
  1955.    }
  1956.    if (((strncmp(argv[i],"-a",2) == 0) || (strcmp(argv[i],"--baseaddr") == 0))
  1957.        && (argc > (i + 1))) {
  1958.      sscanf(argv[++i],"%x",&newval);
  1959.      if ((newval & 0xe3e0) == newval) {
  1960.        iobase = newval;
  1961.        argok = 1;
  1962.      }
  1963.      else {
  1964.        printf("addr must be [02468ace][0-3][02468ace]0\n");
  1965.        exit(-1);
  1966.      }
  1967.      goto next_arg;
  1968.    }
  1969.  next_arg:
  1970.    if (!argok) {
  1971.      printf("Usage: wdsetup [options]\n\
  1972. options are:\n\
  1973. -a addr\t\tspecify board's base io address\n\
  1974. --baseaddr addr\t\n\
  1975. -v verbose_level\tspecify verbosity level\n\
  1976. --verbose verbose_level\n
  1977. -r\t\tdump registers\n\
  1978. --regs\t\tdump registers\n\
  1979. -e\t\tdump eeprom\n\
  1980. -eeprom\t\tdump eeprom\n\
  1981. note: if any of the following options are used, the interactive\n\
  1982.     reconfiguring of the eeprom will be skipped.\n\
  1983. -e\t\tdump eeprom contents\n\
  1984. -r\t\tdump registers\n\
  1985. -p addr\tset board's new io address\n\
  1986. --newaddr addr\t\n\
  1987. -b addr\t\tset new ram start address\n\
  1988. --ramstart addr\t\n\
  1989. -i irq\t\tset new interrupt number\n\
  1990. --irq irq\t\n\
  1991. -m media\tset media type [aui] || [bnc] || [twp]\n\
  1992. --media media\t\n");
  1993.      exit(-1);
  1994.    }
  1995.  }
  1996.  
  1997.  if (iopl(3)) {
  1998.    perror("io-perm2");
  1999.    exit (-1);
  2000.  }
  2001.  
  2002. /* do configuring via command line args here */
  2003.  if (do_set_port || do_set_rambase || do_set_irq || do_set_net_interface) {
  2004.    if (iobase == 0) {
  2005.      return(-1); /* didn't specify address */
  2006.    }
  2007.    smc_card_info.io_base = iobase;
  2008.    smc_card_info.io_base_new = iobase;
  2009.    status = LM_GetCnfg(&smc_card_info);
  2010.    test_status(status);
  2011.    if (do_set_port) {
  2012.      smc_card_info.io_base_new = set_port;
  2013.    }
  2014.    if (do_set_rambase) {
  2015.      if ((set_rambase & 0xffe000) == set_rambase) {
  2016.        smc_card_info.ram_base = set_rambase;
  2017.      }
  2018.      else return(-1); /* bad ram address */
  2019.    }
  2020.    if (do_set_irq) {
  2021.      smc_card_info.irq_value = set_irq;
  2022.    }
  2023.    if (do_set_net_interface) {
  2024.      media = smc_card_info.full_bid & MEDIA_MASK;
  2025.      switch(set_net_interface) {
  2026.      case AUI_INTERFACE:
  2027.        if ((media != ETHERNET_MEDIA) && (media != EW_MEDIA)) exit(-1);
  2028.        break;
  2029.      case BNC_INTERFACE:
  2030.        if ((media != ETHERNET_MEDIA) && (media != EW_MEDIA)) exit(-1);
  2031.        break;
  2032.      case AUI_10BT_INTERFACE: 
  2033.        if ((media != TWISTED_PAIR_MEDIA) && (media != EW_MEDIA)) exit(-1);
  2034.        break;
  2035.      default:
  2036.        return(-1); /* bad set_net_interface type */
  2037.        break;
  2038.      }
  2039.      smc_card_info.mode_bits &= ~INTERFACE_TYPE_MASK;
  2040.      smc_card_info.mode_bits |= set_net_interface;
  2041.    }
  2042.    status = LM_PutCnfg(&smc_card_info);
  2043.    return(0); /* normal return for command line configuring */
  2044.  }
  2045. /* non command line configuring */
  2046.  
  2047.  printf("Setup for Western Digital and SMC ethercards, version %s\n",
  2048.     wdsetup_version);
  2049.  if (iobase == 0) {
  2050.    /* look for cards at all possible addresses */
  2051.    numfound = 0;
  2052.    for (iobase = 0x200; iobase <= 0x3e0; iobase += 0x20) {
  2053.      if (lm_gc_is_board_there(iobase)) {
  2054.        found_addr[numfound++] = iobase;
  2055.      }
  2056.    }
  2057.    if (numfound == 0) {
  2058.      printf("no cards recognized.\n");
  2059.      exit(-1);
  2060.    }
  2061.    if (numfound == 1) iobase = found_addr[0];
  2062.    if (numfound > 1) {
  2063.      printf("%d cards recognized.\naddresses = ",numfound);
  2064.      for (i = 0; i < numfound; i++) {
  2065.        printf("%04x ",found_addr[i]);
  2066.      }
  2067.      printf("\nWhich address do you want to set-up ? ");
  2068.      fgets(response,80,stdin);
  2069.      sscanf(response,"%x",&iobase);
  2070.    }
  2071.  }
  2072.  smc_card_info.io_base = iobase;
  2073.  smc_card_info.io_base_new = iobase;
  2074.  status = LM_GetCnfg(&smc_card_info);
  2075.  test_status(status);
  2076.  if (verbose > 1) {
  2077.    printf("media_type = %x\n",smc_card_info.media_type);
  2078.    printf("mode_bits = %x\n",smc_card_info.mode_bits);
  2079.    printf("full_bid = %x\n",smc_card_info.full_bid);
  2080.  }
  2081.  if (cmd_regs) {
  2082.    show_regs(iobase);
  2083.    exit(0);
  2084.  }
  2085.  if (cmd_eeprom) {
  2086.    onepage = (smc_card_info.full_bid & INTERFACE_CHIP_MASK) == INTERFACE_5X3_CHIP;
  2087.    show_eeprom(iobase, onepage);
  2088.    exit(0);
  2089.  }
  2090.  soft_cnfg_info = smc_card_info;
  2091.  status = LM_Get_SoftCnfg(&soft_cnfg_info);
  2092.  if (verbose >= 2) printf("lmgetsoftcnfg returned %x\n",status);
  2093.  fixed_cnfg = (status != NO_FIXED_CNFG);
  2094.  if (smc_card_info.clone) printf("Clone: ");
  2095.  printf("Board type:\t%s\n",smc_card_info.adapter_name);
  2096.  printf("node address: ");
  2097.  for (i = 0; i < 6; i++) printf("%02x",inb_p(iobase + 8 + i));
  2098.  if (fixed_cnfg) {
  2099.    printf("\n\n\t\t\tFixed (current)\tSoft\n");
  2100.    printf("\t\t\tsetup\t\tsetup\n\n");
  2101.  }
  2102.  else printf("\n\n\t\t\tcurrent setup\n\n");
  2103.  jumpers = (inb_p(iobase + WD_JUMPERS) & 7) ^ 7;
  2104.  printf("i/o base addr\t\t%04x",smc_card_info.io_base);
  2105.  if (fixed_cnfg) printf("\t\t%04x",soft_cnfg_info.io_base);
  2106.  printf("\nirq\t\t\t%s%d",
  2107.     (smc_card_info.mode_bits & INTERRUPT_STATUS_BIT) ?
  2108.     "" : "(Disabled) ",smc_card_info.irq_value);
  2109.  if (fixed_cnfg) {
  2110.    printf("\t\t%s%d",
  2111.     (soft_cnfg_info.mode_bits & INTERRUPT_STATUS_BIT) ?
  2112.     "" : "(Disabled) ",soft_cnfg_info.irq_value);
  2113.  }
  2114.  printf("\nram size\t\t%d K",smc_card_info.ram_size);
  2115.  if (fixed_cnfg) {
  2116.    printf("\t\t%d K",soft_cnfg_info.ram_size);
  2117.  }
  2118.  printf("\nram base address\t%06x",smc_card_info.ram_base);
  2119.  if (fixed_cnfg) {
  2120.    printf("\t\t%06x",soft_cnfg_info.ram_base);
  2121.  }
  2122.  if ((smc_card_info.full_bid & BOARD_16BIT) &&
  2123.      (smc_card_info.full_bid & SLOT_16BIT)) {
  2124.    zerows = smc_card_info.mode_bits & ZERO_WAIT_STATE_16_BIT;
  2125.  }
  2126.  else zerows = smc_card_info.mode_bits & ZERO_WAIT_STATE_8_BIT;
  2127.  printf("\nadd wait states\t\t%s", zerows ? "no" : "yes");
  2128.  if (fixed_cnfg) {
  2129.    printf("\t\t%s", zerows ? "no" : "yes");
  2130.  }
  2131.  printf("\nnetwork connection\t");
  2132.  net_interface = smc_card_info.mode_bits & INTERFACE_TYPE_MASK;
  2133.  switch(net_interface) {
  2134.    case AUI_INTERFACE: printf("aui");
  2135.      break;
  2136.    case AUI_10BT_INTERFACE: printf("twp");
  2137.      break;
  2138.    case BNC_INTERFACE: printf("bnc");
  2139.      break;
  2140.    default: printf("unknown");
  2141.    break;
  2142.    }
  2143.  if (fixed_cnfg) {
  2144.    switch(net_interface) {
  2145.    case AUI_INTERFACE: printf("\t\taui");
  2146.      break;
  2147.    case AUI_10BT_INTERFACE: printf("\t\ttwp");
  2148.      break;
  2149.    case BNC_INTERFACE: printf("\t\tbnc");
  2150.      break;
  2151.    default: printf("\t\tunknown");
  2152.      break;
  2153.    }
  2154.  }
  2155.  printf("\n\n");
  2156.  if (smc_card_info.rom_size == 0) printf("rom size\t\t(Disabled)");
  2157.  else printf("rom size\t\t%d K",smc_card_info.rom_size);
  2158.  if (fixed_cnfg) {
  2159.    if (soft_cnfg_info.rom_size == 0) printf("\t\t(Disabled)");
  2160.    else printf("\t\t%d K",soft_cnfg_info.rom_size);
  2161.  }
  2162.  printf("\nrom base address\t%05x",smc_card_info.rom_base);
  2163.  if (fixed_cnfg) {
  2164.    printf("\t\t%05x",soft_cnfg_info.rom_base);
  2165.  }
  2166.  printf("\n\nchange the soft configuration in eeprom? (y) ");
  2167.  fgets(response,80,stdin);
  2168.  if ((response[0] == 'y') || (response[0] == 'Y') || (response[0] == '\n')) {
  2169.    itsok = 0;
  2170.    while (!itsok) {
  2171.      printf("What io address do you want (%x) : ",smc_card_info.io_base);
  2172.      fgets(response,80,stdin);
  2173.      itsok = 1;
  2174.      if (response[0] != '\n') {
  2175.        sscanf(response,"%x",&newval);
  2176.        if ((newval & 0x3e0) == newval) {
  2177.      smc_card_info.io_base_new = newval;
  2178.        }
  2179.        else {
  2180.      itsok = 0;
  2181.      printf("addr must be [2-3][02468ace]0\n");
  2182.        }
  2183.      }
  2184.    }
  2185.    itsok = 0;
  2186.    while (!itsok) {
  2187.      printf("What irq do you want (%d) : ",smc_card_info.irq_value);
  2188.      fgets(response,80,stdin);
  2189.      itsok = 1;
  2190.      if (response[0] != '\n') {
  2191.        sscanf(response,"%d",&newval);
  2192.        switch(newval) {
  2193.        case 3:
  2194.        case 4:
  2195.        case 5:
  2196.        case 7:
  2197.        case 9:
  2198.        case 10:
  2199.        case 11:
  2200.        case 15:
  2201.      smc_card_info.irq_value = newval;
  2202.      break;
  2203.        default:
  2204.      itsok = 0;
  2205.      break;
  2206.        }
  2207.      }
  2208.    }
  2209.    itsok = 0;
  2210.    while (!itsok) {
  2211.      printf("enter ram start address (%06x) : ",smc_card_info.ram_base);
  2212.      fgets(response,80,stdin);
  2213.      itsok = 1;
  2214.      if (response[0] != '\n') {
  2215.        sscanf(response,"%x",&newval);
  2216.        if ((newval & 0xffe000) == newval) {
  2217.      printf("ram address ok\n");
  2218.      smc_card_info.ram_base = newval;
  2219.        }
  2220.        else itsok = 0;
  2221.      }
  2222.    }
  2223.    itsok = 0;
  2224.    while (!itsok) {
  2225.      printf("add wait states ? (%s) : ", zerows ? "no" : "yes");
  2226.      fgets(response,80,stdin);
  2227.      itsok = 1;
  2228.      if (response[0] != '\n') {
  2229.        if ((response[0] == 'y') || (response[0] == 'Y')) {
  2230.      smc_card_info.mode_bits &= ~ZERO_WAIT_STATE_MASK;
  2231.        }
  2232.        else {
  2233.      if ((response[0] == 'n') || (response[0] == 'N')) {
  2234.        smc_card_info.mode_bits &= ~ZERO_WAIT_STATE_MASK;
  2235.        smc_card_info.mode_bits |=
  2236.          ZERO_WAIT_STATE_8_BIT | ZERO_WAIT_STATE_16_BIT;
  2237.      }
  2238.      else itsok = 0;
  2239.        }
  2240.      }
  2241.    }
  2242.    itsok = 0;
  2243.    media = smc_card_info.full_bid & MEDIA_MASK;
  2244.    while (!itsok) {
  2245.      if ((media == ETHERNET_MEDIA) || (media == EW_MEDIA)) {
  2246.        printf("\n1 = aui");
  2247.        printf("\n2 = bnc");
  2248.      }
  2249.      if ((media == TWISTED_PAIR_MEDIA) || (media == EW_MEDIA)) {
  2250.        printf("\n3 = twisted pair");
  2251.      }
  2252.      printf("\nnetwork connection ? ");
  2253.      switch(net_interface) {
  2254.      case AUI_INTERFACE: printf("(aui)");
  2255.        break;
  2256.      case AUI_10BT_INTERFACE: printf("(twp)");
  2257.        break;
  2258.      case BNC_INTERFACE: printf("(bnc)");
  2259.        break;
  2260.      default: printf("(unknown)");
  2261.        break;
  2262.      }
  2263.      printf(" : ");
  2264.      fgets(response,80,stdin);
  2265.      if (response[0] != '\n') {
  2266.        switch(response[0]) {
  2267.        case '1':
  2268.      if ((media == ETHERNET_MEDIA) || (media == EW_MEDIA)) {
  2269.        smc_card_info.mode_bits &= ~INTERFACE_TYPE_MASK;
  2270.        smc_card_info.mode_bits |= AUI_INTERFACE;
  2271.        itsok = 1;
  2272.      }
  2273.      break;
  2274.        case '2':
  2275.      if ((media == ETHERNET_MEDIA) || (media == EW_MEDIA)) {
  2276.        smc_card_info.mode_bits &= ~INTERFACE_TYPE_MASK;
  2277.        smc_card_info.mode_bits |= BNC_INTERFACE;
  2278.        itsok = 1;
  2279.      }
  2280.      break;
  2281.        case '3': 
  2282.      if ((media == TWISTED_PAIR_MEDIA) || (media == EW_MEDIA)) {
  2283.        smc_card_info.mode_bits &= ~INTERFACE_TYPE_MASK;
  2284.        smc_card_info.mode_bits |= AUI_10BT_INTERFACE;
  2285.        itsok = 1;
  2286.      }
  2287.        }
  2288.      }
  2289.      else itsok = 1;
  2290.    }
  2291.    smc_card_info.config_mode = STORE_REGS | STORE_EEROM;
  2292.    LM_PutCnfg(&smc_card_info);
  2293.    /* now see if jumpers are set to soft config position */
  2294.    if (jumpers == 0) {
  2295.    }
  2296.    else {
  2297.      printf("Note - Change W1 or W2 to select new soft configuration values.\n");
  2298.    }
  2299.  }
  2300.  exit(0);
  2301. }
  2302.