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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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