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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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