source: rtems/c/src/lib/libbsp/powerpc/mpc8260ads/network/if_hdlcsubr.c @ 2d0bc83

5
Last change on this file since 2d0bc83 was d8d6a08, checked in by Sebastian Huber <sebastian.huber@…>, on 01/27/18 at 10:12:44

bsps: Move network define to source files

Define INSIDE_RTEMS_BSD_TCPIP_STACK in the network interface driver
source files to avoid some build system magic.

  • Property mode set to 100644
File size: 8.9 KB
Line 
1/*
2 * Created from if_ethersubr.c by Andy Dachs <a.dachs@sstl.co.uk>
3 * Surrey Satellite Technology Limited (SSTL), 2001
4 * Modified (hacked) to support IP frames transmitted over HDLC. This
5 * all needs tidying up in future but it does actually work for point
6 * to point communications. I have an SDL WANic400 synchronous
7 * communications card that comes with Windows NT drivers.  The drivers
8 * support a mode that they call "Ethernet Emulation".  That simply
9 * puts the IP frame in an HDLC frame without any ethernet header. i.e.
10 * <HDLC Flag><IpFrame><CRC><HDLC Flag>.  There is no addressing beyond
11 * the IP header information so is only suitable for point to point links
12 * with a single protocol. "At some point" I will add a Frame Relay header
13 * but at the moment I have difficulties getting the WANic card driver's
14 * Frame Relay driver to work.
15 *
16 * Copyright (c) 1982, 1989, 1993
17 *      The Regents of the University of California.  All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 *    notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 *    notice, this list of conditions and the following disclaimer in the
26 *    documentation and/or other materials provided with the distribution.
27 * 3. All advertising materials mentioning features or use of this software
28 *    must display the following acknowledgement:
29 *      This product includes software developed by the University of
30 *      California, Berkeley and its contributors.
31 * 4. Neither the name of the University nor the names of its contributors
32 *    may be used to endorse or promote products derived from this software
33 *    without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 *
47 *      @(#)if_ethersubr.c      8.1 (Berkeley) 6/10/93
48 */
49
50#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
51
52#include <rtems/rtems_bsdnet.h>
53
54#include <sys/param.h>
55/*#include <sys/systm.h>
56#include <sys/kernel.h> */
57#define KERNEL
58#include <sys/malloc.h>
59#include <sys/mbuf.h>
60#include <sys/protosw.h>
61#include <sys/socket.h>
62#include <sys/sockio.h>
63#include <errno.h>
64#include <sys/syslog.h>
65#include <sys/sysctl.h>
66
67#include <net/if.h>
68#include <net/netisr.h>
69#include <net/route.h>
70#include <net/if_llc.h>
71#include <net/if_dl.h>
72#include <net/if_types.h>
73#include <net/ethernet.h>
74
75#include <netinet/in.h>
76#include <netinet/in_var.h>
77#include <netinet/if_ether.h>
78
79#include <stdio.h>
80
81#include "if_hdlcsubr.h"
82
83/*
84u_char  etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
85*/
86#define senderr(e) { error = (e); goto bad;}
87
88/*
89 * HDLC output routine.
90 * Just transmit the packet (hardware adds flags and CRC)
91 */
92int
93hdlc_output(ifp, m0, dst, rt0)
94        register struct ifnet *ifp;
95        struct mbuf *m0;
96        struct sockaddr *dst;
97        struct rtentry *rt0;
98{
99        short type;
100        int s, error = 0;
101#if 0
102        u_char  edst[6];
103#endif
104        register struct mbuf *m = m0;
105        register struct rtentry *rt;
106        struct mbuf *mcopy = (struct mbuf *)0;
107/*      register struct ether_header *eh; */
108        int off, len = m->m_pkthdr.len;
109
110/*      printk( "hdlc output" ); */
111/*      struct arpcom *ac = (struct arpcom *)ifp; */
112
113        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
114                senderr(ENETDOWN);
115        rt = rt0;
116        if (rt) {
117                if ((rt->rt_flags & RTF_UP) == 0) {
118                        rt0 = rt = rtalloc1(dst, 1, 0UL);
119                        if (rt0)
120                                rt->rt_refcnt--;
121                        else
122                                senderr(EHOSTUNREACH);
123                }
124                if (rt->rt_flags & RTF_GATEWAY) {
125                        if (rt->rt_gwroute == 0)
126                                goto lookup;
127                        if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
128                                rtfree(rt); rt = rt0;
129                        lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
130                                                          0UL);
131                                if ((rt = rt->rt_gwroute) == 0)
132                                        senderr(EHOSTUNREACH);
133                        }
134                }
135                if (rt->rt_flags & RTF_REJECT)
136                        if (rt->rt_rmx.rmx_expire == 0 ||
137                            rtems_bsdnet_seconds_since_boot() < rt->rt_rmx.rmx_expire)
138                                senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
139        }
140        switch (dst->sa_family) {
141
142        case AF_INET:
143#if 0
144                if (!arpresolve(ac, rt, m, dst, edst, rt0))
145                        return (0);     /* if not yet resolved */
146#endif
147
148                /* If broadcasting on a simplex interface, loopback a copy */
149                if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
150                        mcopy = m_copy(m, 0, (int)M_COPYALL);
151                off = m->m_pkthdr.len - m->m_len;
152                type = htons(ETHERTYPE_IP);
153                break;
154#if 0
155        case AF_UNSPEC:
156                eh = (struct ether_header *)dst->sa_data;
157                (void)memcpy(edst, eh->ether_dhost, sizeof (edst));
158                type = eh->ether_type;
159                break;
160#endif
161        default:
162                printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
163                        dst->sa_family);
164                senderr(EAFNOSUPPORT);
165        }
166
167        if (mcopy)
168                (void) looutput(ifp, mcopy, dst, rt);
169#if 0
170        /*
171         * Add local net header.  If no space in first mbuf,
172         * allocate another.
173         */
174        M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
175#endif
176
177        if (m == 0)
178                senderr(ENOBUFS);
179
180#if 0
181        eh = mtod(m, struct ether_header *);
182        (void)memcpy(&eh->ether_type, &type,
183                sizeof(eh->ether_type));
184        (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
185        (void)memcpy(eh->ether_shost, ac->ac_enaddr,
186            sizeof(eh->ether_shost));
187#endif
188
189        s = splimp();
190        /*
191         * Queue message on interface, and start output if interface
192         * not yet active.
193         */
194        if (IF_QFULL(&ifp->if_snd)) {
195                IF_DROP(&ifp->if_snd);
196                splx(s);
197                senderr(ENOBUFS);
198        }
199        IF_ENQUEUE(&ifp->if_snd, m);
200        if ((ifp->if_flags & IFF_OACTIVE) == 0)
201                (*ifp->if_start)(ifp);
202        splx(s);
203
204        ifp->if_obytes += len /*+ sizeof (struct ether_header)*/;
205        if (m->m_flags & M_MCAST)
206                ifp->if_omcasts++;
207        return (error);
208
209bad:
210        if (m)
211                m_freem(m);
212        return (error);
213}
214
215/*
216 * Process a received Ethernet packet;
217 * the packet is in the mbuf chain m without
218 * the ether header, which is provided separately.
219 */
220void
221hdlc_input(ifp, m)
222        struct ifnet *ifp;
223        struct mbuf *m;
224{
225        register struct ifqueue *inq;
226        int s;
227
228        struct ether_header eh;
229
230        if ((ifp->if_flags & IFF_UP) == 0) {
231                m_freem(m);
232                return;
233        }
234        ifp->if_ibytes += m->m_pkthdr.len;
235/*
236        if (memcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
237            sizeof(etherbroadcastaddr)) == 0)
238                m->m_flags |= M_BCAST;
239        else if (eh->ether_dhost[0] & 1)
240                m->m_flags |= M_MCAST;
241*/
242        if (m->m_flags & (M_BCAST|M_MCAST))
243                ifp->if_imcasts++;
244
245        /*
246         * RTEMS addition -- allow application to `tap into'
247         * the incoming packet stream.
248         */
249        if (ifp->if_tap && (*ifp->if_tap)(ifp, &eh, m)) {
250                m_freem(m);
251                return;
252        }
253
254        schednetisr(NETISR_IP);
255        inq = &ipintrq;
256
257        s = splimp();
258        if (IF_QFULL(inq)) {
259          IF_DROP(inq);
260          m_freem(m);
261        } else
262          IF_ENQUEUE(inq, m);
263        splx(s);
264}
265
266/*
267 * Perform common duties while attaching to interface list
268 */
269void
270hdlc_ifattach(ifp)
271        register struct ifnet *ifp;
272{
273        register struct ifaddr *ifa;
274        register struct sockaddr_dl *sdl;
275
276        ifp->if_type = IFT_ETHER;
277        ifp->if_addrlen = 0;
278        ifp->if_hdrlen  = 0;
279        ifp->if_mtu  = 2048;
280        if (ifp->if_baudrate == 0)
281            ifp->if_baudrate = 8000000;
282        for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
283                if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
284                    sdl->sdl_family == AF_LINK) {
285                        sdl->sdl_type = IFT_ETHER;
286                        sdl->sdl_alen = ifp->if_addrlen;
287/*
288                        memcpy(LLADDR(sdl),
289                              (caddr_t)((struct arpcom *)ifp)->ac_enaddr,
290                              ifp->if_addrlen);
291*/
292                        break;
293                }
294}
295
296/* SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); */
297
298int
299hdlc_ioctl(struct ifnet *ifp, int command, caddr_t data)
300{
301        struct ifaddr *ifa = (struct ifaddr *) data;
302        struct ifreq *ifr = (struct ifreq *) data;
303        int error = 0;
304
305        switch (command) {
306        case SIOCSIFADDR:
307                ifp->if_flags |= IFF_UP;
308
309                switch (ifa->ifa_addr->sa_family) {
310#if 0
311#ifdef INET
312                case AF_INET:
313                        ifp->if_init(ifp->if_softc);    /* before arpwhohas */
314
315                        arp_ifinit((struct arpcom *)ifp, ifa);
316                        break;
317#endif
318#endif
319                default:
320                        ifp->if_init(ifp->if_softc);
321                        break;
322                }
323                break;
324
325        case SIOCGIFADDR:
326                {
327                        struct sockaddr *sa;
328
329                        sa = (struct sockaddr *) & ifr->ifr_data;
330/*
331                        memcpy((caddr_t) sa->sa_data,
332                              ((struct arpcom *)ifp->if_softc)->ac_enaddr,
333                              ETHER_ADDR_LEN);
334*/
335                }
336                break;
337
338        case SIOCSIFMTU:
339                /*
340                 * Set the interface MTU.
341                 */
342                if (ifr->ifr_mtu > ETHERMTU) {
343                        error = EINVAL;
344                } else {
345                        ifp->if_mtu = ifr->ifr_mtu;
346                }
347                break;
348        }
349        return (error);
350}
Note: See TracBrowser for help on using the repository browser.