OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [orpmon/] [drivers/] [eth.c] - Blame information for rev 1017

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 809 simons
#include "common.h"
2
#include "support.h"
3
#include "board.h"
4
#include "uart.h"
5
#include "eth.h"
6 855 markom
#include "int.h"
7 809 simons
#include "spr_defs.h"
8
 
9
extern int printf (const char *fmt, ...);
10
extern void lolev_ie(void);
11
extern void lolev_idis(void);
12
 
13
int tx_next;  /* Next buffer to be given to the user */
14
int tx_last;  /* Next buffer to be checked if packet sent */
15
int tx_full;
16
int rx_next;  /* Next buffer to be checked for new packet and given to the user */
17 828 markom
void (*receive)(volatile unsigned char *add, int len); /* Pointer to function to be called
18 809 simons
                                        when frame is received */
19
 
20 834 simons
unsigned long eth_data[((ETH_TXBD_NUM + ETH_RXBD_NUM) * ETH_MAXBUF_LEN)/4] = {0};
21
#undef ETH_DATA_BASE
22
#define ETH_DATA_BASE ((unsigned long)eth_data)
23
 
24 833 simons
static void
25
print_packet(unsigned long add, int len)
26
{
27
  int i;
28
 
29 855 markom
  printf("ipacket: add = %lx len = %d\n", add, len);
30 833 simons
  for(i = 0; i < len; i++) {
31
      if(!(i % 16))
32
          printf("\n");
33
      printf(" %.2x", *(((unsigned char *)add) + i));
34
  }
35
  printf("\n");
36
}
37
 
38 809 simons
void init_tx_bd_pool(void)
39
{
40
  eth_bd  *bd;
41
  int i;
42
 
43
  bd = (eth_bd *)ETH_BD_BASE;
44
 
45 855 markom
  for(i = 0; i < ETH_TXBD_NUM; i++) {
46 809 simons
    /* Set Tx BD status */
47 834 simons
    bd[i].len_status = 0 << 16 | ETH_TX_BD_PAD | ETH_TX_BD_CRC | ETH_RX_BD_IRQ;
48 809 simons
 
49
    /* Initialize Tx buffer pointer */
50 833 simons
    bd[i].addr = ETH_DATA_BASE + (i * ETH_MAXBUF_LEN);
51 809 simons
  }
52
 
53 834 simons
  bd[i-1].len_status |= ETH_TX_BD_WRAP; // Last Tx BD - Wrap
54 809 simons
}
55
 
56
void init_rx_bd_pool(void)
57
{
58
  eth_bd  *bd;
59
  int i;
60
 
61
  bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM;
62
 
63
  for(i = 0; i < ETH_RXBD_NUM; i++){
64
 
65 833 simons
    /* Set Rx BD status */
66 834 simons
    bd[i].len_status = 0 << 16 | ETH_RX_BD_EMPTY | ETH_RX_BD_IRQ;
67 809 simons
 
68 833 simons
    /* Initialize Rx buffer pointer */
69
    bd[i].addr = ETH_DATA_BASE + ((ETH_TXBD_NUM + i) * ETH_MAXBUF_LEN);
70 809 simons
  }
71
 
72 842 simons
  bd[i-1].len_status |= ETH_RX_BD_WRAP; // Last Rx BD - Wrap
73 809 simons
}
74
 
75 855 markom
/* Ethernet interrupt handler */
76
void eth_int (void)
77
{
78
}
79
 
80 809 simons
void eth_init (void (*rec)(volatile unsigned char *, int))
81
{
82
  /* Reset ethernet core */
83
  REG32(ETH_REG_BASE + ETH_MODER) = ETH_MODER_RST;    /* Reset ON */
84
  REG32(ETH_REG_BASE + ETH_MODER) &= ~ETH_MODER_RST;  /* Reset OFF */
85
 
86
  /* Setting TX BD number */
87 1017 simons
  REG32(ETH_REG_BASE + ETH_TX_BD_NUM) = ETH_TXBD_NUM;
88 809 simons
 
89
  /* Set min/max packet length */
90 987 simons
  REG32(ETH_REG_BASE + ETH_PACKETLEN) = 0x00640600;
91 809 simons
 
92
  /* Set IPGT register to recomended value */
93
  REG32(ETH_REG_BASE + ETH_IPGT) =  0x00000012;
94
 
95
  /* Set IPGR1 register to recomended value */
96
  REG32(ETH_REG_BASE + ETH_IPGR1) =  0x0000000c;
97
 
98
  /* Set IPGR2 register to recomended value */
99
  REG32(ETH_REG_BASE + ETH_IPGR2) =  0x00000012;
100
 
101
  /* Set COLLCONF register to recomended value */
102 833 simons
  REG32(ETH_REG_BASE + ETH_COLLCONF) =  0x000f003f;
103 809 simons
 
104
#if 0
105
  REG32(ETH_REG_BASE + ETH_CTRLMODER) = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
106
#else
107
  REG32(ETH_REG_BASE + ETH_CTRLMODER) = 0;
108
#endif
109
 
110
  /* Initialize RX and TX buffer descriptors */
111
  init_rx_bd_pool();
112
  init_tx_bd_pool();
113
 
114
  /* Initialize tx pointers */
115
  tx_next = 0;
116
  tx_last = 0;
117
  tx_full = 0;
118
 
119
  /* Initialize rx pointers */
120
  rx_next = 0;
121
  receive = rec;
122
 
123
  /* Set local MAC address */
124
  REG32(ETH_REG_BASE + ETH_MAC_ADDR1) = ETH_MACADDR0 << 8 |
125
            ETH_MACADDR1;
126
  REG32(ETH_REG_BASE + ETH_MAC_ADDR0) = ETH_MACADDR2 << 24 |
127
            ETH_MACADDR3 << 16 |
128
            ETH_MACADDR4 << 8 |
129
            ETH_MACADDR5;
130
 
131
  /* Clear all pending interrupts */
132
  REG32(ETH_REG_BASE + ETH_INT) = 0xffffffff;
133
 
134
  /* Promisc, IFG, CRCEn */
135
  REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_PAD | ETH_MODER_IFG | ETH_MODER_CRCEN;
136
 
137
  /* Enable interrupt sources */
138
#if 0
139
  regs->int_mask = ETH_INT_MASK_TXB        |
140
                   ETH_INT_MASK_TXE        |
141
                   ETH_INT_MASK_RXF        |
142
                   ETH_INT_MASK_RXE        |
143
                   ETH_INT_MASK_BUSY       |
144
                   ETH_INT_MASK_TXC        |
145
                   ETH_INT_MASK_RXC;
146 833 simons
#else
147
  REG32(ETH_REG_BASE + ETH_INT_MASK) = 0x00000000;
148 809 simons
#endif
149
 
150
  /* Enable receiver and transmiter */
151
  REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_RXEN | ETH_MODER_TXEN;
152
 
153 855 markom
  /* Register interrupt handler */
154
  int_add (ETH_IRQ, eth_int);
155 809 simons
}
156
 
157
/* Returns pointer to next free buffer; NULL if none available */
158
void *eth_get_tx_buf ()
159
{
160
  eth_bd  *bd;
161
  unsigned long add;
162
 
163
  if(tx_full)
164
    return (void *)0;
165
 
166
  bd = (eth_bd *)ETH_BD_BASE;
167
 
168 834 simons
  if(bd[tx_next].len_status & ETH_TX_BD_READY)
169 809 simons
    return (void *)0;
170
 
171
  add = bd[tx_next].addr;
172
 
173
  tx_next = (tx_next + 1) & ETH_TXBD_NUM_MASK;
174
 
175
  if(tx_next == tx_last)
176
    tx_full = 1;
177
 
178
  return (void *)add;
179
}
180
 
181
/* Send a packet at address */
182
void eth_send (void *buf, unsigned long len)
183
{
184
  eth_bd  *bd;
185
 
186
  bd = (eth_bd *)ETH_BD_BASE;
187
 
188
  bd[tx_last].addr = (unsigned long)buf;
189 834 simons
  bd[tx_last].len_status &= 0x0000ffff & ~ETH_TX_BD_STATS;
190
  bd[tx_last].len_status |= len << 16 | ETH_TX_BD_READY;
191 809 simons
 
192
  tx_last = (tx_last + 1) & ETH_TXBD_NUM_MASK;
193
  tx_full = 0;
194
}
195
 
196
/* Waits for packet and pass it to the upper layers */
197
unsigned long eth_rx (void)
198
{
199
  eth_bd  *bd;
200
  unsigned long len = 0;
201
 
202
  bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM;
203
 
204
  while(1) {
205
 
206
    int bad = 0;
207
 
208 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_EMPTY)
209 809 simons
      return len;
210
 
211 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_OVERRUN) {
212 809 simons
      printf("eth rx: ETH_RX_BD_OVERRUN\n");
213
      bad = 1;
214
    }
215 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_INVSIMB) {
216 809 simons
      printf("eth rx: ETH_RX_BD_INVSIMB\n");
217
      bad = 1;
218
    }
219 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_DRIBBLE) {
220 809 simons
      printf("eth rx: ETH_RX_BD_DRIBBLE\n");
221
      bad = 1;
222
    }
223 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_TOOLONG) {
224 809 simons
      printf("eth rx: ETH_RX_BD_TOOLONG\n");
225
      bad = 1;
226
    }
227 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_SHORT) {
228 809 simons
      printf("eth rx: ETH_RX_BD_SHORT\n");
229
      bad = 1;
230
    }
231 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_CRCERR) {
232 809 simons
      printf("eth rx: ETH_RX_BD_CRCERR\n");
233
      bad = 1;
234
    }
235 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_LATECOL) {
236 809 simons
      printf("eth rx: ETH_RX_BD_LATECOL\n");
237
      bad = 1;
238
    }
239
 
240
    if(!bad) {
241 834 simons
      receive((void *)bd[rx_next].addr, bd[rx_next].len_status >> 16);
242
      len += bd[rx_next].len_status >> 16;
243 809 simons
    }
244
 
245 834 simons
    bd[rx_next].len_status &= ~ETH_RX_BD_STATS;
246
    bd[rx_next].len_status |= ETH_RX_BD_EMPTY;
247 809 simons
 
248
    rx_next = (rx_next + 1) & ETH_RXBD_NUM_MASK;
249
  }
250
}
251
 
252
void eth_int_enable(void)
253
{
254
  REG32(ETH_REG_BASE + ETH_INT_MASK) =  ETH_INT_MASK_TXB        |
255
                                        ETH_INT_MASK_TXE        |
256
                                        ETH_INT_MASK_RXF        |
257
                                        ETH_INT_MASK_RXE        |
258
                                        ETH_INT_MASK_BUSY       |
259
                                        ETH_INT_MASK_TXC        |
260
                                        ETH_INT_MASK_RXC;
261
}
262
 
263
void eth_halt(void)
264
{
265
  /* Enable receiver and transmiter */
266
  REG32(ETH_REG_BASE + ETH_MODER) &= ~(ETH_MODER_RXEN | ETH_MODER_TXEN);
267
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.