1 |
|
/* |
2 |
|
* ether.cpp - SheepShaver Ethernet Device Driver (DLPI) |
3 |
|
* |
4 |
< |
* SheepShaver (C) 1997-2004 Marc Hellwig and Christian Bauer |
4 |
> |
* SheepShaver (C) 1997-2005 Marc Hellwig and Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
27 |
|
#include <string.h> |
28 |
|
|
29 |
|
#include "sysdeps.h" |
30 |
+ |
#include "cpu_emulation.h" |
31 |
|
#include "ether.h" |
32 |
|
#include "ether_defs.h" |
33 |
|
#include "macos_util.h" |
33 |
– |
#include "cpu_emulation.h" |
34 |
|
#include "emul_op.h" |
35 |
|
#include "main.h" |
36 |
|
|
37 |
|
#define DEBUG 0 |
38 |
|
#include "debug.h" |
39 |
|
|
40 |
+ |
#if DIRECT_ADDRESSING |
41 |
+ |
#warning "This code is not direct addressing clean" |
42 |
+ |
#endif |
43 |
|
|
44 |
|
// Packet types |
45 |
|
enum { |
61 |
|
static const int kGSmask = 0x1F; |
62 |
|
|
63 |
|
struct multicast_node { |
64 |
< |
multicast_node *next; |
64 |
> |
nw_multicast_node_p next; |
65 |
|
uint8 addr[kEnetPhysicalAddressLength]; |
66 |
|
}; |
67 |
|
|
89 |
|
|
90 |
|
void AddMulticast(uint8 *addr) |
91 |
|
{ |
92 |
< |
multicast_node *n = new multicast_node; |
92 |
> |
multicast_node *n = (multicast_node *)Mac2HostAddr(Mac_sysalloc(sizeof(multicast_node))); |
93 |
|
memcpy(n->addr, addr, kEnetPhysicalAddressLength); |
94 |
|
n->next = multicast_list; |
95 |
|
multicast_list = n; |
109 |
|
while (q) { |
110 |
|
if (q->next == p) { |
111 |
|
q->next = p->next; |
112 |
< |
delete p; |
112 |
> |
Mac_sysfree(Host2MacAddr((uint8 *)p)); |
113 |
|
return; |
114 |
|
} |
115 |
|
q = q->next; |
127 |
|
return NULL; |
128 |
|
} |
129 |
|
|
130 |
< |
uint32 minor_num; // Minor device number of this stream |
131 |
< |
uint32 dlpi_state; // DLPI state of this stream |
132 |
< |
uint32 flags; // Flags |
133 |
< |
uint16 dlsap; // SAP bound to this stream |
134 |
< |
bool framing_8022; // Using 802.2 framing? This is only used to report the MAC type for DL_INFO_ACK and can be set with an ioctl() call |
135 |
< |
queue_t *rdq; // Read queue for this stream |
136 |
< |
uint32 group_sap[kGroupSAPMapSize]; // Map of bound group SAPs |
137 |
< |
uint8 snap[k8022SNAPLength]; // SNAP bound to this stream |
138 |
< |
multicast_node *multicast_list; // List of enabled multicast addresses |
130 |
> |
nw_uint32 minor_num; // Minor device number of this stream |
131 |
> |
nw_uint32 dlpi_state; // DLPI state of this stream |
132 |
> |
nw_uint32 flags; // Flags |
133 |
> |
nw_uint16 dlsap; // SAP bound to this stream |
134 |
> |
nw_bool framing_8022; // Using 802.2 framing? This is only used to report the MAC type for DL_INFO_ACK and can be set with an ioctl() call |
135 |
> |
nw_queue_p rdq; // Read queue for this stream |
136 |
> |
nw_uint32 group_sap[kGroupSAPMapSize]; // Map of bound group SAPs |
137 |
> |
uint8 snap[k8022SNAPLength]; // SNAP bound to this stream |
138 |
> |
nw_multicast_node_p multicast_list; // List of enabled multicast addresses |
139 |
> |
}; |
140 |
> |
|
141 |
> |
// Hack to make DLPIStream list initialization early to NULL (do we really need this?) |
142 |
> |
struct DLPIStreamInit { |
143 |
> |
DLPIStreamInit(nw_DLPIStream_p *dlpi_stream_p) { *dlpi_stream_p = NULL; } |
144 |
|
}; |
145 |
|
|
146 |
|
// Stream flags |
152 |
|
}; |
153 |
|
|
154 |
|
// List of opened streams (used internally by OpenTransport) |
155 |
< |
static DLPIStream *dlpi_stream_list = NULL; |
155 |
> |
static nw_DLPIStream_p dlpi_stream_list; |
156 |
> |
static DLPIStreamInit dlpi_stream_init(&dlpi_stream_list); |
157 |
|
|
158 |
|
// Are we open? |
159 |
|
bool ether_driver_opened = false; |
183 |
|
static uint32 allocb_tvect = 0; |
184 |
|
mblk_t *allocb(size_t arg1, int arg2) |
185 |
|
{ |
186 |
< |
return (mblk_t *)CallMacOS2(allocb_ptr, allocb_tvect, arg1, arg2); |
186 |
> |
return (mblk_t *)Mac2HostAddr(CallMacOS2(allocb_ptr, allocb_tvect, arg1, arg2)); |
187 |
|
} |
188 |
|
typedef void (*freeb_ptr)(mblk_t *); |
189 |
|
static uint32 freeb_tvect = 0; |
201 |
|
static uint32 copyb_tvect = 0; |
202 |
|
static inline mblk_t *copyb(mblk_t *arg1) |
203 |
|
{ |
204 |
< |
return (mblk_t *)CallMacOS1(copyb_ptr, copyb_tvect, arg1); |
204 |
> |
return (mblk_t *)Mac2HostAddr(CallMacOS1(copyb_ptr, copyb_tvect, arg1)); |
205 |
|
} |
206 |
|
typedef mblk_t *(*dupmsg_ptr)(mblk_t *); |
207 |
|
static uint32 dupmsg_tvect = 0; |
208 |
|
static inline mblk_t *dupmsg(mblk_t *arg1) |
209 |
|
{ |
210 |
< |
return (mblk_t *)CallMacOS1(dupmsg_ptr, dupmsg_tvect, arg1); |
210 |
> |
return (mblk_t *)Mac2HostAddr(CallMacOS1(dupmsg_ptr, dupmsg_tvect, arg1)); |
211 |
|
} |
212 |
|
typedef mblk_t *(*getq_ptr)(queue_t *); |
213 |
|
static uint32 getq_tvect = 0; |
214 |
|
static inline mblk_t *getq(queue_t *arg1) |
215 |
|
{ |
216 |
< |
return (mblk_t *)CallMacOS1(getq_ptr, getq_tvect, arg1); |
216 |
> |
return (mblk_t *)Mac2HostAddr(CallMacOS1(getq_ptr, getq_tvect, arg1)); |
217 |
|
} |
218 |
|
typedef int (*putq_ptr)(queue_t *, mblk_t *); |
219 |
|
static uint32 putq_tvect = 0; |
285 |
|
static uint32 mi_next_ptr_tvect = 0; |
286 |
|
static inline DLPIStream *mi_next_ptr(DLPIStream *arg1) |
287 |
|
{ |
288 |
< |
return (DLPIStream *)CallMacOS1(mi_next_ptr_ptr, mi_next_ptr_tvect, arg1); |
288 |
> |
return (DLPIStream *)Mac2HostAddr(CallMacOS1(mi_next_ptr_ptr, mi_next_ptr_tvect, arg1)); |
289 |
|
} |
290 |
|
|
291 |
|
|
321 |
|
ether_driver_opened = false; |
322 |
|
|
323 |
|
// Import functions from OTKernelLib |
324 |
< |
allocb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006allocb"); |
324 |
> |
allocb_tvect = FindLibSymbol("\013OTKernelLib", "\006allocb"); |
325 |
|
D(bug("allocb TVECT at %08lx\n", allocb_tvect)); |
326 |
|
if (allocb_tvect == 0) |
327 |
|
return false; |
328 |
< |
freeb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\005freeb"); |
328 |
> |
freeb_tvect = FindLibSymbol("\013OTKernelLib", "\005freeb"); |
329 |
|
D(bug("freeb TVECT at %08lx\n", freeb_tvect)); |
330 |
|
if (freeb_tvect == 0) |
331 |
|
return false; |
332 |
< |
freemsg_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\007freemsg"); |
332 |
> |
freemsg_tvect = FindLibSymbol("\013OTKernelLib", "\007freemsg"); |
333 |
|
D(bug("freemsg TVECT at %08lx\n", freemsg_tvect)); |
334 |
|
if (freemsg_tvect == 0) |
335 |
|
return false; |
336 |
< |
copyb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\005copyb"); |
336 |
> |
copyb_tvect = FindLibSymbol("\013OTKernelLib", "\005copyb"); |
337 |
|
D(bug("copyb TVECT at %08lx\n", copyb_tvect)); |
338 |
|
if (copyb_tvect == 0) |
339 |
|
return false; |
340 |
< |
dupmsg_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006dupmsg"); |
340 |
> |
dupmsg_tvect = FindLibSymbol("\013OTKernelLib", "\006dupmsg"); |
341 |
|
D(bug("dupmsg TVECT at %08lx\n", dupmsg_tvect)); |
342 |
|
if (dupmsg_tvect == 0) |
343 |
|
return false; |
344 |
< |
getq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\004getq"); |
344 |
> |
getq_tvect = FindLibSymbol("\013OTKernelLib", "\004getq"); |
345 |
|
D(bug("getq TVECT at %08lx\n", getq_tvect)); |
346 |
|
if (getq_tvect == 0) |
347 |
|
return false; |
348 |
< |
putq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\004putq"); |
348 |
> |
putq_tvect = FindLibSymbol("\013OTKernelLib", "\004putq"); |
349 |
|
D(bug("putq TVECT at %08lx\n", putq_tvect)); |
350 |
|
if (putq_tvect == 0) |
351 |
|
return false; |
352 |
< |
putnext_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\007putnext"); |
352 |
> |
putnext_tvect = FindLibSymbol("\013OTKernelLib", "\007putnext"); |
353 |
|
D(bug("putnext TVECT at %08lx\n", putnext_tvect)); |
354 |
|
if (putnext_tvect == 0) |
355 |
|
return false; |
356 |
< |
putnextctl1_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\013putnextctl1"); |
356 |
> |
putnextctl1_tvect = FindLibSymbol("\013OTKernelLib", "\013putnextctl1"); |
357 |
|
D(bug("putnextctl1 TVECT at %08lx\n", putnextctl1_tvect)); |
358 |
|
if (putnextctl1_tvect == 0) |
359 |
|
return false; |
360 |
< |
canputnext_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\012canputnext"); |
360 |
> |
canputnext_tvect = FindLibSymbol("\013OTKernelLib", "\012canputnext"); |
361 |
|
D(bug("canputnext TVECT at %08lx\n", canputnext_tvect)); |
362 |
|
if (canputnext_tvect == 0) |
363 |
|
return false; |
364 |
< |
qreply_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006qreply"); |
364 |
> |
qreply_tvect = FindLibSymbol("\013OTKernelLib", "\006qreply"); |
365 |
|
D(bug("qreply TVECT at %08lx\n", qreply_tvect)); |
366 |
|
if (qreply_tvect == 0) |
367 |
|
return false; |
368 |
< |
flushq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006flushq"); |
368 |
> |
flushq_tvect = FindLibSymbol("\013OTKernelLib", "\006flushq"); |
369 |
|
D(bug("flushq TVECT at %08lx\n", flushq_tvect)); |
370 |
|
if (flushq_tvect == 0) |
371 |
|
return false; |
372 |
< |
msgdsize_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\010msgdsize"); |
372 |
> |
msgdsize_tvect = FindLibSymbol("\013OTKernelLib", "\010msgdsize"); |
373 |
|
D(bug("msgdsize TVECT at %08lx\n", msgdsize_tvect)); |
374 |
|
if (msgdsize_tvect == 0) |
375 |
|
return false; |
376 |
< |
otenterint_tvect = (uint32)FindLibSymbol("\017OTKernelUtilLib", "\020OTEnterInterrupt"); |
376 |
> |
otenterint_tvect = FindLibSymbol("\017OTKernelUtilLib", "\020OTEnterInterrupt"); |
377 |
|
D(bug("OTEnterInterrupt TVECT at %08lx\n", otenterint_tvect)); |
378 |
|
if (otenterint_tvect == 0) |
379 |
|
return false; |
380 |
< |
otleaveint_tvect = (uint32)FindLibSymbol("\017OTKernelUtilLib", "\020OTLeaveInterrupt"); |
380 |
> |
otleaveint_tvect = FindLibSymbol("\017OTKernelUtilLib", "\020OTLeaveInterrupt"); |
381 |
|
D(bug("OTLeaveInterrupt TVECT at %08lx\n", otleaveint_tvect)); |
382 |
|
if (otleaveint_tvect == 0) |
383 |
|
return false; |
384 |
< |
mi_open_comm_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\014mi_open_comm"); |
384 |
> |
mi_open_comm_tvect = FindLibSymbol("\013OTKernelLib", "\014mi_open_comm"); |
385 |
|
D(bug("mi_open_comm TVECT at %08lx\n", mi_open_comm_tvect)); |
386 |
|
if (mi_open_comm_tvect == 0) |
387 |
|
return false; |
388 |
< |
mi_close_comm_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\015mi_close_comm"); |
388 |
> |
mi_close_comm_tvect = FindLibSymbol("\013OTKernelLib", "\015mi_close_comm"); |
389 |
|
D(bug("mi_close_comm TVECT at %08lx\n", mi_close_comm_tvect)); |
390 |
|
if (mi_close_comm_tvect == 0) |
391 |
|
return false; |
392 |
< |
mi_next_ptr_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\013mi_next_ptr"); |
392 |
> |
mi_next_ptr_tvect = FindLibSymbol("\013OTKernelLib", "\013mi_next_ptr"); |
393 |
|
D(bug("mi_next_ptr TVECT at %08lx\n", mi_next_ptr_tvect)); |
394 |
|
if (mi_next_ptr_tvect == 0) |
395 |
|
return false; |
398 |
|
dlpi_stream_list = NULL; |
399 |
|
|
400 |
|
// Ask add-on for ethernet hardware address |
401 |
< |
AO_get_ethernet_address(hardware_address); |
401 |
> |
AO_get_ethernet_address(Host2MacAddr(hardware_address)); |
402 |
|
|
403 |
|
// Yes, we're open |
404 |
|
ether_driver_opened = true; |
442 |
|
return 0; |
443 |
|
|
444 |
|
// Allocate DLPIStream structure |
445 |
< |
int err = mi_open_comm(&dlpi_stream_list, sizeof(DLPIStream), rdq, dev, flag, sflag, creds); |
445 |
> |
int err = mi_open_comm((DLPIStream **)&dlpi_stream_list, sizeof(DLPIStream), rdq, dev, flag, sflag, creds); |
446 |
|
if (err) |
447 |
|
return err; |
448 |
|
DLPIStream *the_stream = (DLPIStream *)rdq->q_ptr; |
479 |
|
|
480 |
|
// Disable all registered multicast addresses |
481 |
|
while (the_stream->multicast_list) { |
482 |
< |
AO_disable_multicast(the_stream->multicast_list->addr); |
482 |
> |
AO_disable_multicast(Host2MacAddr(the_stream->multicast_list->addr)); |
483 |
|
the_stream->RemoveMulticast(the_stream->multicast_list->addr); |
484 |
|
} |
485 |
|
the_stream->multicast_list = NULL; |
486 |
|
|
487 |
|
// Delete the DLPIStream |
488 |
< |
return mi_close_comm(&dlpi_stream_list, rdq); |
488 |
> |
return mi_close_comm((DLPIStream **)&dlpi_stream_list, rdq); |
489 |
|
} |
490 |
|
|
491 |
|
|
508 |
|
if (the_stream == NULL) |
509 |
|
return MAC_ENXIO; |
510 |
|
|
511 |
< |
D(bug(" db_type %d\n", mp->b_datap->db_type)); |
511 |
> |
D(bug(" db_type %d\n", (int)mp->b_datap->db_type)); |
512 |
|
switch (mp->b_datap->db_type) { |
513 |
|
|
514 |
|
case M_DATA: |
520 |
|
|
521 |
|
case M_PROTO: |
522 |
|
case M_PCPROTO: { |
523 |
< |
union DL_primitives *dlp = (union DL_primitives *)mp->b_rptr; |
523 |
> |
union DL_primitives *dlp = (union DL_primitives *)(void *)mp->b_rptr; |
524 |
|
uint32 prim = dlp->dl_primitive; |
525 |
|
D(bug(" dl_primitive %d\n", prim)); |
526 |
|
switch (prim) { |
614 |
|
|
615 |
|
static void ether_ioctl(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
616 |
|
{ |
617 |
< |
struct iocblk *ioc = (struct iocblk *)mp->b_rptr; |
618 |
< |
D(bug(" ether_ioctl(%p,%p) cmd %d\n", q, mp, ioc->ioc_cmd)); |
617 |
> |
struct iocblk *ioc = (struct iocblk *)(void *)mp->b_rptr; |
618 |
> |
D(bug(" ether_ioctl(%p,%p) cmd %d\n", q, mp, (int)ioc->ioc_cmd)); |
619 |
|
|
620 |
|
switch (ioc->ioc_cmd) { |
621 |
|
|
625 |
|
ioc->ioc_error = MAC_EINVAL; |
626 |
|
goto ioctl_error; |
627 |
|
} |
628 |
< |
uint32 framing_type = *(uint32 *)info_mp->b_rptr; |
628 |
> |
uint32 framing_type = ntohl(*(uint32 *)(void *)info_mp->b_rptr); |
629 |
|
D(bug(" I_OTSetFramingType type %d\n", framing_type)); |
630 |
|
if (framing_type != kOTGetFramingValue) |
631 |
|
the_stream->framing_8022 = (framing_type == kOTFraming8022); |
672 |
|
ioc->ioc_error = MAC_EINVAL; |
673 |
|
goto ioctl_error; |
674 |
|
} |
675 |
< |
dlrc = (dl_recv_control_t *)info_mp->b_rptr; |
676 |
< |
D(bug(" I_OTSetRawMode primitive %d\n", dlrc->dl_primitive)); |
675 |
> |
dlrc = (dl_recv_control_t *)(void *)info_mp->b_rptr; |
676 |
> |
D(bug(" I_OTSetRawMode primitive %d\n", (int)dlrc->dl_primitive)); |
677 |
|
ioc->ioc_error = MAC_EINVAL; |
678 |
|
goto ioctl_error; |
679 |
|
} |
806 |
|
static mblk_t *build_tx_packet_header(DLPIStream *the_stream, mblk_t *mp, bool fast_path) |
807 |
|
{ |
808 |
|
// Only handle unit_data requests |
809 |
< |
dl_unitdata_req_t *req = (dl_unitdata_req_t *)mp->b_rptr; |
809 |
> |
dl_unitdata_req_t *req = (dl_unitdata_req_t *)(void *)mp->b_rptr; |
810 |
|
if (req->dl_primitive != DL_UNITDATA_REQ) { |
811 |
|
freemsg(mp); |
812 |
|
return NULL; |
824 |
|
dlsap = the_stream->dlsap; |
825 |
|
break; |
826 |
|
case kEnetAndSAPAddressLength: |
827 |
< |
dlsap = *(uint16 *)(destAddrOrig + kEnetPhysicalAddressLength); |
827 |
> |
dlsap = ntohs(*(uint16 *)(destAddrOrig + kEnetPhysicalAddressLength)); |
828 |
|
break; |
829 |
|
case kEnetPhysicalAddressLength + k8022DLSAPLength + k8022SNAPLength: // SNAP SAP |
830 |
< |
dlsap = *(uint16 *)(destAddrOrig + kEnetPhysicalAddressLength); |
830 |
> |
dlsap = ntohs(*(uint16 *)(destAddrOrig + kEnetPhysicalAddressLength)); |
831 |
|
break; |
832 |
|
default: |
833 |
|
dlsap = the_stream->dlsap; |
879 |
|
// Resize header info in message block |
880 |
|
if ((mp = reuse_message_block(mp, hdrsize)) == NULL) |
881 |
|
return NULL; |
882 |
< |
struct T8022FullPacketHeader *packetHeader = (struct T8022FullPacketHeader *)mp->b_rptr; |
882 |
> |
struct T8022FullPacketHeader *packetHeader = (struct T8022FullPacketHeader *)(void *)mp->b_rptr; |
883 |
|
|
884 |
|
// Set protocol type/size field |
885 |
|
packetHeader->fEnetPart.fProto = proto; |
919 |
|
|
920 |
|
static void transmit_packet(mblk_t *mp) |
921 |
|
{ |
922 |
< |
EnetPacketHeader *enetHeader = (EnetPacketHeader *)mp->b_rptr; |
922 |
> |
EnetPacketHeader *enetHeader = (EnetPacketHeader *)(void *)mp->b_rptr; |
923 |
|
|
924 |
|
// Fill in length in 802.3 packets |
925 |
|
if (enetHeader->fProto == 0) |
929 |
|
OTCopy48BitAddress(hardware_address, enetHeader->fSourceAddr); |
930 |
|
|
931 |
|
// Tell add-on to transmit packet |
932 |
< |
AO_transmit_packet(mp); |
932 |
> |
AO_transmit_packet(Host2MacAddr((uint8 *)mp)); |
933 |
|
freemsg(mp); |
934 |
|
} |
935 |
|
|
976 |
|
|
977 |
|
// Set message type |
978 |
|
nmp->b_datap->db_type = M_PROTO; |
979 |
< |
dl_unitdata_ind_t *ind = (dl_unitdata_ind_t*)nmp->b_rptr; |
979 |
> |
dl_unitdata_ind_t *ind = (dl_unitdata_ind_t*)(void *)nmp->b_rptr; |
980 |
|
ind->dl_primitive = DL_UNITDATA_IND; |
981 |
|
nmp->b_wptr += (sizeof(dl_unitdata_ind_t) + 2*addr_len); |
982 |
|
|
993 |
|
ind->dl_group_address = dest_addr_type; |
994 |
|
|
995 |
|
// Set address fields |
996 |
< |
T8022FullPacketHeader *packetHeader = (T8022FullPacketHeader *)mp->b_rptr; |
996 |
> |
T8022FullPacketHeader *packetHeader = (T8022FullPacketHeader *)(void *)mp->b_rptr; |
997 |
|
T8022AddressStruct *destAddr = ((T8022AddressStruct*)(nmp->b_rptr + ind->dl_dest_addr_offset)); |
998 |
|
T8022AddressStruct *srcAddr = ((T8022AddressStruct*)(nmp->b_rptr + ind->dl_src_addr_offset)); |
999 |
|
|
1025 |
|
void ether_packet_received(mblk_t *mp) |
1026 |
|
{ |
1027 |
|
// Extract address and types |
1028 |
< |
EnetPacketHeader *pkt = (EnetPacketHeader *)mp->b_rptr; |
1028 |
> |
EnetPacketHeader *pkt = (EnetPacketHeader *)(void *)mp->b_rptr; |
1029 |
|
T8022FullPacketHeader *fullpkt = (T8022FullPacketHeader *)pkt; |
1030 |
|
uint16 sourceSAP, destSAP; |
1031 |
|
destSAP = fullpkt->fEnetPart.fProto; |
1101 |
|
} |
1102 |
|
} |
1103 |
|
|
1104 |
+ |
void ether_dispatch_packet(uint32 p, uint32 size) |
1105 |
+ |
{ |
1106 |
+ |
// Wrap packet in message block |
1107 |
+ |
num_rx_packets++; |
1108 |
+ |
mblk_t *mp; |
1109 |
+ |
if ((mp = allocb(size, 0)) != NULL) { |
1110 |
+ |
D(bug(" packet data at %p\n", (void *)mp->b_rptr)); |
1111 |
+ |
Mac2Host_memcpy(mp->b_rptr, p, size); |
1112 |
+ |
mp->b_wptr += size; |
1113 |
+ |
ether_packet_received(mp); |
1114 |
+ |
} else { |
1115 |
+ |
D(bug("WARNING: Cannot allocate mblk for received packet\n")); |
1116 |
+ |
num_rx_no_mem++; |
1117 |
+ |
} |
1118 |
+ |
} |
1119 |
+ |
|
1120 |
|
|
1121 |
|
/* |
1122 |
|
* Build and send an error acknowledge |
1133 |
|
return; |
1134 |
|
|
1135 |
|
ack_mp->b_datap->db_type = M_PCPROTO; |
1136 |
< |
dl_error_ack_t *errp = (dl_error_ack_t *)ack_mp->b_wptr; |
1136 |
> |
dl_error_ack_t *errp = (dl_error_ack_t *)(void *)ack_mp->b_wptr; |
1137 |
|
errp->dl_primitive = DL_ERROR_ACK; |
1138 |
|
errp->dl_error_primitive = prim; |
1139 |
|
errp->dl_errno = err; |
1163 |
|
} |
1164 |
|
|
1165 |
|
ack_mp->b_datap->db_type = M_PCPROTO; |
1166 |
< |
dl_ok_ack_t *ackp = (dl_ok_ack_t *)ack_mp->b_rptr; |
1166 |
> |
dl_ok_ack_t *ackp = (dl_ok_ack_t *)(void *)ack_mp->b_rptr; |
1167 |
|
ackp->dl_primitive = DL_OK_ACK; |
1168 |
|
ackp->dl_correct_primitive = prim; |
1169 |
|
ack_mp->b_wptr = ack_mp->b_rptr + sizeof(dl_ok_ack_t); |
1203 |
|
|
1204 |
|
// Set up message type |
1205 |
|
ack_mp->b_datap->db_type = M_PCPROTO; |
1206 |
< |
dl_info_ack_t *ackp = (dl_info_ack_t *)ack_mp->b_rptr; |
1206 |
> |
dl_info_ack_t *ackp = (dl_info_ack_t *)(void *)ack_mp->b_rptr; |
1207 |
|
ackp->dl_primitive = DL_INFO_ACK; |
1208 |
|
|
1209 |
|
// Info/version fields |
1255 |
|
static void DLPI_phys_addr(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
1256 |
|
{ |
1257 |
|
D(bug(" DLPI_phys_addr(%p,%p)\n", the_stream, mp)); |
1258 |
< |
dl_phys_addr_req_t *req = (dl_phys_addr_req_t *)mp->b_rptr; |
1258 |
> |
dl_phys_addr_req_t *req = (dl_phys_addr_req_t *)(void *)mp->b_rptr; |
1259 |
|
|
1260 |
|
// Allocate message block for reply |
1261 |
|
mblk_t *ack_mp; |
1266 |
|
|
1267 |
|
// Set up message type |
1268 |
|
ack_mp->b_datap->db_type = M_PCPROTO; |
1269 |
< |
dl_phys_addr_ack_t *ackp = (dl_phys_addr_ack_t *)ack_mp->b_wptr; |
1269 |
> |
dl_phys_addr_ack_t *ackp = (dl_phys_addr_ack_t *)(void *)ack_mp->b_wptr; |
1270 |
|
ackp->dl_primitive = DL_PHYS_ADDR_ACK; |
1271 |
|
|
1272 |
|
// Fill in address |
1295 |
|
|
1296 |
|
static void DLPI_bind(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
1297 |
|
{ |
1298 |
< |
dl_bind_req_t *req = (dl_bind_req_t *)mp->b_rptr; |
1298 |
> |
dl_bind_req_t *req = (dl_bind_req_t *)(void *)mp->b_rptr; |
1299 |
|
uint32 sap = req->dl_sap; |
1300 |
|
D(bug(" DLPI_bind(%p,%p) SAP %04x\n", the_stream, mp, sap)); |
1301 |
|
|
1332 |
|
|
1333 |
|
// Set up message type |
1334 |
|
ack_mp->b_datap->db_type = M_PCPROTO; |
1335 |
< |
dl_bind_ack_t *ackp = (dl_bind_ack_t *)ack_mp->b_rptr; |
1335 |
> |
dl_bind_ack_t *ackp = (dl_bind_ack_t *)(void *)ack_mp->b_rptr; |
1336 |
|
ackp->dl_primitive = DL_BIND_ACK; |
1337 |
|
|
1338 |
|
// Fill in other fields |
1405 |
|
|
1406 |
|
static void DLPI_subs_bind(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
1407 |
|
{ |
1408 |
< |
dl_subs_bind_req_t *req = (dl_subs_bind_req_t *)mp->b_rptr; |
1408 |
> |
dl_subs_bind_req_t *req = (dl_subs_bind_req_t *)(void *)mp->b_rptr; |
1409 |
|
uint8 *sap = ((uint8 *)req) + req->dl_subs_sap_offset; |
1410 |
|
int32 length = req->dl_subs_sap_length; |
1411 |
< |
uint16 theSap = *((uint16 *)sap); |
1411 |
> |
uint16 theSap = ntohs(*((uint16 *)sap)); |
1412 |
|
int32 error = 0; |
1413 |
|
D(bug(" DLPI_subs_bind(%p,%p) SAP %02x%02x%02x%02x%02x\n", the_stream, mp, sap[0], sap[1], sap[2], sap[3], sap[4])); |
1414 |
|
|
1463 |
|
|
1464 |
|
// Set up message type |
1465 |
|
ack_mp->b_datap->db_type = M_PCPROTO; |
1466 |
< |
dl_subs_bind_ack_t *ackp = (dl_subs_bind_ack_t *)ack_mp->b_wptr; |
1466 |
> |
dl_subs_bind_ack_t *ackp = (dl_subs_bind_ack_t *)(void *)ack_mp->b_wptr; |
1467 |
|
memset(ackp, 0, sizeof(dl_subs_bind_ack_t) + length); |
1468 |
|
ackp->dl_primitive = DL_SUBS_BIND_ACK; |
1469 |
|
|
1490 |
|
|
1491 |
|
static void DLPI_subs_unbind(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
1492 |
|
{ |
1493 |
< |
dl_subs_unbind_req_t *req = (dl_subs_unbind_req_t *)mp->b_rptr; |
1493 |
> |
dl_subs_unbind_req_t *req = (dl_subs_unbind_req_t *)(void *)mp->b_rptr; |
1494 |
|
uint8 *sap = ((uint8 *)req) + req->dl_subs_sap_offset; |
1495 |
|
int32 length = req->dl_subs_sap_length; |
1496 |
|
int32 error = 0; |
1541 |
|
|
1542 |
|
static void DLPI_enable_multi(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
1543 |
|
{ |
1544 |
< |
dl_enabmulti_req_t* req = (dl_enabmulti_req_t*)mp->b_rptr; |
1544 |
> |
dl_enabmulti_req_t* req = (dl_enabmulti_req_t*)(void *)mp->b_rptr; |
1545 |
|
uint8 *reqaddr = (uint8 *)(mp->b_rptr + req->dl_addr_offset); |
1546 |
|
D(bug(" DLPI_enable_multi(%p,%p) addr %02x%02x%02x%02x%02x%02x\n", the_stream, mp, reqaddr[0], reqaddr[1], reqaddr[2], reqaddr[3], reqaddr[4], reqaddr[5])); |
1547 |
|
|
1558 |
|
} |
1559 |
|
|
1560 |
|
// Tell add-on to enable multicast address |
1561 |
< |
AO_enable_multicast(reqaddr); |
1561 |
> |
AO_enable_multicast(Host2MacAddr((uint8 *)reqaddr)); |
1562 |
|
|
1563 |
|
// Add new address to multicast list |
1564 |
< |
uint8 *addr = new uint8[kEnetPhysicalAddressLength]; |
1564 |
> |
uint8 *addr = Mac2HostAddr(Mac_sysalloc(kEnetPhysicalAddressLength)); |
1565 |
|
OTCopy48BitAddress(reqaddr, addr); |
1566 |
|
the_stream->AddMulticast(addr); |
1567 |
|
|
1580 |
|
|
1581 |
|
static void DLPI_disable_multi(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
1582 |
|
{ |
1583 |
< |
dl_disabmulti_req_t *req = (dl_disabmulti_req_t*)mp->b_rptr; |
1583 |
> |
dl_disabmulti_req_t *req = (dl_disabmulti_req_t*)(void *)mp->b_rptr; |
1584 |
|
uint8 *reqaddr = (uint8 *)(mp->b_rptr + req->dl_addr_offset); |
1585 |
|
D(bug(" DLPI_disable_multi(%p,%p) addr %02x%02x%02x%02x%02x%02x\n", the_stream, mp, reqaddr[0], reqaddr[1], reqaddr[2], reqaddr[3], reqaddr[4], reqaddr[5])); |
1586 |
|
|
1599 |
|
|
1600 |
|
// Found, then remove |
1601 |
|
the_stream->RemoveMulticast(addr); |
1602 |
< |
delete addr; |
1602 |
> |
Mac_sysfree(Host2MacAddr(addr)); |
1603 |
|
|
1604 |
|
// Tell add-on to disable multicast address |
1605 |
< |
AO_disable_multicast(reqaddr); |
1605 |
> |
AO_disable_multicast(Host2MacAddr((uint8 *)reqaddr)); |
1606 |
|
|
1607 |
|
// No longer check multicast packets if no multicast addresses are registered |
1608 |
|
if (the_stream->multicast_list == NULL) |
1621 |
|
static void DLPI_unit_data(DLPIStream *the_stream, queue_t *q, mblk_t *mp) |
1622 |
|
{ |
1623 |
|
D(bug(" DLPI_unit_data(%p,%p)\n", the_stream, mp)); |
1624 |
< |
dl_unitdata_req_t *req = (dl_unitdata_req_t *)mp->b_rptr; |
1624 |
> |
dl_unitdata_req_t *req = (dl_unitdata_req_t *)(void *)mp->b_rptr; |
1625 |
|
|
1626 |
|
// Stream must be idle |
1627 |
|
if (the_stream->dlpi_state != DL_IDLE) { |
1636 |
|
return; |
1637 |
|
} |
1638 |
|
bp->b_datap->db_type = M_PROTO; |
1639 |
< |
errp = (dl_uderror_ind_t *)bp->b_wptr; |
1639 |
> |
errp = (dl_uderror_ind_t *)(void *)bp->b_wptr; |
1640 |
|
errp->dl_primitive = DL_UDERROR_IND; |
1641 |
|
errp->dl_errno = DL_OUTSTATE; |
1642 |
|
errp->dl_unix_errno = 0; |
1655 |
|
if ((mp = build_tx_packet_header(the_stream, mp, false)) != NULL) |
1656 |
|
transmit_packet(mp); |
1657 |
|
} |
1658 |
+ |
|
1659 |
+ |
|
1660 |
+ |
/* |
1661 |
+ |
* Ethernet packet allocator |
1662 |
+ |
*/ |
1663 |
+ |
|
1664 |
+ |
#if SIZEOF_VOID_P != 4 || REAL_ADDRESSING == 0 |
1665 |
+ |
static uint32 ether_packet = 0; // Ethernet packet (cached allocation) |
1666 |
+ |
static uint32 n_ether_packets = 0; // Number of ethernet packets allocated so far (should be at most 1) |
1667 |
+ |
|
1668 |
+ |
EthernetPacket::EthernetPacket() |
1669 |
+ |
{ |
1670 |
+ |
++n_ether_packets; |
1671 |
+ |
if (ether_packet && n_ether_packets == 1) |
1672 |
+ |
packet = ether_packet; |
1673 |
+ |
else { |
1674 |
+ |
packet = Mac_sysalloc(1516); |
1675 |
+ |
assert(packet != 0); |
1676 |
+ |
Mac_memset(packet, 0, 1516); |
1677 |
+ |
if (ether_packet == 0) |
1678 |
+ |
ether_packet = packet; |
1679 |
+ |
} |
1680 |
+ |
} |
1681 |
+ |
|
1682 |
+ |
EthernetPacket::~EthernetPacket() |
1683 |
+ |
{ |
1684 |
+ |
--n_ether_packets; |
1685 |
+ |
if (packet != ether_packet) |
1686 |
+ |
Mac_sysfree(packet); |
1687 |
+ |
if (n_ether_packets > 0) { |
1688 |
+ |
bug("WARNING: Nested allocation of ethernet packets!\n"); |
1689 |
+ |
} |
1690 |
+ |
} |
1691 |
+ |
#endif |