^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Generic HDLC support routines for Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Frame Relay support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) Theory of PVC state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) DCE mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) (exist,new) -> 0,0 when "PVC create" or if "link unreliable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 0,x -> 1,1 if "link reliable" when sending FULL STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 1,1 -> 1,0 if received FULL STATUS ACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) (active) -> 0 when "ifconfig PVC down" or "link unreliable" or "PVC create"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) -> 1 when "PVC up" and (exist,new) = 1,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) DTE mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) (exist,new,active) = FULL STATUS if "link reliable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) = 0, 0, 0 if "link unreliable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) No LMI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) active = open and "link reliable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) exist = new = not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) CCITT LMI: ITU-T Q.933 Annex A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ANSI LMI: ANSI T1.617 Annex D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) CISCO LMI: the original, aka "Gang of Four" LMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/hdlc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/inetdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/pkt_sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #undef DEBUG_PKT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #undef DEBUG_ECN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #undef DEBUG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #undef DEBUG_PROTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #undef DEBUG_PVC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define FR_UI 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define FR_PAD 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define NLPID_IP 0xCC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define NLPID_IPV6 0x8E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define NLPID_SNAP 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define NLPID_PAD 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define NLPID_CCITT_ANSI_LMI 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define NLPID_CISCO_LMI 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define LMI_CCITT_ANSI_DLCI 0 /* LMI DLCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define LMI_CISCO_DLCI 1023
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define LMI_CALLREF 0x00 /* Call Reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI locking shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define LMI_ANSI_CISCO_REPTYPE 0x01 /* report type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define LMI_CCITT_REPTYPE 0x51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define LMI_ANSI_CISCO_ALIVE 0x03 /* keep alive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define LMI_CCITT_ALIVE 0x53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define LMI_ANSI_CISCO_PVCSTAT 0x07 /* PVC status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define LMI_CCITT_PVCSTAT 0x57
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define LMI_FULLREP 0x00 /* full report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define LMI_INTEGRITY 0x01 /* link integrity report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define LMI_SINGLE 0x02 /* single PVC report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define LMI_STATUS_ENQUIRY 0x75
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LMI_STATUS 0x7D /* reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define LMI_REPT_LEN 1 /* report type element length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define LMI_INTEG_LEN 2 /* link integrity element length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define LMI_CCITT_CISCO_LENGTH 13 /* LMI frame lengths */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define LMI_ANSI_LENGTH 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct fr_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #if defined(__LITTLE_ENDIAN_BITFIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned ea1: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned cr: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned dlcih: 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned ea2: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned de: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned becn: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned fecn: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned dlcil: 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned dlcih: 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned cr: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned ea1: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned dlcil: 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned fecn: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned becn: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned de: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned ea2: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct pvc_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct net_device *frad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct net_device *main;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct net_device *ether; /* bridged Ethernet interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct pvc_device *next; /* Sorted in ascending DLCI order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int open_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int new: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int active: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int exist: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned int deleted: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int fecn: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned int becn: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned int bandwidth; /* Cisco LMI reporting only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct frad_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) fr_proto settings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct pvc_device *first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int dce_pvc_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned long last_poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int reliable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int dce_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int fullrep_sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u32 last_errors; /* last errors bit list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u8 n391cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u8 txseq; /* TX sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 rxseq; /* RX sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int fr_ioctl(struct net_device *dev, struct ifreq *ifr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static inline u16 q922_to_dlci(u8 *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static inline void dlci_to_q922(u8 *hdr, u16 dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) hdr[0] = (dlci >> 2) & 0xFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) hdr[1] = ((dlci << 4) & 0xF0) | 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline struct frad_state* state(hdlc_device *hdlc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return(struct frad_state *)(hdlc->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static inline struct pvc_device *find_pvc(hdlc_device *hdlc, u16 dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct pvc_device *pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) while (pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (pvc->dlci == dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (pvc->dlci > dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return NULL; /* the list is sorted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static struct pvc_device *add_pvc(struct net_device *dev, u16 dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct pvc_device *pvc, **pvc_p = &state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) while (*pvc_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if ((*pvc_p)->dlci == dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return *pvc_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if ((*pvc_p)->dlci > dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break; /* the list is sorted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) pvc_p = &(*pvc_p)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) pvc = kzalloc(sizeof(*pvc), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #ifdef DEBUG_PVC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!pvc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) pvc->dlci = dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pvc->frad = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) pvc->next = *pvc_p; /* Put it in the chain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *pvc_p = pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static inline int pvc_is_used(struct pvc_device *pvc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return pvc->main || pvc->ether;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static inline void pvc_carrier(int on, struct pvc_device *pvc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (pvc->main)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (!netif_carrier_ok(pvc->main))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) netif_carrier_on(pvc->main);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (pvc->ether)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (!netif_carrier_ok(pvc->ether))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) netif_carrier_on(pvc->ether);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (pvc->main)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (netif_carrier_ok(pvc->main))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) netif_carrier_off(pvc->main);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (pvc->ether)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (netif_carrier_ok(pvc->ether))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) netif_carrier_off(pvc->ether);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static inline void delete_unused_pvcs(hdlc_device *hdlc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct pvc_device **pvc_p = &state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) while (*pvc_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!pvc_is_used(*pvc_p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct pvc_device *pvc = *pvc_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #ifdef DEBUG_PVC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) printk(KERN_DEBUG "freeing unused pvc: %p\n", pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) *pvc_p = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) kfree(pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) pvc_p = &(*pvc_p)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static inline struct net_device **get_dev_p(struct pvc_device *pvc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (type == ARPHRD_ETHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return &pvc->ether;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return &pvc->main;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int fr_hard_header(struct sk_buff *skb, u16 dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (!skb->dev) { /* Control packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) switch (dlci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case LMI_CCITT_ANSI_DLCI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) skb_push(skb, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) skb->data[3] = NLPID_CCITT_ANSI_LMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case LMI_CISCO_DLCI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) skb_push(skb, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) skb->data[3] = NLPID_CISCO_LMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else if (skb->dev->type == ARPHRD_DLCI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) switch (skb->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) skb_push(skb, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) skb->data[3] = NLPID_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) skb_push(skb, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) skb->data[3] = NLPID_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) skb_push(skb, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) skb->data[3] = FR_PAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) skb->data[4] = NLPID_SNAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* OUI 00-00-00 indicates an Ethertype follows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) skb->data[5] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) skb->data[6] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) skb->data[7] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* This should be an Ethertype: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *(__be16 *)(skb->data + 8) = skb->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) } else if (skb->dev->type == ARPHRD_ETHER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) skb_push(skb, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) skb->data[3] = FR_PAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) skb->data[4] = NLPID_SNAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* OUI 00-80-C2 stands for the 802.1 organization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) skb->data[5] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) skb->data[6] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) skb->data[7] = 0xC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* PID 00-07 stands for Ethernet frames without FCS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) skb->data[8] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) skb->data[9] = 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) dlci_to_q922(skb->data, dlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) skb->data[2] = FR_UI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int pvc_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct pvc_device *pvc = dev->ml_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if ((pvc->frad->flags & IFF_UP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return -EIO; /* Frad must be UP in order to activate PVC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (pvc->open_count++ == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (state(hdlc)->settings.lmi == LMI_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pvc->state.active = netif_carrier_ok(pvc->frad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) pvc_carrier(pvc->state.active, pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int pvc_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct pvc_device *pvc = dev->ml_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (--pvc->open_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (state(hdlc)->settings.lmi == LMI_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pvc->state.active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (state(hdlc)->settings.dce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pvc->state.active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct pvc_device *pvc = dev->ml_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) fr_proto_pvc_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (ifr->ifr_settings.type == IF_GET_PROTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (dev->type == ARPHRD_ETHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ifr->ifr_settings.type = IF_PROTO_FR_PVC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (ifr->ifr_settings.size < sizeof(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* data size wanted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ifr->ifr_settings.size = sizeof(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) info.dlci = pvc->dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) memcpy(info.master, pvc->frad->name, IFNAMSIZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) &info, sizeof(info)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static netdev_tx_t pvc_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct pvc_device *pvc = dev->ml_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!pvc->state.active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (dev->type == ARPHRD_ETHER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int pad = ETH_ZLEN - skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (pad > 0) { /* Pad the frame with zeros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (__skb_pad(skb, pad, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) skb_put(skb, pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* We already requested the header space with dev->needed_headroom.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * So this is just a protection in case the upper layer didn't take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * dev->needed_headroom into consideration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (skb_headroom(skb) < 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct sk_buff *skb2 = skb_realloc_headroom(skb, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (!skb2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) skb = skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (fr_hard_header(skb, pvc->dlci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dev->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (pvc->state.fecn) /* TX Congestion counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dev->stats.tx_compressed++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) skb->dev = pvc->frad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) skb->protocol = htons(ETH_P_HDLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dev_queue_xmit(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dev->stats.tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static inline void fr_log_dlci_active(struct pvc_device *pvc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) netdev_info(pvc->frad, "DLCI %d [%s%s%s]%s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) pvc->dlci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) pvc->main ? pvc->main->name : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) pvc->main && pvc->ether ? " " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pvc->ether ? pvc->ether->name : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) pvc->state.new ? " new" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) !pvc->state.exist ? "deleted" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) pvc->state.active ? "active" : "inactive");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static inline u8 fr_lmi_nextseq(u8 x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) x++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return x ? x : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static void fr_lmi_send(struct net_device *dev, int fullrep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct pvc_device *pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int lmi = state(hdlc)->settings.lmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) int dce = state(hdlc)->settings.dce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int stat_len = (lmi == LMI_CISCO) ? 6 : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (dce && fullrep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) len += state(hdlc)->dce_pvc_count * (2 + stat_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (len > HDLC_MAX_MRU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) netdev_warn(dev, "Too many PVCs while sending LMI full report\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) skb = dev_alloc_skb(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) netdev_warn(dev, "Memory squeeze on fr_lmi_send()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) memset(skb->data, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) skb_reserve(skb, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (lmi == LMI_CISCO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) fr_hard_header(skb, LMI_CISCO_DLCI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) fr_hard_header(skb, LMI_CCITT_ANSI_DLCI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) data = skb_tail_pointer(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) data[i++] = LMI_CALLREF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (lmi == LMI_ANSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) data[i++] = LMI_ANSI_LOCKSHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) LMI_ANSI_CISCO_REPTYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) data[i++] = LMI_REPT_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) data[i++] = LMI_INTEG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) data[i++] = state(hdlc)->txseq =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) fr_lmi_nextseq(state(hdlc)->txseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) data[i++] = state(hdlc)->rxseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (dce && fullrep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) while (pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) LMI_ANSI_CISCO_PVCSTAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) data[i++] = stat_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* LMI start/restart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (state(hdlc)->reliable && !pvc->state.exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) pvc->state.exist = pvc->state.new = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) fr_log_dlci_active(pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* ifconfig PVC up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (pvc->open_count && !pvc->state.active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) pvc->state.exist && !pvc->state.new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) pvc_carrier(1, pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) pvc->state.active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) fr_log_dlci_active(pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (lmi == LMI_CISCO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) data[i] = pvc->dlci >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) data[i + 1] = pvc->dlci & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) data[i] = (pvc->dlci >> 4) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) data[i + 1] = ((pvc->dlci << 3) & 0x78) | 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) data[i + 2] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (pvc->state.new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) data[i + 2] |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) else if (pvc->state.active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) data[i + 2] |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) i += stat_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) skb_put(skb, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) skb->priority = TC_PRIO_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) skb->protocol = htons(ETH_P_HDLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) dev_queue_xmit(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static void fr_set_link_state(int reliable, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct pvc_device *pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) state(hdlc)->reliable = reliable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (reliable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) netif_dormant_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) state(hdlc)->n391cnt = 0; /* Request full status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (state(hdlc)->settings.lmi == LMI_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) while (pvc) { /* Activate all PVCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) pvc_carrier(1, pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) pvc->state.exist = pvc->state.active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) pvc->state.new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) netif_dormant_on(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) while (pvc) { /* Deactivate all PVCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) pvc_carrier(0, pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) pvc->state.exist = pvc->state.active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) pvc->state.new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!state(hdlc)->settings.dce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) pvc->state.bandwidth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static void fr_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct frad_state *st = from_timer(st, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct net_device *dev = st->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int i, cnt = 0, reliable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) u32 list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (state(hdlc)->settings.dce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) reliable = state(hdlc)->request &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) time_before(jiffies, state(hdlc)->last_poll +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) state(hdlc)->settings.t392 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) state(hdlc)->request = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) state(hdlc)->last_errors <<= 1; /* Shift the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (state(hdlc)->request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (state(hdlc)->reliable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) netdev_info(dev, "No LMI status reply received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) state(hdlc)->last_errors |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) list = state(hdlc)->last_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) for (i = 0; i < state(hdlc)->settings.n393; i++, list >>= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) cnt += (list & 1); /* errors count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) reliable = (cnt < state(hdlc)->settings.n392);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (state(hdlc)->reliable != reliable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) netdev_info(dev, "Link %sreliable\n", reliable ? "" : "un");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) fr_set_link_state(reliable, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (state(hdlc)->settings.dce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) state(hdlc)->timer.expires = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) state(hdlc)->settings.t392 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (state(hdlc)->n391cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) state(hdlc)->n391cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) fr_lmi_send(dev, state(hdlc)->n391cnt == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) state(hdlc)->last_poll = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) state(hdlc)->request = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) state(hdlc)->timer.expires = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) state(hdlc)->settings.t391 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) add_timer(&state(hdlc)->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct pvc_device *pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) u8 rxseq, txseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int lmi = state(hdlc)->settings.lmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int dce = state(hdlc)->settings.dce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) LMI_CCITT_CISCO_LENGTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) netdev_info(dev, "Short LMI frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) NLPID_CCITT_ANSI_LMI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) netdev_info(dev, "Received non-LMI frame with LMI DLCI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (skb->data[4] != LMI_CALLREF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) netdev_info(dev, "Invalid LMI Call reference (0x%02X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) skb->data[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) netdev_info(dev, "Invalid LMI Message type (0x%02X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) skb->data[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (lmi == LMI_ANSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (skb->data[6] != LMI_ANSI_LOCKSHIFT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) netdev_info(dev, "Not ANSI locking shift in LMI message (0x%02X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) skb->data[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) i = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) i = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) LMI_ANSI_CISCO_REPTYPE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) netdev_info(dev, "Not an LMI Report type IE (0x%02X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) skb->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (skb->data[++i] != LMI_REPT_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) netdev_info(dev, "Invalid LMI Report type IE length (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) skb->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) reptype = skb->data[++i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) netdev_info(dev, "Unsupported LMI Report type (0x%02X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) reptype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) LMI_ANSI_CISCO_ALIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) netdev_info(dev, "Not an LMI Link integrity verification IE (0x%02X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) skb->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (skb->data[++i] != LMI_INTEG_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) netdev_info(dev, "Invalid LMI Link integrity verification IE length (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) skb->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) state(hdlc)->rxseq = skb->data[i++]; /* TX sequence from peer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) rxseq = skb->data[i++]; /* Should confirm our sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) txseq = state(hdlc)->txseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (dce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) state(hdlc)->last_poll = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (!state(hdlc)->reliable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) error = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (rxseq == 0 || rxseq != txseq) { /* Ask for full report next time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) state(hdlc)->n391cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) error = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (dce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (state(hdlc)->fullrep_sent && !error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* Stop sending full report - the last one has been confirmed by DTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) state(hdlc)->fullrep_sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) while (pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (pvc->state.new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) pvc->state.new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Tell DTE that new PVC is now active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (state(hdlc)->dce_changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) reptype = LMI_FULLREP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) state(hdlc)->fullrep_sent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) state(hdlc)->dce_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) state(hdlc)->request = 1; /* got request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* DTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) state(hdlc)->request = 0; /* got response, no request pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (reptype != LMI_FULLREP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) while (pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) pvc->state.deleted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) no_ram = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) while (skb->len >= i + 2 + stat_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) u16 dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) u32 bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned int active, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) LMI_ANSI_CISCO_PVCSTAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) netdev_info(dev, "Not an LMI PVC status IE (0x%02X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) skb->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (skb->data[++i] != stat_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) netdev_info(dev, "Invalid LMI PVC status IE length (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) skb->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) new = !! (skb->data[i + 2] & 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) active = !! (skb->data[i + 2] & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (lmi == LMI_CISCO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) dlci = (skb->data[i] << 8) | skb->data[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) bw = (skb->data[i + 3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) (skb->data[i + 4] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) (skb->data[i + 5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dlci = ((skb->data[i] & 0x3F) << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ((skb->data[i + 1] & 0x78) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) bw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) pvc = add_pvc(dev, dlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (!pvc && !no_ram) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) netdev_warn(dev, "Memory squeeze on fr_lmi_recv()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) no_ram = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) pvc->state.exist = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pvc->state.deleted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (active != pvc->state.active ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) new != pvc->state.new ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) bw != pvc->state.bandwidth ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) !pvc->state.exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) pvc->state.new = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) pvc->state.active = active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) pvc->state.bandwidth = bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) pvc_carrier(active, pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) fr_log_dlci_active(pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) i += stat_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) while (pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (pvc->state.deleted && pvc->state.exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) pvc_carrier(0, pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) pvc->state.active = pvc->state.new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) pvc->state.exist = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) pvc->state.bandwidth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) fr_log_dlci_active(pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* Next full report after N391 polls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) state(hdlc)->n391cnt = state(hdlc)->settings.n391;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static int fr_rx(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct net_device *frad = skb->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) hdlc_device *hdlc = dev_to_hdlc(frad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct fr_hdr *fh = (struct fr_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) u8 *data = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) u16 dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct pvc_device *pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct net_device *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) goto rx_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) dlci = q922_to_dlci(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if ((dlci == LMI_CCITT_ANSI_DLCI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) (state(hdlc)->settings.lmi == LMI_ANSI ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) state(hdlc)->settings.lmi == LMI_CCITT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) (dlci == LMI_CISCO_DLCI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) state(hdlc)->settings.lmi == LMI_CISCO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (fr_lmi_recv(frad, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) goto rx_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) pvc = find_pvc(hdlc, dlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (!pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) #ifdef DEBUG_PKT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) netdev_info(frad, "No PVC for received frame's DLCI %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) dlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (pvc->state.fecn != fh->fecn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) #ifdef DEBUG_ECN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", frad->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) dlci, fh->fecn ? "N" : "FF");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) pvc->state.fecn ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (pvc->state.becn != fh->becn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) #ifdef DEBUG_ECN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", frad->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) dlci, fh->becn ? "N" : "FF");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) pvc->state.becn ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) frad->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (data[3] == NLPID_IP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) dev = pvc->main;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) skb->protocol = htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) } else if (data[3] == NLPID_IPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) dev = pvc->main;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) skb->protocol = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) } else if (skb->len > 10 && data[3] == FR_PAD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) data[4] == NLPID_SNAP && data[5] == FR_PAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) u16 oui = ntohs(*(__be16*)(data + 6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) u16 pid = ntohs(*(__be16*)(data + 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) skb_pull(skb, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) switch ((((u32)oui) << 16) | pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) case ETH_P_ARP: /* routed frame with SNAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) case ETH_P_IPX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case ETH_P_IP: /* a long variant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) case ETH_P_IPV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) dev = pvc->main;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) skb->protocol = htons(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case 0x80C20007: /* bridged Ethernet frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if ((dev = pvc->ether) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) skb->protocol = eth_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) netdev_info(frad, "Unsupported protocol, OUI=%x PID=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) oui, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) netdev_info(frad, "Unsupported protocol, NLPID=%x length=%i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) data[3], skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) dev->stats.rx_packets++; /* PVC traffic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) dev->stats.rx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (pvc->state.becn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) dev->stats.rx_compressed++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) rx_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) frad->stats.rx_errors++; /* Mark error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static void fr_start(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) #ifdef DEBUG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) printk(KERN_DEBUG "fr_start\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (state(hdlc)->settings.lmi != LMI_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) state(hdlc)->reliable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) state(hdlc)->request = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) state(hdlc)->fullrep_sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) state(hdlc)->last_errors = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) state(hdlc)->n391cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) state(hdlc)->txseq = state(hdlc)->rxseq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) state(hdlc)->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) timer_setup(&state(hdlc)->timer, fr_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /* First poll after 1 s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) state(hdlc)->timer.expires = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) add_timer(&state(hdlc)->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) fr_set_link_state(1, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static void fr_stop(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) #ifdef DEBUG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) printk(KERN_DEBUG "fr_stop\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (state(hdlc)->settings.lmi != LMI_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) del_timer_sync(&state(hdlc)->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) fr_set_link_state(0, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static void fr_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct pvc_device *pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) while (pvc) { /* Shutdown all PVCs for this FRAD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (pvc->main)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) dev_close(pvc->main);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (pvc->ether)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) dev_close(pvc->ether);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) pvc = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static void pvc_setup(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) dev->type = ARPHRD_DLCI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) dev->flags = IFF_POINTOPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) dev->hard_header_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) dev->addr_len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) netif_keep_dst(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static const struct net_device_ops pvc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .ndo_open = pvc_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .ndo_stop = pvc_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .ndo_start_xmit = pvc_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .ndo_do_ioctl = pvc_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) hdlc_device *hdlc = dev_to_hdlc(frad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct pvc_device *pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) int used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if ((pvc = add_pvc(frad, dlci)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) netdev_warn(frad, "Memory squeeze on fr_add_pvc()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (*get_dev_p(pvc, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) used = pvc_is_used(pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (type == ARPHRD_ETHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) dev = alloc_netdev(0, "pvceth%d", NET_NAME_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ether_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) dev = alloc_netdev(0, "pvc%d", NET_NAME_UNKNOWN, pvc_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) netdev_warn(frad, "Memory squeeze on fr_pvc()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) delete_unused_pvcs(hdlc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (type == ARPHRD_ETHER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) dev->priv_flags &= ~IFF_TX_SKB_SHARING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) eth_hw_addr_random(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) *(__be16*)dev->dev_addr = htons(dlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) dlci_to_q922(dev->broadcast, dlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) dev->netdev_ops = &pvc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) dev->mtu = HDLC_MAX_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dev->min_mtu = 68;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) dev->max_mtu = HDLC_MAX_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dev->needed_headroom = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) dev->priv_flags |= IFF_NO_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dev->ml_priv = pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (register_netdevice(dev) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) delete_unused_pvcs(hdlc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) dev->needs_free_netdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) *get_dev_p(pvc, type) = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (!used) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) state(hdlc)->dce_pvc_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) struct pvc_device *pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if ((pvc = find_pvc(hdlc, dlci)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if ((dev = *get_dev_p(pvc, type)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (dev->flags & IFF_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) return -EBUSY; /* PVC in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) unregister_netdevice(dev); /* the destructor will free_netdev(dev) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) *get_dev_p(pvc, type) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (!pvc_is_used(pvc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) state(hdlc)->dce_pvc_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) delete_unused_pvcs(hdlc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static void fr_destroy(struct net_device *frad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) hdlc_device *hdlc = dev_to_hdlc(frad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct pvc_device *pvc = state(hdlc)->first_pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) state(hdlc)->first_pvc = NULL; /* All PVCs destroyed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) state(hdlc)->dce_pvc_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) state(hdlc)->dce_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) while (pvc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct pvc_device *next = pvc->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* destructors will free_netdev() main and ether */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (pvc->main)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) unregister_netdevice(pvc->main);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (pvc->ether)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) unregister_netdevice(pvc->ether);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) kfree(pvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) pvc = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static struct hdlc_proto proto = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) .close = fr_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) .start = fr_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) .stop = fr_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) .detach = fr_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) .ioctl = fr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) .netif_rx = fr_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) const size_t size = sizeof(fr_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) fr_proto new_settings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) fr_proto_pvc pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) switch (ifr->ifr_settings.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) case IF_GET_PROTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ifr->ifr_settings.type = IF_PROTO_FR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (ifr->ifr_settings.size < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ifr->ifr_settings.size = size; /* data size wanted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (copy_to_user(fr_s, &state(hdlc)->settings, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) case IF_PROTO_FR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (dev->flags & IFF_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (copy_from_user(&new_settings, fr_s, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (new_settings.lmi == LMI_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) new_settings.lmi = LMI_ANSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if ((new_settings.lmi != LMI_NONE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) new_settings.lmi != LMI_ANSI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) new_settings.lmi != LMI_CCITT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) new_settings.lmi != LMI_CISCO) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) new_settings.t391 < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) new_settings.t392 < 2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) new_settings.n391 < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) new_settings.n392 < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) new_settings.n393 < new_settings.n392 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) new_settings.n393 > 32 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) (new_settings.dce != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) new_settings.dce != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) result = attach_hdlc_protocol(dev, &proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) sizeof(struct frad_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) state(hdlc)->first_pvc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) state(hdlc)->dce_pvc_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) memcpy(&state(hdlc)->settings, &new_settings, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) dev->type = ARPHRD_FRAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) case IF_PROTO_FR_ADD_PVC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) case IF_PROTO_FR_DEL_PVC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) case IF_PROTO_FR_ADD_ETH_PVC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) case IF_PROTO_FR_DEL_ETH_PVC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if (copy_from_user(&pvc, ifr->ifr_settings.ifs_ifsu.fr_pvc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) sizeof(fr_proto_pvc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if (pvc.dlci <= 0 || pvc.dlci >= 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return -EINVAL; /* Only 10 bits, DLCI 0 reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) result = ARPHRD_ETHER; /* bridged Ethernet device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) result = ARPHRD_DLCI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return fr_add_pvc(dev, pvc.dlci, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return fr_del_pvc(hdlc, pvc.dlci, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static int __init mod_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) register_hdlc_protocol(&proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) static void __exit mod_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) unregister_hdlc_protocol(&proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) module_init(mod_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) module_exit(mod_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) MODULE_LICENSE("GPL v2");