source: rtems/c/src/libchip/network/cs8900.c @ 03e9564

4.104.114.84.95
Last change on this file since 03e9564 was 03e9564, checked in by Joel Sherrill <joel.sherrill@…>, on 01/04/02 at 18:17:23

2002-01-03 Ralf Corsepius <corsepiu@…>

  • network/cs8900.c: Include rtems/bspIo.h instead of bspIo.h.
  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2  ------------------------------------------------------------------------
3  $Id$
4  ------------------------------------------------------------------------
5 
6  My Right Boot, a boot ROM for embedded hardware.
7 
8  Copyright Cybertec Pty Ltd, 2000
9  All rights reserved Cybertec Pty Ltd, 2000
10 
11  COPYRIGHT (c) 1989-1998.
12  On-Line Applications Research Corporation (OAR).
13
14  The license and distribution terms for this file may be
15  found in the file LICENSE in this distribution or at
16  http://www.OARcorp.com/rtems/license.html.
17 
18  ------------------------------------------------------------------------
19
20  CS8900 net boot driver.
21
22 */
23
24#include <rtems/bspIo.h>
25#include <rtems.h>
26
27#include <libchip/cs8900.h>
28
29/*
30 * Our local data.
31 */
32
33#ifdef CS8900_VERBOSE
34static BOOLEAN cs8900_io_verbose;
35#endif
36
37static rtems_isr_void_entry old_handler[CS8900_DEVICES];
38static void                 *old_parameter[CS8900_DEVICES];
39
40/*
41 * Tables of IO addresses and interrupt levels for each device attached.
42 */
43
44static const unsigned long ethernet_io_base[CS8900_DEVICES] =
45{
46  ETHERNET_BASE
47};
48
49static const unsigned long ethernet_mem_base[CS8900_DEVICES] =
50{
51  ETHERNET_BASE + CS8900_MEMORY_BASE
52};
53
54static const unsigned int ethernet_irq_level[CS8900_DEVICES] =
55{
56  ETHERNET_IRQ_LEVEL
57};
58
59static const unsigned int ethernet_irq_priority[CS8900_DEVICES] =
60{
61  ETHERNET_IRQ_PRIORITY
62};
63
64static const unsigned int ethernet_irq_vector[CS8900_DEVICES] =
65{
66  ETHERNET_IRQ_VECTOR,
67};
68
69void cs8900_io_set_reg (int dev, unsigned short reg, unsigned short data)
70{
71#ifdef CS8900_DATA_BUS_SWAPPED
72  data = (data >> 8) | (data << 8);
73#endif
74
75#ifdef CS8900_VERBOSE
76  if (cs8900_io_verbose)
77    printf ("CS8900: io set reg=0x%04x, data=0x%04x\n", reg, data);
78#endif
79   
80  WRITE_REGISTER_16 (ethernet_io_base[dev] + reg, data);
81}
82
83unsigned short cs8900_io_get_reg (int dev, unsigned short reg)
84{
85  unsigned long data;
86
87  READ_REGISTER_16 (ethernet_io_base[dev] + reg, data);
88
89#ifdef CS8900_DATA_BUS_SWAPPED
90  data = (data >> 8) | (data << 8);
91#endif
92 
93#ifdef CS8900_VERBOSE
94  if (cs8900_io_verbose)
95    printk ("CS8900: io get reg=0x%04x, data=0x%04x\n", reg, data);
96#endif
97 
98  return data;
99}
100
101void cs8900_mem_set_reg (int dev, unsigned long reg, unsigned short data)
102{
103#ifdef CS8900_DATA_BUS_SWAPPED
104  data = (data >> 8) | (data << 8);
105#endif
106
107#ifdef CS8900_VERBOSE
108  if (cs8900_io_verbose)
109    printk ("CS8900: mem set reg=0x%04x, data=0x%04x\n", reg, data);
110#endif
111
112  WRITE_REGISTER_16 (ethernet_io_base[dev] + reg, data);
113}
114
115unsigned short cs8900_mem_get_reg (int dev, unsigned long reg)
116{
117  unsigned short data;
118  READ_REGISTER_16 (ethernet_io_base[dev] + reg, data);
119 
120#ifdef CS8900_DATA_BUS_SWAPPED
121  data = (data >> 8) | (data << 8);
122#endif
123
124#ifdef CS8900_VERBOSE
125  if (cs8900_io_verbose)
126    printk ("CS8900: mem get reg=0x%04x, data=0x%04x\n", reg, data);
127#endif
128
129  return data;
130}
131
132void cs8900_put_data_block (int dev, int len, unsigned char *data)
133{
134#ifndef CS8900_DATA_BUS_SWAPPED
135  unsigned short swap_word;
136#endif
137  unsigned short *src = (unsigned short *) ((unsigned long) data);
138  unsigned short *dst = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_TxFrameLoc);
139
140  while (len > 1)
141  {
142#ifndef CS8900_DATA_BUS_SWAPPED
143    swap_word = *src++;
144    *dst++ = (swap_word >> 8) | (swap_word << 8);
145#else
146    *dst++ = *src++;
147#endif
148    len -= 2;
149  }
150
151  if (len)
152  {
153#ifndef CS8900_DATA_BUS_SWAPPED
154    swap_word = *src++;
155    *dst++ = (swap_word >> 8) | (swap_word << 8);
156#else
157    *dst++ = *src++;
158#endif
159  } 
160}
161
162unsigned short cs8900_get_data_block (int dev, unsigned char *data)
163{
164  unsigned short          swap_word;
165  volatile unsigned short *src = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_RxLength);
166  unsigned short          *dst;
167  unsigned short          len;
168  unsigned short          rx_len;
169  unsigned short          len_odd;
170 
171#ifdef CS8900_DATA_BUS_SWAPPED
172    swap_word = *src++;
173    len = (swap_word >> 8) | (swap_word << 8);
174#else
175    len = *src++;
176#endif
177   
178  dst = (unsigned short *) ((unsigned long) data);
179
180  len_odd = len & 1;
181  rx_len  = len & ~1;
182 
183  for (; rx_len; rx_len -= 2)
184  {
185#ifndef CS8900_DATA_BUS_SWAPPED
186    swap_word = *src++;
187    *dst++ = (swap_word >> 8) | (swap_word << 8);
188#else
189    *dst++ = *src++;
190#endif
191  }
192
193  if (len_odd)
194  {
195#ifndef CS8900_DATA_BUS_SWAPPED
196    swap_word = *src++;
197    *dst++ = (swap_word >> 8) | (swap_word << 8);
198#else
199    *dst++ = *src++;
200#endif
201  }
202
203  return len;
204}
205
206void
207cs8900_tx_load (int dev, struct mbuf *m)
208{
209  volatile unsigned short *dst = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_TxFrameLoc);
210  unsigned int            len;
211  unsigned char           *src;
212  int                     remainder = 0;
213  unsigned char           remainder_data = '\0';
214 
215  while (m)
216  {
217    /*
218     * We can get empty mbufs from the stack.
219     */
220
221    len = m->m_len;
222    src = mtod (m, unsigned char*);
223
224    if (len)
225    {
226      if (remainder)
227      {
228#ifndef CS8900_DATA_BUS_SWAPPED
229        *dst++ = remainder_data | (*src++ << 8);
230#else
231        *dst++ = *src++ | (remainder_data << 8);
232#endif
233        len--;
234        remainder = 0;
235      }
236
237      if (len & 1)
238      {
239        remainder = 1;
240        len--;
241      }
242   
243      for (; len; len -= 2)
244#ifndef CS8900_DATA_BUS_SWAPPED
245        *dst++ = (*src++) | (*(++src) << 8);
246#else
247      *dst++ = (*src++ << 8) | *(++src);
248#endif
249   
250      if (remainder)
251        remainder_data = *src++;
252    }
253   
254    m = m->m_next;
255  }
256
257  if (remainder)
258  {
259#ifndef CS8900_DATA_BUS_SWAPPED
260    *dst = (unsigned short) remainder_data;
261#else
262    *dst = (unsigned short) (remainder_data << 8);
263#endif
264  }
265}
266
267void cs8900_attach_interrupt (int dev, cs8900_device *cs)
268{
269  rtems_interrupt_catch_with_void (cs8900_interrupt,
270                                   ethernet_irq_vector[dev],
271                                   &old_handler[dev],
272                                   cs,
273                                   &old_parameter[dev]);
274 
275  CF_SIM_WRITE_ICR (CF_BASE,
276                    ethernet_irq_level[dev],
277                    CF_SIM_ICR_AVEC_AUTO,
278                    ethernet_irq_level[dev],
279                    ethernet_irq_priority[dev]);
280  CF_SIM_IMR_ENABLE (CF_BASE, 1 << ethernet_irq_level[dev]);
281}
282
283void cs8900_detach_interrupt (int dev)
284{
285  CF_SIM_IMR_DISABLE (CF_BASE, 1 << ethernet_irq_level[dev]);
286 
287  rtems_interrupt_catch_with_void (old_handler,
288                                   ethernet_irq_vector[dev],
289                                   NULL,
290                                   old_parameter[dev],
291                                   NULL);
292}
293
294void cs8900_get_mac_addr (int dev, unsigned char *mac_address)
295{
296  memcpy (mac_address, rct_get_mac_address (dev), 6);
297}
Note: See TracBrowser for help on using the repository browser.