/* if_en.c 4.12 81/11/23 */
* Ethernet interface driver
#include "../net/inet_pcb.h"
#include "../net/inet_systm.h"
#include "../net/ip_var.h"
#include "../net/tcp.h" /* XXX */
#include "../net/tcp_var.h"
int enprobe(), enattach(), enrint(), enxint(), encollide();
struct uba_device
*eninfo
[NEN
];
struct uba_driver endriver
=
{ enprobe
, 0, enattach
, 0, enstd
, "en", eninfo
};
#define ENUNIT(x) minor(x)
struct en_packet
*xpkt
, *rpkt
;
struct pte
*enrmr
, *enxmr
;
register struct endevice
*addr
= (struct endevice
*)reg
;
br
= 0; cvec
= br
; br
= cvec
;
enrint(0); enxint(0); encollide(0);
addr
->en_ostat
= EN_IEN
|EN_GO
;
printf("ethernet address %d\n", ~addr
->en_addr
&0xff);
extern struct ifnet ifen
;
ifen
.if_addr
.s_host
= LOCALHST
;
ifen
.if_addr
.s_net
= LOCALNET
;
ifen
.if_addr
.s_imp
= LOCALIMP
;
register struct endevice
*addr
;
register struct uba_device
*ui
;
if (unit
>= NEN
|| (ui
= eninfo
[unit
]) == 0 || ui
->ui_alive
== 0) {
printf("en%d: not alive\n", unit
);
int n
, j
, i
, k
; char *cp
;
if (memall(&Mbmap
[j
], k
, proc
, CSYS
) == 0)
vmaccess(&Mbmap
[j
], (caddr_t
)cp
, k
);
rpkt
= (struct en_packet
*)
(cp
+ 1024 - sizeof (struct en_prefix
));
xpkt
= (struct en_packet
*)
(cp
+ 5 * 1024 + 1024 - sizeof (struct en_prefix
));
addr
= (struct endevice
*)ui
->ui_addr
;
uballoc(uban
, (caddr_t
)rpkt
, 1024+512, UBA_NEED16
|UBA_NEEDBDP
);
uballoc(uban
, (caddr_t
)xpkt
, 1024+512, UBA_NEED16
|UBA_NEEDBDP
);
enuba
= ui
->ui_hd
->uh_uba
;
enrbdp
= (imp_stat
.iaddr
>> 28) & 0xf;
enwbdp
= (imp_stat
.oaddr
>> 28) & 0xf;
enrproto
= UBAMR_MRV
| (enrbdp
<< 21);
enwproto
= UBAMR_MRV
| (enwbdp
<< 21);
enrmr
= &enuba
->uba_map
[((imp_stat
.iaddr
>>9)&0x1ff) + 1];
enxmr
= &enuba
->uba_map
[((imp_stat
.oaddr
>>9)&0x1ff) + 1];
printf("enrbdp %x enrproto %x enrmr %x imp_stat.iaddr %x\n",
enrbdp
, enrproto
, enrmr
, imp_stat
.iaddr
);
printf("eninit(%d): iaddr = %x, oaddr = %x\n",
unit
, imp_stat
.iaddr
, imp_stat
.oaddr
);
for (unit
= 0; unit
< NEN
; unit
++) {
if (ui
== 0 || ui
->ui_ubanum
!= uban
|| ui
->ui_alive
== 0)
ubarelse(uban
, &imp_stat
.iaddr
);
ubarelse(uban
, &imp_stat
.oaddr
);
register struct mbuf
*m
, *mp
;
register struct endevice
*addr
;
register caddr_t cp
, top
;
if (ui
== 0 || ui
->ui_alive
== 0) {
printf("en%d (imp_output): not alive\n", unit
);
addr
= (struct endevice
*)ui
->ui_addr
;
if (!imp_stat
.outactive
) {
if ((m
= imp_stat
.outq_head
) == NULL
)
imp_stat
.outactive
= 1; /* set myself active */
imp_stat
.outq_head
= m
->m_act
; /* -> next packet chain */
* Pack mbufs into ethernet packet.
top
= (caddr_t
)xpkt
+ sizeof(struct en_packet
);
if (cp
+ m
->m_len
> top
) {
printf("imp_snd: my packet runneth over\n");
if (((int)cp
&0x3ff)==0 && ((int)dp
&0x3ff)==0) {
struct pte
*pte
= &Mbmap
[mtopf(dp
)*2];
*(int *)enxmr
= enwproto
| pte
++->pg_pfnum
;
*(int *)(enxmr
+1) = enwproto
| pte
->pg_pfnum
;
enxswapd
= enxswapnow
= 1;
bcopy(mtod(m
, caddr_t
), cp
,
if (enxswapnow
== 0 && enxswapd
) {
if (enlastx
&& enlastx
== xpkt
->Header
.en_dhost
)
imp_stat
.endelay
= enlastdel
;
enlastx
= xpkt
->Header
.en_dhost
;
len
= ntohs((u_short
)(((struct ip
*)((int)xpkt
+ L1822
))->ip_len
)) +
if (len
> sizeof(struct en_packet
)) {
printf("imp_output: ridiculous IP length %d\n", len
);
#if defined(VAX780) || defined(VAX750)
UBA_PURGE780(enuba
, enwbdp
);
UBA_PURGE750(enuba
, enwbdp
);
addr
->en_oba
= imp_stat
.oaddr
;
addr
->en_odelay
= imp_stat
.endelay
;
addr
->en_owc
= -((len
+ 1) >> 1);
printf("en%d: sending packet (%d bytes)\n", unit
, len
);
addr
->en_ostat
= EN_IEN
|EN_GO
;
* Output interrupt handler.
register struct endevice
*addr
;
register struct uba_device
*ui
;
addr
= (struct endevice
*)ui
->ui_addr
;
printf("en%d: enxint ostat=%b\n", unit
, addr
->en_ostat
, EN_BITS
);
if (!imp_stat
.outactive
) {
printf("en%d: phantom output intr ostat=%b\n",
unit
, addr
->en_ostat
, EN_BITS
);
if (addr
->en_ostat
&EN_OERROR
)
printf("en%d: output error ostat=%b\n", unit
,
addr
->en_ostat
, EN_BITS
);
register struct endevice
*addr
;
register struct uba_device
*ui
;
addr
= (struct endevice
*)ui
->ui_addr
;
printf("en%d: collision ostat=%b\n", unit
, addr
->en_ostat
, EN_BITS
);
if (!imp_stat
.outactive
) {
printf("en%d: phantom collision intr ostat=%b\n",
unit
, addr
->en_ostat
, EN_BITS
);
if (imp_stat
.enmask
== 0) {
printf("en%d: output error ostat=%b\n", unit
,
addr
->en_ostat
, EN_BITS
);
imp_stat
.endelay
= mfpr(ICR
) & ~imp_stat
.enmask
;
register struct endevice
*addr
;
register struct uba_device
*ui
;
struct mbuf
*p
, *top
= 0;
addr
= (struct endevice
*)ui
->ui_addr
;
printf("en%d: enrint istat=%b\n", unit
, addr
->en_istat
, EN_BITS
);
if (addr
->en_istat
&EN_IERROR
) {
printf("en%d: input error istat=%b\n", unit
,
addr
->en_istat
, EN_BITS
);
#if defined(VAX780) || defined(VAX750)
UBA_PURGE780(enuba
, enrbdp
);
UBA_PURGE750(enuba
, enrbdp
);
ip
= (struct ip
*)((int)rpkt
+ L1822
);
len
= ntohs((u_short
*)ip
->ip_len
) + L1822
;
if (len
> sizeof(struct en_packet
) || len
< sizeof (struct ip
)) {
printf("enrint: bad ip length %d\n", len
);
hlen
= L1822
+ sizeof (struct ip
);
hlen
+= ((struct tcpiphdr
*)ip
)->ti_off
<< 2;
bcopy((caddr_t
)rpkt
, mtod(m
, caddr_t
), hlen
);
cp
= (caddr_t
)rpkt
+ hlen
;
m
->m_off
= (int)p
- (int)m
;
if (((int)cp
& 0x3ff) == 0) {
struct pte
*cpte
= &Mbmap
[mtopf(cp
)*2];
struct pte
*ppte
= &Mbmap
[mtopf(p
)*2];
t
= *ppte
; *ppte
++ = *cpte
; *cpte
++ = t
;
t
= *ppte
; *ppte
= *cpte
; *cpte
= t
;
mtpr(TBIS
, (caddr_t
)cp
+512);
mtpr(TBIS
, (caddr_t
)p
+512);
cpte
[0].pg_pfnum
| enrproto
;
cpte
[-1].pg_pfnum
| enrproto
;
m
->m_len
= MIN(MLEN
, len
);
bcopy(cp
, mtod(m
, caddr_t
), (unsigned)m
->m_len
);
if (imp_stat
.inq_head
!= NULL
)
imp_stat
.inq_tail
->m_act
= m
;
printf("en%d: received packet (%d bytes)\n", unit
, len
);
printf("en%d: flushing packet %x\n", unit
, top
);
addr
->en_iba
= imp_stat
.iaddr
;
addr
->en_istat
= EN_IEN
|EN_GO
;
putchar("0123456789abcdef"[(c
>>((1-j
)*4))&0xf]);