source: rtems/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/testing.c @ 6273201

4.115
Last change on this file since 6273201 was b7a6d23a, checked in by Till Straumann <strauman@…>, on 12/03/09 at 16:56:50
  • importing 'beatnik' BSP from SLAC repository.
  • Property mode set to 100644
File size: 6.9 KB
Line 
1#ifndef KERNEL
2#define KERNEL
3#endif
4
5#include <rtems.h>
6#include <rtems/rtems_bsdnet_internal.h>
7#include <bsp.h>
8#include <sys/mbuf.h>
9
10#include "mv64340_eth_ll.h"
11
12#include <string.h>
13#include <assert.h>
14
15#include <netinet/in.h>
16#include <stdio.h>
17
18#define RX_SPACING 1
19#define TX_SPACING 1
20
21#define RX_RING_SIZE (MV64340_RX_QUEUE_SIZE*RX_SPACING)
22#define TX_RING_SIZE (MV64340_TX_QUEUE_SIZE*TX_SPACING)
23
24
25struct eth_rx_desc rx_ring[RX_RING_SIZE] __attribute__((aligned(32)));
26struct eth_rx_desc rx_ring[RX_RING_SIZE] = {{0},};
27
28struct eth_tx_desc tx_ring[TX_RING_SIZE] __attribute__((aligned(32)));
29struct eth_tx_desc tx_ring[TX_RING_SIZE] = {{0},};
30
31/* packet buffers */
32char rx_buf[MV64340_RX_QUEUE_SIZE][2048] __attribute__((aligned(8)));
33char rx_buf[MV64340_RX_QUEUE_SIZE][2048];
34
35char tx_buf[MV64340_RX_QUEUE_SIZE][2048] __attribute__((aligned(8)));
36char tx_buf[MV64340_RX_QUEUE_SIZE][2048];
37
38char BcHeader[22] = {
39        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* dst */
40        0x00, 0x01, 0xaf, 0x13, 0xb5, 0x3e, /* src */
41        00, 00, /* len */
42        0xAA,   /* dsap */
43        0xAA,   /* ssap */
44        0x03,   /* ctrl */
45        0x08, 0x00, 0x56,       /* snap_org [stanford] */
46        0x80, 0x5b,                     /* snap_type (stanford kernel) */
47};
48
49struct mv64340_private mveth = {
50        port_num: 0,
51        port_mac_addr: {0x00,0x01,0xAF,0x13,0xB5,0x3C},
52        /* port_config .. tx_resource_err are set by port_init */
53        0
54};
55
56struct pkt_info p0,p1;
57
58static inline void rx_stopq(int port)
59{
60        MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port), 0x0000ff00);
61}
62
63static inline void tx_stopq(int port)
64{
65        MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port), 0x0000ff00);
66}
67
68#define MV64360_ENET2MEM_SNOOP_NONE 0x0000
69#define MV64360_ENET2MEM_SNOOP_WT       0x1000
70#define MV64360_ENET2MEM_SNOOP_WB       0x2000
71
72#if 0
73int
74mveth_init(struct mv64340_private *mp)
75{
76int i;
77        mp->p_rx_desc_area = rx_ring;
78        mp->p_tx_desc_area = tx_ring;
79
80        rx_stopq(mp->port_num);
81        tx_stopq(mp->port_num);
82
83        /* MotLoad has cache snooping disabled on the ENET2MEM windows.
84         * Some comments in (linux) indicate that there are errata
85         * which cause problems which is a real bummer.
86         * We try it anyways...
87         */
88        {
89        unsigned long disbl, bar;
90        disbl = MV_READ(MV64340_ETH_BASE_ADDR_ENABLE_REG);
91        /* disable all 6 windows */
92        MV_WRITE(MV64340_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
93        /* set WB snooping */
94        for ( i=0; i<6*8; i+=8 ) {
95                if ( (bar = MV_READ(MV64340_ETH_BAR_0 + i)) && MV_READ(MV64340_ETH_SIZE_REG_0 + i) ) {
96                        MV_WRITE(MV64340_ETH_BAR_0 + i, bar | MV64360_ENET2MEM_SNOOP_WB);
97                        /* read back to flush fifo [linux comment] */
98                        (void)MV_READ(MV64340_ETH_BAR_0 + i);
99                }
100        }
101        /* restore/re-enable */
102        MV_WRITE(MV64340_ETH_BASE_ADDR_ENABLE_REG, disbl);
103        }
104
105        eth_port_init(mp);
106
107        sleep(1);
108
109        mveth_init_tx_desc_ring(mp);
110        mveth_init_rx_desc_ring(mp);
111#if 0
112        for ( i = 0; i<MV64340_RX_QUEUE_SIZE; i++ ) {
113                p0.byte_cnt     = sizeof(rx_buf[0]);
114                p0.buf_ptr      = (dma_addr_t)rx_buf[i];
115                p0.return_info  = (void*)i;
116                /* other fields are not used by ll driver */
117                assert ( ETH_OK == eth_rx_return_buff(mp,&p0) );
118        }
119        memset(&p0, 0, sizeof(p0));
120#endif
121
122        return eth_port_start(mp);
123}
124#endif
125
126void
127mveth_stop(struct mv64340_private *mp)
128{
129extern void mveth_stop_hw();
130        rtems_bsdnet_semaphore_obtain();
131                mveth_stop_hw(mp);
132        rtems_bsdnet_semaphore_release();
133}
134
135extern int mveth_send_mbuf();
136extern int mveth_swipe_tx();
137
138int
139mveth_tx(struct mv64340_private *mp, char *data, int len, int nbufs)
140{
141int rval = -1,l;
142char        *p;
143struct mbuf *m;
144char    *emsg = 0;
145
146        rtems_bsdnet_semaphore_obtain();
147        MGETHDR(m, M_WAIT, MT_DATA);
148        if ( !m ) {
149                emsg="Unable to allocate header\n";
150                goto bail;
151        }
152        MCLGET(m, M_WAIT);
153        if ( !(m->m_flags & M_EXT) ) {
154                m_freem(m);
155                emsg="Unable to allocate cluster\n";
156                goto bail;
157        }
158        p = mtod(m, char *);
159        l = 0;
160        switch (nbufs) {
161                case 3:
162                default:
163                        emsg="nbufs arg must be 1..3\n";
164                        goto bail;
165
166                case 1:
167                        l += sizeof(BcHeader);
168                        memcpy(p, &BcHeader, sizeof(BcHeader));
169                        p += sizeof(BcHeader);
170
171                case 2:
172                        memcpy(p,data,len);
173                        l += len;
174                        m->m_len = m->m_pkthdr.len = l;
175                        if ( 2 == nbufs ) {
176                        M_PREPEND(m, sizeof (BcHeader), M_WAIT);
177                                if (!m) {
178                                        emsg = "Unable to prepend\n";
179                                        goto bail;
180                                }
181                                p = mtod(m, char*);
182                                memcpy(p,&BcHeader,sizeof(BcHeader));
183                                l += sizeof(BcHeader);
184                        }
185                break;
186        }
187        *(short*)(mtod(m, char*) + 12) = htons(l-14);
188        rval = mveth_send_mbuf(mp,m);
189
190bail:
191        rtems_bsdnet_semaphore_release();
192        if (emsg)
193                printf(emsg);
194
195#if 0
196    /*
197     * Add local net header.  If no space in first mbuf,
198     * allocate another.
199     */
200    M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
201    if (m == 0)
202        senderr(ENOBUFS);
203    eh = mtod(m, struct ether_header *);
204    (void)memcpy(&eh->ether_type, &type,
205        sizeof(eh->ether_type));
206    (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
207    (void)memcpy(eh->ether_shost, ac->ac_enaddr,
208        sizeof(eh->ether_shost));
209#endif
210        return rval;
211}
212
213int
214mveth_protected(int (*p)(struct mv64340_private*), struct mv64340_private *mp)
215{
216int rval;
217        rtems_bsdnet_semaphore_obtain();
218                rval = p(mp);
219        rtems_bsdnet_semaphore_release();
220        return rval;
221}
222
223int
224mveth_rx(struct mv64340_private *mp)
225{
226extern int mveth_swipe_rx();
227        return mveth_protected(mveth_swipe_rx,mp);
228}
229
230int
231mveth_reclaim(struct mv64340_private *mp)
232{
233extern int mveth_swipe_tx();
234        return mveth_protected(mveth_swipe_tx,mp);
235}
236
237
238int preth(FILE *f, char *p)
239{
240int i;
241        for (i=0; i<4; i++)
242                fprintf(f,"%02X:",p[i]);
243        fprintf(f,"%02X",p[i]);
244        return 6;
245}
246
247char *errcode2str(st)
248{
249char *rval;
250        switch(st) {
251                case ETH_OK:
252                        rval = "OK";
253                break;
254                case ETH_ERROR:
255                        rval = "Fundamental error.";
256                break;
257                case ETH_RETRY:
258                        rval = "Could not process request. Try later.";
259                break;
260                case ETH_END_OF_JOB:
261                        rval = "Ring has nothing to process.";
262                break;
263                case ETH_QUEUE_FULL:
264                        rval = "Ring resource error.";
265                break;
266                case ETH_QUEUE_LAST_RESOURCE:
267                        rval = "Ring resources about to exhaust.";
268                break;
269                default:
270                        rval = "UNKNOWN"; break;
271        }
272        return rval;
273}
274
275
276#if 0
277int
278mveth_rx(struct mv64340_private *mp)
279{
280int st;
281struct pkt_info p;
282        if ( ETH_OK != (st=eth_port_receive(mp, &p)) ) {
283                fprintf(stderr,"receive: %s\n", errcode2str(st));
284                return -1;
285        }
286        printf("%i bytes received from ", p.byte_cnt);
287        preth(stdout,(char*)p.buf_ptr+6);
288        printf(" (desc. stat: 0x%08x)\n", p.cmd_sts);
289               
290        p.byte_cnt = sizeof(rx_buf[0]);
291        p.buf_ptr -= RX_BUF_OFFSET;
292        if ( ETH_OK != (st=eth_rx_return_buff(mp,&p) ) ) {
293                fprintf(stderr,"returning buffer: %s\n", errcode2str(st));
294                return -1;
295        }
296        return 0;
297}
298#endif
299
300int
301dring()
302{
303int i;
304if (1) {
305struct eth_rx_desc *pr;
306printf("RX:\n");
307        for (i=0, pr=rx_ring; i<RX_RING_SIZE; i+=RX_SPACING, pr+=RX_SPACING) {
308                dcbi(pr);
309                printf("cnt: 0x%04x, size: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x\n",
310                        pr->byte_cnt, pr->buf_size, pr->cmd_sts, pr->next_desc_ptr, pr->buf_ptr);
311        }
312}
313if (1) {
314struct eth_tx_desc *pt;
315printf("TX:\n");
316        for (i=0, pt=tx_ring; i<TX_RING_SIZE; i+=TX_SPACING, pt+=TX_SPACING) {
317                dcbi(pt);
318                printf("cnt: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x\n",
319                        pt->byte_cnt, pt->cmd_sts, pt->next_desc_ptr, pt->buf_ptr);
320        }
321}
322        return 0;
323}
Note: See TracBrowser for help on using the repository browser.