/* if_en.c 4.14 81/11/26 */
* Ethernet interface driver
#include "../h/protosw.h"
#include "../net/in_systm.h"
#include "../net/if_en.h"
#include "../net/if_uba.h"
#include "../net/ip_var.h"
int enprobe(), enattach(), enrint(), enxint(), encollide();
struct uba_device
*eninfo
[NEN
];
struct uba_driver endriver
=
{ enprobe
, 0, enattach
, 0, enstd
, "es", eninfo
};
#define ENUNIT(x) minor(x)
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
;
/* net initialization, based on ui->ui_flags?!? */
register struct uba_device
*ui
;
register struct endevice
*addr
;
register struct en_softc
*es
;
if (unit
>= NEN
|| (ui
= eninfo
[unit
]) == 0 || ui
->ui_alive
== 0) {
printf("es%d: not alive\n", unit
);
if (if_ubainit(es
->es_ifuba
, ui
->ui_ubanum
,
sizeof (struct en_header
), btop(ENMTU
)) == 0) {
printf("es%d: can't initialize\n", unit
);
addr
= (struct endevice
*)ui
->ui_addr
;
addr
->en_istat
= addr
->en_ostat
= 0;
for (unit
= 0; unit
< NEN
; unit
++) {
if (ui
== 0 || ui
->ui_ubanum
!= uban
|| ui
->ui_alive
== 0)
register struct endevice
*addr
;
register struct en_softc
*es
;
register struct ifuba
*ifu
;
IF_DEQUEUE(&es
->es_if
->if_snd
, m
);
dest
= mtod(m
, struct en_header
*)->en_dhost
;
es
->es_olen
= if_wubaput(&es
->es_ifuba
, m
);
if (es
->es_lastx
&& es
->es_lastx
== dest
)
es
->es_delay
= enlastdel
;
UBAPURGE(ifu
->ifu_uba
, ifu
->ifu_w
.ifrw_bdp
);
addr
= (struct endevice
*)ui
->ui_addr
;
addr
->en_oba
= (int)ifu
->ifu_w
.ifrw_addr
;
addr
->en_odelay
= es
->es_delay
;
addr
->en_owc
= -((es
->es_olen
+ 1) >> 1);
addr
->en_ostat
= EN_IEN
|EN_GO
;
register struct endevice
*addr
;
register struct uba_device
*ui
;
register struct en_softc
*es
;
addr
= (struct endevice
*)ui
->ui_addr
;
if (addr
->en_ostat
&EN_OERROR
)
printf("es%d: output error\n", unit
);
if (es
->es_if
->if_snd
.ifq_head
== 0) {
register struct en_softc
*es
;
es
->es_if
->if_collisions
++;
printf("es%d: send error\n", unit
);
es
->es_delay
= mfpr(ICR
) &~ es
->es_mask
;
register struct en_softc
*es
;
register struct ifuba
*ifu
;
addr
= (struct endevice
*)eninfo
[unit
]->ui_addr
;
if (addr
->en_istat
&EN_IERROR
) {
printf("es%d: input error\n", unit
);
ifu
= en_softc
[unit
].es_ifuba
;
UBAPURGE(ifu
->ifu_uba
, ifu
->ifu_r
.ifrw_bdp
);
en
= (struct en_header
*)(ifu
->ifu_r
.ifrw_addr
);
#define endataaddr(en, off, type) ((type)(((caddr_t)((en)+1)+(off))))
if (en
->en_type
>= ENPUP_TRAIL
&&
en
->en_type
< ENPUP_TRAIL
+ENPUP_NTRAILER
) {
off
= (en
->en_type
- ENPUP_TRAIL
) * 512;
en
->en_type
= *endataaddr(en
, off
, u_short
*);
len
= endataaddr(en
, off
, struct ip
*)->ip_len
;
printf("en%d: unknow pkt type 0x%x\n", en
->en_type
);
m
= if_rubaget(&ifu
->ifu_r
, len
, off
);
addr
->en_iba
= es
->es_ifuba
->ifu_r
.ifrw_info
;
addr
->en_iwc
= -(sizeof (struct en_header
) + ENMTU
) >> 1;
addr
->en_istat
= EN_IEN
|EN_GO
;
* Ethernet output routine.
* Encapsulate a packet of type family for the local net.
register struct en_header
*en
;
register struct ip
*ip
= mtod(m0
, struct ip
*);
off
= ip
->ip_len
- (ip
->ip_hl
<< 2);
if (off
&& off
% 512 == 0 && m0
->m_off
>= MMINOFF
+ 2) {
type
= ENPUP_TRAIL
+ (off
>>9);
*mtod(m0
, u_short
*) = ENPUP_IPTYPE
;
dest
= ip
->ip_dst
.s_addr
>> 24;
printf("en%d: can't encapsulate pf%d\n", ifp
->if_unit
, pf
);
if (MMINOFF
+ sizeof (struct en_header
) > m0
->m_off
) {
m
->m_len
= sizeof (struct en_header
);
m
->m_off
-= sizeof (struct en_header
);
m
->m_len
+= sizeof (struct en_header
);
en
= mtod(m
, struct en_header
*);
en
->en_shost
= ifp
->if_host
[0];
IF_ENQUEUE(&ifp
->if_snd
, m
);
if (en_softc
[ifp
->if_unit
].es_oactive
== 0)