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 | /* * Generic HDLC support routines for Linux * * Copyright (C) 1999-2005 Krzysztof Halasa <khc@pm.waw.pl> * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. */ #ifndef __HDLC_H #define __HDLC_H #define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ #if 0 #define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ #else #define HDLC_MAX_MRU 1600 /* as required for FR network */ #endif #ifdef __KERNEL__ #include <linux/skbuff.h> #include <linux/netdevice.h> #include <linux/hdlc/ioctl.h> /* Used by all network devices here, pointed to by netdev_priv(dev) */ struct hdlc_device_desc { int (*netif_rx)(struct sk_buff *skb); struct net_device_stats stats; }; /* This structure is a private property of HDLC protocols. Hardware drivers have no interest here */ struct hdlc_proto { int (*open)(struct net_device *dev); void (*close)(struct net_device *dev); void (*start)(struct net_device *dev); /* if open & DCD */ void (*stop)(struct net_device *dev); /* if open & !DCD */ void (*detach)(struct net_device *dev); int (*ioctl)(struct net_device *dev, struct ifreq *ifr); __be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev); struct module *module; struct hdlc_proto *next; /* next protocol in the list */ }; typedef struct hdlc_device { /* used by HDLC layer to take control over HDLC device from hw driver*/ int (*attach)(struct net_device *dev, unsigned short encoding, unsigned short parity); /* hardware driver must handle this instead of dev->hard_start_xmit */ int (*xmit)(struct sk_buff *skb, struct net_device *dev); /* Things below are for HDLC layer internal use only */ const struct hdlc_proto *proto; int carrier; int open; spinlock_t state_lock; void *state; void *priv; }hdlc_device; /* Exported from hdlc module */ /* Called by hardware driver when a user requests HDLC service */ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); /* Must be used by hardware driver on module startup/exit */ #define register_hdlc_device(dev) register_netdev(dev) void unregister_hdlc_device(struct net_device *dev); void register_hdlc_protocol(struct hdlc_proto *proto); void unregister_hdlc_protocol(struct hdlc_proto *proto); struct net_device *alloc_hdlcdev(void *priv); static __inline__ struct hdlc_device_desc* dev_to_desc(struct net_device *dev) { return netdev_priv(dev); } static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) { return netdev_priv(dev) + sizeof(struct hdlc_device_desc); } static __inline__ void debug_frame(const struct sk_buff *skb) { int i; for (i=0; i < skb->len; i++) { if (i == 100) { printk("...\n"); return; } printk(" %02X", skb->data[i]); } printk("\n"); } /* Must be called by hardware driver when HDLC device is being opened */ int hdlc_open(struct net_device *dev); /* Must be called by hardware driver when HDLC device is being closed */ void hdlc_close(struct net_device *dev); int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, int (*rx)(struct sk_buff *skb), size_t size); /* May be used by hardware driver to gain control over HDLC device */ void detach_hdlc_protocol(struct net_device *dev); static __inline__ struct net_device_stats *hdlc_stats(struct net_device *dev) { return &dev_to_desc(dev)->stats; } static __inline__ __be16 hdlc_type_trans(struct sk_buff *skb, struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); skb->dev = dev; skb_reset_mac_header(skb); if (hdlc->proto->type_trans) return hdlc->proto->type_trans(skb, dev); else return htons(ETH_P_HDLC); } #endif /* __KERNEL */ #endif /* __HDLC_H */ |