Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | /* * Copyright (c) 1997-2000 LAN Media Corporation (LMC) * All rights reserved. www.lanmedia.com * * This code is written by: * Andrew Stanley-Jones (asj@cban.com) * Rob Braun (bbraun@vix.com), * Michael Graff (explorer@vix.com) and * Matt Thomas (matt@3am-software.com). * * With Help By: * David Boggs * Ron Crane * Allan Cox * * This software may be used and distributed according to the terms * of the GNU General Public License version 2, incorporated herein by reference. * * Driver for the LanMedia LMC5200, LMC5245, LMC1000, LMC1200 cards. */ #include <linux/version.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> #include <linux/timer.h> #include <linux/ptrace.h> #include <linux/errno.h> #include <linux/ioport.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/pci.h> #include <asm/segment.h> #include <asm/smp.h> #include <linux/in.h> #include <linux/if_arp.h> #include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/bitops.h> #include <asm/io.h> #include <asm/dma.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <net/syncppp.h> #include <linux/inet.h> #include <linux/tqueue.h> #include <linux/proc_fs.h> #include "lmc_ver.h" #include "lmc.h" #include "lmc_var.h" #include "lmc_debug.h" #include "lmc_ioctl.h" #include "lmc_proto.h" //#include "lmc_proto_raw.h" /* * The compile-time variable SPPPSTUP causes the module to be * compiled without referencing any of the sync ppp routines. */ #ifdef SPPPSTUB #define SPPP_detach(d) (void)0 #define SPPP_open(d) 0 #define SPPP_reopen(d) (void)0 #define SPPP_close(d) (void)0 #define SPPP_attach(d) (void)0 #define SPPP_do_ioctl(d,i,c) -EOPNOTSUPP #else #if LINUX_VERSION_CODE < 0x20363 #define SPPP_attach(x) sppp_attach((struct ppp_device *)(x)->lmc_device) #define SPPP_detach(x) sppp_detach((x)->lmc_device) #define SPPP_open(x) sppp_open((x)->lmc_device) #define SPPP_reopen(x) sppp_reopen((x)->lmc_device) #define SPPP_close(x) sppp_close((x)->lmc_device) #define SPPP_do_ioctl(x, y, z) sppp_do_ioctl((x)->lmc_device, (y), (z)) #else #define SPPP_attach(x) sppp_attach((x)->pd) #define SPPP_detach(x) sppp_detach((x)->pd->dev) #define SPPP_open(x) sppp_open((x)->pd->dev) #define SPPP_reopen(x) sppp_reopen((x)->pd->dev) #define SPPP_close(x) sppp_close((x)->pd->dev) #define SPPP_do_ioctl(x, y, z) sppp_do_ioctl((x)->pd->dev, (y), (z)) #endif #endif // init void lmc_proto_init(lmc_softc_t *sc) /*FOLD00*/ { lmc_trace(sc->lmc_device, "lmc_proto_init in"); switch(sc->if_type){ case LMC_PPP: #if LINUX_VERSION_CODE >= 0x20363 sc->pd = kmalloc(sizeof(struct ppp_device), GFP_KERNEL); if (!sc->pd) { printk("lmc_proto_init(): kmalloc failure!\n"); return; } sc->pd->dev = sc->lmc_device; #endif sc->if_ptr = sc->pd; break; case LMC_RAW: break; default: break; } lmc_trace(sc->lmc_device, "lmc_proto_init out"); } // attach void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/ { lmc_trace(sc->lmc_device, "lmc_proto_attach in"); switch(sc->if_type){ case LMC_PPP: { struct net_device *dev = sc->lmc_device; SPPP_attach(sc); dev->do_ioctl = lmc_ioctl; } break; case LMC_NET: { struct net_device *dev = sc->lmc_device; /* * They set a few basics because they don't use sync_ppp */ dev->flags |= IFF_POINTOPOINT; dev->hard_header = 0; dev->hard_header_len = 0; dev->addr_len = 0; } case LMC_RAW: /* Setup the task queue, maybe we should notify someone? */ { } default: break; } lmc_trace(sc->lmc_device, "lmc_proto_attach out"); } // detach void lmc_proto_detach(lmc_softc_t *sc) /*FOLD00*/ { switch(sc->if_type){ case LMC_PPP: SPPP_detach(sc); break; case LMC_RAW: /* Tell someone we're detaching? */ break; default: break; } } // reopen void lmc_proto_reopen(lmc_softc_t *sc) /*FOLD00*/ { lmc_trace(sc->lmc_device, "lmc_proto_reopen in"); switch(sc->if_type){ case LMC_PPP: SPPP_reopen(sc); break; case LMC_RAW: /* Reset the interface after being down, prerape to receive packets again */ break; default: break; } lmc_trace(sc->lmc_device, "lmc_proto_reopen out"); } // ioctl int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd) /*FOLD00*/ { lmc_trace(sc->lmc_device, "lmc_proto_ioctl out"); switch(sc->if_type){ case LMC_PPP: return SPPP_do_ioctl (sc, ifr, cmd); break; default: return -EOPNOTSUPP; break; } lmc_trace(sc->lmc_device, "lmc_proto_ioctl out"); } // open void lmc_proto_open(lmc_softc_t *sc) /*FOLD00*/ { int ret; lmc_trace(sc->lmc_device, "lmc_proto_open in"); switch(sc->if_type){ case LMC_PPP: ret = SPPP_open(sc); if(ret < 0) printk("%s: syncPPP open failed: %d\n", sc->name, ret); break; case LMC_RAW: /* We're about to start getting packets! */ break; default: break; } lmc_trace(sc->lmc_device, "lmc_proto_open out"); } // close void lmc_proto_close(lmc_softc_t *sc) /*FOLD00*/ { lmc_trace(sc->lmc_device, "lmc_proto_close in"); switch(sc->if_type){ case LMC_PPP: SPPP_close(sc); break; case LMC_RAW: /* Interface going down */ break; default: break; } lmc_trace(sc->lmc_device, "lmc_proto_close out"); } unsigned short lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/ { lmc_trace(sc->lmc_device, "lmc_proto_type in"); switch(sc->if_type){ case LMC_PPP: return htons(ETH_P_WAN_PPP); break; case LMC_NET: return htons(ETH_P_802_2); break; case LMC_RAW: /* Packet type for skbuff kind of useless */ return htons(ETH_P_802_2); break; default: printk(KERN_WARNING "%s: No protocol set for this interface, assuming 802.2 (which is wrong!!)\n", sc->name); return htons(ETH_P_802_2); break; } lmc_trace(sc->lmc_device, "lmc_proto_tye out"); } void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/ { lmc_trace(sc->lmc_device, "lmc_proto_netif in"); switch(sc->if_type){ case LMC_PPP: case LMC_NET: default: netif_rx(skb); break; case LMC_RAW: break; } lmc_trace(sc->lmc_device, "lmc_proto_netif out"); } |