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

Subversion Repositories or1k

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

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 1030 simons
  // Set PHY to 10 Mbps full duplex
90
  REG32(ETH_REG_BASE + ETH_MIIADDRESS) = 0<<8;
91
  REG32(ETH_REG_BASE + ETH_MIITX_DATA) = 0x0100;
92
  REG32(ETH_REG_BASE + ETH_MIICOMMAND) = ETH_MIICOMMAND_WCTRLDATA;
93
 
94
  printf("Ethernet configured for 10Mbps. Pres any key.");
95
  getc();
96
/*
97
  while(1){
98
    REG32(ETH_REG_BASE + ETH_MIIADDRESS) = 1<<8;
99
    REG32(ETH_REG_BASE + ETH_MIICOMMAND) = ETH_MIICOMMAND_RSTAT;
100
    if(REG32(ETH_REG_BASE + ETH_MIIRX_DATA) & 0x04)
101
      break;
102
  }
103
*/
104 809 simons
  /* Set min/max packet length */
105 1029 simons
  REG32(ETH_REG_BASE + ETH_PACKETLEN) = 0x00400600;
106 809 simons
 
107
  /* Set IPGT register to recomended value */
108
  REG32(ETH_REG_BASE + ETH_IPGT) =  0x00000012;
109
 
110
  /* Set IPGR1 register to recomended value */
111
  REG32(ETH_REG_BASE + ETH_IPGR1) =  0x0000000c;
112
 
113
  /* Set IPGR2 register to recomended value */
114
  REG32(ETH_REG_BASE + ETH_IPGR2) =  0x00000012;
115
 
116
  /* Set COLLCONF register to recomended value */
117 833 simons
  REG32(ETH_REG_BASE + ETH_COLLCONF) =  0x000f003f;
118 809 simons
 
119
#if 0
120
  REG32(ETH_REG_BASE + ETH_CTRLMODER) = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
121
#else
122
  REG32(ETH_REG_BASE + ETH_CTRLMODER) = 0;
123
#endif
124
 
125
  /* Initialize RX and TX buffer descriptors */
126
  init_rx_bd_pool();
127
  init_tx_bd_pool();
128
 
129
  /* Initialize tx pointers */
130
  tx_next = 0;
131
  tx_last = 0;
132
  tx_full = 0;
133
 
134
  /* Initialize rx pointers */
135
  rx_next = 0;
136
  receive = rec;
137
 
138
  /* Set local MAC address */
139
  REG32(ETH_REG_BASE + ETH_MAC_ADDR1) = ETH_MACADDR0 << 8 |
140
            ETH_MACADDR1;
141
  REG32(ETH_REG_BASE + ETH_MAC_ADDR0) = ETH_MACADDR2 << 24 |
142
            ETH_MACADDR3 << 16 |
143
            ETH_MACADDR4 << 8 |
144
            ETH_MACADDR5;
145
 
146
  /* Clear all pending interrupts */
147
  REG32(ETH_REG_BASE + ETH_INT) = 0xffffffff;
148
 
149
  /* Promisc, IFG, CRCEn */
150
  REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_PAD | ETH_MODER_IFG | ETH_MODER_CRCEN;
151
 
152
  /* Enable interrupt sources */
153
#if 0
154
  regs->int_mask = ETH_INT_MASK_TXB        |
155
                   ETH_INT_MASK_TXE        |
156
                   ETH_INT_MASK_RXF        |
157
                   ETH_INT_MASK_RXE        |
158
                   ETH_INT_MASK_BUSY       |
159
                   ETH_INT_MASK_TXC        |
160
                   ETH_INT_MASK_RXC;
161 833 simons
#else
162
  REG32(ETH_REG_BASE + ETH_INT_MASK) = 0x00000000;
163 809 simons
#endif
164
 
165
  /* Enable receiver and transmiter */
166
  REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_RXEN | ETH_MODER_TXEN;
167
 
168 855 markom
  /* Register interrupt handler */
169
  int_add (ETH_IRQ, eth_int);
170 809 simons
}
171
 
172
/* Returns pointer to next free buffer; NULL if none available */
173
void *eth_get_tx_buf ()
174
{
175
  eth_bd  *bd;
176
  unsigned long add;
177
 
178
  if(tx_full)
179
    return (void *)0;
180
 
181
  bd = (eth_bd *)ETH_BD_BASE;
182
 
183 834 simons
  if(bd[tx_next].len_status & ETH_TX_BD_READY)
184 809 simons
    return (void *)0;
185
 
186
  add = bd[tx_next].addr;
187
 
188
  tx_next = (tx_next + 1) & ETH_TXBD_NUM_MASK;
189
 
190
  if(tx_next == tx_last)
191
    tx_full = 1;
192
 
193
  return (void *)add;
194
}
195
 
196
/* Send a packet at address */
197
void eth_send (void *buf, unsigned long len)
198
{
199
  eth_bd  *bd;
200
 
201
  bd = (eth_bd *)ETH_BD_BASE;
202
 
203
  bd[tx_last].addr = (unsigned long)buf;
204 834 simons
  bd[tx_last].len_status &= 0x0000ffff & ~ETH_TX_BD_STATS;
205
  bd[tx_last].len_status |= len << 16 | ETH_TX_BD_READY;
206 809 simons
 
207
  tx_last = (tx_last + 1) & ETH_TXBD_NUM_MASK;
208
  tx_full = 0;
209
}
210
 
211
/* Waits for packet and pass it to the upper layers */
212
unsigned long eth_rx (void)
213
{
214
  eth_bd  *bd;
215
  unsigned long len = 0;
216
 
217
  bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM;
218
 
219
  while(1) {
220
 
221
    int bad = 0;
222
 
223 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_EMPTY)
224 809 simons
      return len;
225
 
226 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_OVERRUN) {
227 809 simons
      printf("eth rx: ETH_RX_BD_OVERRUN\n");
228
      bad = 1;
229
    }
230 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_INVSIMB) {
231 809 simons
      printf("eth rx: ETH_RX_BD_INVSIMB\n");
232
      bad = 1;
233
    }
234 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_DRIBBLE) {
235 809 simons
      printf("eth rx: ETH_RX_BD_DRIBBLE\n");
236
      bad = 1;
237
    }
238 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_TOOLONG) {
239 809 simons
      printf("eth rx: ETH_RX_BD_TOOLONG\n");
240
      bad = 1;
241
    }
242 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_SHORT) {
243 809 simons
      printf("eth rx: ETH_RX_BD_SHORT\n");
244
      bad = 1;
245
    }
246 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_CRCERR) {
247 809 simons
      printf("eth rx: ETH_RX_BD_CRCERR\n");
248
      bad = 1;
249
    }
250 834 simons
    if(bd[rx_next].len_status & ETH_RX_BD_LATECOL) {
251 809 simons
      printf("eth rx: ETH_RX_BD_LATECOL\n");
252
      bad = 1;
253
    }
254
 
255
    if(!bad) {
256 834 simons
      receive((void *)bd[rx_next].addr, bd[rx_next].len_status >> 16);
257
      len += bd[rx_next].len_status >> 16;
258 809 simons
    }
259
 
260 834 simons
    bd[rx_next].len_status &= ~ETH_RX_BD_STATS;
261
    bd[rx_next].len_status |= ETH_RX_BD_EMPTY;
262 809 simons
 
263
    rx_next = (rx_next + 1) & ETH_RXBD_NUM_MASK;
264
  }
265
}
266
 
267
void eth_int_enable(void)
268
{
269
  REG32(ETH_REG_BASE + ETH_INT_MASK) =  ETH_INT_MASK_TXB        |
270
                                        ETH_INT_MASK_TXE        |
271
                                        ETH_INT_MASK_RXF        |
272
                                        ETH_INT_MASK_RXE        |
273
                                        ETH_INT_MASK_BUSY       |
274
                                        ETH_INT_MASK_TXC        |
275
                                        ETH_INT_MASK_RXC;
276
}
277
 
278
void eth_halt(void)
279
{
280
  /* Enable receiver and transmiter */
281
  REG32(ETH_REG_BASE + ETH_MODER) &= ~(ETH_MODER_RXEN | ETH_MODER_TXEN);
282
}

powered by: WebSVN 2.1.0

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