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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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