您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

3c509.c 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * Split out into 3c509.c and 3c5x9.c, to make it possible to build a
  3. * 3c529 module without including ISA, ISAPnP and EISA code.
  4. *
  5. */
  6. #include "eisa.h"
  7. #include "isa.h"
  8. #include "io.h"
  9. #include "timer.h"
  10. #include "string.h"
  11. #include "etherboot.h"
  12. #include "3c509.h"
  13. /*
  14. * 3c509 cards have their own method of contention resolution; this
  15. * effectively defines another bus type.
  16. *
  17. */
  18. /*
  19. * A physical t509 device
  20. *
  21. */
  22. struct t509_device {
  23. char *magic; /* must be first */
  24. uint16_t id_port;
  25. uint16_t ioaddr;
  26. unsigned char current_tag;
  27. };
  28. /*
  29. * A t509 driver
  30. *
  31. */
  32. struct t509_driver {
  33. const char *name;
  34. };
  35. /*
  36. * Ensure that there is sufficient space in the shared dev_bus
  37. * structure for a struct pci_device.
  38. *
  39. */
  40. DEV_BUS( struct t509_device, t509_dev );
  41. static char t509_magic[0]; /* guaranteed unique symbol */
  42. /*
  43. * Find a port that can be used for contention select
  44. *
  45. * Called only once, so inlined for efficiency.
  46. *
  47. */
  48. static inline int find_id_port ( struct t509_device *t509 ) {
  49. for ( t509->id_port = EP_ID_PORT_START ;
  50. t509->id_port < EP_ID_PORT_END ;
  51. t509->id_port += EP_ID_PORT_INC ) {
  52. outb ( 0x00, t509->id_port );
  53. outb ( 0xff, t509->id_port );
  54. if ( inb ( t509->id_port ) & 0x01 ) {
  55. /* Found a suitable port */
  56. return 1;
  57. }
  58. }
  59. /* No id port available */
  60. return 0;
  61. }
  62. /*
  63. * Send ID sequence to the ID port
  64. *
  65. * Called only once, so inlined for efficiency.
  66. *
  67. */
  68. static inline void send_id_sequence ( struct t509_device *t509 ) {
  69. unsigned short lrs_state, i;
  70. outb ( 0x00, t509->id_port );
  71. outb ( 0x00, t509->id_port );
  72. lrs_state = 0xff;
  73. for ( i = 0; i < 255; i++ ) {
  74. outb ( lrs_state, t509->id_port );
  75. lrs_state <<= 1;
  76. lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
  77. }
  78. }
  79. /*
  80. * We get eeprom data from the id_port given an offset into the eeprom.
  81. * Basically; after the ID_sequence is sent to all of the cards; they enter
  82. * the ID_CMD state where they will accept command requests. 0x80-0xbf loads
  83. * the eeprom data. We then read the port 16 times and with every read; the
  84. * cards check for contention (ie: if one card writes a 0 bit and another
  85. * writes a 1 bit then the host sees a 0. At the end of the cycle; each card
  86. * compares the data on the bus; if there is a difference then that card goes
  87. * into ID_WAIT state again). In the meantime; one bit of data is returned in
  88. * the AX register which is conveniently returned to us by inb(). Hence; we
  89. * read 16 times getting one bit of data with each read.
  90. */
  91. static uint16_t id_read_eeprom ( struct t509_device *t509, int offset ) {
  92. int i, data = 0;
  93. outb ( 0x80 + offset, t509->id_port );
  94. /* Do we really need this wait? Won't be noticeable anyway */
  95. udelay(10000);
  96. for ( i = 0; i < 16; i++ ) {
  97. data = ( data << 1 ) | ( inw ( t509->id_port ) & 1 );
  98. }
  99. return data;
  100. }
  101. /*
  102. * Find the next t509 device
  103. *
  104. * Called only once, so inlined for efficiency.
  105. *
  106. */
  107. static inline int fill_t509_device ( struct t509_device *t509 ) {
  108. int i;
  109. uint16_t iobase;
  110. /*
  111. * We need an ID port, if we don't already have one.
  112. *
  113. */
  114. if ( ! t509->id_port ) {
  115. if ( ! find_id_port ( t509 ) ) {
  116. DBG ( "No ID port available for contention select\n" );
  117. return 0;
  118. }
  119. }
  120. /*
  121. * If this is the start of the scan, clear all tag registers.
  122. * Otherwise, tell already-found NICs not to respond.
  123. *
  124. */
  125. if ( t509->current_tag == 0 ) {
  126. outb ( 0xd0, t509->id_port );
  127. } else {
  128. outb ( 0xd8, t509->id_port ) ;
  129. }
  130. /* Send the ID sequence */
  131. send_id_sequence ( t509 );
  132. /* Check the manufacturer ID */
  133. if ( id_read_eeprom ( t509, EEPROM_MFG_ID ) != MFG_ID ) {
  134. /* No more t509 devices */
  135. return 0;
  136. }
  137. /* Do contention select by reading the MAC address */
  138. for ( i = 0 ; i < 3 ; i++ ) {
  139. id_read_eeprom ( t509, i );
  140. }
  141. /* By now, only one device will be left active. Get its I/O
  142. * address, tag and activate the adaptor. Tagging will
  143. * prevent it taking part in the next scan, enabling us to see
  144. * the next device.
  145. */
  146. iobase = id_read_eeprom ( t509, EEPROM_ADDR_CFG );
  147. t509->ioaddr = 0x200 + ( ( iobase & 0x1f ) << 4 );
  148. outb ( ++t509->current_tag, t509->id_port ); /* tag */
  149. outb ( ( 0xe0 | iobase ), t509->id_port ); /* activate */
  150. return 1;
  151. }
  152. /*
  153. * Find a t509 device matching the specified driver. ("Matching the
  154. * specified driver" is, in this case, a no-op, but we want to
  155. * preserve the common bus API).
  156. *
  157. * Called only once, so inlined for efficiency.
  158. *
  159. */
  160. static inline int find_t509_device ( struct t509_device *t509,
  161. struct t509_driver *driver __unused ) {
  162. /* Initialise struct t509 if it's the first time it's been used. */
  163. if ( t509->magic != t509_magic ) {
  164. memset ( t509, 0, sizeof ( *t509 ) );
  165. t509->magic = t509_magic;
  166. }
  167. /* Find the next t509 device */
  168. if ( ! fill_t509_device ( t509 ) )
  169. return 0;
  170. return 1;
  171. }
  172. /*
  173. * Find the next T509 device that can be used to boot using the
  174. * specified driver.
  175. *
  176. */
  177. int find_t509_boot_device ( struct dev *dev, struct t509_driver *driver ) {
  178. struct t509_device *t509 = ( struct t509_device * )dev->bus;
  179. if ( ! find_t509_device ( t509, driver ) )
  180. return 0;
  181. dev->name = driver->name;
  182. dev->devid.bus_type = ISA_BUS_TYPE;
  183. dev->devid.vendor_id = MFG_ID;
  184. dev->devid.device_id = PROD_ID;
  185. return 1;
  186. }
  187. /*
  188. * The ISA probe function
  189. *
  190. */
  191. static int el3_t509_probe ( struct dev *dev, struct t509_device *t509 ) {
  192. struct nic *nic = nic_device ( dev );
  193. nic->ioaddr = t509->ioaddr;
  194. nic->irqno = 0;
  195. printf ( "3c509 board on ISA at %#hx - ", nic->ioaddr );
  196. /* Hand off to generic t5x9 probe routine */
  197. return t5x9_probe ( nic, ISA_PROD_ID ( PROD_ID ), ISA_PROD_ID_MASK );
  198. }
  199. static struct t509_driver el3_t509_driver = { "3c509 (ISA)" };
  200. BOOT_DRIVER ( "3c509", find_t509_boot_device, el3_t509_driver,
  201. el3_t509_probe );
  202. /*
  203. * The EISA probe function
  204. *
  205. */
  206. static int el3_eisa_probe ( struct dev *dev, struct eisa_device *eisa ) {
  207. struct nic *nic = nic_device ( dev );
  208. enable_eisa_device ( eisa );
  209. nic->ioaddr = eisa->ioaddr;
  210. nic->irqno = 0;
  211. printf ( "3C5x9 board on EISA at %#hx - ", nic->ioaddr );
  212. /* Hand off to generic t5x9 probe routine */
  213. return t5x9_probe ( nic, ISA_PROD_ID ( PROD_ID ), ISA_PROD_ID_MASK );
  214. }
  215. static struct eisa_id el3_eisa_adapters[] = {
  216. { "3Com 3c509 EtherLink III (EISA)", MFG_ID, PROD_ID },
  217. };
  218. static struct eisa_driver el3_eisa_driver =
  219. EISA_DRIVER ( "3c509 (EISA)", el3_eisa_adapters );
  220. BOOT_DRIVER ( "3c509 (EISA)", find_eisa_boot_device, el3_eisa_driver,
  221. el3_eisa_probe );
  222. /*
  223. * We currently build both ISA and EISA support into a single ROM
  224. * image, though there's no reason why this couldn't be split to
  225. * reduce code size; just split this .c file into two in the obvious
  226. * place.
  227. *
  228. */
  229. ISA_ROM ( "3c509","3c509, ISA/EISA" );