aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wan/c101.c26
-rw-r--r--drivers/net/wan/hd6457x.c26
-rw-r--r--drivers/net/wan/hdlc_cisco.c14
-rw-r--r--drivers/net/wan/hdlc_fr.c14
-rw-r--r--drivers/net/wan/hdlc_generic.c65
-rw-r--r--drivers/net/wan/wanxl.c5
-rw-r--r--include/linux/hdlc.h2
7 files changed, 82 insertions, 70 deletions
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index c92ac9fde083..2c09ec908a3f 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -116,27 +116,33 @@ static inline void openwin(card_t *card, u8 page)
116#include "hd6457x.c" 116#include "hd6457x.c"
117 117
118 118
119static inline void set_carrier(port_t *port)
120{
121 if (!sca_in(MSCI1_OFFSET + ST3, port) & ST3_DCD)
122 netif_carrier_on(port_to_dev(port));
123 else
124 netif_carrier_off(port_to_dev(port));
125}
126
127
119static void sca_msci_intr(port_t *port) 128static void sca_msci_intr(port_t *port)
120{ 129{
121 struct net_device *dev = port_to_dev(port); 130 u8 stat = sca_in(MSCI1_OFFSET + ST1, port); /* read MSCI ST1 status */
122 card_t* card = port_to_card(port);
123 u8 stat = sca_in(MSCI1_OFFSET + ST1, card); /* read MSCI ST1 status */
124 131
125 /* Reset MSCI TX underrun status bit */ 132 /* Reset MSCI TX underrun status bit */
126 sca_out(stat & ST1_UDRN, MSCI0_OFFSET + ST1, card); 133 sca_out(stat & ST1_UDRN, MSCI0_OFFSET + ST1, port);
127 134
128 if (stat & ST1_UDRN) { 135 if (stat & ST1_UDRN) {
129 struct net_device_stats *stats = hdlc_stats(dev); 136 struct net_device_stats *stats = hdlc_stats(port_to_dev(port));
130 stats->tx_errors++; /* TX Underrun error detected */ 137 stats->tx_errors++; /* TX Underrun error detected */
131 stats->tx_fifo_errors++; 138 stats->tx_fifo_errors++;
132 } 139 }
133 140
134 /* Reset MSCI CDCD status bit - uses ch#2 DCD input */ 141 /* Reset MSCI CDCD status bit - uses ch#2 DCD input */
135 sca_out(stat & ST1_CDCD, MSCI1_OFFSET + ST1, card); 142 sca_out(stat & ST1_CDCD, MSCI1_OFFSET + ST1, port);
136 143
137 if (stat & ST1_CDCD) 144 if (stat & ST1_CDCD)
138 hdlc_set_carrier(!(sca_in(MSCI1_OFFSET + ST3, card) & ST3_DCD), 145 set_carrier(port);
139 dev);
140} 146}
141 147
142 148
@@ -190,7 +196,7 @@ static int c101_open(struct net_device *dev)
190 sca_out(IE1_UDRN, MSCI0_OFFSET + IE1, port); 196 sca_out(IE1_UDRN, MSCI0_OFFSET + IE1, port);
191 sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port); 197 sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port);
192 198
193 hdlc_set_carrier(!(sca_in(MSCI1_OFFSET + ST3, port) & ST3_DCD), dev); 199 set_carrier(port);
194 printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port)); 200 printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port));
195 201
196 /* enable MSCI1 CDCD interrupt */ 202 /* enable MSCI1 CDCD interrupt */
@@ -378,7 +384,7 @@ static int __init c101_run(unsigned long irq, unsigned long winbase)
378 } 384 }
379 385
380 sca_init_sync_port(card); /* Set up C101 memory */ 386 sca_init_sync_port(card); /* Set up C101 memory */
381 hdlc_set_carrier(!(sca_in(MSCI1_OFFSET + ST3, card) & ST3_DCD), dev); 387 set_carrier(card);
382 388
383 printk(KERN_INFO "%s: Moxa C101 on IRQ%u," 389 printk(KERN_INFO "%s: Moxa C101 on IRQ%u,"
384 " using %u TX + %u RX packets rings\n", 390 " using %u TX + %u RX packets rings\n",
diff --git a/drivers/net/wan/hd6457x.c b/drivers/net/wan/hd6457x.c
index d3743321a977..dce2bb317b82 100644
--- a/drivers/net/wan/hd6457x.c
+++ b/drivers/net/wan/hd6457x.c
@@ -168,6 +168,23 @@ static inline u32 buffer_offset(port_t *port, u16 desc, int transmit)
168} 168}
169 169
170 170
171static inline void sca_set_carrier(port_t *port)
172{
173 if (!(sca_in(get_msci(port) + ST3, port_to_card(port)) & ST3_DCD)) {
174#ifdef DEBUG_LINK
175 printk(KERN_DEBUG "%s: sca_set_carrier on\n",
176 port_to_dev(port)->name);
177#endif
178 netif_carrier_on(port_to_dev(port));
179 } else {
180#ifdef DEBUG_LINK
181 printk(KERN_DEBUG "%s: sca_set_carrier off\n",
182 port_to_dev(port)->name);
183#endif
184 netif_carrier_off(port_to_dev(port));
185 }
186}
187
171 188
172static void sca_init_sync_port(port_t *port) 189static void sca_init_sync_port(port_t *port)
173{ 190{
@@ -237,9 +254,7 @@ static void sca_init_sync_port(port_t *port)
237 sca_out(DIR_BOFE, DIR_TX(phy_node(port)), card); 254 sca_out(DIR_BOFE, DIR_TX(phy_node(port)), card);
238 } 255 }
239 } 256 }
240 257 sca_set_carrier(port);
241 hdlc_set_carrier(!(sca_in(get_msci(port) + ST3, card) & ST3_DCD),
242 port_to_dev(port));
243} 258}
244 259
245 260
@@ -262,8 +277,7 @@ static inline void sca_msci_intr(port_t *port)
262 } 277 }
263 278
264 if (stat & ST1_CDCD) 279 if (stat & ST1_CDCD)
265 hdlc_set_carrier(!(sca_in(msci + ST3, card) & ST3_DCD), 280 sca_set_carrier(port);
266 port_to_dev(port));
267} 281}
268#endif 282#endif
269 283
@@ -566,7 +580,7 @@ static void sca_open(struct net_device *dev)
566 - all DMA interrupts 580 - all DMA interrupts
567*/ 581*/
568 582
569 hdlc_set_carrier(!(sca_in(msci + ST3, card) & ST3_DCD), dev); 583 sca_set_carrier(port);
570 584
571#ifdef __HD64570_H 585#ifdef __HD64570_H
572 /* MSCI TX INT and RX INT A IRQ enable */ 586 /* MSCI TX INT and RX INT A IRQ enable */
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 1fd04662c4fc..f289daba0c7b 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -192,9 +192,7 @@ static int cisco_rx(struct sk_buff *skb)
192 "uptime %ud%uh%um%us)\n", 192 "uptime %ud%uh%um%us)\n",
193 dev->name, days, hrs, 193 dev->name, days, hrs,
194 min, sec); 194 min, sec);
195#if 0 195 netif_dormant_off(dev);
196 netif_carrier_on(dev);
197#endif
198 hdlc->state.cisco.up = 1; 196 hdlc->state.cisco.up = 1;
199 } 197 }
200 } 198 }
@@ -227,9 +225,7 @@ static void cisco_timer(unsigned long arg)
227 hdlc->state.cisco.settings.timeout * HZ)) { 225 hdlc->state.cisco.settings.timeout * HZ)) {
228 hdlc->state.cisco.up = 0; 226 hdlc->state.cisco.up = 0;
229 printk(KERN_INFO "%s: Link down\n", dev->name); 227 printk(KERN_INFO "%s: Link down\n", dev->name);
230#if 0 228 netif_dormant_on(dev);
231 netif_carrier_off(dev);
232#endif
233 } 229 }
234 230
235 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, 231 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
@@ -265,10 +261,7 @@ static void cisco_stop(struct net_device *dev)
265{ 261{
266 hdlc_device *hdlc = dev_to_hdlc(dev); 262 hdlc_device *hdlc = dev_to_hdlc(dev);
267 del_timer_sync(&hdlc->state.cisco.timer); 263 del_timer_sync(&hdlc->state.cisco.timer);
268#if 0 264 netif_dormant_on(dev);
269 if (netif_carrier_ok(dev))
270 netif_carrier_off(dev);
271#endif
272 hdlc->state.cisco.up = 0; 265 hdlc->state.cisco.up = 0;
273 hdlc->state.cisco.request_sent = 0; 266 hdlc->state.cisco.request_sent = 0;
274} 267}
@@ -328,6 +321,7 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
328 dev->type = ARPHRD_CISCO; 321 dev->type = ARPHRD_CISCO;
329 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 322 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
330 dev->addr_len = 0; 323 dev->addr_len = 0;
324 netif_dormant_on(dev);
331 return 0; 325 return 0;
332 } 326 }
333 327
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 523afe17564e..7bb737bbdeb9 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -301,7 +301,7 @@ static int pvc_open(struct net_device *dev)
301 if (pvc->open_count++ == 0) { 301 if (pvc->open_count++ == 0) {
302 hdlc_device *hdlc = dev_to_hdlc(pvc->master); 302 hdlc_device *hdlc = dev_to_hdlc(pvc->master);
303 if (hdlc->state.fr.settings.lmi == LMI_NONE) 303 if (hdlc->state.fr.settings.lmi == LMI_NONE)
304 pvc->state.active = hdlc->carrier; 304 pvc->state.active = netif_carrier_ok(pvc->master);
305 305
306 pvc_carrier(pvc->state.active, pvc); 306 pvc_carrier(pvc->state.active, pvc);
307 hdlc->state.fr.dce_changed = 1; 307 hdlc->state.fr.dce_changed = 1;
@@ -545,11 +545,7 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
545 545
546 hdlc->state.fr.reliable = reliable; 546 hdlc->state.fr.reliable = reliable;
547 if (reliable) { 547 if (reliable) {
548#if 0 548 netif_dormant_off(dev);
549 if (!netif_carrier_ok(dev))
550 netif_carrier_on(dev);
551#endif
552
553 hdlc->state.fr.n391cnt = 0; /* Request full status */ 549 hdlc->state.fr.n391cnt = 0; /* Request full status */
554 hdlc->state.fr.dce_changed = 1; 550 hdlc->state.fr.dce_changed = 1;
555 551
@@ -562,11 +558,7 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
562 } 558 }
563 } 559 }
564 } else { 560 } else {
565#if 0 561 netif_dormant_on(dev);
566 if (netif_carrier_ok(dev))
567 netif_carrier_off(dev);
568#endif
569
570 while (pvc) { /* Deactivate all PVCs */ 562 while (pvc) { /* Deactivate all PVCs */
571 pvc_carrier(0, pvc); 563 pvc_carrier(0, pvc);
572 pvc->state.exist = pvc->state.active = 0; 564 pvc->state.exist = pvc->state.active = 0;
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c
index b7da55140fbd..04ca1f7b6424 100644
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc_generic.c
@@ -34,10 +34,11 @@
34#include <linux/inetdevice.h> 34#include <linux/inetdevice.h>
35#include <linux/lapb.h> 35#include <linux/lapb.h>
36#include <linux/rtnetlink.h> 36#include <linux/rtnetlink.h>
37#include <linux/notifier.h>
37#include <linux/hdlc.h> 38#include <linux/hdlc.h>
38 39
39 40
40static const char* version = "HDLC support module revision 1.18"; 41static const char* version = "HDLC support module revision 1.19";
41 42
42#undef DEBUG_LINK 43#undef DEBUG_LINK
43 44
@@ -73,57 +74,51 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
73 74
74 75
75 76
76static void __hdlc_set_carrier_on(struct net_device *dev) 77static inline void hdlc_proto_start(struct net_device *dev)
77{ 78{
78 hdlc_device *hdlc = dev_to_hdlc(dev); 79 hdlc_device *hdlc = dev_to_hdlc(dev);
79 if (hdlc->proto.start) 80 if (hdlc->proto.start)
80 return hdlc->proto.start(dev); 81 return hdlc->proto.start(dev);
81#if 0
82#ifdef DEBUG_LINK
83 if (netif_carrier_ok(dev))
84 printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
85#endif
86 netif_carrier_on(dev);
87#endif
88} 82}
89 83
90 84
91 85
92static void __hdlc_set_carrier_off(struct net_device *dev) 86static inline void hdlc_proto_stop(struct net_device *dev)
93{ 87{
94 hdlc_device *hdlc = dev_to_hdlc(dev); 88 hdlc_device *hdlc = dev_to_hdlc(dev);
95 if (hdlc->proto.stop) 89 if (hdlc->proto.stop)
96 return hdlc->proto.stop(dev); 90 return hdlc->proto.stop(dev);
97
98#if 0
99#ifdef DEBUG_LINK
100 if (!netif_carrier_ok(dev))
101 printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
102#endif
103 netif_carrier_off(dev);
104#endif
105} 91}
106 92
107 93
108 94
109void hdlc_set_carrier(int on, struct net_device *dev) 95static int hdlc_device_event(struct notifier_block *this, unsigned long event,
96 void *ptr)
110{ 97{
111 hdlc_device *hdlc = dev_to_hdlc(dev); 98 struct net_device *dev = ptr;
99 hdlc_device *hdlc;
112 unsigned long flags; 100 unsigned long flags;
113 on = on ? 1 : 0; 101 int on;
102
103 if (dev->get_stats != hdlc_get_stats)
104 return NOTIFY_DONE; /* not an HDLC device */
105
106 if (event != NETDEV_CHANGE)
107 return NOTIFY_DONE; /* Only interrested in carrier changes */
108
109 on = netif_carrier_ok(dev);
114 110
115#ifdef DEBUG_LINK 111#ifdef DEBUG_LINK
116 printk(KERN_DEBUG "hdlc_set_carrier %i\n", on); 112 printk(KERN_DEBUG "%s: hdlc_device_event NETDEV_CHANGE, carrier %i\n",
113 dev->name, on);
117#endif 114#endif
118 115
116 hdlc = dev_to_hdlc(dev);
119 spin_lock_irqsave(&hdlc->state_lock, flags); 117 spin_lock_irqsave(&hdlc->state_lock, flags);
120 118
121 if (hdlc->carrier == on) 119 if (hdlc->carrier == on)
122 goto carrier_exit; /* no change in DCD line level */ 120 goto carrier_exit; /* no change in DCD line level */
123 121
124#ifdef DEBUG_LINK
125 printk(KERN_INFO "%s: carrier %s\n", dev->name, on ? "ON" : "off");
126#endif
127 hdlc->carrier = on; 122 hdlc->carrier = on;
128 123
129 if (!hdlc->open) 124 if (!hdlc->open)
@@ -131,14 +126,15 @@ void hdlc_set_carrier(int on, struct net_device *dev)
131 126
132 if (hdlc->carrier) { 127 if (hdlc->carrier) {
133 printk(KERN_INFO "%s: Carrier detected\n", dev->name); 128 printk(KERN_INFO "%s: Carrier detected\n", dev->name);
134 __hdlc_set_carrier_on(dev); 129 hdlc_proto_start(dev);
135 } else { 130 } else {
136 printk(KERN_INFO "%s: Carrier lost\n", dev->name); 131 printk(KERN_INFO "%s: Carrier lost\n", dev->name);
137 __hdlc_set_carrier_off(dev); 132 hdlc_proto_stop(dev);
138 } 133 }
139 134
140carrier_exit: 135carrier_exit:
141 spin_unlock_irqrestore(&hdlc->state_lock, flags); 136 spin_unlock_irqrestore(&hdlc->state_lock, flags);
137 return NOTIFY_DONE;
142} 138}
143 139
144 140
@@ -165,7 +161,7 @@ int hdlc_open(struct net_device *dev)
165 161
166 if (hdlc->carrier) { 162 if (hdlc->carrier) {
167 printk(KERN_INFO "%s: Carrier detected\n", dev->name); 163 printk(KERN_INFO "%s: Carrier detected\n", dev->name);
168 __hdlc_set_carrier_on(dev); 164 hdlc_proto_start(dev);
169 } else 165 } else
170 printk(KERN_INFO "%s: No carrier\n", dev->name); 166 printk(KERN_INFO "%s: No carrier\n", dev->name);
171 167
@@ -190,7 +186,7 @@ void hdlc_close(struct net_device *dev)
190 186
191 hdlc->open = 0; 187 hdlc->open = 0;
192 if (hdlc->carrier) 188 if (hdlc->carrier)
193 __hdlc_set_carrier_off(dev); 189 hdlc_proto_stop(dev);
194 190
195 spin_unlock_irq(&hdlc->state_lock); 191 spin_unlock_irq(&hdlc->state_lock);
196 192
@@ -303,7 +299,6 @@ MODULE_LICENSE("GPL v2");
303 299
304EXPORT_SYMBOL(hdlc_open); 300EXPORT_SYMBOL(hdlc_open);
305EXPORT_SYMBOL(hdlc_close); 301EXPORT_SYMBOL(hdlc_close);
306EXPORT_SYMBOL(hdlc_set_carrier);
307EXPORT_SYMBOL(hdlc_ioctl); 302EXPORT_SYMBOL(hdlc_ioctl);
308EXPORT_SYMBOL(hdlc_setup); 303EXPORT_SYMBOL(hdlc_setup);
309EXPORT_SYMBOL(alloc_hdlcdev); 304EXPORT_SYMBOL(alloc_hdlcdev);
@@ -315,9 +310,18 @@ static struct packet_type hdlc_packet_type = {
315}; 310};
316 311
317 312
313static struct notifier_block hdlc_notifier = {
314 .notifier_call = hdlc_device_event,
315};
316
317
318static int __init hdlc_module_init(void) 318static int __init hdlc_module_init(void)
319{ 319{
320 int result;
321
320 printk(KERN_INFO "%s\n", version); 322 printk(KERN_INFO "%s\n", version);
323 if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0)
324 return result;
321 dev_add_pack(&hdlc_packet_type); 325 dev_add_pack(&hdlc_packet_type);
322 return 0; 326 return 0;
323} 327}
@@ -327,6 +331,7 @@ static int __init hdlc_module_init(void)
327static void __exit hdlc_module_exit(void) 331static void __exit hdlc_module_exit(void)
328{ 332{
329 dev_remove_pack(&hdlc_packet_type); 333 dev_remove_pack(&hdlc_packet_type);
334 unregister_netdevice_notifier(&hdlc_notifier);
330} 335}
331 336
332 337
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index d564224cdca9..b2031dfc4bb1 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -149,7 +149,10 @@ static inline void wanxl_cable_intr(port_t *port)
149 printk(KERN_INFO "%s: %s%s module, %s cable%s%s\n", 149 printk(KERN_INFO "%s: %s%s module, %s cable%s%s\n",
150 port->dev->name, pm, dte, cable, dsr, dcd); 150 port->dev->name, pm, dte, cable, dsr, dcd);
151 151
152 hdlc_set_carrier(value & STATUS_CABLE_DCD, port->dev); 152 if (value & STATUS_CABLE_DCD)
153 netif_carrier_on(port->dev);
154 else
155 netif_carrier_off(port->dev);
153} 156}
154 157
155 158
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index 4513f9e40937..d5ebbb29aeae 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -224,8 +224,6 @@ static __inline__ void debug_frame(const struct sk_buff *skb)
224int hdlc_open(struct net_device *dev); 224int hdlc_open(struct net_device *dev);
225/* Must be called by hardware driver when HDLC device is being closed */ 225/* Must be called by hardware driver when HDLC device is being closed */
226void hdlc_close(struct net_device *dev); 226void hdlc_close(struct net_device *dev);
227/* Called by hardware driver when DCD line level changes */
228void hdlc_set_carrier(int on, struct net_device *dev);
229 227
230/* May be used by hardware driver to gain control over HDLC device */ 228/* May be used by hardware driver to gain control over HDLC device */
231static __inline__ void hdlc_proto_detach(hdlc_device *hdlc) 229static __inline__ void hdlc_proto_detach(hdlc_device *hdlc)