1*2d966958Swdenk /* 2*2d966958Swdenk * LiMon Monitor (LiMon) - Network. 3*2d966958Swdenk * 4*2d966958Swdenk * Copyright 1994 - 2000 Neil Russell. 5*2d966958Swdenk * (See License) 6*2d966958Swdenk * 7*2d966958Swdenk * 8*2d966958Swdenk * History 9*2d966958Swdenk * 9/16/00 bor adapted to TQM823L/STK8xxL board, RARP/TFTP boot added 10*2d966958Swdenk */ 11*2d966958Swdenk 12*2d966958Swdenk #ifndef __NET_H__ 13*2d966958Swdenk #define __NET_H__ 14*2d966958Swdenk 15*2d966958Swdenk #if !defined(CONFIG_NET_MULTI) && defined(CONFIG_8xx) 16*2d966958Swdenk #include <commproc.h> 17*2d966958Swdenk #if defined(FEC_ENET) || defined(SCC_ENET) 18*2d966958Swdenk #define CONFIG_NET_MULTI 19*2d966958Swdenk #endif 20*2d966958Swdenk #endif 21*2d966958Swdenk #include <asm/byteorder.h> /* for nton* / ntoh* stuff */ 22*2d966958Swdenk 23*2d966958Swdenk 24*2d966958Swdenk /* 25*2d966958Swdenk * The number of receive packet buffers, and the required packet buffer 26*2d966958Swdenk * alignment in memory. 27*2d966958Swdenk * 28*2d966958Swdenk */ 29*2d966958Swdenk 30*2d966958Swdenk #define PKTBUFSRX 4 31*2d966958Swdenk #define PKTALIGN 32 32*2d966958Swdenk 33*2d966958Swdenk typedef ulong IPaddr_t; 34*2d966958Swdenk 35*2d966958Swdenk 36*2d966958Swdenk 37*2d966958Swdenk /* 38*2d966958Swdenk * The current receive packet handler. Called with a pointer to the 39*2d966958Swdenk * application packet, and a protocol type (PORT_BOOTPC or PORT_TFTP). 40*2d966958Swdenk * All other packets are dealt with without calling the handler. 41*2d966958Swdenk */ 42*2d966958Swdenk typedef void rxhand_f(uchar *, unsigned, unsigned, unsigned); 43*2d966958Swdenk 44*2d966958Swdenk /* 45*2d966958Swdenk * A timeout handler. Called after time interval has expired. 46*2d966958Swdenk */ 47*2d966958Swdenk typedef void thand_f(void); 48*2d966958Swdenk 49*2d966958Swdenk #ifdef CONFIG_NET_MULTI 50*2d966958Swdenk 51*2d966958Swdenk #define NAMESIZE 16 52*2d966958Swdenk 53*2d966958Swdenk enum eth_state_t { 54*2d966958Swdenk ETH_STATE_INIT, 55*2d966958Swdenk ETH_STATE_PASSIVE, 56*2d966958Swdenk ETH_STATE_ACTIVE 57*2d966958Swdenk }; 58*2d966958Swdenk 59*2d966958Swdenk struct eth_device { 60*2d966958Swdenk char name[NAMESIZE]; 61*2d966958Swdenk unsigned char enetaddr[6]; 62*2d966958Swdenk int iobase; 63*2d966958Swdenk int state; 64*2d966958Swdenk 65*2d966958Swdenk int (*init) (struct eth_device*, bd_t*); 66*2d966958Swdenk int (*send) (struct eth_device*, volatile void* pachet, int length); 67*2d966958Swdenk int (*recv) (struct eth_device*); 68*2d966958Swdenk void (*halt) (struct eth_device*); 69*2d966958Swdenk 70*2d966958Swdenk struct eth_device *next; 71*2d966958Swdenk void *priv; 72*2d966958Swdenk }; 73*2d966958Swdenk 74*2d966958Swdenk extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */ 75*2d966958Swdenk extern int eth_register(struct eth_device* dev);/* Register network device */ 76*2d966958Swdenk extern void eth_try_another(int first_restart); /* Change the device */ 77*2d966958Swdenk extern struct eth_device *eth_get_dev(void); /* get the current device MAC */ 78*2d966958Swdenk extern void eth_set_enetaddr(int num, char* a); /* Set new MAC address */ 79*2d966958Swdenk #endif 80*2d966958Swdenk 81*2d966958Swdenk extern int eth_init(bd_t *bis); /* Initialize the device */ 82*2d966958Swdenk extern int eth_send(volatile void *packet, int length); /* Send a packet */ 83*2d966958Swdenk extern int eth_rx(void); /* Check for received packets */ 84*2d966958Swdenk extern void eth_halt(void); /* stop SCC */ 85*2d966958Swdenk 86*2d966958Swdenk 87*2d966958Swdenk /**********************************************************************/ 88*2d966958Swdenk /* 89*2d966958Swdenk * Protocol headers. 90*2d966958Swdenk */ 91*2d966958Swdenk 92*2d966958Swdenk /* 93*2d966958Swdenk * Ethernet header 94*2d966958Swdenk */ 95*2d966958Swdenk typedef struct { 96*2d966958Swdenk uchar et_dest[6]; /* Destination node */ 97*2d966958Swdenk uchar et_src[6]; /* Source node */ 98*2d966958Swdenk ushort et_protlen; /* Protocol or length */ 99*2d966958Swdenk uchar et_dsap; /* 802 DSAP */ 100*2d966958Swdenk uchar et_ssap; /* 802 SSAP */ 101*2d966958Swdenk uchar et_ctl; /* 802 control */ 102*2d966958Swdenk uchar et_snap1; /* SNAP */ 103*2d966958Swdenk uchar et_snap2; 104*2d966958Swdenk uchar et_snap3; 105*2d966958Swdenk ushort et_prot; /* 802 protocol */ 106*2d966958Swdenk } Ethernet_t; 107*2d966958Swdenk 108*2d966958Swdenk #define ETHER_HDR_SIZE 14 /* Ethernet header size */ 109*2d966958Swdenk #define E802_HDR_SIZE 22 /* 802 ethernet header size */ 110*2d966958Swdenk #define PROT_IP 0x0800 /* IP protocol */ 111*2d966958Swdenk #define PROT_ARP 0x0806 /* IP ARP protocol */ 112*2d966958Swdenk #define PROT_RARP 0x8035 /* IP ARP protocol */ 113*2d966958Swdenk 114*2d966958Swdenk #define IPPROTO_ICMP 1 /* Internet Control Message Protocol */ 115*2d966958Swdenk #define IPPROTO_UDP 17 /* User Datagram Protocol */ 116*2d966958Swdenk 117*2d966958Swdenk /* 118*2d966958Swdenk * Internet Protocol (IP) header. 119*2d966958Swdenk */ 120*2d966958Swdenk typedef struct { 121*2d966958Swdenk uchar ip_hl_v; /* header length and version */ 122*2d966958Swdenk uchar ip_tos; /* type of service */ 123*2d966958Swdenk ushort ip_len; /* total length */ 124*2d966958Swdenk ushort ip_id; /* identification */ 125*2d966958Swdenk ushort ip_off; /* fragment offset field */ 126*2d966958Swdenk uchar ip_ttl; /* time to live */ 127*2d966958Swdenk uchar ip_p; /* protocol */ 128*2d966958Swdenk ushort ip_sum; /* checksum */ 129*2d966958Swdenk IPaddr_t ip_src; /* Source IP address */ 130*2d966958Swdenk IPaddr_t ip_dst; /* Destination IP address */ 131*2d966958Swdenk ushort udp_src; /* UDP source port */ 132*2d966958Swdenk ushort udp_dst; /* UDP destination port */ 133*2d966958Swdenk ushort udp_len; /* Length of UDP packet */ 134*2d966958Swdenk ushort udp_xsum; /* Checksum */ 135*2d966958Swdenk } IP_t; 136*2d966958Swdenk 137*2d966958Swdenk #define IP_HDR_SIZE_NO_UDP (sizeof (IP_t) - 8) 138*2d966958Swdenk #define IP_HDR_SIZE (sizeof (IP_t)) 139*2d966958Swdenk 140*2d966958Swdenk 141*2d966958Swdenk /* 142*2d966958Swdenk * Address Resolution Protocol (ARP) header. 143*2d966958Swdenk */ 144*2d966958Swdenk typedef struct 145*2d966958Swdenk { 146*2d966958Swdenk ushort ar_hrd; /* Format of hardware address */ 147*2d966958Swdenk # define ARP_ETHER 1 /* Ethernet hardware address */ 148*2d966958Swdenk ushort ar_pro; /* Format of protocol address */ 149*2d966958Swdenk uchar ar_hln; /* Length of hardware address */ 150*2d966958Swdenk uchar ar_pln; /* Length of protocol address */ 151*2d966958Swdenk ushort ar_op; /* Operation */ 152*2d966958Swdenk # define ARPOP_REQUEST 1 /* Request to resolve address */ 153*2d966958Swdenk # define ARPOP_REPLY 2 /* Response to previous request */ 154*2d966958Swdenk 155*2d966958Swdenk # define RARPOP_REQUEST 3 /* Request to resolve address */ 156*2d966958Swdenk # define RARPOP_REPLY 4 /* Response to previous request */ 157*2d966958Swdenk 158*2d966958Swdenk /* 159*2d966958Swdenk * The remaining fields are variable in size, according to 160*2d966958Swdenk * the sizes above, and are defined as appropriate for 161*2d966958Swdenk * specific hardware/protocol combinations. 162*2d966958Swdenk */ 163*2d966958Swdenk uchar ar_data[0]; 164*2d966958Swdenk #if 0 165*2d966958Swdenk uchar ar_sha[]; /* Sender hardware address */ 166*2d966958Swdenk uchar ar_spa[]; /* Sender protocol address */ 167*2d966958Swdenk uchar ar_tha[]; /* Target hardware address */ 168*2d966958Swdenk uchar ar_tpa[]; /* Target protocol address */ 169*2d966958Swdenk #endif /* 0 */ 170*2d966958Swdenk } ARP_t; 171*2d966958Swdenk 172*2d966958Swdenk #define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */ 173*2d966958Swdenk 174*2d966958Swdenk /* 175*2d966958Swdenk * ICMP stuff (just enough to handle (host) redirect messages) 176*2d966958Swdenk */ 177*2d966958Swdenk #define ICMP_REDIRECT 5 /* Redirect (change route) */ 178*2d966958Swdenk 179*2d966958Swdenk /* Codes for REDIRECT. */ 180*2d966958Swdenk #define ICMP_REDIR_NET 0 /* Redirect Net */ 181*2d966958Swdenk #define ICMP_REDIR_HOST 1 /* Redirect Host */ 182*2d966958Swdenk 183*2d966958Swdenk typedef struct icmphdr { 184*2d966958Swdenk uchar type; 185*2d966958Swdenk uchar code; 186*2d966958Swdenk ushort checksum; 187*2d966958Swdenk union { 188*2d966958Swdenk struct { 189*2d966958Swdenk ushort id; 190*2d966958Swdenk ushort sequence; 191*2d966958Swdenk } echo; 192*2d966958Swdenk ulong gateway; 193*2d966958Swdenk struct { 194*2d966958Swdenk ushort __unused; 195*2d966958Swdenk ushort mtu; 196*2d966958Swdenk } frag; 197*2d966958Swdenk } un; 198*2d966958Swdenk } ICMP_t; 199*2d966958Swdenk 200*2d966958Swdenk 201*2d966958Swdenk 202*2d966958Swdenk /* 203*2d966958Swdenk * Maximum packet size; used to allocate packet storage. 204*2d966958Swdenk * TFTP packets can be 524 bytes + IP header + ethernet header. 205*2d966958Swdenk * Lets be conservative, and go for 38 * 16. (Must also be 206*2d966958Swdenk * a multiple of 32 bytes). 207*2d966958Swdenk */ 208*2d966958Swdenk /* 209*2d966958Swdenk * AS.HARNOIS : Better to set PKTSIZE to maximum size because 210*2d966958Swdenk * traffic type is not always controlled 211*2d966958Swdenk * maximum packet size = 1518 212*2d966958Swdenk * maximum packet size and multiple of 32 bytes = 1536 213*2d966958Swdenk */ 214*2d966958Swdenk #define PKTSIZE 1518 215*2d966958Swdenk #define PKTSIZE_ALIGN 1536 216*2d966958Swdenk /*#define PKTSIZE 608*/ 217*2d966958Swdenk 218*2d966958Swdenk /* 219*2d966958Swdenk * Maximum receive ring size; that is, the number of packets 220*2d966958Swdenk * we can buffer before overflow happens. Basically, this just 221*2d966958Swdenk * needs to be enough to prevent a packet being discarded while 222*2d966958Swdenk * we are processing the previous one. 223*2d966958Swdenk */ 224*2d966958Swdenk #define RINGSZ 4 225*2d966958Swdenk #define RINGSZ_LOG2 2 226*2d966958Swdenk 227*2d966958Swdenk /**********************************************************************/ 228*2d966958Swdenk /* 229*2d966958Swdenk * Globals. 230*2d966958Swdenk * 231*2d966958Swdenk * Note: 232*2d966958Swdenk * 233*2d966958Swdenk * All variables of type IPaddr_t are stored in NETWORK byte order 234*2d966958Swdenk * (big endian). 235*2d966958Swdenk */ 236*2d966958Swdenk 237*2d966958Swdenk /* net.c */ 238*2d966958Swdenk /** BOOTP EXTENTIONS **/ 239*2d966958Swdenk extern IPaddr_t NetOurGatewayIP; /* Our gateway IP addresse */ 240*2d966958Swdenk extern IPaddr_t NetOurSubnetMask; /* Our subnet mask (0 = unknown)*/ 241*2d966958Swdenk extern IPaddr_t NetOurDNSIP; /* Our Domain Name Server (0 = unknown)*/ 242*2d966958Swdenk extern char NetOurNISDomain[32]; /* Our NIS domain */ 243*2d966958Swdenk extern char NetOurHostName[32]; /* Our hostname */ 244*2d966958Swdenk extern char NetOurRootPath[64]; /* Our root path */ 245*2d966958Swdenk extern ushort NetBootFileSize; /* Our boot file size in blocks */ 246*2d966958Swdenk /** END OF BOOTP EXTENTIONS **/ 247*2d966958Swdenk extern ulong NetBootFileXferSize; /* size of bootfile in bytes */ 248*2d966958Swdenk extern uchar NetOurEther[6]; /* Our ethernet address */ 249*2d966958Swdenk extern uchar NetServerEther[6]; /* Boot server enet address */ 250*2d966958Swdenk extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ 251*2d966958Swdenk extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ 252*2d966958Swdenk extern volatile uchar * NetTxPacket; /* THE transmit packet */ 253*2d966958Swdenk extern volatile uchar * NetRxPackets[PKTBUFSRX];/* Receive packets */ 254*2d966958Swdenk extern volatile uchar * NetRxPkt; /* Current receive packet */ 255*2d966958Swdenk extern int NetRxPktLen; /* Current rx packet length */ 256*2d966958Swdenk extern unsigned NetIPID; /* IP ID (counting) */ 257*2d966958Swdenk extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */ 258*2d966958Swdenk 259*2d966958Swdenk extern int NetState; /* Network loop state */ 260*2d966958Swdenk #define NETLOOP_CONTINUE 1 261*2d966958Swdenk #define NETLOOP_RESTART 2 262*2d966958Swdenk #define NETLOOP_SUCCESS 3 263*2d966958Swdenk #define NETLOOP_FAIL 4 264*2d966958Swdenk 265*2d966958Swdenk #ifdef CONFIG_NET_MULTI 266*2d966958Swdenk extern int NetRestartWrap; /* Tried all network devices */ 267*2d966958Swdenk #endif 268*2d966958Swdenk 269*2d966958Swdenk typedef enum { BOOTP, RARP, ARP, TFTP, DHCP } proto_t; 270*2d966958Swdenk 271*2d966958Swdenk /* from net/net.c */ 272*2d966958Swdenk extern char BootFile[128]; /* Boot File name */ 273*2d966958Swdenk 274*2d966958Swdenk /* Initialize the network adapter */ 275*2d966958Swdenk extern int NetLoop(proto_t); 276*2d966958Swdenk 277*2d966958Swdenk /* Shutdown adapters and cleanup */ 278*2d966958Swdenk extern void NetStop(void); 279*2d966958Swdenk 280*2d966958Swdenk /* Load failed. Start again. */ 281*2d966958Swdenk extern void NetStartAgain(void); 282*2d966958Swdenk 283*2d966958Swdenk /* Set ethernet header */ 284*2d966958Swdenk extern void NetSetEther(volatile uchar *, uchar *, uint); 285*2d966958Swdenk 286*2d966958Swdenk /* Set IP header */ 287*2d966958Swdenk extern void NetSetIP(volatile uchar *, IPaddr_t, int, int, int); 288*2d966958Swdenk 289*2d966958Swdenk /* Checksum */ 290*2d966958Swdenk extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ 291*2d966958Swdenk extern uint NetCksum(uchar *, int); /* Calculate the checksum */ 292*2d966958Swdenk 293*2d966958Swdenk /* Set callbacks */ 294*2d966958Swdenk extern void NetSetHandler(rxhand_f *); /* Set RX packet handler */ 295*2d966958Swdenk extern void NetSetTimeout(int, thand_f *); /* Set timeout handler */ 296*2d966958Swdenk 297*2d966958Swdenk /* Transmit "NetTxPacket" */ 298*2d966958Swdenk extern void NetSendPacket(volatile uchar *, int); 299*2d966958Swdenk 300*2d966958Swdenk /* Processes a received packet */ 301*2d966958Swdenk extern void NetReceive(volatile uchar *, int); 302*2d966958Swdenk 303*2d966958Swdenk /* Print an IP address on the console */ 304*2d966958Swdenk extern void print_IPaddr (IPaddr_t); 305*2d966958Swdenk 306*2d966958Swdenk /* 307*2d966958Swdenk * The following functions are a bit ugly, but necessary to deal with 308*2d966958Swdenk * alignment restrictions on ARM. 309*2d966958Swdenk * 310*2d966958Swdenk * We're using inline functions, which had the smallest memory 311*2d966958Swdenk * footprint in our tests. 312*2d966958Swdenk */ 313*2d966958Swdenk /* return IP *in network byteorder* */ 314*2d966958Swdenk static inline IPaddr_t NetReadIP(void *from) 315*2d966958Swdenk { 316*2d966958Swdenk IPaddr_t ip; 317*2d966958Swdenk memcpy((void*)&ip, from, sizeof(ip)); 318*2d966958Swdenk return ip; 319*2d966958Swdenk } 320*2d966958Swdenk 321*2d966958Swdenk /* return ulong *in network byteorder* */ 322*2d966958Swdenk static inline ulong NetReadLong(ulong *from) 323*2d966958Swdenk { 324*2d966958Swdenk ulong l; 325*2d966958Swdenk memcpy((void*)&l, (void*)from, sizeof(l)); 326*2d966958Swdenk return l; 327*2d966958Swdenk } 328*2d966958Swdenk 329*2d966958Swdenk /* write IP *in network byteorder* */ 330*2d966958Swdenk static inline void NetWriteIP(void *to, IPaddr_t ip) 331*2d966958Swdenk { 332*2d966958Swdenk memcpy(to, (void*)&ip, sizeof(ip)); 333*2d966958Swdenk } 334*2d966958Swdenk 335*2d966958Swdenk /* copy IP */ 336*2d966958Swdenk static inline void NetCopyIP(void *to, void *from) 337*2d966958Swdenk { 338*2d966958Swdenk memcpy(to, from, sizeof(IPaddr_t)); 339*2d966958Swdenk } 340*2d966958Swdenk 341*2d966958Swdenk /* copy ulong */ 342*2d966958Swdenk static inline void NetCopyLong(ulong *to, ulong *from) 343*2d966958Swdenk { 344*2d966958Swdenk memcpy((void*)to, (void*)from, sizeof(ulong)); 345*2d966958Swdenk } 346*2d966958Swdenk 347*2d966958Swdenk /* Convert an IP address to a string */ 348*2d966958Swdenk extern void ip_to_string (IPaddr_t x, char *s); 349*2d966958Swdenk 350*2d966958Swdenk /* read an IP address from a environment variable */ 351*2d966958Swdenk extern IPaddr_t getenv_IPaddr (char *); 352*2d966958Swdenk 353*2d966958Swdenk /* copy a filename (allow for "..." notation, limit length) */ 354*2d966958Swdenk extern void copy_filename (uchar *dst, uchar *src, int size); 355*2d966958Swdenk 356*2d966958Swdenk /**********************************************************************/ 357*2d966958Swdenk 358*2d966958Swdenk #endif /* __NET_H__ */ 359