iPXE
Functions | Variables
cs89x0.c File Reference
#include <errno.h>
#include <ipxe/ethernet.h>
#include "etherboot.h"
#include "nic.h"
#include <ipxe/isa.h>
#include "cs89x0.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_ONLY)
 Per an email message from Russ Nelson nelso.nosp@m.n@cr.nosp@m.ynwr..nosp@m.com on 18 March 2008 this file is now licensed under GPL Version 2. More...
 
static int readreg (int portno)
 
static void writereg (int portno, int value)
 
static int wait_eeprom_ready (void)
 
static int get_eeprom_data (int off, int len, unsigned short *buffer)
 
static int get_eeprom_chksum (int off __unused, int len, unsigned short *buffer)
 
static void clrline (void)
 
static void control_dc_dc (int on_not_off)
 
static int detect_tp (void)
 
static int send_test_pkt (struct nic *nic)
 
static int detect_aui (struct nic *nic)
 
static int detect_bnc (struct nic *nic)
 
static void cs89x0_reset (struct nic *nic)
 
static void cs89x0_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
 
static int cs89x0_poll (struct nic *nic, int retrieve)
 
static void cs89x0_irq (struct nic *nic __unused, irq_action_t action __unused)
 
static int cs89x0_probe_addr (isa_probe_addr_t ioaddr)
 
static int cs89x0_probe (struct nic *nic, struct isa_device *isa __unused)
 
static void cs89x0_disable (struct nic *nic, struct isa_device *isa __unused)
 
 ISA_DRIVER (cs89x0_driver, cs89x0_probe_addrs, cs89x0_probe_addr, ISAPNP_VENDOR('C', 'S', 'C'), 0x0007)
 
 DRIVER ("cs89x0", nic_driver, isa_driver, cs89x0_driver, cs89x0_probe, cs89x0_disable)
 
 ISA_ROM ("cs89x0", "Crystal Semiconductor CS89x0")
 

Variables

static unsigned short eth_nic_base
 
static unsigned long eth_mem_start
 
static unsigned short eth_irqno
 
static unsigned short eth_cs_type
 
static unsigned short eth_auto_neg_cnf
 
static unsigned short eth_adapter_cnf
 
static unsigned short eth_linectl
 
static struct nic_operations cs89x0_operations
 
static isa_probe_addr_t cs89x0_probe_addrs []
 

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_ONLY  )

Per an email message from Russ Nelson nelso.nosp@m.n@cr.nosp@m.ynwr..nosp@m.com on 18 March 2008 this file is now licensed under GPL Version 2.

From: Russ Nelson nelso.nosp@m.n@cr.nosp@m.ynwr..nosp@m.com Date: Tue, 18 Mar 2008 12:42:00 -0400 Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot – quote from email As copyright holder, if I say it doesn't conflict with the GPL, then it doesn't conflict with the GPL.

However, there's no point in causing people's brains to overheat, so yes, I grant permission for the code to be relicensed under the GPLv2. Please make sure that this change in licensing makes its way upstream. -russ – quote from email

◆ readreg()

static int readreg ( int  portno)
inlinestatic

Definition at line 109 of file cs89x0.c.

110 {
111  outw(portno, eth_nic_base + ADD_PORT);
112  return inw(eth_nic_base + DATA_PORT);
113 }
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
#define outw(data, io_addr)
Definition: io.h:319
#define DATA_PORT
Definition: cs89x0.h:347
#define ADD_PORT
Definition: cs89x0.h:346
static unsigned short eth_nic_base
Definition: cs89x0.c:97

References ADD_PORT, DATA_PORT, eth_nic_base, inw(), and outw.

Referenced by cs89x0_poll(), cs89x0_probe(), cs89x0_reset(), cs89x0_transmit(), detect_tp(), get_eeprom_data(), send_test_pkt(), and wait_eeprom_ready().

◆ writereg()

static void writereg ( int  portno,
int  value 
)
inlinestatic

Definition at line 115 of file cs89x0.c.

116 {
117  outw(portno, eth_nic_base + ADD_PORT);
119  return;
120 }
#define outw(data, io_addr)
Definition: io.h:319
#define DATA_PORT
Definition: cs89x0.h:347
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define ADD_PORT
Definition: cs89x0.h:346
static unsigned short eth_nic_base
Definition: cs89x0.c:97

References ADD_PORT, DATA_PORT, eth_nic_base, outw, and value.

Referenced by control_dc_dc(), cs89x0_probe(), cs89x0_reset(), detect_aui(), detect_bnc(), detect_tp(), get_eeprom_data(), and send_test_pkt().

◆ wait_eeprom_ready()

static int wait_eeprom_ready ( void  )
static

Definition at line 126 of file cs89x0.c.

127 {
128  unsigned long tmo = currticks() + 4*TICKS_PER_SEC;
129 
130  /* check to see if the EEPROM is ready, a timeout is used -
131  just in case EEPROM is ready when SI_BUSY in the
132  PP_SelfST is clear */
133  while(readreg(PP_SelfST) & SI_BUSY) {
134  if (currticks() >= tmo)
135  return -1; }
136  return 0;
137 }
#define SI_BUSY
Definition: cs89x0.h:278
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
#define PP_SelfST
Definition: cs89x0.h:78
static int readreg(int portno)
Definition: cs89x0.c:109
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42

References currticks(), PP_SelfST, readreg(), SI_BUSY, and TICKS_PER_SEC.

Referenced by get_eeprom_data().

◆ get_eeprom_data()

static int get_eeprom_data ( int  off,
int  len,
unsigned short *  buffer 
)
static

Definition at line 139 of file cs89x0.c.

140 {
141  int i;
142 
143 #ifdef EDEBUG
144  printf("\ncs: EEPROM data from %hX for %hX:",off,len);
145 #endif
146  for (i = 0; i < len; i++) {
147  if (wait_eeprom_ready() < 0)
148  return -1;
149  /* Now send the EEPROM read command and EEPROM location
150  to read */
151  writereg(PP_EECMD, (off + i) | EEPROM_READ_CMD);
152  if (wait_eeprom_ready() < 0)
153  return -1;
154  buffer[i] = readreg(PP_EEData);
155 #ifdef EDEBUG
156  if (!(i%10))
157  printf("\ncs: ");
158  printf("%hX ", buffer[i]);
159 #endif
160  }
161 #ifdef EDEBUG
162  putchar('\n');
163 #endif
164 
165  return(0);
166 }
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
#define EEPROM_READ_CMD
Definition: cs89x0.h:352
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
#define PP_EECMD
Definition: cs89x0.h:56
static void writereg(int portno, int value)
Definition: cs89x0.c:115
static int wait_eeprom_ready(void)
Definition: cs89x0.c:126
static int readreg(int portno)
Definition: cs89x0.c:109
uint32_t len
Length.
Definition: ena.h:14
#define PP_EEData
Definition: cs89x0.h:57
int putchar(int character)
Write a single character to each console device.
Definition: console.c:28

References buffer, EEPROM_READ_CMD, len, PP_EECMD, PP_EEData, printf(), putchar(), readreg(), wait_eeprom_ready(), and writereg().

Referenced by cs89x0_probe().

◆ get_eeprom_chksum()

static int get_eeprom_chksum ( int off  __unused,
int  len,
unsigned short *  buffer 
)
static

Definition at line 168 of file cs89x0.c.

169 {
170  int i, cksum;
171 
172  cksum = 0;
173  for (i = 0; i < len; i++)
174  cksum += buffer[i];
175  cksum &= 0xffff;
176  if (cksum == 0)
177  return 0;
178  return -1;
179 }
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
uint32_t len
Length.
Definition: ena.h:14

References buffer, and len.

Referenced by cs89x0_probe().

◆ clrline()

static void clrline ( void  )
static

Definition at line 185 of file cs89x0.c.

186 {
187  int i;
188 
189  putchar('\r');
190  for (i = 79; i--; ) putchar(' ');
191  printf("\rcs: ");
192  return;
193 }
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
int putchar(int character)
Write a single character to each console device.
Definition: console.c:28

References printf(), and putchar().

Referenced by cs89x0_probe(), detect_aui(), detect_bnc(), and detect_tp().

◆ control_dc_dc()

static void control_dc_dc ( int  on_not_off)
static

Definition at line 195 of file cs89x0.c.

196 {
197  unsigned int selfcontrol;
198  unsigned long tmo = currticks() + TICKS_PER_SEC;
199 
200  /* control the DC to DC convertor in the SelfControl register. */
201  selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
202  if (((eth_adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
203  selfcontrol |= HCB1;
204  else
205  selfcontrol &= ~HCB1;
206  writereg(PP_SelfCTL, selfcontrol);
207 
208  /* Wait for the DC/DC converter to power up - 1000ms */
209  while (currticks() < tmo);
210 
211  return;
212 }
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
#define HCB1_ENBL
Definition: cs89x0.h:215
static unsigned short eth_adapter_cnf
Definition: cs89x0.c:102
static void writereg(int portno, int value)
Definition: cs89x0.c:115
#define A_CNF_DC_DC_POLARITY
Definition: cs89x0.h:404
#define PP_SelfCTL
Definition: cs89x0.h:66
#define HCB1
Definition: cs89x0.h:217
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42

References A_CNF_DC_DC_POLARITY, currticks(), eth_adapter_cnf, HCB1, HCB1_ENBL, PP_SelfCTL, TICKS_PER_SEC, and writereg().

Referenced by detect_aui(), detect_bnc(), and detect_tp().

◆ detect_tp()

static int detect_tp ( void  )
static

Definition at line 214 of file cs89x0.c.

215 {
216  unsigned long tmo;
217 
218  /* Turn on the chip auto detection of 10BT/ AUI */
219 
220  clrline(); printf("attempting %s:","TP");
221 
222  /* If connected to another full duplex capable 10-Base-T card
223  the link pulses seem to be lost when the auto detect bit in
224  the LineCTL is set. To overcome this the auto detect bit
225  will be cleared whilst testing the 10-Base-T interface.
226  This would not be necessary for the sparrow chip but is
227  simpler to do it anyway. */
229  control_dc_dc(0);
230 
231  /* Delay for the hardware to work out if the TP cable is
232  present - 150ms */
233  for (tmo = currticks() + 4; currticks() < tmo; );
234 
235  if ((readreg(PP_LineST) & LINK_OK) == 0)
236  return 0;
237 
238  if (eth_cs_type != CS8900) {
239 
241 
243  printf(" negotiating duplex... ");
244  while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
245  if (currticks() - tmo > 40*TICKS_PER_SEC) {
246  printf("time out ");
247  break;
248  }
249  }
250  }
252  printf("using full duplex");
253  else
254  printf("using half duplex");
255  }
256 
257  return A_CNF_MEDIA_10B_T;
258 }
#define AUTO_NEG_BUSY
Definition: cs89x0.h:298
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
static unsigned short eth_cs_type
Definition: cs89x0.c:100
static unsigned short eth_linectl
Definition: cs89x0.c:103
#define A_CNF_MEDIA_10B_T
Definition: cs89x0.h:401
#define PP_AutoNegCTL
Definition: cs89x0.h:69
#define FDX_ACTIVE
Definition: cs89x0.h:303
#define PP_LineCTL
Definition: cs89x0.h:65
#define PP_LineST
Definition: cs89x0.h:77
static void writereg(int portno, int value)
Definition: cs89x0.c:115
#define AUTO_NEG_MASK
Definition: cs89x0.h:295
static void clrline(void)
Definition: cs89x0.c:185
static int readreg(int portno)
Definition: cs89x0.c:109
#define CS8900
Definition: cs89x0.h:440
static unsigned short eth_auto_neg_cnf
Definition: cs89x0.c:101
#define LINK_OK
Definition: cs89x0.h:269
#define PP_AutoNegST
Definition: cs89x0.h:81
#define AUTO_NEG_ENABLE
Definition: cs89x0.h:291
#define AUTO_NEG_BITS
Definition: cs89x0.h:294
static void control_dc_dc(int on_not_off)
Definition: cs89x0.c:195
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define AUI_ONLY
Definition: cs89x0.h:202

References A_CNF_MEDIA_10B_T, AUI_ONLY, AUTO_NEG_BITS, AUTO_NEG_BUSY, AUTO_NEG_ENABLE, AUTO_NEG_MASK, clrline(), control_dc_dc(), CS8900, currticks(), eth_auto_neg_cnf, eth_cs_type, eth_linectl, FDX_ACTIVE, LINK_OK, PP_AutoNegCTL, PP_AutoNegST, PP_LineCTL, PP_LineST, printf(), readreg(), TICKS_PER_SEC, and writereg().

Referenced by cs89x0_probe().

◆ send_test_pkt()

static int send_test_pkt ( struct nic nic)
static

Definition at line 261 of file cs89x0.c.

262 {
263  static unsigned char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
264  0, 46, /*A 46 in network order */
265  0, 0, /*DSAP=0 & SSAP=0 fields */
266  0xf3,0 /*Control (Test Req+P bit set)*/ };
267  unsigned long tmo;
268 
270 
271  memcpy(testpacket, nic->node_addr, ETH_ALEN);
272  memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN);
273 
276 
277  /* Test to see if the chip has allocated memory for the packet */
278  for (tmo = currticks() + 2;
279  (readreg(PP_BusST) & READY_FOR_TX_NOW) == 0; )
280  if (currticks() >= tmo)
281  return(0);
282 
283  /* Write the contents of the packet */
284  outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
285  (ETH_ZLEN+1)>>1);
286 
287  printf(" sending test packet ");
288  /* wait a couple of timer ticks for packet to be received */
289  for (tmo = currticks() + 2; currticks() < tmo; );
290 
291  if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
292  printf("succeeded");
293  return 1;
294  }
295  printf("failed");
296  return 0;
297 }
#define SERIAL_TX_ON
Definition: cs89x0.h:201
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
#define TX_LEN_PORT
Definition: cs89x0.h:344
#define outw(data, io_addr)
Definition: io.h:319
void outsw(volatile uint16_t *io_addr, const uint16_t *data, unsigned int count)
Write 16-bit words to I/O-mapped device.
#define PP_LineCTL
Definition: cs89x0.h:65
static void writereg(int portno, int value)
Definition: cs89x0.c:115
#define TX_AFTER_ALL
Definition: cs89x0.h:343
#define TX_FRAME_PORT
Definition: cs89x0.h:339
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int readreg(int portno)
Definition: cs89x0.c:109
#define TX_SEND_OK_BITS
Definition: cs89x0.h:254
#define PP_BusST
Definition: cs89x0.h:79
#define READY_FOR_TX_NOW
Definition: cs89x0.h:286
#define ETH_ALEN
Definition: if_ether.h:8
#define ETH_ZLEN
Definition: if_ether.h:10
Definition: nic.h:49
#define TX_CMD_PORT
Definition: cs89x0.h:340
unsigned char * node_addr
Definition: nic.h:52
#define PP_TxEvent
Definition: cs89x0.h:73
static unsigned short eth_nic_base
Definition: cs89x0.c:97
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define TX_OK
Definition: cs89x0.h:250

References currticks(), ETH_ALEN, eth_nic_base, ETH_ZLEN, memcpy(), nic::node_addr, outsw(), outw, PP_BusST, PP_LineCTL, PP_TxEvent, printf(), readreg(), READY_FOR_TX_NOW, SERIAL_TX_ON, TX_AFTER_ALL, TX_CMD_PORT, TX_FRAME_PORT, TX_LEN_PORT, TX_OK, TX_SEND_OK_BITS, and writereg().

Referenced by detect_aui(), and detect_bnc().

◆ detect_aui()

static int detect_aui ( struct nic nic)
static

Definition at line 300 of file cs89x0.c.

301 {
302  clrline(); printf("attempting %s:","AUI");
303  control_dc_dc(0);
304 
306 
307  if (send_test_pkt(nic)) {
308  return A_CNF_MEDIA_AUI; }
309  else
310  return 0;
311 }
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
static unsigned short eth_linectl
Definition: cs89x0.c:103
#define PP_LineCTL
Definition: cs89x0.h:65
static void writereg(int portno, int value)
Definition: cs89x0.c:115
static void clrline(void)
Definition: cs89x0.c:185
#define A_CNF_MEDIA_AUI
Definition: cs89x0.h:402
Definition: nic.h:49
#define AUTO_AUI_10BASET
Definition: cs89x0.h:203
static void control_dc_dc(int on_not_off)
Definition: cs89x0.c:195
static int send_test_pkt(struct nic *nic)
Definition: cs89x0.c:261
#define AUI_ONLY
Definition: cs89x0.h:202

References A_CNF_MEDIA_AUI, AUI_ONLY, AUTO_AUI_10BASET, clrline(), control_dc_dc(), eth_linectl, PP_LineCTL, printf(), send_test_pkt(), and writereg().

Referenced by cs89x0_probe().

◆ detect_bnc()

static int detect_bnc ( struct nic nic)
static

Definition at line 313 of file cs89x0.c.

314 {
315  clrline(); printf("attempting %s:","BNC");
316  control_dc_dc(1);
317 
319 
320  if (send_test_pkt(nic)) {
321  return A_CNF_MEDIA_10B_2; }
322  else
323  return 0;
324 }
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
static unsigned short eth_linectl
Definition: cs89x0.c:103
#define PP_LineCTL
Definition: cs89x0.h:65
static void writereg(int portno, int value)
Definition: cs89x0.c:115
static void clrline(void)
Definition: cs89x0.c:185
Definition: nic.h:49
#define AUTO_AUI_10BASET
Definition: cs89x0.h:203
static void control_dc_dc(int on_not_off)
Definition: cs89x0.c:195
static int send_test_pkt(struct nic *nic)
Definition: cs89x0.c:261
#define A_CNF_MEDIA_10B_2
Definition: cs89x0.h:403
#define AUI_ONLY
Definition: cs89x0.h:202

References A_CNF_MEDIA_10B_2, AUI_ONLY, AUTO_AUI_10BASET, clrline(), control_dc_dc(), eth_linectl, PP_LineCTL, printf(), send_test_pkt(), and writereg().

Referenced by cs89x0_probe().

◆ cs89x0_reset()

static void cs89x0_reset ( struct nic nic)
static

Definition at line 330 of file cs89x0.c.

331 {
332  int i;
333  unsigned long reset_tmo;
334 
336 
337  /* wait for two ticks; that is 2*55ms */
338  for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );
339 
340  if (eth_cs_type != CS8900) {
341  /* Hardware problem requires PNP registers to be reconfigured
342  after a reset */
343  if (eth_irqno != 0xFFFF) {
346  outb(0, eth_nic_base + DATA_PORT + 1); }
347 
348  if (eth_mem_start) {
350  outb((eth_mem_start >> 8) & 0xff, eth_nic_base + DATA_PORT);
351  outb((eth_mem_start >> 24) & 0xff, eth_nic_base + DATA_PORT + 1); } }
352 
353  /* Wait until the chip is reset */
354  for (reset_tmo = currticks() + 2;
355  (readreg(PP_SelfST) & INIT_DONE) == 0 &&
356  currticks() < reset_tmo; );
357 
358  /* disable interrupts and memory accesses */
359  writereg(PP_BusCTL, 0);
360 
361  /* set the ethernet address */
362  for (i=0; i < ETH_ALEN/2; i++)
363  writereg(PP_IA+i*2,
364  nic->node_addr[i*2] |
365  (nic->node_addr[i*2+1] << 8));
366 
367  /* receive only error free packets addressed to this card */
369 
370  /* do not generate any interrupts on receive operations */
371  writereg(PP_RxCFG, 0);
372 
373  /* do not generate any interrupts on transmit operations */
374  writereg(PP_TxCFG, 0);
375 
376  /* do not generate any interrupts on buffer operations */
377  writereg(PP_BufCFG, 0);
378 
379  /* reset address port, so that autoprobing will keep working */
381 
382  return;
383 }
#define DEF_RX_ACCEPT
Definition: cs89x0.h:166
#define PP_RxCTL
Definition: cs89x0.h:61
#define PP_BufCFG
Definition: cs89x0.h:64
#define outw(data, io_addr)
Definition: io.h:319
static unsigned short eth_cs_type
Definition: cs89x0.c:100
#define PP_IA
Definition: cs89x0.h:85
static void writereg(int portno, int value)
Definition: cs89x0.c:115
#define PP_CS8920_ISAINT
Definition: cs89x0.h:43
#define PP_SelfST
Definition: cs89x0.h:78
#define DATA_PORT
Definition: cs89x0.h:347
static int readreg(int portno)
Definition: cs89x0.c:109
#define CS8900
Definition: cs89x0.h:440
#define INIT_DONE
Definition: cs89x0.h:277
static unsigned short eth_irqno
Definition: cs89x0.c:99
#define PP_CS8920_ISAMemB
Definition: cs89x0.h:50
#define ETH_ALEN
Definition: if_ether.h:8
Definition: nic.h:49
#define PP_SelfCTL
Definition: cs89x0.h:66
unsigned char * node_addr
Definition: nic.h:52
#define outb(data, io_addr)
Definition: io.h:309
#define ADD_PORT
Definition: cs89x0.h:346
#define PP_RxCFG
Definition: cs89x0.h:60
#define PP_TxCFG
Definition: cs89x0.h:62
static unsigned short eth_nic_base
Definition: cs89x0.c:97
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define POWER_ON_RESET
Definition: cs89x0.h:210
#define PP_ChipID
Definition: cs89x0.h:37
#define PP_BusCTL
Definition: cs89x0.h:67
static unsigned long eth_mem_start
Definition: cs89x0.c:98

References ADD_PORT, CS8900, currticks(), DATA_PORT, DEF_RX_ACCEPT, ETH_ALEN, eth_cs_type, eth_irqno, eth_mem_start, eth_nic_base, INIT_DONE, nic::node_addr, outb, outw, POWER_ON_RESET, PP_BufCFG, PP_BusCTL, PP_ChipID, PP_CS8920_ISAINT, PP_CS8920_ISAMemB, PP_IA, PP_RxCFG, PP_RxCTL, PP_SelfCTL, PP_SelfST, PP_TxCFG, readreg(), and writereg().

Referenced by cs89x0_disable(), cs89x0_probe(), and cs89x0_transmit().

◆ cs89x0_transmit()

static void cs89x0_transmit ( struct nic nic,
const char *  d,
unsigned int  t,
unsigned int  s,
const char *  p 
)
static

Definition at line 389 of file cs89x0.c.

395 {
396  unsigned long tmo;
397  int sr;
398 
399  /* does this size have to be rounded??? please,
400  somebody have a look in the specs */
401  if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)
402  sr = ETH_ZLEN;
403 
404 retry:
405  /* initiate a transmit sequence */
408 
409  /* Test to see if the chip has allocated memory for the packet */
410  if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {
411  /* Oops... this should not happen! */
412  printf("cs: unable to send packet; retrying...\n");
413  for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
414  cs89x0_reset(nic);
415  goto retry; }
416 
417  /* Write the contents of the packet */
420  ETH_ALEN/2);
421  outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);
422  outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
423  for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr > 0; sr--)
425 
426  /* wait for transfer to succeed */
427  for (tmo = currticks()+5*TICKS_PER_SEC;
428  (s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
429  /* nothing */ ;
430  if ((s & TX_SEND_OK_BITS) != TX_OK) {
431  printf("\ntransmission error %#hX\n", s);
432  }
433 
434  return;
435 }
#define TICKS_PER_SEC
Number of ticks per second.
Definition: timer.h:15
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
#define TX_LEN_PORT
Definition: cs89x0.h:344
#define outw(data, io_addr)
Definition: io.h:319
void outsw(volatile uint16_t *io_addr, const uint16_t *data, unsigned int count)
Write 16-bit words to I/O-mapped device.
#define TX_AFTER_ALL
Definition: cs89x0.h:343
#define TX_FRAME_PORT
Definition: cs89x0.h:339
#define ETH_HLEN
Definition: if_ether.h:9
static int readreg(int portno)
Definition: cs89x0.c:109
#define TX_SEND_OK_BITS
Definition: cs89x0.h:254
#define PP_BusST
Definition: cs89x0.h:79
#define READY_FOR_TX_NOW
Definition: cs89x0.h:286
#define ETH_ALEN
Definition: if_ether.h:8
#define ETH_ZLEN
Definition: if_ether.h:10
Definition: nic.h:49
#define TX_CMD_PORT
Definition: cs89x0.h:340
static void cs89x0_reset(struct nic *nic)
Definition: cs89x0.c:330
unsigned char * node_addr
Definition: nic.h:52
uint32_t d
Definition: md4.c:31
#define PP_TxEvent
Definition: cs89x0.h:73
static unsigned short eth_nic_base
Definition: cs89x0.c:97
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define TX_OK
Definition: cs89x0.h:250

References cs89x0_reset(), currticks(), d, ETH_ALEN, ETH_HLEN, eth_nic_base, ETH_ZLEN, nic::node_addr, outsw(), outw, PP_BusST, PP_TxEvent, printf(), readreg(), READY_FOR_TX_NOW, TICKS_PER_SEC, TX_AFTER_ALL, TX_CMD_PORT, TX_FRAME_PORT, TX_LEN_PORT, TX_OK, and TX_SEND_OK_BITS.

◆ cs89x0_poll()

static int cs89x0_poll ( struct nic nic,
int  retrieve 
)
static

Definition at line 441 of file cs89x0.c.

442 {
443  int status;
444 
446 
447  if ((status & RX_OK) == 0)
448  return(0);
449 
450  if ( ! retrieve ) return 1;
451 
455  if (nic->packetlen & 1)
457  return 1;
458 }
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
uint8_t status
Status.
Definition: ena.h:16
static int readreg(int portno)
Definition: cs89x0.c:109
unsigned int packetlen
Definition: nic.h:54
void insw(volatile uint16_t *io_addr, uint16_t *data, unsigned int count)
Read 16-bit words from I/O-mapped device.
Definition: nic.h:49
unsigned char * packet
Definition: nic.h:53
#define RX_OK
Definition: cs89x0.h:237
static unsigned short eth_nic_base
Definition: cs89x0.c:97
#define PP_RxEvent
Definition: cs89x0.h:72
#define RX_FRAME_PORT
Definition: cs89x0.h:338

References eth_nic_base, insw(), inw(), nic::packet, nic::packetlen, PP_RxEvent, readreg(), RX_FRAME_PORT, RX_OK, and status.

◆ cs89x0_irq()

static void cs89x0_irq ( struct nic *nic  __unused,
irq_action_t action  __unused 
)
static

Definition at line 460 of file cs89x0.c.

461 {
462  switch ( action ) {
463  case DISABLE :
464  break;
465  case ENABLE :
466  break;
467  case FORCE :
468  break;
469  }
470 }
Definition: nic.h:35
Definition: nic.h:37
Definition: nic.h:36

References DISABLE, ENABLE, and FORCE.

◆ cs89x0_probe_addr()

static int cs89x0_probe_addr ( isa_probe_addr_t  ioaddr)
static

Definition at line 483 of file cs89x0.c.

483  {
484  /* if they give us an odd I/O address, then do ONE write to
485  the address port, to get it back to address zero, where we
486  expect to find the EISA signature word. */
487  if (ioaddr & 1) {
488  ioaddr &= ~1;
489  if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
490  return 0;
492  }
493 
495  return 0;
496 
497  return 1;
498 }
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
#define CHIP_EISA_ID_SIG
Definition: cs89x0.h:100
#define outw(data, io_addr)
Definition: io.h:319
static unsigned long ioaddr
Definition: davicom.c:129
#define DATA_PORT
Definition: cs89x0.h:347
#define ADD_SIG
Definition: cs89x0.h:98
#define ADD_PORT
Definition: cs89x0.h:346
#define ADD_MASK
Definition: cs89x0.h:97
#define PP_ChipID
Definition: cs89x0.h:37

References ADD_MASK, ADD_PORT, ADD_SIG, CHIP_EISA_ID_SIG, DATA_PORT, inw(), ioaddr, outw, and PP_ChipID.

◆ cs89x0_probe()

static int cs89x0_probe ( struct nic nic,
struct isa_device *isa  __unused 
)
static

Definition at line 500 of file cs89x0.c.

500  {
501  int i, result = -1;
502  unsigned rev_type = 0, isa_cnf, cs_revision;
503  unsigned short eeprom_buff[CHKSUM_LEN];
504 
505  nic->ioaddr &= ~1; /* LSB = 1 indicates a more aggressive probe */
507 
508  /* get the chip type */
509  rev_type = readreg(PRODUCT_ID_ADD);
510  eth_cs_type = rev_type &~ REVISON_BITS;
511  cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
512 
513  printf("\ncs: cs89%c0%s rev %c, base %#hX",
514  eth_cs_type==CS8900?'0':'2',
515  eth_cs_type==CS8920M?"M":"",
516  cs_revision,
517  eth_nic_base);
518 #ifndef EMBEDDED
519  /* First check to see if an EEPROM is attached*/
520  if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
521  printf("\ncs: no EEPROM...\n");
523  return 0;
525  eeprom_buff) < 0) {
526  printf("\ncs: EEPROM read failed...\n");
528  return 0;
530  eeprom_buff) < 0) {
531  printf("\ncs: EEPROM checksum bad...\n");
533  return 0;
534  }
535 
536  /* get transmission control word but keep the
537  autonegotiation bits */
538  eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
539  /* Store adapter configuration */
540  eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
541  /* Store ISA configuration */
542  isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];
543 
544  /* store the initial memory base address */
545  eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
546 
547  printf("%s%s%s, addr ",
548  (eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",
549  (eth_adapter_cnf & A_CNF_AUI)?", AUI":"",
550  (eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");
551 
552  /* If this is a CS8900 then no pnp soft */
553  if (eth_cs_type != CS8900 &&
554  /* Check if the ISA IRQ has been set */
555  (i = readreg(PP_CS8920_ISAINT) & 0xff,
556  (i != 0 && i < CS8920_NO_INTS)))
557  eth_irqno = i;
558  else {
559  i = isa_cnf & INT_NO_MASK;
560  if (eth_cs_type == CS8900) {
561  /* the table that follows is dependent
562  upon how you wired up your cs8900
563  in your system. The table is the
564  same as the cs8900 engineering demo
565  board. irq_map also depends on the
566  contents of the table. Also see
567  write_irq, which is the reverse
568  mapping of the table below. */
569  if (i < 4) i = "\012\013\014\005"[i];
570  else printf("\ncs: BUG: isa_config is %d\n", i); }
571  eth_irqno = i; }
572 
573  nic->irqno = eth_irqno;
574 
575  /* Retrieve and print the ethernet address. */
576  for (i=0; i<ETH_ALEN; i++) {
577  nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];
578  }
579 
580  DBG ( "%s\n", eth_ntoa ( nic->node_addr ) );
581 
582 #endif
583 #ifdef EMBEDDED
584  /* Retrieve and print the ethernet address. */
585  {
586  unsigned char MAC_HW_ADDR[6]={MAC_HW_ADDR_DRV};
587  memcpy(nic->node_addr, MAC_HW_ADDR, 6);
588  }
589 
590  DBG ( "%s\n", eth_ntoa ( nic->node_addr ) );
591 
594 #endif
595 #ifndef EMBEDDED
596  /* Set the LineCTL quintuplet based on adapter
597  configuration read from EEPROM */
601  else
602  eth_linectl = 0;
603 
604  /* check to make sure that they have the "right"
605  hardware available */
608  break;
610  break;
612  break;
613  default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |
614  A_CNF_10B_2);
615  }
616  if (!result) {
617  printf("cs: EEPROM is configured for unavailable media\n");
618  error:
622  return 0;
623  }
624 #endif
625  /* Initialize the card for probing of the attached media */
626  cs89x0_reset(nic);
627 
628  /* set the hardware to the configured choice */
630  case A_CNF_MEDIA_10B_T:
631  result = detect_tp();
632  if (!result) {
633  clrline();
634  printf("10Base-T (RJ-45%s",
635  ") has no cable\n"); }
636  /* check "ignore missing media" bit */
638  /* Yes! I don't care if I see a link pulse */
640  break;
641  case A_CNF_MEDIA_AUI:
642  result = detect_aui(nic);
643  if (!result) {
644  clrline();
645  printf("10Base-5 (AUI%s",
646  ") has no cable\n"); }
647  /* check "ignore missing media" bit */
649  /* Yes! I don't care if I see a carrrier */
651  break;
652  case A_CNF_MEDIA_10B_2:
653  result = detect_bnc(nic);
654  if (!result) {
655  clrline();
656  printf("10Base-2 (BNC%s",
657  ") has no cable\n"); }
658  /* check "ignore missing media" bit */
660  /* Yes! I don't care if I can xmit a packet */
662  break;
663  case A_CNF_MEDIA_AUTO:
666  if ((result = detect_tp()) != 0)
667  break;
669  if ((result = detect_aui(nic)) != 0)
670  break;
672  if ((result = detect_bnc(nic)) != 0)
673  break;
674  clrline(); printf("no media detected\n");
675  goto error;
676  }
677  clrline();
678  switch(result) {
679  case 0: printf("no network cable attached to configured media\n");
680  goto error;
681  case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
682  break;
683  case A_CNF_MEDIA_AUI: printf("using 10Base-5 (AUI)\n");
684  break;
685  case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
686  break;
687  }
688 
689  /* Turn on both receive and transmit operations */
691  SERIAL_TX_ON);
692 
693  return 0;
694 #ifdef EMBEDDED
695  error:
699  return 0;
700 #endif
701 
703  return 1;
704 }
unsigned char irqno
Definition: nic.h:56
#define SERIAL_TX_ON
Definition: cs89x0.h:201
#define PRODUCT_ID_ADD
Definition: cs89x0.h:112
#define AUTO_NEG_CNF_OFFSET
Definition: cs89x0.h:381
#define A_CNF_LOW_RX_SQUELCH
Definition: cs89x0.h:406
static const void const void void * result
Definition: crypto.h:335
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
static int detect_tp(void)
Definition: cs89x0.c:214
#define START_EEPROM_DATA
Definition: cs89x0.h:447
#define SERIAL_RX_ON
Definition: cs89x0.h:200
#define CHKSUM_LEN
Definition: cs89x0.h:445
#define outw(data, io_addr)
Definition: io.h:319
static unsigned short eth_cs_type
Definition: cs89x0.c:100
static unsigned short eth_linectl
Definition: cs89x0.c:103
#define A_CNF_MEDIA_10B_T
Definition: cs89x0.h:401
struct arbelprm_completion_with_error error
Definition: arbel.h:12
static unsigned short eth_adapter_cnf
Definition: cs89x0.c:102
#define A_CNF_10B_2
Definition: cs89x0.h:398
#define PP_LineCTL
Definition: cs89x0.h:65
#define CS8920M
Definition: cs89x0.h:442
#define LOW_RX_SQUELCH
Definition: cs89x0.h:207
static void writereg(int portno, int value)
Definition: cs89x0.c:115
#define PP_CS8920_ISAINT
Definition: cs89x0.h:43
#define PP_SelfST
Definition: cs89x0.h:78
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned int ioaddr
Definition: nic.h:55
static void clrline(void)
Definition: cs89x0.c:185
#define ISA_CNF_OFFSET
Definition: cs89x0.h:379
static int readreg(int portno)
Definition: cs89x0.c:109
#define CS8900
Definition: cs89x0.h:440
static unsigned short eth_auto_neg_cnf
Definition: cs89x0.c:101
static unsigned short eth_irqno
Definition: cs89x0.c:99
#define PACKET_PAGE_OFFSET
Definition: cs89x0.h:409
static struct nic_operations cs89x0_operations
Definition: cs89x0.c:472
#define A_CNF_MEDIA_AUI
Definition: cs89x0.h:402
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
#define A_CNF_MEDIA_TYPE
Definition: cs89x0.h:399
#define ETH_ALEN
Definition: if_ether.h:8
#define ADAPTER_CNF_OFFSET
Definition: cs89x0.h:395
Definition: nic.h:49
#define AUTO_AUI_10BASET
Definition: cs89x0.h:203
#define EEPROM_PRESENT
Definition: cs89x0.h:279
#define CS8920_NO_INTS
Definition: cs89x0.h:453
#define IMM_BIT
Definition: cs89x0.h:393
static void cs89x0_reset(struct nic *nic)
Definition: cs89x0.c:330
unsigned char * node_addr
Definition: nic.h:52
#define A_CNF_AUI
Definition: cs89x0.h:397
#define EE_AUTO_NEG_ENABLE
Definition: cs89x0.h:389
#define INT_NO_MASK
Definition: cs89x0.h:412
static int get_eeprom_data(int off, int len, unsigned short *buffer)
Definition: cs89x0.c:139
#define ADD_PORT
Definition: cs89x0.h:346
#define A_CNF_10B_T
Definition: cs89x0.h:396
#define A_CNF_MEDIA_10B_2
Definition: cs89x0.h:403
static unsigned short eth_nic_base
Definition: cs89x0.c:97
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
struct nic_operations * nic_op
Definition: nic.h:50
#define PP_ChipID
Definition: cs89x0.h:37
#define A_CNF_EXTND_10B_2
Definition: cs89x0.h:407
static int detect_aui(struct nic *nic)
Definition: cs89x0.c:300
#define A_CNF_MEDIA_AUTO
Definition: cs89x0.h:400
static unsigned long eth_mem_start
Definition: cs89x0.c:98
static int get_eeprom_chksum(int off __unused, int len, unsigned short *buffer)
Definition: cs89x0.c:168
#define REVISON_BITS
Definition: cs89x0.h:443
static int detect_bnc(struct nic *nic)
Definition: cs89x0.c:313

References A_CNF_10B_2, A_CNF_10B_T, A_CNF_AUI, A_CNF_EXTND_10B_2, A_CNF_LOW_RX_SQUELCH, A_CNF_MEDIA_10B_2, A_CNF_MEDIA_10B_T, A_CNF_MEDIA_AUI, A_CNF_MEDIA_AUTO, A_CNF_MEDIA_TYPE, ADAPTER_CNF_OFFSET, ADD_PORT, AUTO_AUI_10BASET, AUTO_NEG_CNF_OFFSET, CHKSUM_LEN, clrline(), CS8900, CS8920_NO_INTS, CS8920M, cs89x0_operations, cs89x0_reset(), DBG, detect_aui(), detect_bnc(), detect_tp(), EE_AUTO_NEG_ENABLE, EEPROM_PRESENT, error, eth_adapter_cnf, ETH_ALEN, eth_auto_neg_cnf, eth_cs_type, eth_irqno, eth_linectl, eth_mem_start, eth_nic_base, eth_ntoa(), get_eeprom_chksum(), get_eeprom_data(), IMM_BIT, INT_NO_MASK, nic::ioaddr, nic::irqno, ISA_CNF_OFFSET, LOW_RX_SQUELCH, memcpy(), nic::nic_op, nic::node_addr, outw, PACKET_PAGE_OFFSET, PP_ChipID, PP_CS8920_ISAINT, PP_LineCTL, PP_SelfST, printf(), PRODUCT_ID_ADD, readreg(), result, REVISON_BITS, SERIAL_RX_ON, SERIAL_TX_ON, START_EEPROM_DATA, and writereg().

◆ cs89x0_disable()

static void cs89x0_disable ( struct nic nic,
struct isa_device *isa  __unused 
)
static

Definition at line 706 of file cs89x0.c.

707  {
708  cs89x0_reset(nic);
709 }
Definition: nic.h:49
static void cs89x0_reset(struct nic *nic)
Definition: cs89x0.c:330

References cs89x0_reset().

◆ ISA_DRIVER()

ISA_DRIVER ( cs89x0_driver  ,
cs89x0_probe_addrs  ,
cs89x0_probe_addr  ,
ISAPNP_VENDOR( 'C', 'S', 'C')  ,
0x0007   
)

◆ DRIVER()

DRIVER ( "cs89x0"  ,
nic_driver  ,
isa_driver  ,
cs89x0_driver  ,
cs89x0_probe  ,
cs89x0_disable   
)

◆ ISA_ROM()

ISA_ROM ( "cs89x0"  ,
"Crystal Semiconductor CS89x0"   
)

Variable Documentation

◆ eth_nic_base

unsigned short eth_nic_base
static

◆ eth_mem_start

unsigned long eth_mem_start
static

Definition at line 98 of file cs89x0.c.

Referenced by cs89x0_probe(), and cs89x0_reset().

◆ eth_irqno

unsigned short eth_irqno
static

Definition at line 99 of file cs89x0.c.

Referenced by cs89x0_probe(), and cs89x0_reset().

◆ eth_cs_type

unsigned short eth_cs_type
static

Definition at line 100 of file cs89x0.c.

Referenced by cs89x0_probe(), cs89x0_reset(), and detect_tp().

◆ eth_auto_neg_cnf

unsigned short eth_auto_neg_cnf
static

Definition at line 101 of file cs89x0.c.

Referenced by cs89x0_probe(), and detect_tp().

◆ eth_adapter_cnf

unsigned short eth_adapter_cnf
static

Definition at line 102 of file cs89x0.c.

Referenced by control_dc_dc(), and cs89x0_probe().

◆ eth_linectl

unsigned short eth_linectl
static

Definition at line 103 of file cs89x0.c.

Referenced by cs89x0_probe(), detect_aui(), detect_bnc(), and detect_tp().

◆ cs89x0_operations

struct nic_operations cs89x0_operations
static
Initial value:
= {
.connect = dummy_connect,
.poll = cs89x0_poll,
.transmit = cs89x0_transmit,
.irq = cs89x0_irq,
}
static int cs89x0_poll(struct nic *nic, int retrieve)
Definition: cs89x0.c:441
int dummy_connect(struct nic *nic __unused)
Definition: legacy.c:151
static void cs89x0_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
Definition: cs89x0.c:389
static void cs89x0_irq(struct nic *nic __unused, irq_action_t action __unused)
Definition: cs89x0.c:460

Definition at line 472 of file cs89x0.c.

Referenced by cs89x0_probe().

◆ cs89x0_probe_addrs

isa_probe_addr_t cs89x0_probe_addrs[]
static
Initial value:
= {
0x300, 0x320, 0x340, 0x200, 0x220, 0x240,
0x260, 0x280, 0x2a0, 0x2c0, 0x2e0,
0x301, 0x321, 0x341, 0x201, 0x221, 0x241,
0x261, 0x281, 0x2a1, 0x2c1, 0x2e1,
}

Definition at line 711 of file cs89x0.c.