2 * Copyright 1996 The Australian National University.
3 * Copyright 1996 Fujitsu Laboratories Limited
5 * This software may be distributed under the terms of the Gnu
6 * Public License version 2 or later
9 * Routines for controlling the FORMAC+
11 #include <linux/types.h>
12 #include <linux/string.h>
13 #include <linux/kernel.h>
14 #include <linux/skbuff.h>
15 #include <linux/interrupt.h>
16 #include <linux/if_ether.h> /* For the statistics structure. */
17 #include <linux/netdevice.h>
18 #include <linux/if_arp.h>
19 #include <linux/inet.h>
22 #include <asm/ap1000/apreg.h>
23 #include <asm/ap1000/apservice.h>
24 #include <asm/pgtable.h>
27 #include "smt-types.h"
31 #include "apfddi-reg.h"
35 /* Values for dma_state */
41 * Messages greater than this value are transferred to the FDDI send buffer
44 #define DMA_XMIT_THRESHOLD 64
45 #define DMA_RECV_THRESHOLD 64
48 * If the FDDI receive buffer is occupied by less than this value, then
49 * sending has priority.
51 #define RECV_THRESHOLD (20*1024)
53 #define DMA_RESET_MASKS ((AP_CLR_INTR_MASK<<DMA_INTR_NORMAL_SH) | \
54 (AP_CLR_INTR_MASK<<DMA_INTR_ERROR_SH))
56 #define DMA_INTR_REQS ((AP_INTR_REQ<<DMA_INTR_NORMAL_SH) | \
57 (AP_INTR_REQ<<DMA_INTR_ERROR_SH))
59 static void mac_print_state(void);
61 typedef unsigned int mac_status_t
;
63 static volatile struct mac_queue
*mac_queue_top
= NULL
;
64 static volatile struct mac_queue
*mac_queue_bottom
= NULL
;
67 LoopbackType loopback
;
78 int xmit_chain_start
[3];
84 volatile struct mac_queue
*cur_macq
; /* Current queue el for send DMA */
85 volatile struct mac_buf cur_mbuf
; /* Current mac_buf for send DMA */
86 struct sk_buff
*cur_skb
; /* skb for received packets by DMA */
90 #define SPFRAMES_SIZE 64 /* # words for special frames area */
91 #define RECV_BUF_START SPFRAMES_SIZE
92 #define RECV_BUF_END (BUFFER_SIZE / 2 + 2048)
93 #define RECV_BUF_SIZE (RECV_BUF_END - RECV_BUF_START)
94 #define XMIT_BUF_START RECV_BUF_END
95 #define XMIT_BUF_END BUFFER_SIZE
97 #define S2_RMT_EVENTS (S2_CLAIM_STATE | S2_MY_CLAIM | S2_HIGHER_CLAIM | \
98 S2_LOWER_CLAIM | S2_BEACON_STATE | S2_MY_BEACON | \
99 S2_OTHER_BEACON | S2_RING_OP | S2_MULTIPLE_DA | \
100 S2_TOKEN_ERR | S2_DUPL_CLAIM | S2_TRT_EXP_RECOV)
102 struct mac_info
*this_mac_info
;
103 struct formac_state this_mac_state
;
106 mac_init(struct mac_info
*mip
)
108 struct formac_state
*msp
= &this_mac_state
;
110 bif_add_debug_key('f',mac_print_state
,"show FDDI mac state");
114 mac
->cmdreg1
= C1_SOFTWARE_RESET
;
115 mac
->said
= (mip
->s_address
[0] << 8) + mip
->s_address
[1];
116 mac
->laim
= (mip
->l_address
[0] << 8) + mip
->l_address
[1];
117 mac
->laic
= (mip
->l_address
[2] << 8) + mip
->l_address
[3];
118 mac
->lail
= (mip
->l_address
[4] << 8) + mip
->l_address
[5];
119 mac
->sagp
= (mip
->s_group_adrs
[0] << 8) + mip
->s_group_adrs
[1];
120 mac
->lagm
= (mip
->l_group_adrs
[0] << 8) + mip
->l_group_adrs
[1];
121 mac
->lagc
= (mip
->l_group_adrs
[2] << 8) + mip
->l_group_adrs
[3];
122 mac
->lagl
= (mip
->l_group_adrs
[4] << 8) + mip
->l_group_adrs
[5];
123 mac
->tmax
= mip
->tmax
>> 5;
124 mac
->tvx
= (mip
->tvx
- 254) / 255; /* it's -ve, round downwards */
125 mac
->treq0
= mip
->treq
;
126 mac
->treq1
= mip
->treq
>> 16;
130 mac
->mdreg2
= /*M2_STRIP_FCS +*/ M2_CHECK_PARITY
+ M2_EVEN_PARITY
131 + 3 * M2_RCV_BYTE_BDRY
+ M2_ENABLE_HSREQ
132 + M2_ENABLE_NPDMA
+ M2_SYNC_NPDMA
+ M2_RECV_BAD_FRAMES
;
133 mac
->eacb
= RECV_BUF_START
- 1;
134 mac
->earv
= XMIT_BUF_START
- 1;
135 mac
->eas
= mac
->earv
;
136 mac
->eaa0
= BUFFER_SIZE
- 1;
137 mac
->eaa1
= mac
->eaa0
;
138 mac
->eaa2
= mac
->eaa1
;
140 mac
->rpr
= RECV_BUF_START
;
141 mac
->wpr
= RECV_BUF_START
+ 1;
142 mac
->swpr
= RECV_BUF_START
;
143 mac
->wpxs
= mac
->eas
;
144 mac
->swpxs
= mac
->eas
;
145 mac
->rpxs
= mac
->eas
;
146 mac
->wpxa0
= XMIT_BUF_START
;
147 mac
->rpxa0
= XMIT_BUF_START
;
149 memset(msp
, 0, sizeof(*msp
));
150 msp
->recv_ptr
= RECV_BUF_START
;
152 msp
->xmit_ptr
= XMIT_BUF_START
;
153 msp
->xmit_free
= XMIT_BUF_START
+ 1;
154 msp
->xmit_start
= XMIT_BUF_START
;
155 msp
->xmit_chains
= 0;
156 msp
->frames_xmitted
= 0;
157 msp
->frames_recvd
= 0;
158 msp
->recv_aborted
= 0;
160 mac
->mdreg1
= M1_MODE_MEMORY
;
168 mac_inited(struct mac_info
*mip
)
170 struct formac_state
*msp
= &this_mac_state
;
171 mac_status_t st1
, st2
;
173 if (mac
->said
!= (mip
->s_address
[0] << 8) + mip
->s_address
[1]
174 || mac
->laim
!= (mip
->l_address
[0] << 8) + mip
->l_address
[1]
175 || mac
->laic
!= (mip
->l_address
[2] << 8) + mip
->l_address
[3]
176 || mac
->lail
!= (mip
->l_address
[4] << 8) + mip
->l_address
[5]
177 || mac
->sagp
!= (mip
->s_group_adrs
[0] << 8) + mip
->s_group_adrs
[1]
178 || mac
->lagm
!= (mip
->l_group_adrs
[0] << 8) + mip
->l_group_adrs
[1]
179 || mac
->lagc
!= (mip
->l_group_adrs
[2] << 8) + mip
->l_group_adrs
[3]
180 || mac
->lagl
!= (mip
->l_group_adrs
[4] << 8) + mip
->l_group_adrs
[5])
182 if ((mac
->mdreg1
& ~M1_ADDET
) != (M1_MODE_ONLINE
| M1_SELECT_RA
185 if (mac
->treq0
!= (mip
->treq
& 0xffff)
186 || mac
->treq1
!= ((unsigned)mip
->treq
>> 16))
189 st1
= (mac
->st1u
<< 16) + mac
->st1l
;
190 st2
= (mac
->st2u
<< 16) + mac
->st2l
;
191 if ((st2
& S2_RING_OP
) == 0)
194 /* It's probably OK, reset some things to be safe. */
197 mac
->tmax
= mip
->tmax
>> 5;
198 mac
->tvx
= (mip
->tvx
- 254) / 255; /* it's -ve, round downwards */
202 mac
->mdreg2
= /*M2_STRIP_FCS +*/ M2_CHECK_PARITY
+ M2_EVEN_PARITY
203 + 3 * M2_RCV_BYTE_BDRY
+ M2_ENABLE_HSREQ
204 + M2_ENABLE_NPDMA
+ M2_SYNC_NPDMA
+ M2_RECV_BAD_FRAMES
;
206 /* clear out the receive queue */
207 mac
->mdreg1
= (mac
->mdreg1
& ~M1_ADDET
) | M1_ADDET_DISABLE_RECV
;
208 mac
->rpr
= RECV_BUF_START
;
209 mac
->wpr
= RECV_BUF_START
+ 1;
210 mac
->swpr
= RECV_BUF_START
;
212 memset(msp
, 0, sizeof(*msp
));
213 msp
->recv_ptr
= RECV_BUF_START
;
216 /* XXX reset transmit pointers */
217 mac
->cmdreg2
= C2_ABORT_XMIT
;
218 mac
->cmdreg2
= C2_RESET_XMITQS
;
219 mac
->wpxa0
= XMIT_BUF_START
;
220 mac
->rpxa0
= XMIT_BUF_START
;
221 msp
->xmit_ptr
= XMIT_BUF_START
;
222 msp
->xmit_free
= XMIT_BUF_START
+ 1;
223 msp
->xmit_start
= XMIT_BUF_START
;
224 msp
->xmit_chains
= 0;
227 mac
->cmdreg1
= C1_CLR_ALL_LOCKS
;
229 msp
->frames_xmitted
= 0;
230 msp
->frames_recvd
= 0;
231 msp
->recv_aborted
= 0;
234 mac
->mdreg1
= (mac
->mdreg1
& ~M1_ADDET
) | M1_ADDET_NSA
;
235 mac
->imsk1u
= ~(S1_XMIT_ABORT
| S1_END_FRAME_ASYNC0
) >> 16;
236 mac
->imsk1l
= ~(S1_PAR_ERROR_ASYNC0
| S1_QUEUE_LOCK_ASYNC0
);
237 mac
->imsk2u
= ~(S2_RECV_COMPLETE
| S2_RECV_BUF_FULL
| S2_RECV_FIFO_OVF
238 | S2_ERR_SPECIAL_FR
| S2_RMT_EVENTS
239 | S2_NP_SIMULT_LOAD
) >> 16;
240 mac
->imsk2l
= ~(S2_RMT_EVENTS
| S2_MISSED_FRAME
);
245 void mac_make_spframes(void)
248 struct mac_info
*mip
= this_mac_info
;
250 struct formac_state
*msp
= &this_mac_state
;
252 /* initialize memory to avoid parity errors */
254 *csr1
&= ~CS1_BUF_WR_TAG
;
255 for (bp
= &buffer_mem
[BUFFER_SIZE
]; bp
> &buffer_mem
[XMIT_BUF_START
];)
257 for (; bp
> buffer_mem
;)
259 buffer_mem
[msp
->recv_ptr
] = 0;
262 *bp
++ = 0; /* auto-void frame pointer (not used) */
264 /* make claim frame */
265 sa
= bp
- buffer_mem
;
266 *bp
++ = 0xd8000011; /* claim frame descr. + length */
267 *bp
++ = 0xc3; /* FC value for claim frame, long addr */
268 *bp
++ = (mip
->l_address
[0] << 24) + (mip
->l_address
[1] << 16)
269 + (mip
->l_address
[2] << 8) + mip
->l_address
[3];
270 *bp
++ = (mip
->l_address
[4] << 24) + (mip
->l_address
[5] << 16)
271 + (mip
->l_address
[0] << 8) + mip
->l_address
[1];
272 *bp
++ = (mip
->l_address
[2] << 24) + (mip
->l_address
[3] << 16)
273 + (mip
->l_address
[4] << 8) + mip
->l_address
[5];
275 mac
->sacl
= bp
- buffer_mem
; /* points to pointer to claim frame */
276 *bp
++ = 0xa0000000 + sa
; /* pointer to start of claim frame */
278 /* make beacon frame */
279 sa
= bp
- buffer_mem
;
280 *bp
++ = 0xd8000011; /* beacon frame descr. + length */
281 *bp
++ = 0xc2; /* FC value for beacon frame, long addr */
282 *bp
++ = 0; /* DA = 0 */
283 *bp
++ = (mip
->l_address
[0] << 8) + mip
->l_address
[1];
284 *bp
++ = (mip
->l_address
[2] << 24) + (mip
->l_address
[3] << 16)
285 + (mip
->l_address
[4] << 8) + mip
->l_address
[5];
286 *bp
++ = 0; /* beacon reason = failed claim */
287 mac
->sabc
= bp
- buffer_mem
;
288 *bp
++ = 0xa0000000 + sa
; /* pointer to start of beacon frame */
291 void mac_reset(LoopbackType loopback
)
294 struct formac_state
*msp
= &this_mac_state
;
296 msp
->loopback
= loopback
;
299 mode
= M1_MODE_ONLINE
;
302 mode
= M1_MODE_INT_LOOP
;
305 mode
= M1_MODE_EXT_LOOP
;
308 mac
->mdreg1
= mode
| M1_ADDET_NSA
| M1_SELECT_RA
| M1_FULL_DUPLEX
;
309 mac
->cmdreg1
= C1_IDLE_LISTEN
;
310 mac
->cmdreg1
= C1_CLR_ALL_LOCKS
;
311 mac
->imsk1u
= ~(S1_XMIT_ABORT
| S1_END_FRAME_ASYNC0
) >> 16;
312 mac
->imsk1l
= ~(S1_PAR_ERROR_ASYNC0
| S1_QUEUE_LOCK_ASYNC0
);
313 mac
->imsk2u
= ~(S2_RECV_COMPLETE
| S2_RECV_BUF_FULL
| S2_RECV_FIFO_OVF
314 | S2_ERR_SPECIAL_FR
| S2_RMT_EVENTS
315 | S2_NP_SIMULT_LOAD
) >> 16;
316 mac
->imsk2l
= ~(S2_RMT_EVENTS
| S2_MISSED_FRAME
);
321 mac
->cmdreg1
= C1_CLAIM_LISTEN
;
324 void mac_disable(void)
326 mac
->mdreg1
= M1_MODE_MEMORY
;
331 mac
->wpr
= mac
->swpr
+ 1;
332 if (mac
->wpr
> mac
->earv
)
333 mac
->wpr
= mac
->eacb
+ 1;
334 buffer_mem
[mac
->swpr
] = 0;
339 struct formac_state
*msp
= &this_mac_state
;
342 printk("%d receive buffer overflows\n", msp
->recv_ovf
);
344 printk("%d frames on wrong byte bdry\n", msp
->wrong_bb
);
345 printk("%d frames transmitted, %d aborted\n", msp
->frames_xmitted
,
347 printk("%d frames received, %d aborted\n", msp
->frames_recvd
,
349 printk("%d frames received with errors\n", msp
->recv_error
);
354 /* disable the receiver */
355 mac
->mdreg1
= (mac
->mdreg1
& ~M1_ADDET
) | M1_ADDET_DISABLE_RECV
;
360 mac_status_t st1
, st2
;
361 struct formac_state
*msp
= &this_mac_state
;
362 int up
, f
, d
, l
, r
, e
, i
;
364 st1
= (mac
->st1u
<< 16) + mac
->st1l
;
365 st2
= (mac
->st2u
<< 16) + mac
->st2l
;
367 if (st2
& S2_NP_SIMULT_LOAD
)
368 panic("NP/formac simultaneous load!!!");
370 up
= (st2
& S2_RING_OP
) != 0;
371 if (up
!= msp
->ring_op
) {
372 /* ring has come up or down */
374 printk("mac: ring %s\n", up
? "up": "down");
379 if (st1
& S1_XMIT_ABORT
) {
381 if (st1
& S1_QUEUE_LOCK_ASYNC0
) {
382 printk("mac: xmit queue locked, resetting xmit buffer\n");
383 mac
->cmdreg2
= C2_RESET_XMITQS
; /* XXX bit gross */
384 mac
->rpxa0
= XMIT_BUF_START
;
385 buffer_mem
[XMIT_BUF_START
] = 0;
386 msp
->xmit_ptr
= XMIT_BUF_START
;
387 msp
->xmit_start
= XMIT_BUF_START
;
388 msp
->xmit_chains
= 0;
389 mac
->cmdreg1
= C1_CLR_ASYNCQ0_LOCK
;
390 st1
&= ~(S1_END_CHAIN_ASYNC0
| S1_END_FRAME_ASYNC0
391 | S1_XINSTR_FULL_ASYNC0
);
393 st1
|= S1_END_FRAME_ASYNC0
;
394 } else if (st1
& S1_QUEUE_LOCK_ASYNC0
) {
395 printk("mac: xmit queue locked, why?\n");
396 mac
->cmdreg1
= C1_CLR_ASYNCQ0_LOCK
;
399 if (st1
& S1_END_FRAME_ASYNC0
) {
400 /* advance xmit_start */
402 while (e
!= msp
->xmit_ptr
) {
403 /* find the end of the current frame */
404 f
= buffer_mem
[e
]; /* read pointer */
408 d
= buffer_mem
[f
]; /* read descriptor */
409 l
= ((d
& 0xffff) + ((d
>> TD_BYTE_BDRY_LG
) & 3) + 3) >> 2;
410 e
= f
+ 1 + l
; /* index of ptr at end of frame */
412 if ((r
<= msp
->xmit_ptr
&& r
< e
&& e
<= msp
->xmit_ptr
)
413 || (r
> msp
->xmit_ptr
&& (r
< e
|| e
<= msp
->xmit_ptr
)))
414 break; /* up to current frame */
415 /* printk("frame @ %x done\n", msp->xmit_start); */
417 if ((st1
& S1_XMIT_ABORT
) == 0)
418 ++msp
->frames_xmitted
;
419 if ((msp
->xmit_chains
== 1 && e
== msp
->xmit_ptr
) ||
420 (msp
->xmit_chains
> 1 && e
== msp
->xmit_chain_start
[1])) {
421 /* we've finished chain 0 */
423 for (i
= 0; i
< msp
->xmit_chains
; ++i
)
424 msp
->xmit_chain_start
[i
] = msp
->xmit_chain_start
[i
+1];
425 if (msp
->xmit_chains
>= 2) {
426 mac
->cmdreg2
= C2_XMIT_ASYNCQ0
;
427 /* printk("mac_poll: xmit chain\n"); */
429 if (msp
->xmit_chains
== 0)
434 * Now that we have a bit more space in the transmit buffer,
435 * see if we want to put another frame in.
438 printk("Removed space in transmit buffer.\n");
444 if (st2
& S2_RMT_EVENTS
) {
448 if (st2
& S2_RECV_COMPLETE
) {
450 * A frame has just finished arriving in the receive buffer.
455 printk("Frame has just trickled in...\n");
460 if (st2
& S2_RECV_BUF_FULL
) {
462 * receive buffer overflow: reset and unlock the receive buffer.
464 /* printk("mac: receive buffer full\n"); */
465 mac
->rpr
= RECV_BUF_START
;
466 mac
->wpr
= RECV_BUF_START
+ 1;
467 mac
->swpr
= RECV_BUF_START
;
468 msp
->recv_ptr
= RECV_BUF_START
;
470 buffer_mem
[RECV_BUF_START
] = 0;
471 mac
->cmdreg1
= C1_CLR_RECVQ_LOCK
;
475 } else if (st2
& S2_RECV_FIFO_OVF
) {
476 printk("mac: receive FIFO overflow\n");
477 /* any further action required here? */
479 } else if (st2
& S2_MISSED_FRAME
) {
480 printk("mac: missed frame\n");
484 if (st2
& S2_ERR_SPECIAL_FR
) {
485 printk("mac: bug: error in special frame\n");
491 mac_xmit_alloc(sp
, bb
)
497 nwords
= (sp
->length
+ bb
+ 3) >> 2;
498 sp
->fr_start
= mac_xalloc(nwords
+ 2);
499 sp
->fr_end
= sp
->fr_start
+ nwords
+ 1;
500 sp
->ptr
= (char *) &buffer_mem
[sp
->fr_start
+ 1] + bb
;
501 buffer_mem
[sp
->fr_start
] = TD_MAGIC
+ (bb
<< TD_BYTE_BDRY_LG
) + sp
->length
;
508 struct formac_state
*msp
= &this_mac_state
;
510 buffer_mem
[sp
->fr_end
] = 0; /* null pointer at end of frame */
511 buffer_mem
[msp
->xmit_ptr
] = PT_MAGIC
+ sp
->fr_start
;
512 if (msp
->xmit_chains
<= 2) {
513 msp
->xmit_chain_start
[msp
->xmit_chains
] = msp
->xmit_ptr
;
514 if (msp
->xmit_chains
< 2)
515 mac
->cmdreg2
= C2_XMIT_ASYNCQ0
;
518 buffer_mem
[msp
->xmit_more_ptr
] |= TD_MORE
;
520 msp
->xmit_ptr
= sp
->fr_end
;
521 msp
->xmit_more_ptr
= sp
->fr_start
;
526 mac_xalloc(int nwords
)
529 struct formac_state
*msp
= &this_mac_state
;
532 * Find some room in the transmit buffer.
534 fr_start
= msp
->xmit_free
;
535 if (fr_start
> msp
->xmit_start
) {
536 if (fr_start
+ nwords
> XMIT_BUF_END
) {
537 /* no space at end - see if we can start again from the front */
538 fr_start
= XMIT_BUF_START
;
539 if (fr_start
+ nwords
> msp
->xmit_start
)
540 panic("no space in xmit buffer (1)");
543 if (fr_start
+ nwords
> msp
->xmit_start
)
544 panic("no space in xmit buffer (2)");
547 msp
->xmit_free
= fr_start
+ nwords
;
556 struct formac_state
*msp
= &this_mac_state
;
557 int status
, bb
, orig_recv_ptr
;
559 orig_recv_ptr
= msp
->recv_ptr
;
561 status
= buffer_mem
[msp
->recv_ptr
];
562 if ((status
& RS_VALID
) == 0) {
564 printk("recv buf out of sync: recv_ptr=%x status=%x\n",
565 msp
->recv_ptr
, status
);
566 printk(" rpr=%x swpr=%x, buf[rpr]=%x\n", mac
->rpr
, mac
->swpr
,
567 buffer_mem
[mac
->rpr
]);
568 msp
->recv_ptr
= mac
->swpr
;
572 if (mac
->rpr
== orig_recv_ptr
)
573 mac
->rpr
= msp
->recv_ptr
;
576 if (status
& RS_ABORTED
)
579 bb
= (status
>> RS_BYTE_BDRY_LG
) & 3;
584 if ((status
& RS_ERROR
) == 0)
587 msp
->recv_ptr
+= NWORDS((status
& RS_LENGTH
) + bb
);
589 if (++msp
->recv_ptr
>= RECV_BUF_END
)
590 msp
->recv_ptr
-= RECV_BUF_SIZE
;
593 if (mac
->rpr
== orig_recv_ptr
)
594 mac
->rpr
= msp
->recv_ptr
;
596 sp
->fr_start
= msp
->recv_ptr
;
597 sp
->length
= (status
& RS_LENGTH
) + bb
; /* + 4 (status) - 4 (FCS) */
598 sp
->ptr
= (void *) &buffer_mem
[sp
->fr_start
];
599 if ((msp
->recv_ptr
+= NWORDS(sp
->length
) + 1) >= RECV_BUF_END
)
600 msp
->recv_ptr
-= RECV_BUF_SIZE
;
601 sp
->fr_end
= msp
->recv_ptr
;
602 sp
->wraplen
= (RECV_BUF_END
- sp
->fr_start
) * 4;
603 sp
->wrapptr
= (void *) &buffer_mem
[RECV_BUF_START
];
609 mac_discard_frame(sp
)
612 mac
->rpr
= sp
->fr_end
;
616 * Return the number of bytes free in the async 0 transmit queue.
621 struct formac_state
*msp
= &this_mac_state
;
624 if (msp
->xmit_free
> msp
->xmit_start
) {
625 nw
= XMIT_BUF_END
- msp
->xmit_free
;
626 if (nw
< msp
->xmit_start
- XMIT_BUF_START
)
627 nw
= msp
->xmit_start
- XMIT_BUF_START
;
629 nw
= msp
->xmit_start
- msp
->xmit_free
;
630 return nw
<= 2? 0: (nw
- 2) << 2;
634 * Return the number of bytes of frames available in the receive queue.
641 nw
= mac
->swpr
- mac
->rpr
;
643 nw
+= mac
->earv
- mac
->eacb
;
648 * Return 1 iff all transmission has been completed, 0 otherwise.
650 int mac_xmit_done(void)
652 struct formac_state
*msp
= &this_mac_state
;
654 return msp
->xmit_chains
== 0;
658 * Append skbuff packet to queue.
660 int mac_queue_append (struct sk_buff
*skb
)
662 struct mac_queue
*el
;
664 save_flags(flags
); cli();
667 printk("Appending queue element skb 0x%x\n", skb
);
670 if ((el
= (struct mac_queue
*)kmalloc(sizeof(*el
), GFP_ATOMIC
)) == NULL
) {
671 restore_flags(flags
);
677 if (mac_queue_top
== NULL
) {
678 mac_queue_top
= mac_queue_bottom
= el
;
681 mac_queue_bottom
->next
= el
;
682 mac_queue_bottom
= el
;
684 restore_flags(flags
);
689 * If the packet originated from the same FDDI subnet as we are on,
690 * there is no need to perform checksumming as FDDI will does this
693 #define CHECK_IF_CHECKSUM_REQUIRED(skb) \
694 if ((skb)->protocol == ETH_P_IP) { \
695 extern struct cap_init cap_init; \
696 int *from_ip = (int *)((skb)->data+12); \
697 int *to_ip = (int *)((skb)->data+16); \
698 if ((*from_ip & cap_init.netmask) == (*to_ip & cap_init.netmask)) \
699 (skb)->ip_summed = CHECKSUM_UNNECESSARY; \
703 * Try to send and/or recv frames.
705 void mac_process(void)
707 volatile struct dma_chan
*dma
= (volatile struct dma_chan
*) DMA3
;
708 struct formac_state
*msp
= &this_mac_state
;
709 struct mac_queue
*el
;
710 int nw
=0, mrl
= 0, fstart
, send_buffer_full
= 0;
713 save_flags(flags
); cli();
716 printk("In mac_process()\n");
720 * Check if the DMA is being used.
722 if (msp
->dma_state
!= IDLE
) {
723 restore_flags(flags
);
727 while (mac_queue_top
!= NULL
|| /* Something to transmit */
728 (mrl
= mac_recv_level()) > 0) { /* Frames in receive buffer */
729 send_buffer_full
= 0;
731 printk("mac_process(): something to do... mqt %x mrl is %d\n",
734 if (mac_queue_top
!= NULL
&& mrl
< RECV_THRESHOLD
) {
735 el
= (struct mac_queue
*)mac_queue_top
;
738 * Check there is enough space in the FDDI send buffer.
740 if (mac_xmit_space() < el
->skb
->len
) {
742 printk("process_queue(): FDDI send buffer is full\n");
744 send_buffer_full
= 1;
748 printk("mac_process(): sending a frame\n");
751 * Update mac_queue_top.
753 mac_queue_top
= mac_queue_top
->next
;
756 * Allocate space in the FDDI send buffer.
758 msp
->cur_mbuf
.length
= el
->skb
->len
-3;
759 mac_xmit_alloc((struct mac_buf
*)&msp
->cur_mbuf
, 3);
762 * If message size is greater than DMA_XMIT_THRESHOLD, send
763 * using DMA, otherwise use memcpy().
765 if (el
->skb
->len
> DMA_XMIT_THRESHOLD
) {
770 printk("mac_process(): Starting send DMA...\n");
772 nw
= msp
->cur_mbuf
.fr_end
- msp
->cur_mbuf
.fr_start
+ 1;
773 mac
->wpxa0
= msp
->cur_mbuf
.fr_start
+ 1;
775 *csr0
|= CS0_HREQ_WA0
;
778 msp
->dma_state
= XMITTING
;
779 dma
->st
= DMA_DMST_RST
;
780 dma
->st
= DMA_RESET_MASKS
;
781 dma
->hskip
= 1; /* skip = 0, count = 1 */
782 dma
->vskip
= 1; /* skip = 0, count = 1 */
783 dma
->maddr
= (u_char
*)
784 mmu_v2p((unsigned long)el
->skb
->data
);
785 dma
->cmd
= DMA_DCMD_ST
+ DMA_DCMD_TYP_AUTO
+
787 *csr0
&= ~CS0_DMA_RECV
;
788 *csr0
|= CS0_DMA_ENABLE
;
791 * Don't process any more packets since the DMA is
796 else { /* el->skb->len <= DMA_XMIT_THRESHOLD */
798 * Copy the data directly into the FDDI buffer.
801 printk("mac_proces(): Copying send data...\n");
803 memcpy(msp
->cur_mbuf
.ptr
- 3, el
->skb
->data
,
804 ROUND4(el
->skb
->len
));
805 mac_queue_frame((struct mac_buf
*)&msp
->cur_mbuf
);
806 dev_kfree_skb(el
->skb
);
807 kfree_s(el
, sizeof(*el
));
813 * We have reached here if there is not enough space in the
814 * send buffer. Try to receive some packets instead.
818 if (mac_recv_frame((struct mac_buf
*)&msp
->cur_mbuf
)) {
819 volatile int fc
, llc_header_word2
;
823 printk("mac_process(): Receiving frames...\n");
826 * Get the fc, note only word accesses are allowed from the
829 if (msp
->cur_mbuf
.wraplen
> 4) {
830 fc
= *(int *)(msp
->cur_mbuf
.ptr
+4);
834 * fc_word must be at the start of the FDDI buffer.
837 printk("Grabbed fc_word from wrapptr, wraplen %d\n",
838 msp
->cur_mbuf
.wraplen
);
840 fc
= *(int *)msp
->cur_mbuf
.wrapptr
;
845 printk("fc is 0x%x\n", fc
);
847 if (fc
< 0x50 || fc
> 0x57) {
848 mac_discard_frame((struct mac_buf
*)&msp
->cur_mbuf
);
853 * Determine the size of the packet data and allocate a socket
856 pkt_len
= msp
->cur_mbuf
.length
- FDDI_HARDHDR_LEN
;
858 printk("Packet of length %d\n", pkt_len
);
860 msp
->cur_skb
= dev_alloc_skb(ROUND4(pkt_len
));
862 if (msp
->cur_skb
== NULL
) {
863 printk("mac_process(): Memory squeeze, dropping packet.\n");
864 apfddi_stats
->rx_dropped
++;
865 restore_flags(flags
);
868 msp
->cur_skb
->dev
= apfddi_device
;
871 * Hardware header isn't copied to skbuff.
873 msp
->cur_skb
->mac
.raw
= msp
->cur_skb
->data
;
874 apfddi_stats
->rx_packets
++;
877 * Determine protocol from llc header.
879 if (msp
->cur_mbuf
.wraplen
< FDDI_HARDHDR_LEN
) {
880 llc_header_word2
= *(int *)(msp
->cur_mbuf
.wrapptr
+
882 msp
->cur_mbuf
.wraplen
- 4));
885 llc_header_word2
= *(int *)(msp
->cur_mbuf
.ptr
+
886 FDDI_HARDHDR_LEN
- 4);
888 msp
->cur_skb
->protocol
= llc_header_word2
& 0xFFFF;
890 printk("Got protocol 0x%x\n", msp
->cur_skb
->protocol
);
894 * Copy data into socket buffer, which may be wrapped around the
895 * FDDI buffer. Use memcpy if the size of the data is less
896 * than DMA_RECV_THRESHOLD. Note if DMA is used, then wrap-
897 * arounds are handled automatically.
899 if (pkt_len
< DMA_RECV_THRESHOLD
) {
900 if (msp
->cur_mbuf
.length
< msp
->cur_mbuf
.wraplen
) {
901 memcpy(skb_put(msp
->cur_skb
, ROUND4(pkt_len
)),
902 msp
->cur_mbuf
.ptr
+ FDDI_HARDHDR_LEN
,
905 else if (msp
->cur_mbuf
.wraplen
< FDDI_HARDHDR_LEN
) {
907 printk("Wrap case 2\n");
909 memcpy(skb_put(msp
->cur_skb
, ROUND4(pkt_len
)),
910 msp
->cur_mbuf
.wrapptr
+
911 (FDDI_HARDHDR_LEN
- msp
->cur_mbuf
.wraplen
),
916 printk("wrap case 3\n");
918 memcpy(skb_put(msp
->cur_skb
,
919 ROUND4(msp
->cur_mbuf
.wraplen
-
921 msp
->cur_mbuf
.ptr
+ FDDI_HARDHDR_LEN
,
922 ROUND4(msp
->cur_mbuf
.wraplen
- FDDI_HARDHDR_LEN
));
923 memcpy(skb_put(msp
->cur_skb
,
924 ROUND4(msp
->cur_mbuf
.length
-
925 msp
->cur_mbuf
.wraplen
)),
926 msp
->cur_mbuf
.wrapptr
,
927 ROUND4(msp
->cur_mbuf
.length
-
928 msp
->cur_mbuf
.wraplen
));
932 if (msp
->cur_skb
->protocol
== ETH_P_IP
) {
933 dump_packet("apfddi_rx:", msp
->cur_skb
->data
, pkt_len
, 0);
935 else if (msp
->cur_skb
->protocol
== ETH_P_ARP
) {
936 struct arphdr
*arp
= (struct arphdr
*)msp
->cur_skb
->data
;
937 printk("arp->ar_op is 0x%x ar_hrd %d ar_pro 0x%x ar_hln %d ar_ln %d\n",
938 arp
->ar_op
, arp
->ar_hrd
, arp
->ar_pro
, arp
->ar_hln
,
940 printk("sender hardware address: %x:%x:%x:%x:%x:%x\n",
941 *((u_char
*)msp
->cur_skb
->data
+8),
942 *((u_char
*)msp
->cur_skb
->data
+9),
943 *((u_char
*)msp
->cur_skb
->data
+10),
944 *((u_char
*)msp
->cur_skb
->data
+11),
945 *((u_char
*)msp
->cur_skb
->data
+12),
946 *((u_char
*)msp
->cur_skb
->data
+13));
947 printk("sender IP number %d.%d.%d.%d\n",
948 *((u_char
*)msp
->cur_skb
->data
+14),
949 *((u_char
*)msp
->cur_skb
->data
+15),
950 *((u_char
*)msp
->cur_skb
->data
+16),
951 *((u_char
*)msp
->cur_skb
->data
+17));
952 printk("receiver hardware address: %x:%x:%x:%x:%x:%x\n",
953 *((u_char
*)msp
->cur_skb
->data
+18),
954 *((u_char
*)msp
->cur_skb
->data
+19),
955 *((u_char
*)msp
->cur_skb
->data
+20),
956 *((u_char
*)msp
->cur_skb
->data
+21),
957 *((u_char
*)msp
->cur_skb
->data
+22),
958 *((u_char
*)msp
->cur_skb
->data
+23));
959 printk("receiver IP number %d.%d.%d.%d\n",
960 *((u_char
*)msp
->cur_skb
->data
+24),
961 *((u_char
*)msp
->cur_skb
->data
+25),
962 *((u_char
*)msp
->cur_skb
->data
+26),
963 *((u_char
*)msp
->cur_skb
->data
+27));
966 CHECK_IF_CHECKSUM_REQUIRED(msp
->cur_skb
);
969 * Inform the network layer of the new packet.
972 printk("Calling netif_rx()\n");
974 netif_rx(msp
->cur_skb
);
977 * Remove frame from FDDI buffer.
979 mac_discard_frame((struct mac_buf
*)&msp
->cur_mbuf
);
984 * Set up dma and break.
987 printk("mac_process(): Starting receive DMA...\n");
989 nw
= NWORDS(pkt_len
);
990 msp
->dma_state
= RECVING
;
991 *csr0
&= ~(CS0_HREQ
| CS0_DMA_ENABLE
);
992 /* *csr1 |= CS1_RESET_FIFO;
993 *csr1 &= ~CS1_RESET_FIFO; */
994 if ((*csr1
& CS1_FIFO_LEVEL
) != 0) {
996 printk("fifo not empty! (csr1 = 0x%x) emptying...", *csr1
);
999 } while ((*csr1
& CS1_FIFO_LEVEL
) != 0);
1002 fstart
= msp
->cur_mbuf
.fr_start
+ NWORDS(FDDI_HARDHDR_LEN
);
1003 if (fstart
>= RECV_BUF_END
)
1004 fstart
-= RECV_BUF_SIZE
;
1007 printk("rpr=0x%x, nw=0x%x, stat=0x%x\n",
1008 mac
->rpr
, nw
, buffer_mem
[msp
->cur_mbuf
.fr_start
]);
1010 dma
->st
= DMA_DMST_RST
;
1011 dma
->st
= DMA_RESET_MASKS
;
1012 dma
->hskip
= 1; /* skip = 0, count = 1 */
1013 dma
->vskip
= 1; /* skip = 0, count = 1 */
1014 dma
->maddr
= (u_char
*)
1015 mmu_v2p((unsigned long)
1016 skb_put(msp
->cur_skb
, ROUND4(pkt_len
)));
1017 dma
->cmd
= DMA_DCMD_ST
+ DMA_DCMD_TYP_AUTO
+ DMA_DCMD_TD_DM
1019 *csr0
|= CS0_HREQ_RECV
| CS0_DMA_RECV
;
1020 *csr0
|= CS0_DMA_ENABLE
;
1022 printk("mac_process(): DMA is away!\n");
1029 printk("mac_recv_frame failed\n");
1031 if (msp
->recv_empty
&& send_buffer_full
)
1036 * Update mac_queue_bottom.
1038 if (mac_queue_top
== NULL
)
1039 mac_queue_bottom
= NULL
;
1042 printk("End of mac_process()\n");
1044 restore_flags(flags
);
1048 #define DMA_IN(reg) (*(volatile unsigned *)(reg))
1049 #define DMA_OUT(reg,v) (*(volatile unsigned *)(reg) = (v))
1052 * DMA completion handler.
1054 void mac_dma_complete(void)
1056 volatile struct dma_chan
*dma
;
1057 struct formac_state
*msp
= &this_mac_state
;
1060 a
= DMA_IN(DMA3_DMST
);
1061 if (!(a
& DMA_INTR_REQS
)) {
1062 if (msp
->dma_state
!= IDLE
&& (a
& DMA_DMST_AC
) == 0) {
1063 printk("dma completed but no interrupt!\n");
1064 msp
->dma_state
= IDLE
;
1069 DMA_OUT(DMA3_DMST
,AP_CLR_INTR_REQ
<<DMA_INTR_NORMAL_SH
);
1070 DMA_OUT(DMA3_DMST
,AP_CLR_INTR_REQ
<<DMA_INTR_ERROR_SH
);
1072 dma
= (volatile struct dma_chan
*) DMA3
;
1075 printk("In mac_dma_complete\n");
1078 if (msp
->dma_state
== XMITTING
&& ((dma
->st
& DMA_DMST_AC
) == 0)) {
1080 * Transmit DMA finished.
1084 printk("In mac_dma_complete for transmit complete\n");
1086 while (*csr1
& CS1_FIFO_LEVEL
) {
1088 printk("csr0=0x%x csr1=0x%x: fifo not emptying\n", *csr0
,
1093 *csr0
&= ~(CS0_HREQ
| CS0_DMA_ENABLE
);
1094 msp
->dma_state
= IDLE
;
1096 printk("mac_dma_complete(): Calling mac_queue_frame\n");
1098 mac_queue_frame((struct mac_buf
*)&msp
->cur_mbuf
);
1099 dev_kfree_skb(msp
->cur_macq
->skb
);
1100 kfree_s((struct mac_buf
*)msp
->cur_macq
, sizeof(*(msp
->cur_macq
)));
1101 msp
->cur_macq
= NULL
;
1103 printk("mac_dma_complete(): Calling mac_process()\n");
1107 printk("End of mac_dma_complete transmitting\n");
1110 else if (msp
->dma_state
== RECVING
&& ((dma
->st
& DMA_DMST_AC
) == 0)) {
1112 * Receive DMA finished. Copy the last four words from the
1113 * fifo into the buffer, after turning off the host requests.
1114 * We do this to avoid reading past the end of frame.
1119 printk("In mac_dma_complete for receive complete\n");
1121 msp
->dma_state
= IDLE
;
1122 ip
= (int *)mmu_p2v((unsigned long)dma
->cmaddr
);
1125 printk("ip is 0x%x, skb->data is 0x%x\n", ip
, msp
->cur_skb
->data
);
1128 *csr0
&= ~(CS0_DMA_ENABLE
| CS0_HREQ
);
1130 for (i
= 0; (*csr1
& CS1_FIFO_LEVEL
); ++i
)
1133 printk("mac_dma_complete(): not four words remaining in fifo?\n");
1135 printk("Copied last four words out of fifo\n");
1139 * Remove the frame from the FDDI receive buffer.
1141 mac_discard_frame((struct mac_buf
*)&msp
->cur_mbuf
);
1143 CHECK_IF_CHECKSUM_REQUIRED(msp
->cur_skb
);
1146 * Now inject the packet into the network system.
1148 netif_rx(msp
->cur_skb
);
1151 dump_packet("mac_dma_complete:", msp
->cur_skb
->data
, 0, 0);
1155 * Check if any more frames can be processed.
1160 printk("End of mac_dma_complete receiving\n");
1164 printk("End of mac_dma_complete()\n");
1168 static void mac_print_state(void)
1170 struct formac_state
*msp
= &this_mac_state
;
1172 printk("DMA3_DMST is 0x%x dma_state is %d\n", DMA_IN(DMA3_DMST
),
1174 printk("csr0 = 0x%x, csr1 = 0x%x\n", *csr0
, *csr1
);