11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Generic HDLC support routines for Linux 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4b3dd65f958354226275522b5a64157834bdc5415Krzysztof Halasa * Copyright (C) 1999-2005 Krzysztof Halasa <khc@pm.waw.pl> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify it 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * under the terms of version 2 of the GNU General Public License 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as published by the Free Software Foundation. 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __HDLC_H 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __HDLC_H 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ 16eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#if 0 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ 18eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#else 19eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#define HDLC_MAX_MRU 1600 /* as required for FR network */ 20eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#endif 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __KERNEL__ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/skbuff.h> 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netdevice.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/hdlc/ioctl.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa/* This structure is a private property of HDLC protocols. 30eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa Hardware drivers have no interest here */ 31eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa 32eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasastruct hdlc_proto { 33eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa int (*open)(struct net_device *dev); 34eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa void (*close)(struct net_device *dev); 35eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa void (*start)(struct net_device *dev); /* if open & DCD */ 36eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa void (*stop)(struct net_device *dev); /* if open & !DCD */ 37eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa void (*detach)(struct net_device *dev); 38eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa int (*ioctl)(struct net_device *dev, struct ifreq *ifr); 39abf17ffda7b7b6c83a29d7ccea91d46065c6ca3eKrzysztof Halasa __be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev); 4040d25142f2ef27084fc317ac8bb5bae460c8ea72Krzysztof Halasa int (*netif_rx)(struct sk_buff *skb); 414c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemminger netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev); 42eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa struct module *module; 43eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa struct hdlc_proto *next; /* next protocol in the list */ 44eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa}; 45eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa 46eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa 47b74ca3a896b9ab5f952bc440154758e708c48884Wang Chen/* Pointed to by netdev_priv(dev) */ 48eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasatypedef struct hdlc_device { 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* used by HDLC layer to take control over HDLC device from hw driver*/ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int (*attach)(struct net_device *dev, 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short encoding, unsigned short parity); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* hardware driver must handle this instead of dev->hard_start_xmit */ 544c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemminger netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev); 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Things below are for HDLC layer internal use only */ 57eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa const struct hdlc_proto *proto; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int carrier; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int open; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spinlock_t state_lock; 61eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa void *state; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *priv; 634c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemminger} hdlc_device; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 67eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa/* Exported from hdlc module */ 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Called by hardware driver when a user requests HDLC service */ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Must be used by hardware driver on module startup/exit */ 734a31e348e3ecaf54c50240109ac4574b180f8840Krzysztof Halasa#define register_hdlc_device(dev) register_netdev(dev) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid unregister_hdlc_device(struct net_device *dev); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 76eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa 77eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasavoid register_hdlc_protocol(struct hdlc_proto *proto); 78eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasavoid unregister_hdlc_protocol(struct hdlc_proto *proto); 79eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct net_device *alloc_hdlcdev(void *priv); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8240d25142f2ef27084fc317ac8bb5bae460c8ea72Krzysztof Halasastatic inline struct hdlc_device* dev_to_hdlc(struct net_device *dev) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 842baf8a2daab65cdd3f20bfeb4676a2f6aff7c3bfWang Chen return netdev_priv(dev); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __inline__ void debug_frame(const struct sk_buff *skb) 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; i < skb->len; i++) { 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i == 100) { 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("...\n"); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" %02X", skb->data[i]); 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("\n"); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Must be called by hardware driver when HDLC device is being opened */ 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint hdlc_open(struct net_device *dev); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Must be called by hardware driver when HDLC device is being closed */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid hdlc_close(struct net_device *dev); 106991990a12de42281f81b4e3a6471586d2d0caf6aKrzysztof Hałasa/* May be used by hardware driver */ 107991990a12de42281f81b4e3a6471586d2d0caf6aKrzysztof Hałasaint hdlc_change_mtu(struct net_device *dev, int new_mtu); 108991990a12de42281f81b4e3a6471586d2d0caf6aKrzysztof Hałasa/* Must be pointed to by hw driver's dev->netdev_ops->ndo_start_xmit */ 1094c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemmingernetdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasaint attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, 11240d25142f2ef27084fc317ac8bb5bae460c8ea72Krzysztof Halasa size_t size); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* May be used by hardware driver to gain control over HDLC device */ 114eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasavoid detach_hdlc_protocol(struct net_device *dev); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 116ab611487d8ada506e511d2b8f22fb8e7be9939b9Alexey Dobriyanstatic __inline__ __be16 hdlc_type_trans(struct sk_buff *skb, 117ab611487d8ada506e511d2b8f22fb8e7be9939b9Alexey Dobriyan struct net_device *dev) 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hdlc_device *hdlc = dev_to_hdlc(dev); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121459a98ed881802dee55897441bc7f77af614368eArnaldo Carvalho de Melo skb->dev = dev; 122459a98ed881802dee55897441bc7f77af614368eArnaldo Carvalho de Melo skb_reset_mac_header(skb); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 124eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa if (hdlc->proto->type_trans) 125eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa return hdlc->proto->type_trans(skb, dev); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return htons(ETH_P_HDLC); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __KERNEL */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __HDLC_H */ 132