diff options
Diffstat (limited to 'drivers/net/wan/hdlc_fr.c')
-rw-r--r-- | drivers/net/wan/hdlc_fr.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 071a64cacd5c..c4ab0326f911 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/skbuff.h> | 43 | #include <linux/skbuff.h> |
44 | #include <linux/pkt_sched.h> | 44 | #include <linux/pkt_sched.h> |
45 | #include <linux/random.h> | ||
46 | #include <linux/inetdevice.h> | 45 | #include <linux/inetdevice.h> |
47 | #include <linux/lapb.h> | 46 | #include <linux/lapb.h> |
48 | #include <linux/rtnetlink.h> | 47 | #include <linux/rtnetlink.h> |
@@ -136,6 +135,10 @@ typedef struct pvc_device_struct { | |||
136 | }state; | 135 | }state; |
137 | }pvc_device; | 136 | }pvc_device; |
138 | 137 | ||
138 | struct pvc_desc { | ||
139 | struct net_device_stats stats; | ||
140 | pvc_device *pvc; | ||
141 | }; | ||
139 | 142 | ||
140 | struct frad_state { | 143 | struct frad_state { |
141 | fr_proto settings; | 144 | fr_proto settings; |
@@ -171,17 +174,20 @@ static inline void dlci_to_q922(u8 *hdr, u16 dlci) | |||
171 | } | 174 | } |
172 | 175 | ||
173 | 176 | ||
174 | static inline struct frad_state * state(hdlc_device *hdlc) | 177 | static inline struct frad_state* state(hdlc_device *hdlc) |
175 | { | 178 | { |
176 | return(struct frad_state *)(hdlc->state); | 179 | return(struct frad_state *)(hdlc->state); |
177 | } | 180 | } |
178 | 181 | ||
179 | 182 | static inline struct pvc_desc* pvcdev_to_desc(struct net_device *dev) | |
180 | static __inline__ pvc_device* dev_to_pvc(struct net_device *dev) | ||
181 | { | 183 | { |
182 | return dev->priv; | 184 | return dev->priv; |
183 | } | 185 | } |
184 | 186 | ||
187 | static inline struct net_device_stats* pvc_get_stats(struct net_device *dev) | ||
188 | { | ||
189 | return &pvcdev_to_desc(dev)->stats; | ||
190 | } | ||
185 | 191 | ||
186 | static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) | 192 | static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) |
187 | { | 193 | { |
@@ -351,7 +357,7 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) | |||
351 | 357 | ||
352 | static int pvc_open(struct net_device *dev) | 358 | static int pvc_open(struct net_device *dev) |
353 | { | 359 | { |
354 | pvc_device *pvc = dev_to_pvc(dev); | 360 | pvc_device *pvc = pvcdev_to_desc(dev)->pvc; |
355 | 361 | ||
356 | if ((pvc->frad->flags & IFF_UP) == 0) | 362 | if ((pvc->frad->flags & IFF_UP) == 0) |
357 | return -EIO; /* Frad must be UP in order to activate PVC */ | 363 | return -EIO; /* Frad must be UP in order to activate PVC */ |
@@ -371,7 +377,7 @@ static int pvc_open(struct net_device *dev) | |||
371 | 377 | ||
372 | static int pvc_close(struct net_device *dev) | 378 | static int pvc_close(struct net_device *dev) |
373 | { | 379 | { |
374 | pvc_device *pvc = dev_to_pvc(dev); | 380 | pvc_device *pvc = pvcdev_to_desc(dev)->pvc; |
375 | 381 | ||
376 | if (--pvc->open_count == 0) { | 382 | if (--pvc->open_count == 0) { |
377 | hdlc_device *hdlc = dev_to_hdlc(pvc->frad); | 383 | hdlc_device *hdlc = dev_to_hdlc(pvc->frad); |
@@ -390,7 +396,7 @@ static int pvc_close(struct net_device *dev) | |||
390 | 396 | ||
391 | static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 397 | static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
392 | { | 398 | { |
393 | pvc_device *pvc = dev_to_pvc(dev); | 399 | pvc_device *pvc = pvcdev_to_desc(dev)->pvc; |
394 | fr_proto_pvc_info info; | 400 | fr_proto_pvc_info info; |
395 | 401 | ||
396 | if (ifr->ifr_settings.type == IF_GET_PROTO) { | 402 | if (ifr->ifr_settings.type == IF_GET_PROTO) { |
@@ -416,17 +422,9 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
416 | return -EINVAL; | 422 | return -EINVAL; |
417 | } | 423 | } |
418 | 424 | ||
419 | |||
420 | static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) | ||
421 | { | ||
422 | return &dev_to_desc(dev)->stats; | ||
423 | } | ||
424 | |||
425 | |||
426 | |||
427 | static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) | 425 | static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) |
428 | { | 426 | { |
429 | pvc_device *pvc = dev_to_pvc(dev); | 427 | pvc_device *pvc = pvcdev_to_desc(dev)->pvc; |
430 | struct net_device_stats *stats = pvc_get_stats(dev); | 428 | struct net_device_stats *stats = pvc_get_stats(dev); |
431 | 429 | ||
432 | if (pvc->state.active) { | 430 | if (pvc->state.active) { |
@@ -957,7 +955,7 @@ static int fr_rx(struct sk_buff *skb) | |||
957 | 955 | ||
958 | 956 | ||
959 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { | 957 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { |
960 | dev_to_desc(frad)->stats.rx_dropped++; | 958 | dev_to_hdlc(frad)->stats.rx_dropped++; |
961 | return NET_RX_DROP; | 959 | return NET_RX_DROP; |
962 | } | 960 | } |
963 | 961 | ||
@@ -1018,7 +1016,7 @@ static int fr_rx(struct sk_buff *skb) | |||
1018 | } | 1016 | } |
1019 | 1017 | ||
1020 | rx_error: | 1018 | rx_error: |
1021 | dev_to_desc(frad)->stats.rx_errors++; /* Mark error */ | 1019 | dev_to_hdlc(frad)->stats.rx_errors++; /* Mark error */ |
1022 | dev_kfree_skb_any(skb); | 1020 | dev_kfree_skb_any(skb); |
1023 | return NET_RX_DROP; | 1021 | return NET_RX_DROP; |
1024 | } | 1022 | } |
@@ -1109,11 +1107,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) | |||
1109 | used = pvc_is_used(pvc); | 1107 | used = pvc_is_used(pvc); |
1110 | 1108 | ||
1111 | if (type == ARPHRD_ETHER) | 1109 | if (type == ARPHRD_ETHER) |
1112 | dev = alloc_netdev(sizeof(struct net_device_stats), | 1110 | dev = alloc_netdev(sizeof(struct pvc_desc), "pvceth%d", |
1113 | "pvceth%d", ether_setup); | 1111 | ether_setup); |
1114 | else | 1112 | else |
1115 | dev = alloc_netdev(sizeof(struct net_device_stats), | 1113 | dev = alloc_netdev(sizeof(struct pvc_desc), "pvc%d", pvc_setup); |
1116 | "pvc%d", pvc_setup); | ||
1117 | 1114 | ||
1118 | if (!dev) { | 1115 | if (!dev) { |
1119 | printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", | 1116 | printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", |
@@ -1122,10 +1119,9 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) | |||
1122 | return -ENOBUFS; | 1119 | return -ENOBUFS; |
1123 | } | 1120 | } |
1124 | 1121 | ||
1125 | if (type == ARPHRD_ETHER) { | 1122 | if (type == ARPHRD_ETHER) |
1126 | memcpy(dev->dev_addr, "\x00\x01", 2); | 1123 | random_ether_addr(dev->dev_addr); |
1127 | get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); | 1124 | else { |
1128 | } else { | ||
1129 | *(__be16*)dev->dev_addr = htons(dlci); | 1125 | *(__be16*)dev->dev_addr = htons(dlci); |
1130 | dlci_to_q922(dev->broadcast, dlci); | 1126 | dlci_to_q922(dev->broadcast, dlci); |
1131 | } | 1127 | } |
@@ -1137,7 +1133,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) | |||
1137 | dev->change_mtu = pvc_change_mtu; | 1133 | dev->change_mtu = pvc_change_mtu; |
1138 | dev->mtu = HDLC_MAX_MTU; | 1134 | dev->mtu = HDLC_MAX_MTU; |
1139 | dev->tx_queue_len = 0; | 1135 | dev->tx_queue_len = 0; |
1140 | dev->priv = pvc; | 1136 | pvcdev_to_desc(dev)->pvc = pvc; |
1141 | 1137 | ||
1142 | result = dev_alloc_name(dev, dev->name); | 1138 | result = dev_alloc_name(dev, dev->name); |
1143 | if (result < 0) { | 1139 | if (result < 0) { |
@@ -1219,6 +1215,7 @@ static struct hdlc_proto proto = { | |||
1219 | .stop = fr_stop, | 1215 | .stop = fr_stop, |
1220 | .detach = fr_destroy, | 1216 | .detach = fr_destroy, |
1221 | .ioctl = fr_ioctl, | 1217 | .ioctl = fr_ioctl, |
1218 | .netif_rx = fr_rx, | ||
1222 | .module = THIS_MODULE, | 1219 | .module = THIS_MODULE, |
1223 | }; | 1220 | }; |
1224 | 1221 | ||
@@ -1277,7 +1274,7 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
1277 | return result; | 1274 | return result; |
1278 | 1275 | ||
1279 | if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */ | 1276 | if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */ |
1280 | result = attach_hdlc_protocol(dev, &proto, fr_rx, | 1277 | result = attach_hdlc_protocol(dev, &proto, |
1281 | sizeof(struct frad_state)); | 1278 | sizeof(struct frad_state)); |
1282 | if (result) | 1279 | if (result) |
1283 | return result; | 1280 | return result; |