aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-27 17:41:24 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-27 17:41:24 -0400
commita77c64c1a641950626181b4857abb701d8f38ccc (patch)
tree9bfd2a99cc969b3d863d583b9ef18114a4fc4793
parentac7f6b5e44cb0982b98c31fa33298ba73fb5dcfc (diff)
parent0ba8821b12231386c8c1d506c682061f7225ae49 (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (48 commits) [PATCH] bonding: update version number [PATCH] git-netdev-all: pc300_tty build fix [PATCH] Make PC300 WAN driver compile again [PATCH] Modularize generic HDLC [PATCH] more s2io __iomem annotations [PATCH] restore __iomem annotations in e1000 [PATCH] 64bit bugs in s2io [PATCH] bonding: Fix primary selection error at enslavement time [PATCH] bonding: Don't mangle LACPDUs [PATCH] bonding: Validate probe replies in ARP monitor [PATCH] bonding: Don't release slaves when master is admin down [PATCH] bonding: Add priv_flag to avoid event mishandling [PATCH] bonding: Handle large hard_header_len [PATCH] bonding: Remove unneeded NULL test [PATCH] bonding: Format fix in seq_printf call [PATCH] bonding: Convert delay value from s16 to int [PATCH] bonding: Allow bonding to enslave a 10 Gig adapter Delete unused drivers/net/gt64240eth.h [PATCH] skge: fiber support [PATCH] fix possible NULL ptr deref in forcedeth ...
-rw-r--r--Documentation/networking/bonding.txt59
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/net/acenic.c4
-rw-r--r--drivers/net/bonding/bond_3ad.c70
-rw-r--r--drivers/net/bonding/bond_main.c228
-rw-r--r--drivers/net/bonding/bond_sysfs.c56
-rw-r--r--drivers/net/bonding/bonding.h34
-rw-r--r--drivers/net/e1000/e1000_hw.h4
-rw-r--r--drivers/net/forcedeth.c8
-rw-r--r--drivers/net/gt64240eth.h402
-rw-r--r--drivers/net/phy/phy_device.c2
-rw-r--r--drivers/net/s2io.c10
-rw-r--r--drivers/net/skge.c357
-rw-r--r--drivers/net/skge.h37
-rw-r--r--drivers/net/smc91x.h18
-rw-r--r--drivers/net/tokenring/lanstreamer.c59
-rw-r--r--drivers/net/tokenring/lanstreamer.h12
-rw-r--r--drivers/net/typhoon.c4
-rw-r--r--drivers/net/wan/Kconfig12
-rw-r--r--drivers/net/wan/Makefile19
-rw-r--r--drivers/net/wan/hdlc.c (renamed from drivers/net/wan/hdlc_generic.c)169
-rw-r--r--drivers/net/wan/hdlc_cisco.c198
-rw-r--r--drivers/net/wan/hdlc_fr.c389
-rw-r--r--drivers/net/wan/hdlc_ppp.c77
-rw-r--r--drivers/net/wan/hdlc_raw.c50
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c49
-rw-r--r--drivers/net/wan/hdlc_x25.c54
-rw-r--r--drivers/net/wan/pc300.h1
-rw-r--r--drivers/net/wan/pc300_drv.c30
-rw-r--r--drivers/net/wireless/airo.c19
-rw-r--r--drivers/net/wireless/atmel.c18
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h1
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c10
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c15
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c10
-rw-r--r--drivers/net/wireless/ipw2100.c14
-rw-r--r--drivers/net/wireless/ipw2200.c16
-rw-r--r--drivers/net/wireless/orinoco.c10
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c16
-rw-r--r--drivers/net/wireless/ray_cs.c2
-rw-r--r--drivers/net/wireless/wl3501_cs.c6
-rw-r--r--drivers/net/wireless/zd1201.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c137
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h23
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c50
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_netdev.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h2
-rw-r--r--include/linux/hdlc.h201
-rw-r--r--include/linux/hdlc/ioctl.h33
-rw-r--r--include/linux/if.h2
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--include/linux/wireless.h24
-rw-r--r--net/core/net-sysfs.c5
-rw-r--r--net/core/wireless.c67
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c8
59 files changed, 1751 insertions, 1385 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index afac780445cd..dc942eaf490f 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -192,6 +192,17 @@ or, for backwards compatibility, the option value. E.g.,
192arp_interval 192arp_interval
193 193
194 Specifies the ARP link monitoring frequency in milliseconds. 194 Specifies the ARP link monitoring frequency in milliseconds.
195
196 The ARP monitor works by periodically checking the slave
197 devices to determine whether they have sent or received
198 traffic recently (the precise criteria depends upon the
199 bonding mode, and the state of the slave). Regular traffic is
200 generated via ARP probes issued for the addresses specified by
201 the arp_ip_target option.
202
203 This behavior can be modified by the arp_validate option,
204 below.
205
195 If ARP monitoring is used in an etherchannel compatible mode 206 If ARP monitoring is used in an etherchannel compatible mode
196 (modes 0 and 2), the switch should be configured in a mode 207 (modes 0 and 2), the switch should be configured in a mode
197 that evenly distributes packets across all links. If the 208 that evenly distributes packets across all links. If the
@@ -213,6 +224,54 @@ arp_ip_target
213 maximum number of targets that can be specified is 16. The 224 maximum number of targets that can be specified is 16. The
214 default value is no IP addresses. 225 default value is no IP addresses.
215 226
227arp_validate
228
229 Specifies whether or not ARP probes and replies should be
230 validated in the active-backup mode. This causes the ARP
231 monitor to examine the incoming ARP requests and replies, and
232 only consider a slave to be up if it is receiving the
233 appropriate ARP traffic.
234
235 Possible values are:
236
237 none or 0
238
239 No validation is performed. This is the default.
240
241 active or 1
242
243 Validation is performed only for the active slave.
244
245 backup or 2
246
247 Validation is performed only for backup slaves.
248
249 all or 3
250
251 Validation is performed for all slaves.
252
253 For the active slave, the validation checks ARP replies to
254 confirm that they were generated by an arp_ip_target. Since
255 backup slaves do not typically receive these replies, the
256 validation performed for backup slaves is on the ARP request
257 sent out via the active slave. It is possible that some
258 switch or network configurations may result in situations
259 wherein the backup slaves do not receive the ARP requests; in
260 such a situation, validation of backup slaves must be
261 disabled.
262
263 This option is useful in network configurations in which
264 multiple bonding hosts are concurrently issuing ARPs to one or
265 more targets beyond a common switch. Should the link between
266 the switch and target fail (but not the switch itself), the
267 probe traffic generated by the multiple bonding instances will
268 fool the standard ARP monitor into considering the links as
269 still up. Use of the arp_validate option can resolve this, as
270 the ARP monitor will only consider ARP requests and replies
271 associated with its own instance of bonding.
272
273 This option was added in bonding version 3.1.0.
274
216downdelay 275downdelay
217 276
218 Specifies the time, in milliseconds, to wait before disabling 277 Specifies the time, in milliseconds, to wait before disabling
diff --git a/MAINTAINERS b/MAINTAINERS
index 767a43434ae8..63673e6513b7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2679,7 +2679,6 @@ M: josejx@gentoo.org
2679P: Daniel Drake 2679P: Daniel Drake
2680M: dsd@gentoo.org 2680M: dsd@gentoo.org
2681W: http://softmac.sipsolutions.net/ 2681W: http://softmac.sipsolutions.net/
2682L: softmac-dev@sipsolutions.net
2683L: netdev@vger.kernel.org 2682L: netdev@vger.kernel.org
2684S: Maintained 2683S: Maintained
2685 2684
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index a075246f6f43..71a4f60f7325 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -163,11 +163,7 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
163#define SET_NETDEV_DEV(net, pdev) do{} while(0) 163#define SET_NETDEV_DEV(net, pdev) do{} while(0)
164#endif 164#endif
165 165
166#if LINUX_VERSION_CODE >= 0x2051c
167#define ace_sync_irq(irq) synchronize_irq(irq) 166#define ace_sync_irq(irq) synchronize_irq(irq)
168#else
169#define ace_sync_irq(irq) synchronize_irq()
170#endif
171 167
172#ifndef offset_in_page 168#ifndef offset_in_page
173#define offset_in_page(ptr) ((unsigned long)(ptr) & ~PAGE_MASK) 169#define offset_in_page(ptr) ((unsigned long)(ptr) & ~PAGE_MASK)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6a407070c2e8..3fb354d9c515 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -85,6 +85,7 @@
85#define AD_LINK_SPEED_BITMASK_10MBPS 0x2 85#define AD_LINK_SPEED_BITMASK_10MBPS 0x2
86#define AD_LINK_SPEED_BITMASK_100MBPS 0x4 86#define AD_LINK_SPEED_BITMASK_100MBPS 0x4
87#define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 87#define AD_LINK_SPEED_BITMASK_1000MBPS 0x8
88#define AD_LINK_SPEED_BITMASK_10000MBPS 0x10
88//endalloun 89//endalloun
89 90
90// compare MAC addresses 91// compare MAC addresses
@@ -99,7 +100,7 @@ static u16 __get_link_speed(struct port *port);
99static u8 __get_duplex(struct port *port); 100static u8 __get_duplex(struct port *port);
100static inline void __initialize_port_locks(struct port *port); 101static inline void __initialize_port_locks(struct port *port);
101//conversions 102//conversions
102static void __ntohs_lacpdu(struct lacpdu *lacpdu); 103static void __htons_lacpdu(struct lacpdu *lacpdu);
103static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par); 104static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par);
104 105
105 106
@@ -330,7 +331,8 @@ static inline void __release_rx_machine_lock(struct port *port)
330 * 0, 331 * 0,
331 * %AD_LINK_SPEED_BITMASK_10MBPS, 332 * %AD_LINK_SPEED_BITMASK_10MBPS,
332 * %AD_LINK_SPEED_BITMASK_100MBPS, 333 * %AD_LINK_SPEED_BITMASK_100MBPS,
333 * %AD_LINK_SPEED_BITMASK_1000MBPS 334 * %AD_LINK_SPEED_BITMASK_1000MBPS,
335 * %AD_LINK_SPEED_BITMASK_10000MBPS
334 */ 336 */
335static u16 __get_link_speed(struct port *port) 337static u16 __get_link_speed(struct port *port)
336{ 338{
@@ -357,6 +359,10 @@ static u16 __get_link_speed(struct port *port)
357 speed = AD_LINK_SPEED_BITMASK_1000MBPS; 359 speed = AD_LINK_SPEED_BITMASK_1000MBPS;
358 break; 360 break;
359 361
362 case SPEED_10000:
363 speed = AD_LINK_SPEED_BITMASK_10000MBPS;
364 break;
365
360 default: 366 default:
361 speed = 0; // unknown speed value from ethtool. shouldn't happen 367 speed = 0; // unknown speed value from ethtool. shouldn't happen
362 break; 368 break;
@@ -414,23 +420,23 @@ static inline void __initialize_port_locks(struct port *port)
414 420
415//conversions 421//conversions
416/** 422/**
417 * __ntohs_lacpdu - convert the contents of a LACPDU to host byte order 423 * __htons_lacpdu - convert the contents of a LACPDU to network byte order
418 * @lacpdu: the speicifed lacpdu 424 * @lacpdu: the speicifed lacpdu
419 * 425 *
420 * For each multi-byte field in the lacpdu, convert its content 426 * For each multi-byte field in the lacpdu, convert its content
421 */ 427 */
422static void __ntohs_lacpdu(struct lacpdu *lacpdu) 428static void __htons_lacpdu(struct lacpdu *lacpdu)
423{ 429{
424 if (lacpdu) { 430 if (lacpdu) {
425 lacpdu->actor_system_priority = ntohs(lacpdu->actor_system_priority); 431 lacpdu->actor_system_priority = htons(lacpdu->actor_system_priority);
426 lacpdu->actor_key = ntohs(lacpdu->actor_key); 432 lacpdu->actor_key = htons(lacpdu->actor_key);
427 lacpdu->actor_port_priority = ntohs(lacpdu->actor_port_priority); 433 lacpdu->actor_port_priority = htons(lacpdu->actor_port_priority);
428 lacpdu->actor_port = ntohs(lacpdu->actor_port); 434 lacpdu->actor_port = htons(lacpdu->actor_port);
429 lacpdu->partner_system_priority = ntohs(lacpdu->partner_system_priority); 435 lacpdu->partner_system_priority = htons(lacpdu->partner_system_priority);
430 lacpdu->partner_key = ntohs(lacpdu->partner_key); 436 lacpdu->partner_key = htons(lacpdu->partner_key);
431 lacpdu->partner_port_priority = ntohs(lacpdu->partner_port_priority); 437 lacpdu->partner_port_priority = htons(lacpdu->partner_port_priority);
432 lacpdu->partner_port = ntohs(lacpdu->partner_port); 438 lacpdu->partner_port = htons(lacpdu->partner_port);
433 lacpdu->collector_max_delay = ntohs(lacpdu->collector_max_delay); 439 lacpdu->collector_max_delay = htons(lacpdu->collector_max_delay);
434 } 440 }
435} 441}
436 442
@@ -490,11 +496,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
490 // validate lacpdu and port 496 // validate lacpdu and port
491 if (lacpdu && port) { 497 if (lacpdu && port) {
492 // record the new parameter values for the partner operational 498 // record the new parameter values for the partner operational
493 port->partner_oper_port_number = lacpdu->actor_port; 499 port->partner_oper_port_number = ntohs(lacpdu->actor_port);
494 port->partner_oper_port_priority = lacpdu->actor_port_priority; 500 port->partner_oper_port_priority = ntohs(lacpdu->actor_port_priority);
495 port->partner_oper_system = lacpdu->actor_system; 501 port->partner_oper_system = lacpdu->actor_system;
496 port->partner_oper_system_priority = lacpdu->actor_system_priority; 502 port->partner_oper_system_priority = ntohs(lacpdu->actor_system_priority);
497 port->partner_oper_key = lacpdu->actor_key; 503 port->partner_oper_key = ntohs(lacpdu->actor_key);
498 // zero partener's lase states 504 // zero partener's lase states
499 port->partner_oper_port_state = 0; 505 port->partner_oper_port_state = 0;
500 port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY); 506 port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY);
@@ -561,11 +567,11 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port)
561 // validate lacpdu and port 567 // validate lacpdu and port
562 if (lacpdu && port) { 568 if (lacpdu && port) {
563 // check if any parameter is different 569 // check if any parameter is different
564 if ((lacpdu->actor_port != port->partner_oper_port_number) || 570 if ((ntohs(lacpdu->actor_port) != port->partner_oper_port_number) ||
565 (lacpdu->actor_port_priority != port->partner_oper_port_priority) || 571 (ntohs(lacpdu->actor_port_priority) != port->partner_oper_port_priority) ||
566 MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) || 572 MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) ||
567 (lacpdu->actor_system_priority != port->partner_oper_system_priority) || 573 (ntohs(lacpdu->actor_system_priority) != port->partner_oper_system_priority) ||
568 (lacpdu->actor_key != port->partner_oper_key) || 574 (ntohs(lacpdu->actor_key) != port->partner_oper_key) ||
569 ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) 575 ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION))
570 ) { 576 ) {
571 // update the state machine Selected variable 577 // update the state machine Selected variable
@@ -628,11 +634,11 @@ static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
628 // validate lacpdu and port 634 // validate lacpdu and port
629 if (lacpdu && port) { 635 if (lacpdu && port) {
630 // check if all parameters are alike 636 // check if all parameters are alike
631 if (((lacpdu->partner_port == port->actor_port_number) && 637 if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
632 (lacpdu->partner_port_priority == port->actor_port_priority) && 638 (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
633 !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && 639 !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) &&
634 (lacpdu->partner_system_priority == port->actor_system_priority) && 640 (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
635 (lacpdu->partner_key == port->actor_oper_port_key) && 641 (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
636 ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || 642 ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
637 // or this is individual link(aggregation == FALSE) 643 // or this is individual link(aggregation == FALSE)
638 ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) 644 ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
@@ -662,11 +668,11 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
662 // validate lacpdu and port 668 // validate lacpdu and port
663 if (lacpdu && port) { 669 if (lacpdu && port) {
664 // check if any parameter is different 670 // check if any parameter is different
665 if ((lacpdu->partner_port != port->actor_port_number) || 671 if ((ntohs(lacpdu->partner_port) != port->actor_port_number) ||
666 (lacpdu->partner_port_priority != port->actor_port_priority) || 672 (ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) ||
667 MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || 673 MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) ||
668 (lacpdu->partner_system_priority != port->actor_system_priority) || 674 (ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) ||
669 (lacpdu->partner_key != port->actor_oper_port_key) || 675 (ntohs(lacpdu->partner_key) != port->actor_oper_port_key) ||
670 ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || 676 ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) ||
671 ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) || 677 ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) ||
672 ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || 678 ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) ||
@@ -775,6 +781,9 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
775 case AD_LINK_SPEED_BITMASK_1000MBPS: 781 case AD_LINK_SPEED_BITMASK_1000MBPS:
776 bandwidth = aggregator->num_of_ports * 1000; 782 bandwidth = aggregator->num_of_ports * 1000;
777 break; 783 break;
784 case AD_LINK_SPEED_BITMASK_10000MBPS:
785 bandwidth = aggregator->num_of_ports * 10000;
786 break;
778 default: 787 default:
779 bandwidth=0; // to silent the compilor .... 788 bandwidth=0; // to silent the compilor ....
780 } 789 }
@@ -847,7 +856,7 @@ static inline void __update_lacpdu_from_port(struct port *port)
847 */ 856 */
848 857
849 /* Convert all non u8 parameters to Big Endian for transmit */ 858 /* Convert all non u8 parameters to Big Endian for transmit */
850 __ntohs_lacpdu(lacpdu); 859 __htons_lacpdu(lacpdu);
851} 860}
852 861
853////////////////////////////////////////////////////////////////////////////////////// 862//////////////////////////////////////////////////////////////////////////////////////
@@ -2171,7 +2180,6 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
2171 2180
2172 switch (lacpdu->subtype) { 2181 switch (lacpdu->subtype) {
2173 case AD_TYPE_LACPDU: 2182 case AD_TYPE_LACPDU:
2174 __ntohs_lacpdu(lacpdu);
2175 dprintk("Received LACPDU on port %d\n", port->actor_port_number); 2183 dprintk("Received LACPDU on port %d\n", port->actor_port_number);
2176 ad_rx_machine(lacpdu, port); 2184 ad_rx_machine(lacpdu, port);
2177 break; 2185 break;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 850aae21a2fe..0fb5f653d3ce 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -96,6 +96,7 @@ static char *lacp_rate = NULL;
96static char *xmit_hash_policy = NULL; 96static char *xmit_hash_policy = NULL;
97static int arp_interval = BOND_LINK_ARP_INTERV; 97static int arp_interval = BOND_LINK_ARP_INTERV;
98static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; 98static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
99static char *arp_validate = NULL;
99struct bond_params bonding_defaults; 100struct bond_params bonding_defaults;
100 101
101module_param(max_bonds, int, 0); 102module_param(max_bonds, int, 0);
@@ -127,6 +128,8 @@ module_param(arp_interval, int, 0);
127MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); 128MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
128module_param_array(arp_ip_target, charp, NULL, 0); 129module_param_array(arp_ip_target, charp, NULL, 0);
129MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); 130MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
131module_param(arp_validate, charp, 0);
132MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
130 133
131/*----------------------------- Global variables ----------------------------*/ 134/*----------------------------- Global variables ----------------------------*/
132 135
@@ -170,6 +173,14 @@ struct bond_parm_tbl xmit_hashtype_tbl[] = {
170{ NULL, -1}, 173{ NULL, -1},
171}; 174};
172 175
176struct bond_parm_tbl arp_validate_tbl[] = {
177{ "none", BOND_ARP_VALIDATE_NONE},
178{ "active", BOND_ARP_VALIDATE_ACTIVE},
179{ "backup", BOND_ARP_VALIDATE_BACKUP},
180{ "all", BOND_ARP_VALIDATE_ALL},
181{ NULL, -1},
182};
183
173/*-------------------------- Forward declarations ---------------------------*/ 184/*-------------------------- Forward declarations ---------------------------*/
174 185
175static void bond_send_gratuitous_arp(struct bonding *bond); 186static void bond_send_gratuitous_arp(struct bonding *bond);
@@ -638,6 +649,7 @@ verify:
638 case SPEED_10: 649 case SPEED_10:
639 case SPEED_100: 650 case SPEED_100:
640 case SPEED_1000: 651 case SPEED_1000:
652 case SPEED_10000:
641 break; 653 break;
642 default: 654 default:
643 return -1; 655 return -1;
@@ -1210,10 +1222,14 @@ static int bond_compute_features(struct bonding *bond)
1210 unsigned long features = BOND_INTERSECT_FEATURES; 1222 unsigned long features = BOND_INTERSECT_FEATURES;
1211 struct slave *slave; 1223 struct slave *slave;
1212 struct net_device *bond_dev = bond->dev; 1224 struct net_device *bond_dev = bond->dev;
1225 unsigned short max_hard_header_len = ETH_HLEN;
1213 int i; 1226 int i;
1214 1227
1215 bond_for_each_slave(bond, slave, i) 1228 bond_for_each_slave(bond, slave, i) {
1216 features &= (slave->dev->features & BOND_INTERSECT_FEATURES); 1229 features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
1230 if (slave->dev->hard_header_len > max_hard_header_len)
1231 max_hard_header_len = slave->dev->hard_header_len;
1232 }
1217 1233
1218 if ((features & NETIF_F_SG) && 1234 if ((features & NETIF_F_SG) &&
1219 !(features & NETIF_F_ALL_CSUM)) 1235 !(features & NETIF_F_ALL_CSUM))
@@ -1231,6 +1247,7 @@ static int bond_compute_features(struct bonding *bond)
1231 1247
1232 features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); 1248 features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
1233 bond_dev->features = features; 1249 bond_dev->features = features;
1250 bond_dev->hard_header_len = max_hard_header_len;
1234 1251
1235 return 0; 1252 return 0;
1236} 1253}
@@ -1365,6 +1382,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1365 } 1382 }
1366 1383
1367 new_slave->dev = slave_dev; 1384 new_slave->dev = slave_dev;
1385 slave_dev->priv_flags |= IFF_BONDING;
1368 1386
1369 if ((bond->params.mode == BOND_MODE_TLB) || 1387 if ((bond->params.mode == BOND_MODE_TLB) ||
1370 (bond->params.mode == BOND_MODE_ALB)) { 1388 (bond->params.mode == BOND_MODE_ALB)) {
@@ -1417,6 +1435,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1417 1435
1418 bond_compute_features(bond); 1436 bond_compute_features(bond);
1419 1437
1438 new_slave->last_arp_rx = jiffies;
1439
1420 if (bond->params.miimon && !bond->params.use_carrier) { 1440 if (bond->params.miimon && !bond->params.use_carrier) {
1421 link_reporting = bond_check_dev_link(bond, slave_dev, 1); 1441 link_reporting = bond_check_dev_link(bond, slave_dev, 1);
1422 1442
@@ -1493,29 +1513,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1493 1513
1494 switch (bond->params.mode) { 1514 switch (bond->params.mode) {
1495 case BOND_MODE_ACTIVEBACKUP: 1515 case BOND_MODE_ACTIVEBACKUP:
1496 /* if we're in active-backup mode, we need one and 1516 bond_set_slave_inactive_flags(new_slave);
1497 * only one active interface. The backup interfaces 1517 bond_select_active_slave(bond);
1498 * will have their SLAVE_INACTIVE flag set because we
1499 * need them to be drop all packets. Thus, since we
1500 * guarantee that curr_active_slave always point to
1501 * the last usable interface, we just have to verify
1502 * this interface's flag.
1503 */
1504 if (((!bond->curr_active_slave) ||
1505 (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) &&
1506 (new_slave->link != BOND_LINK_DOWN)) {
1507 /* first slave or no active slave yet, and this link
1508 is OK, so make this interface the active one */
1509 bond_change_active_slave(bond, new_slave);
1510 printk(KERN_INFO DRV_NAME
1511 ": %s: first active interface up!\n",
1512 bond->dev->name);
1513 netif_carrier_on(bond->dev);
1514
1515 } else {
1516 dprintk("This is just a backup slave\n");
1517 bond_set_slave_inactive_flags(new_slave);
1518 }
1519 break; 1518 break;
1520 case BOND_MODE_8023AD: 1519 case BOND_MODE_8023AD:
1521 /* in 802.3ad mode, the internal mechanism 1520 /* in 802.3ad mode, the internal mechanism
@@ -1778,7 +1777,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1778 dev_set_mac_address(slave_dev, &addr); 1777 dev_set_mac_address(slave_dev, &addr);
1779 1778
1780 slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | 1779 slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
1781 IFF_SLAVE_INACTIVE); 1780 IFF_SLAVE_INACTIVE | IFF_BONDING |
1781 IFF_SLAVE_NEEDARP);
1782 1782
1783 kfree(slave); 1783 kfree(slave);
1784 1784
@@ -2291,6 +2291,25 @@ static int bond_has_ip(struct bonding *bond)
2291 return 0; 2291 return 0;
2292} 2292}
2293 2293
2294static int bond_has_this_ip(struct bonding *bond, u32 ip)
2295{
2296 struct vlan_entry *vlan, *vlan_next;
2297
2298 if (ip == bond->master_ip)
2299 return 1;
2300
2301 if (list_empty(&bond->vlan_list))
2302 return 0;
2303
2304 list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
2305 vlan_list) {
2306 if (ip == vlan->vlan_ip)
2307 return 1;
2308 }
2309
2310 return 0;
2311}
2312
2294/* 2313/*
2295 * We go to the (large) trouble of VLAN tagging ARP frames because 2314 * We go to the (large) trouble of VLAN tagging ARP frames because
2296 * switches in VLAN mode (especially if ports are configured as 2315 * switches in VLAN mode (especially if ports are configured as
@@ -2429,6 +2448,93 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
2429 } 2448 }
2430} 2449}
2431 2450
2451static void bond_validate_arp(struct bonding *bond, struct slave *slave, u32 sip, u32 tip)
2452{
2453 int i;
2454 u32 *targets = bond->params.arp_targets;
2455
2456 targets = bond->params.arp_targets;
2457 for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
2458 dprintk("bva: sip %u.%u.%u.%u tip %u.%u.%u.%u t[%d] "
2459 "%u.%u.%u.%u bhti(tip) %d\n",
2460 NIPQUAD(sip), NIPQUAD(tip), i, NIPQUAD(targets[i]),
2461 bond_has_this_ip(bond, tip));
2462 if (sip == targets[i]) {
2463 if (bond_has_this_ip(bond, tip))
2464 slave->last_arp_rx = jiffies;
2465 return;
2466 }
2467 }
2468}
2469
2470static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
2471{
2472 struct arphdr *arp;
2473 struct slave *slave;
2474 struct bonding *bond;
2475 unsigned char *arp_ptr;
2476 u32 sip, tip;
2477
2478 if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
2479 goto out;
2480
2481 bond = dev->priv;
2482 read_lock(&bond->lock);
2483
2484 dprintk("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
2485 bond->dev->name, skb->dev ? skb->dev->name : "NULL",
2486 orig_dev ? orig_dev->name : "NULL");
2487
2488 slave = bond_get_slave_by_dev(bond, orig_dev);
2489 if (!slave || !slave_do_arp_validate(bond, slave))
2490 goto out_unlock;
2491
2492 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
2493 if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
2494 (2 * dev->addr_len) +
2495 (2 * sizeof(u32)))))
2496 goto out_unlock;
2497
2498 arp = skb->nh.arph;
2499 if (arp->ar_hln != dev->addr_len ||
2500 skb->pkt_type == PACKET_OTHERHOST ||
2501 skb->pkt_type == PACKET_LOOPBACK ||
2502 arp->ar_hrd != htons(ARPHRD_ETHER) ||
2503 arp->ar_pro != htons(ETH_P_IP) ||
2504 arp->ar_pln != 4)
2505 goto out_unlock;
2506
2507 arp_ptr = (unsigned char *)(arp + 1);
2508 arp_ptr += dev->addr_len;
2509 memcpy(&sip, arp_ptr, 4);
2510 arp_ptr += 4 + dev->addr_len;
2511 memcpy(&tip, arp_ptr, 4);
2512
2513 dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %u.%u.%u.%u"
2514 " tip %u.%u.%u.%u\n", bond->dev->name, slave->dev->name,
2515 slave->state, bond->params.arp_validate,
2516 slave_do_arp_validate(bond, slave), NIPQUAD(sip), NIPQUAD(tip));
2517
2518 /*
2519 * Backup slaves won't see the ARP reply, but do come through
2520 * here for each ARP probe (so we swap the sip/tip to validate
2521 * the probe). In a "redundant switch, common router" type of
2522 * configuration, the ARP probe will (hopefully) travel from
2523 * the active, through one switch, the router, then the other
2524 * switch before reaching the backup.
2525 */
2526 if (slave->state == BOND_STATE_ACTIVE)
2527 bond_validate_arp(bond, slave, sip, tip);
2528 else
2529 bond_validate_arp(bond, slave, tip, sip);
2530
2531out_unlock:
2532 read_unlock(&bond->lock);
2533out:
2534 dev_kfree_skb(skb);
2535 return NET_RX_SUCCESS;
2536}
2537
2432/* 2538/*
2433 * this function is called regularly to monitor each slave's link 2539 * this function is called regularly to monitor each slave's link
2434 * ensuring that traffic is being sent and received when arp monitoring 2540 * ensuring that traffic is being sent and received when arp monitoring
@@ -2593,7 +2699,8 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2593 */ 2699 */
2594 bond_for_each_slave(bond, slave, i) { 2700 bond_for_each_slave(bond, slave, i) {
2595 if (slave->link != BOND_LINK_UP) { 2701 if (slave->link != BOND_LINK_UP) {
2596 if ((jiffies - slave->dev->last_rx) <= delta_in_ticks) { 2702 if ((jiffies - slave_last_rx(bond, slave)) <=
2703 delta_in_ticks) {
2597 2704
2598 slave->link = BOND_LINK_UP; 2705 slave->link = BOND_LINK_UP;
2599 2706
@@ -2638,7 +2745,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2638 2745
2639 if ((slave != bond->curr_active_slave) && 2746 if ((slave != bond->curr_active_slave) &&
2640 (!bond->current_arp_slave) && 2747 (!bond->current_arp_slave) &&
2641 (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && 2748 (((jiffies - slave_last_rx(bond, slave)) >= 3*delta_in_ticks) &&
2642 bond_has_ip(bond))) { 2749 bond_has_ip(bond))) {
2643 /* a backup slave has gone down; three times 2750 /* a backup slave has gone down; three times
2644 * the delta allows the current slave to be 2751 * the delta allows the current slave to be
@@ -2685,7 +2792,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2685 * if it is up and needs to take over as the curr_active_slave 2792 * if it is up and needs to take over as the curr_active_slave
2686 */ 2793 */
2687 if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || 2794 if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
2688 (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && 2795 (((jiffies - slave_last_rx(bond, slave)) >= (2*delta_in_ticks)) &&
2689 bond_has_ip(bond))) && 2796 bond_has_ip(bond))) &&
2690 ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { 2797 ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) {
2691 2798
@@ -2950,7 +3057,7 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave
2950 seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); 3057 seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
2951 seq_printf(seq, "MII Status: %s\n", 3058 seq_printf(seq, "MII Status: %s\n",
2952 (slave->link == BOND_LINK_UP) ? "up" : "down"); 3059 (slave->link == BOND_LINK_UP) ? "up" : "down");
2953 seq_printf(seq, "Link Failure Count: %d\n", 3060 seq_printf(seq, "Link Failure Count: %u\n",
2954 slave->link_failure_count); 3061 slave->link_failure_count);
2955 3062
2956 seq_printf(seq, 3063 seq_printf(seq,
@@ -3210,6 +3317,9 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v
3210 (event_dev ? event_dev->name : "None"), 3317 (event_dev ? event_dev->name : "None"),
3211 event); 3318 event);
3212 3319
3320 if (!(event_dev->priv_flags & IFF_BONDING))
3321 return NOTIFY_DONE;
3322
3213 if (event_dev->flags & IFF_MASTER) { 3323 if (event_dev->flags & IFF_MASTER) {
3214 dprintk("IFF_MASTER\n"); 3324 dprintk("IFF_MASTER\n");
3215 return bond_master_netdev_event(event, event_dev); 3325 return bond_master_netdev_event(event, event_dev);
@@ -3305,6 +3415,21 @@ static void bond_unregister_lacpdu(struct bonding *bond)
3305 dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); 3415 dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
3306} 3416}
3307 3417
3418void bond_register_arp(struct bonding *bond)
3419{
3420 struct packet_type *pt = &bond->arp_mon_pt;
3421
3422 pt->type = htons(ETH_P_ARP);
3423 pt->dev = NULL; /*bond->dev;XXX*/
3424 pt->func = bond_arp_rcv;
3425 dev_add_pack(pt);
3426}
3427
3428void bond_unregister_arp(struct bonding *bond)
3429{
3430 dev_remove_pack(&bond->arp_mon_pt);
3431}
3432
3308/*---------------------------- Hashing Policies -----------------------------*/ 3433/*---------------------------- Hashing Policies -----------------------------*/
3309 3434
3310/* 3435/*
@@ -3391,6 +3516,9 @@ static int bond_open(struct net_device *bond_dev)
3391 } else { 3516 } else {
3392 arp_timer->function = (void *)&bond_loadbalance_arp_mon; 3517 arp_timer->function = (void *)&bond_loadbalance_arp_mon;
3393 } 3518 }
3519 if (bond->params.arp_validate)
3520 bond_register_arp(bond);
3521
3394 add_timer(arp_timer); 3522 add_timer(arp_timer);
3395 } 3523 }
3396 3524
@@ -3418,9 +3546,11 @@ static int bond_close(struct net_device *bond_dev)
3418 bond_unregister_lacpdu(bond); 3546 bond_unregister_lacpdu(bond);
3419 } 3547 }
3420 3548
3549 if (bond->params.arp_validate)
3550 bond_unregister_arp(bond);
3551
3421 write_lock_bh(&bond->lock); 3552 write_lock_bh(&bond->lock);
3422 3553
3423 bond_mc_list_destroy(bond);
3424 3554
3425 /* signal timers not to re-arm */ 3555 /* signal timers not to re-arm */
3426 bond->kill_timers = 1; 3556 bond->kill_timers = 1;
@@ -3451,8 +3581,6 @@ static int bond_close(struct net_device *bond_dev)
3451 break; 3581 break;
3452 } 3582 }
3453 3583
3454 /* Release the bonded slaves */
3455 bond_release_all(bond_dev);
3456 3584
3457 if ((bond->params.mode == BOND_MODE_TLB) || 3585 if ((bond->params.mode == BOND_MODE_TLB) ||
3458 (bond->params.mode == BOND_MODE_ALB)) { 3586 (bond->params.mode == BOND_MODE_ALB)) {
@@ -4179,6 +4307,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
4179 /* Initialize the device options */ 4307 /* Initialize the device options */
4180 bond_dev->tx_queue_len = 0; 4308 bond_dev->tx_queue_len = 0;
4181 bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; 4309 bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
4310 bond_dev->priv_flags |= IFF_BONDING;
4182 4311
4183 /* At first, we block adding VLANs. That's the only way to 4312 /* At first, we block adding VLANs. That's the only way to
4184 * prevent problems that occur when adding VLANs over an 4313 * prevent problems that occur when adding VLANs over an
@@ -4237,6 +4366,9 @@ static void bond_free_all(void)
4237 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { 4366 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
4238 struct net_device *bond_dev = bond->dev; 4367 struct net_device *bond_dev = bond->dev;
4239 4368
4369 bond_mc_list_destroy(bond);
4370 /* Release the bonded slaves */
4371 bond_release_all(bond_dev);
4240 unregister_netdevice(bond_dev); 4372 unregister_netdevice(bond_dev);
4241 bond_deinit(bond_dev); 4373 bond_deinit(bond_dev);
4242 } 4374 }
@@ -4270,6 +4402,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
4270 4402
4271static int bond_check_params(struct bond_params *params) 4403static int bond_check_params(struct bond_params *params)
4272{ 4404{
4405 int arp_validate_value;
4406
4273 /* 4407 /*
4274 * Convert string parameters. 4408 * Convert string parameters.
4275 */ 4409 */
@@ -4473,6 +4607,29 @@ static int bond_check_params(struct bond_params *params)
4473 arp_interval = 0; 4607 arp_interval = 0;
4474 } 4608 }
4475 4609
4610 if (arp_validate) {
4611 if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
4612 printk(KERN_ERR DRV_NAME
4613 ": arp_validate only supported in active-backup mode\n");
4614 return -EINVAL;
4615 }
4616 if (!arp_interval) {
4617 printk(KERN_ERR DRV_NAME
4618 ": arp_validate requires arp_interval\n");
4619 return -EINVAL;
4620 }
4621
4622 arp_validate_value = bond_parse_parm(arp_validate,
4623 arp_validate_tbl);
4624 if (arp_validate_value == -1) {
4625 printk(KERN_ERR DRV_NAME
4626 ": Error: invalid arp_validate \"%s\"\n",
4627 arp_validate == NULL ? "NULL" : arp_validate);
4628 return -EINVAL;
4629 }
4630 } else
4631 arp_validate_value = 0;
4632
4476 if (miimon) { 4633 if (miimon) {
4477 printk(KERN_INFO DRV_NAME 4634 printk(KERN_INFO DRV_NAME
4478 ": MII link monitoring set to %d ms\n", 4635 ": MII link monitoring set to %d ms\n",
@@ -4481,8 +4638,10 @@ static int bond_check_params(struct bond_params *params)
4481 int i; 4638 int i;
4482 4639
4483 printk(KERN_INFO DRV_NAME 4640 printk(KERN_INFO DRV_NAME
4484 ": ARP monitoring set to %d ms with %d target(s):", 4641 ": ARP monitoring set to %d ms, validate %s, with %d target(s):",
4485 arp_interval, arp_ip_count); 4642 arp_interval,
4643 arp_validate_tbl[arp_validate_value].modename,
4644 arp_ip_count);
4486 4645
4487 for (i = 0; i < arp_ip_count; i++) 4646 for (i = 0; i < arp_ip_count; i++)
4488 printk (" %s", arp_ip_target[i]); 4647 printk (" %s", arp_ip_target[i]);
@@ -4516,6 +4675,7 @@ static int bond_check_params(struct bond_params *params)
4516 params->xmit_policy = xmit_hashtype; 4675 params->xmit_policy = xmit_hashtype;
4517 params->miimon = miimon; 4676 params->miimon = miimon;
4518 params->arp_interval = arp_interval; 4677 params->arp_interval = arp_interval;
4678 params->arp_validate = arp_validate_value;
4519 params->updelay = updelay; 4679 params->updelay = updelay;
4520 params->downdelay = downdelay; 4680 params->downdelay = downdelay;
4521 params->use_carrier = use_carrier; 4681 params->use_carrier = use_carrier;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index cfe4dc3a93a3..ced9ed8f995a 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -51,6 +51,7 @@ extern struct bond_params bonding_defaults;
51extern struct bond_parm_tbl bond_mode_tbl[]; 51extern struct bond_parm_tbl bond_mode_tbl[];
52extern struct bond_parm_tbl bond_lacp_tbl[]; 52extern struct bond_parm_tbl bond_lacp_tbl[];
53extern struct bond_parm_tbl xmit_hashtype_tbl[]; 53extern struct bond_parm_tbl xmit_hashtype_tbl[];
54extern struct bond_parm_tbl arp_validate_tbl[];
54 55
55static int expected_refcount = -1; 56static int expected_refcount = -1;
56static struct class *netdev_class; 57static struct class *netdev_class;
@@ -503,6 +504,53 @@ out:
503static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); 504static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
504 505
505/* 506/*
507 * Show and set arp_validate.
508 */
509static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf)
510{
511 struct bonding *bond = to_bond(cd);
512
513 return sprintf(buf, "%s %d\n",
514 arp_validate_tbl[bond->params.arp_validate].modename,
515 bond->params.arp_validate) + 1;
516}
517
518static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count)
519{
520 int new_value;
521 struct bonding *bond = to_bond(cd);
522
523 new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
524 if (new_value < 0) {
525 printk(KERN_ERR DRV_NAME
526 ": %s: Ignoring invalid arp_validate value %s\n",
527 bond->dev->name, buf);
528 return -EINVAL;
529 }
530 if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
531 printk(KERN_ERR DRV_NAME
532 ": %s: arp_validate only supported in active-backup mode.\n",
533 bond->dev->name);
534 return -EINVAL;
535 }
536 printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
537 bond->dev->name, arp_validate_tbl[new_value].modename,
538 new_value);
539
540 if (!bond->params.arp_validate && new_value) {
541 bond_register_arp(bond);
542 } else if (bond->params.arp_validate && !new_value) {
543 bond_unregister_arp(bond);
544 }
545
546 bond->params.arp_validate = new_value;
547
548 return count;
549}
550
551static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
552
553/*
506 * Show and set the arp timer interval. There are two tricky bits 554 * Show and set the arp timer interval. There are two tricky bits
507 * here. First, if ARP monitoring is activated, then we must disable 555 * here. First, if ARP monitoring is activated, then we must disable
508 * MII monitoring. Second, if the ARP timer isn't running, we must 556 * MII monitoring. Second, if the ARP timer isn't running, we must
@@ -914,6 +962,11 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si
914 "ARP monitoring. Disabling ARP monitoring...\n", 962 "ARP monitoring. Disabling ARP monitoring...\n",
915 bond->dev->name); 963 bond->dev->name);
916 bond->params.arp_interval = 0; 964 bond->params.arp_interval = 0;
965 if (bond->params.arp_validate) {
966 bond_unregister_arp(bond);
967 bond->params.arp_validate =
968 BOND_ARP_VALIDATE_NONE;
969 }
917 /* Kill ARP timer, else it brings bond's link down */ 970 /* Kill ARP timer, else it brings bond's link down */
918 if (bond->mii_timer.function) { 971 if (bond->mii_timer.function) {
919 printk(KERN_INFO DRV_NAME 972 printk(KERN_INFO DRV_NAME
@@ -1093,7 +1146,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b
1093 strlen(slave->dev->name)) == 0) { 1146 strlen(slave->dev->name)) == 0) {
1094 old_active = bond->curr_active_slave; 1147 old_active = bond->curr_active_slave;
1095 new_active = slave; 1148 new_active = slave;
1096 if (new_active && (new_active == old_active)) { 1149 if (new_active == old_active) {
1097 /* do nothing */ 1150 /* do nothing */
1098 printk(KERN_INFO DRV_NAME 1151 printk(KERN_INFO DRV_NAME
1099 ": %s: %s is already the current active slave.\n", 1152 ": %s: %s is already the current active slave.\n",
@@ -1273,6 +1326,7 @@ static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, N
1273static struct attribute *per_bond_attrs[] = { 1326static struct attribute *per_bond_attrs[] = {
1274 &class_device_attr_slaves.attr, 1327 &class_device_attr_slaves.attr,
1275 &class_device_attr_mode.attr, 1328 &class_device_attr_mode.attr,
1329 &class_device_attr_arp_validate.attr,
1276 &class_device_attr_arp_interval.attr, 1330 &class_device_attr_arp_interval.attr,
1277 &class_device_attr_arp_ip_target.attr, 1331 &class_device_attr_arp_ip_target.attr,
1278 &class_device_attr_downdelay.attr, 1332 &class_device_attr_downdelay.attr,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 0bdfe2c71453..dc434fb6da85 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
22#include "bond_3ad.h" 22#include "bond_3ad.h"
23#include "bond_alb.h" 23#include "bond_alb.h"
24 24
25#define DRV_VERSION "3.0.3" 25#define DRV_VERSION "3.1.1"
26#define DRV_RELDATE "March 23, 2006" 26#define DRV_RELDATE "September 26, 2006"
27#define DRV_NAME "bonding" 27#define DRV_NAME "bonding"
28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
29 29
@@ -126,6 +126,7 @@ struct bond_params {
126 int xmit_policy; 126 int xmit_policy;
127 int miimon; 127 int miimon;
128 int arp_interval; 128 int arp_interval;
129 int arp_validate;
129 int use_carrier; 130 int use_carrier;
130 int updelay; 131 int updelay;
131 int downdelay; 132 int downdelay;
@@ -149,8 +150,9 @@ struct slave {
149 struct net_device *dev; /* first - useful for panic debug */ 150 struct net_device *dev; /* first - useful for panic debug */
150 struct slave *next; 151 struct slave *next;
151 struct slave *prev; 152 struct slave *prev;
152 s16 delay; 153 int delay;
153 u32 jiffies; 154 u32 jiffies;
155 u32 last_arp_rx;
154 s8 link; /* one of BOND_LINK_XXXX */ 156 s8 link; /* one of BOND_LINK_XXXX */
155 s8 state; /* one of BOND_STATE_XXXX */ 157 s8 state; /* one of BOND_STATE_XXXX */
156 u32 original_flags; 158 u32 original_flags;
@@ -198,6 +200,7 @@ struct bonding {
198 struct bond_params params; 200 struct bond_params params;
199 struct list_head vlan_list; 201 struct list_head vlan_list;
200 struct vlan_group *vlgrp; 202 struct vlan_group *vlgrp;
203 struct packet_type arp_mon_pt;
201}; 204};
202 205
203/** 206/**
@@ -228,6 +231,25 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
228 return (struct bonding *)slave->dev->master->priv; 231 return (struct bonding *)slave->dev->master->priv;
229} 232}
230 233
234#define BOND_ARP_VALIDATE_NONE 0
235#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
236#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
237#define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \
238 BOND_ARP_VALIDATE_BACKUP)
239
240extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slave)
241{
242 return bond->params.arp_validate & (1 << slave->state);
243}
244
245extern inline u32 slave_last_rx(struct bonding *bond, struct slave *slave)
246{
247 if (slave_do_arp_validate(bond, slave))
248 return slave->last_arp_rx;
249
250 return slave->dev->last_rx;
251}
252
231static inline void bond_set_slave_inactive_flags(struct slave *slave) 253static inline void bond_set_slave_inactive_flags(struct slave *slave)
232{ 254{
233 struct bonding *bond = slave->dev->master->priv; 255 struct bonding *bond = slave->dev->master->priv;
@@ -235,12 +257,14 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave)
235 bond->params.mode != BOND_MODE_ALB) 257 bond->params.mode != BOND_MODE_ALB)
236 slave->state = BOND_STATE_BACKUP; 258 slave->state = BOND_STATE_BACKUP;
237 slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; 259 slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
260 if (slave_do_arp_validate(bond, slave))
261 slave->dev->priv_flags |= IFF_SLAVE_NEEDARP;
238} 262}
239 263
240static inline void bond_set_slave_active_flags(struct slave *slave) 264static inline void bond_set_slave_active_flags(struct slave *slave)
241{ 265{
242 slave->state = BOND_STATE_ACTIVE; 266 slave->state = BOND_STATE_ACTIVE;
243 slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; 267 slave->dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_SLAVE_NEEDARP);
244} 268}
245 269
246static inline void bond_set_master_3ad_flags(struct bonding *bond) 270static inline void bond_set_master_3ad_flags(struct bonding *bond)
@@ -284,6 +308,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
284const char *bond_mode_name(int mode); 308const char *bond_mode_name(int mode);
285void bond_select_active_slave(struct bonding *bond); 309void bond_select_active_slave(struct bonding *bond);
286void bond_change_active_slave(struct bonding *bond, struct slave *new_active); 310void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
311void bond_register_arp(struct bonding *);
312void bond_unregister_arp(struct bonding *);
287 313
288#endif /* _LINUX_BONDING_H */ 314#endif /* _LINUX_BONDING_H */
289 315
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index a170e96251f6..4020acb55005 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1367,8 +1367,8 @@ struct e1000_hw_stats {
1367 1367
1368/* Structure containing variables used by the shared code (e1000_hw.c) */ 1368/* Structure containing variables used by the shared code (e1000_hw.c) */
1369struct e1000_hw { 1369struct e1000_hw {
1370 uint8_t *hw_addr; 1370 uint8_t __iomem *hw_addr;
1371 uint8_t *flash_address; 1371 uint8_t __iomem *flash_address;
1372 e1000_mac_type mac_type; 1372 e1000_mac_type mac_type;
1373 e1000_phy_type phy_type; 1373 e1000_phy_type phy_type;
1374 uint32_t phy_init_script; 1374 uint32_t phy_init_script;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 97db910fbc8c..eea1d66c530e 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3789,6 +3789,12 @@ static int nv_loopback_test(struct net_device *dev)
3789 /* setup packet for tx */ 3789 /* setup packet for tx */
3790 pkt_len = ETH_DATA_LEN; 3790 pkt_len = ETH_DATA_LEN;
3791 tx_skb = dev_alloc_skb(pkt_len); 3791 tx_skb = dev_alloc_skb(pkt_len);
3792 if (!tx_skb) {
3793 printk(KERN_ERR "dev_alloc_skb() failed during loopback test"
3794 " of %s\n", dev->name);
3795 ret = 0;
3796 goto out;
3797 }
3792 pkt_data = skb_put(tx_skb, pkt_len); 3798 pkt_data = skb_put(tx_skb, pkt_len);
3793 for (i = 0; i < pkt_len; i++) 3799 for (i = 0; i < pkt_len; i++)
3794 pkt_data[i] = (u8)(i & 0xff); 3800 pkt_data[i] = (u8)(i & 0xff);
@@ -3853,7 +3859,7 @@ static int nv_loopback_test(struct net_device *dev)
3853 tx_skb->end-tx_skb->data, 3859 tx_skb->end-tx_skb->data,
3854 PCI_DMA_TODEVICE); 3860 PCI_DMA_TODEVICE);
3855 dev_kfree_skb_any(tx_skb); 3861 dev_kfree_skb_any(tx_skb);
3856 3862 out:
3857 /* stop engines */ 3863 /* stop engines */
3858 nv_stop_rx(dev); 3864 nv_stop_rx(dev);
3859 nv_stop_tx(dev); 3865 nv_stop_tx(dev);
diff --git a/drivers/net/gt64240eth.h b/drivers/net/gt64240eth.h
deleted file mode 100644
index 0d6f486e4579..000000000000
--- a/drivers/net/gt64240eth.h
+++ /dev/null
@@ -1,402 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2001 Patton Electronics Company
7 * Copyright (C) 2002 Momentum Computer
8 *
9 * Copyright 2000 MontaVista Software Inc.
10 * Author: MontaVista Software, Inc.
11 * stevel@mvista.com or support@mvista.com
12 *
13 * This program is free software; you can distribute it and/or modify it
14 * under the terms of the GNU General Public License (Version 2) as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
25 *
26 * Ethernet driver definitions for the MIPS GT96100 Advanced
27 * Communication Controller.
28 *
29 * Modified for the Marvellous GT64240 Retarded Communication Controller.
30 */
31#ifndef _GT64240ETH_H
32#define _GT64240ETH_H
33
34#include <asm/gt64240.h>
35
36#define ETHERNET_PORTS_DIFFERENCE_OFFSETS 0x400
37
38/* Translate those weanie names from Galileo/VxWorks header files: */
39
40#define GT64240_MRR MAIN_ROUTING_REGISTER
41#define GT64240_CIU_ARBITER_CONFIG COMM_UNIT_ARBITER_CONFIGURATION_REGISTER
42#define GT64240_CIU_ARBITER_CONTROL COMM_UNIT_ARBITER_CONTROL
43#define GT64240_MAIN_LOW_CAUSE LOW_INTERRUPT_CAUSE_REGISTER
44#define GT64240_MAIN_HIGH_CAUSE HIGH_INTERRUPT_CAUSE_REGISTER
45#define GT64240_CPU_LOW_MASK CPU_INTERRUPT_MASK_REGISTER_LOW
46#define GT64240_CPU_HIGH_MASK CPU_INTERRUPT_MASK_REGISTER_HIGH
47#define GT64240_CPU_SELECT_CAUSE CPU_SELECT_CAUSE_REGISTER
48
49#define GT64240_ETH_PHY_ADDR_REG ETHERNET_PHY_ADDRESS_REGISTER
50#define GT64240_ETH_PORT_CONFIG ETHERNET0_PORT_CONFIGURATION_REGISTER
51#define GT64240_ETH_PORT_CONFIG_EXT ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER
52#define GT64240_ETH_PORT_COMMAND ETHERNET0_PORT_COMMAND_REGISTER
53#define GT64240_ETH_PORT_STATUS ETHERNET0_PORT_STATUS_REGISTER
54#define GT64240_ETH_IO_SIZE ETHERNET_PORTS_DIFFERENCE_OFFSETS
55#define GT64240_ETH_SMI_REG ETHERNET_SMI_REGISTER
56#define GT64240_ETH_MIB_COUNT_BASE ETHERNET0_MIB_COUNTER_BASE
57#define GT64240_ETH_SDMA_CONFIG ETHERNET0_SDMA_CONFIGURATION_REGISTER
58#define GT64240_ETH_SDMA_COMM ETHERNET0_SDMA_COMMAND_REGISTER
59#define GT64240_ETH_INT_MASK ETHERNET0_INTERRUPT_MASK_REGISTER
60#define GT64240_ETH_INT_CAUSE ETHERNET0_INTERRUPT_CAUSE_REGISTER
61#define GT64240_ETH_CURR_TX_DESC_PTR0 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0
62#define GT64240_ETH_CURR_TX_DESC_PTR1 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1
63#define GT64240_ETH_1ST_RX_DESC_PTR0 ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0
64#define GT64240_ETH_CURR_RX_DESC_PTR0 ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0
65#define GT64240_ETH_HASH_TBL_PTR ETHERNET0_HASH_TABLE_POINTER_REGISTER
66
67/* Turn on NAPI by default */
68
69#define GT64240_NAPI 1
70
71/* Some 64240 settings that SHOULD eventually be setup in PROM monitor: */
72/* (Board-specific to the DSL3224 Rev A board ONLY!) */
73#define D3224_MPP_CTRL0_SETTING 0x66669900
74#define D3224_MPP_CTRL1_SETTING 0x00000000
75#define D3224_MPP_CTRL2_SETTING 0x00887700
76#define D3224_MPP_CTRL3_SETTING 0x00000044
77#define D3224_GPP_IO_CTRL_SETTING 0x0000e800
78#define D3224_GPP_LEVEL_CTRL_SETTING 0xf001f703
79#define D3224_GPP_VALUE_SETTING 0x00000000
80
81/* Keep the ring sizes a power of two for efficiency. */
82//-#define TX_RING_SIZE 16
83#define TX_RING_SIZE 64 /* TESTING !!! */
84#define RX_RING_SIZE 32
85#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */
86
87#define RX_HASH_TABLE_SIZE 16384
88#define HASH_HOP_NUMBER 12
89
90#define NUM_INTERFACES 3
91
92#define GT64240ETH_TX_TIMEOUT HZ/4
93
94#define MIPS_GT64240_BASE 0xf4000000
95#define GT64240_ETH0_BASE (MIPS_GT64240_BASE + GT64240_ETH_PORT_CONFIG)
96#define GT64240_ETH1_BASE (GT64240_ETH0_BASE + GT64240_ETH_IO_SIZE)
97#define GT64240_ETH2_BASE (GT64240_ETH1_BASE + GT64240_ETH_IO_SIZE)
98
99#if defined(CONFIG_MIPS_DSL3224)
100#define GT64240_ETHER0_IRQ 4
101#define GT64240_ETHER1_IRQ 4
102#else
103#define GT64240_ETHER0_IRQ -1
104#define GT64240_ETHER1_IRQ -1
105#endif
106
107#define REV_GT64240 0x1
108#define REV_GT64240A 0x10
109
110#define GT64240ETH_READ(gp, offset) \
111 GT_READ((gp)->port_offset + (offset))
112
113#define GT64240ETH_WRITE(gp, offset, data) \
114 GT_WRITE((gp)->port_offset + (offset), (data))
115
116#define GT64240ETH_SETBIT(gp, offset, bits) \
117 GT64240ETH_WRITE((gp), (offset), \
118 GT64240ETH_READ((gp), (offset)) | (bits))
119
120#define GT64240ETH_CLRBIT(gp, offset, bits) \
121 GT64240ETH_WRITE((gp), (offset), \
122 GT64240ETH_READ((gp), (offset)) & ~(bits))
123
124#define GT64240_READ(ofs) GT_READ(ofs)
125#define GT64240_WRITE(ofs, data) GT_WRITE((ofs), (data))
126
127/* Bit definitions of the SMI Reg */
128enum {
129 smirDataMask = 0xffff,
130 smirPhyAdMask = 0x1f << 16,
131 smirPhyAdBit = 16,
132 smirRegAdMask = 0x1f << 21,
133 smirRegAdBit = 21,
134 smirOpCode = 1 << 26,
135 smirReadValid = 1 << 27,
136 smirBusy = 1 << 28
137};
138
139/* Bit definitions of the Port Config Reg */
140enum pcr_bits {
141 pcrPM = 1 << 0,
142 pcrRBM = 1 << 1,
143 pcrPBF = 1 << 2,
144 pcrEN = 1 << 7,
145 pcrLPBKMask = 0x3 << 8,
146 pcrLPBKBit = 1 << 8,
147 pcrFC = 1 << 10,
148 pcrHS = 1 << 12,
149 pcrHM = 1 << 13,
150 pcrHDM = 1 << 14,
151 pcrHD = 1 << 15,
152 pcrISLMask = 0x7 << 28,
153 pcrISLBit = 28,
154 pcrACCS = 1 << 31
155};
156
157/* Bit definitions of the Port Config Extend Reg */
158enum pcxr_bits {
159 pcxrIGMP = 1,
160 pcxrSPAN = 2,
161 pcxrPAR = 4,
162 pcxrPRIOtxMask = 0x7 << 3,
163 pcxrPRIOtxBit = 3,
164 pcxrPRIOrxMask = 0x3 << 6,
165 pcxrPRIOrxBit = 6,
166 pcxrPRIOrxOverride = 1 << 8,
167 pcxrDPLXen = 1 << 9,
168 pcxrFCTLen = 1 << 10,
169 pcxrFLP = 1 << 11,
170 pcxrFCTL = 1 << 12,
171 pcxrMFLMask = 0x3 << 14,
172 pcxrMFLBit = 14,
173 pcxrMIBclrMode = 1 << 16,
174 pcxrSpeed = 1 << 18,
175 pcxrSpeeden = 1 << 19,
176 pcxrRMIIen = 1 << 20,
177 pcxrDSCPen = 1 << 21
178};
179
180/* Bit definitions of the Port Command Reg */
181enum pcmr_bits {
182 pcmrFJ = 1 << 15
183};
184
185
186/* Bit definitions of the Port Status Reg */
187enum psr_bits {
188 psrSpeed = 1,
189 psrDuplex = 2,
190 psrFctl = 4,
191 psrLink = 8,
192 psrPause = 1 << 4,
193 psrTxLow = 1 << 5,
194 psrTxHigh = 1 << 6,
195 psrTxInProg = 1 << 7
196};
197
198/* Bit definitions of the SDMA Config Reg */
199enum sdcr_bits {
200 sdcrRCMask = 0xf << 2,
201 sdcrRCBit = 2,
202 sdcrBLMR = 1 << 6,
203 sdcrBLMT = 1 << 7,
204 sdcrPOVR = 1 << 8,
205 sdcrRIFB = 1 << 9,
206 sdcrBSZMask = 0x3 << 12,
207 sdcrBSZBit = 12
208};
209
210/* Bit definitions of the SDMA Command Reg */
211enum sdcmr_bits {
212 sdcmrERD = 1 << 7,
213 sdcmrAR = 1 << 15,
214 sdcmrSTDH = 1 << 16,
215 sdcmrSTDL = 1 << 17,
216 sdcmrTXDH = 1 << 23,
217 sdcmrTXDL = 1 << 24,
218 sdcmrAT = 1 << 31
219};
220
221/* Bit definitions of the Interrupt Cause Reg */
222enum icr_bits {
223 icrRxBuffer = 1,
224 icrTxBufferHigh = 1 << 2,
225 icrTxBufferLow = 1 << 3,
226 icrTxEndHigh = 1 << 6,
227 icrTxEndLow = 1 << 7,
228 icrRxError = 1 << 8,
229 icrTxErrorHigh = 1 << 10,
230 icrTxErrorLow = 1 << 11,
231 icrRxOVR = 1 << 12,
232 icrTxUdr = 1 << 13,
233 icrRxBufferQ0 = 1 << 16,
234 icrRxBufferQ1 = 1 << 17,
235 icrRxBufferQ2 = 1 << 18,
236 icrRxBufferQ3 = 1 << 19,
237 icrRxErrorQ0 = 1 << 20,
238 icrRxErrorQ1 = 1 << 21,
239 icrRxErrorQ2 = 1 << 22,
240 icrRxErrorQ3 = 1 << 23,
241 icrMIIPhySTC = 1 << 28,
242 icrSMIdone = 1 << 29,
243 icrEtherIntSum = 1 << 31
244};
245
246
247/* The Rx and Tx descriptor lists. */
248#ifdef __LITTLE_ENDIAN
249typedef struct {
250 u32 cmdstat;
251 u16 reserved; //-prk21aug01 u32 reserved:16;
252 u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
253 u32 buff_ptr;
254 u32 next;
255} gt64240_td_t;
256
257typedef struct {
258 u32 cmdstat;
259 u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
260 u16 buff_sz; //-prk21aug01 u32 buff_sz:16;
261 u32 buff_ptr;
262 u32 next;
263} gt64240_rd_t;
264#elif defined(__BIG_ENDIAN)
265typedef struct {
266 u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
267 u16 reserved; //-prk21aug01 u32 reserved:16;
268 u32 cmdstat;
269 u32 next;
270 u32 buff_ptr;
271} gt64240_td_t;
272
273typedef struct {
274 u16 buff_sz; //-prk21aug01 u32 buff_sz:16;
275 u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16;
276 u32 cmdstat;
277 u32 next;
278 u32 buff_ptr;
279} gt64240_rd_t;
280#else
281#error Either __BIG_ENDIAN or __LITTLE_ENDIAN must be defined!
282#endif
283
284
285/* Values for the Tx command-status descriptor entry. */
286enum td_cmdstat {
287 txOwn = 1 << 31,
288 txAutoMode = 1 << 30,
289 txEI = 1 << 23,
290 txGenCRC = 1 << 22,
291 txPad = 1 << 18,
292 txFirst = 1 << 17,
293 txLast = 1 << 16,
294 txErrorSummary = 1 << 15,
295 txReTxCntMask = 0x0f << 10,
296 txReTxCntBit = 10,
297 txCollision = 1 << 9,
298 txReTxLimit = 1 << 8,
299 txUnderrun = 1 << 6,
300 txLateCollision = 1 << 5
301};
302
303
304/* Values for the Rx command-status descriptor entry. */
305enum rd_cmdstat {
306 rxOwn = 1 << 31,
307 rxAutoMode = 1 << 30,
308 rxEI = 1 << 23,
309 rxFirst = 1 << 17,
310 rxLast = 1 << 16,
311 rxErrorSummary = 1 << 15,
312 rxIGMP = 1 << 14,
313 rxHashExpired = 1 << 13,
314 rxMissedFrame = 1 << 12,
315 rxFrameType = 1 << 11,
316 rxShortFrame = 1 << 8,
317 rxMaxFrameLen = 1 << 7,
318 rxOverrun = 1 << 6,
319 rxCollision = 1 << 4,
320 rxCRCError = 1
321};
322
323/* Bit fields of a Hash Table Entry */
324enum hash_table_entry {
325 hteValid = 1,
326 hteSkip = 2,
327 hteRD = 4
328};
329
330// The MIB counters
331typedef struct {
332 u32 byteReceived;
333 u32 byteSent;
334 u32 framesReceived;
335 u32 framesSent;
336 u32 totalByteReceived;
337 u32 totalFramesReceived;
338 u32 broadcastFramesReceived;
339 u32 multicastFramesReceived;
340 u32 cRCError;
341 u32 oversizeFrames;
342 u32 fragments;
343 u32 jabber;
344 u32 collision;
345 u32 lateCollision;
346 u32 frames64;
347 u32 frames65_127;
348 u32 frames128_255;
349 u32 frames256_511;
350 u32 frames512_1023;
351 u32 frames1024_MaxSize;
352 u32 macRxError;
353 u32 droppedFrames;
354 u32 outMulticastFrames;
355 u32 outBroadcastFrames;
356 u32 undersizeFrames;
357} mib_counters_t;
358
359
360struct gt64240_private {
361 gt64240_rd_t *rx_ring;
362 gt64240_td_t *tx_ring;
363 // The Rx and Tx rings must be 16-byte aligned
364 dma_addr_t rx_ring_dma;
365 dma_addr_t tx_ring_dma;
366 char *hash_table;
367 // The Hash Table must be 8-byte aligned
368 dma_addr_t hash_table_dma;
369 int hash_mode;
370
371 // The Rx buffers must be 8-byte aligned
372 char *rx_buff;
373 dma_addr_t rx_buff_dma;
374 // Tx buffers (tx_skbuff[i]->data) with less than 8 bytes
375 // of payload must be 8-byte aligned
376 struct sk_buff *tx_skbuff[TX_RING_SIZE];
377 int rx_next_out; /* The next free ring entry to receive */
378 int tx_next_in; /* The next free ring entry to send */
379 int tx_next_out; /* The last ring entry the ISR processed */
380 int tx_count; /* current # of pkts waiting to be sent in Tx ring */
381 int intr_work_done; /* number of Rx and Tx pkts processed in the isr */
382 int tx_full; /* Tx ring is full */
383
384 mib_counters_t mib;
385 struct net_device_stats stats;
386
387 int io_size;
388 int port_num; // 0 or 1
389 u32 port_offset;
390
391 int phy_addr; // PHY address
392 u32 last_psr; // last value of the port status register
393
394 int options; /* User-settable misc. driver options. */
395 int drv_flags;
396 spinlock_t lock; /* Serialise access to device */
397 struct mii_if_info mii_if;
398
399 u32 msg_enable;
400};
401
402#endif /* _GT64240ETH_H */
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 2d1ecfdc80db..ecd3da151e2d 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -522,7 +522,7 @@ EXPORT_SYMBOL(genphy_read_status);
522 522
523static int genphy_config_init(struct phy_device *phydev) 523static int genphy_config_init(struct phy_device *phydev)
524{ 524{
525 u32 val; 525 int val;
526 u32 features; 526 u32 features;
527 527
528 /* For now, I'll claim that the generic driver supports 528 /* For now, I'll claim that the generic driver supports
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index f5dbeb27b6f0..1bf23e41f580 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2904,7 +2904,7 @@ static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device
2904{ 2904{
2905 u64 val64 = 0x0; 2905 u64 val64 = 0x0;
2906 nic_t *sp = dev->priv; 2906 nic_t *sp = dev->priv;
2907 XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; 2907 XENA_dev_config_t __iomem *bar0 = sp->bar0;
2908 2908
2909 //address transaction 2909 //address transaction
2910 val64 = val64 | MDIO_MMD_INDX_ADDR(addr) 2910 val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
@@ -2953,7 +2953,7 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev)
2953 u64 val64 = 0x0; 2953 u64 val64 = 0x0;
2954 u64 rval64 = 0x0; 2954 u64 rval64 = 0x0;
2955 nic_t *sp = dev->priv; 2955 nic_t *sp = dev->priv;
2956 XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; 2956 XENA_dev_config_t __iomem *bar0 = sp->bar0;
2957 2957
2958 /* address transaction */ 2958 /* address transaction */
2959 val64 = val64 | MDIO_MMD_INDX_ADDR(addr) 2959 val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
@@ -3276,7 +3276,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
3276 * SUCCESS on success and FAILURE on failure. 3276 * SUCCESS on success and FAILURE on failure.
3277 */ 3277 */
3278 3278
3279static int wait_for_cmd_complete(void *addr, u64 busy_bit) 3279static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit)
3280{ 3280{
3281 int ret = FAILURE, cnt = 0; 3281 int ret = FAILURE, cnt = 0;
3282 u64 val64; 3282 u64 val64;
@@ -4303,11 +4303,11 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
4303 sp->stats.tx_errors = 4303 sp->stats.tx_errors =
4304 le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); 4304 le32_to_cpu(mac_control->stats_info->tmac_any_err_frms);
4305 sp->stats.rx_errors = 4305 sp->stats.rx_errors =
4306 le32_to_cpu(mac_control->stats_info->rmac_drop_frms); 4306 le64_to_cpu(mac_control->stats_info->rmac_drop_frms);
4307 sp->stats.multicast = 4307 sp->stats.multicast =
4308 le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); 4308 le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms);
4309 sp->stats.rx_length_errors = 4309 sp->stats.rx_length_errors =
4310 le32_to_cpu(mac_control->stats_info->rmac_long_frms); 4310 le64_to_cpu(mac_control->stats_info->rmac_long_frms);
4311 4311
4312 return (&sp->stats); 4312 return (&sp->stats);
4313} 4313}
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 9142d91355bc..705e9a8fa30f 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -58,6 +58,7 @@
58#define TX_WATCHDOG (5 * HZ) 58#define TX_WATCHDOG (5 * HZ)
59#define NAPI_WEIGHT 64 59#define NAPI_WEIGHT 64
60#define BLINK_MS 250 60#define BLINK_MS 250
61#define LINK_HZ (HZ/2)
61 62
62MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); 63MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
63MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); 64MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
@@ -605,7 +606,12 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
605 if (hw->chip_id == CHIP_ID_GENESIS) { 606 if (hw->chip_id == CHIP_ID_GENESIS) {
606 switch (mode) { 607 switch (mode) {
607 case LED_MODE_OFF: 608 case LED_MODE_OFF:
608 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); 609 if (hw->phy_type == SK_PHY_BCOM)
610 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
611 else {
612 skge_write32(hw, SK_REG(port, TX_LED_VAL), 0);
613 skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF);
614 }
609 skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); 615 skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
610 skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); 616 skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
611 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); 617 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
@@ -625,8 +631,14 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
625 skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); 631 skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
626 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); 632 skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
627 633
628 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); 634 if (hw->phy_type == SK_PHY_BCOM)
629 break; 635 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
636 else {
637 skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON);
638 skge_write32(hw, SK_REG(port, TX_LED_VAL), 100);
639 skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
640 }
641
630 } 642 }
631 } else { 643 } else {
632 switch (mode) { 644 switch (mode) {
@@ -879,6 +891,9 @@ static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
879 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); 891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
880 *val = xm_read16(hw, port, XM_PHY_DATA); 892 *val = xm_read16(hw, port, XM_PHY_DATA);
881 893
894 if (hw->phy_type == SK_PHY_XMAC)
895 goto ready;
896
882 for (i = 0; i < PHY_RETRIES; i++) { 897 for (i = 0; i < PHY_RETRIES; i++) {
883 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) 898 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
884 goto ready; 899 goto ready;
@@ -965,7 +980,8 @@ static void genesis_reset(struct skge_hw *hw, int port)
965 xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ 980 xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */
966 981
967 /* disable Broadcom PHY IRQ */ 982 /* disable Broadcom PHY IRQ */
968 xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); 983 if (hw->phy_type == SK_PHY_BCOM)
984 xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
969 985
970 xm_outhash(hw, port, XM_HSM, zero); 986 xm_outhash(hw, port, XM_HSM, zero);
971} 987}
@@ -1000,60 +1016,64 @@ static void bcom_check_link(struct skge_hw *hw, int port)
1000 1016
1001 if (netif_carrier_ok(dev)) 1017 if (netif_carrier_ok(dev))
1002 skge_link_down(skge); 1018 skge_link_down(skge);
1003 } else { 1019 return;
1004 if (skge->autoneg == AUTONEG_ENABLE && 1020 }
1005 (status & PHY_ST_AN_OVER)) {
1006 u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP);
1007 u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
1008
1009 if (lpa & PHY_B_AN_RF) {
1010 printk(KERN_NOTICE PFX "%s: remote fault\n",
1011 dev->name);
1012 return;
1013 }
1014 1021
1015 /* Check Duplex mismatch */ 1022 if (skge->autoneg == AUTONEG_ENABLE) {
1016 switch (aux & PHY_B_AS_AN_RES_MSK) { 1023 u16 lpa, aux;
1017 case PHY_B_RES_1000FD:
1018 skge->duplex = DUPLEX_FULL;
1019 break;
1020 case PHY_B_RES_1000HD:
1021 skge->duplex = DUPLEX_HALF;
1022 break;
1023 default:
1024 printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
1025 dev->name);
1026 return;
1027 }
1028 1024
1025 if (!(status & PHY_ST_AN_OVER))
1026 return;
1029 1027
1030 /* We are using IEEE 802.3z/D5.0 Table 37-4 */ 1028 lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
1031 switch (aux & PHY_B_AS_PAUSE_MSK) { 1029 if (lpa & PHY_B_AN_RF) {
1032 case PHY_B_AS_PAUSE_MSK: 1030 printk(KERN_NOTICE PFX "%s: remote fault\n",
1033 skge->flow_control = FLOW_MODE_SYMMETRIC; 1031 dev->name);
1034 break; 1032 return;
1035 case PHY_B_AS_PRR: 1033 }
1036 skge->flow_control = FLOW_MODE_REM_SEND;
1037 break;
1038 case PHY_B_AS_PRT:
1039 skge->flow_control = FLOW_MODE_LOC_SEND;
1040 break;
1041 default:
1042 skge->flow_control = FLOW_MODE_NONE;
1043 }
1044 1034
1045 skge->speed = SPEED_1000; 1035 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
1036
1037 /* Check Duplex mismatch */
1038 switch (aux & PHY_B_AS_AN_RES_MSK) {
1039 case PHY_B_RES_1000FD:
1040 skge->duplex = DUPLEX_FULL;
1041 break;
1042 case PHY_B_RES_1000HD:
1043 skge->duplex = DUPLEX_HALF;
1044 break;
1045 default:
1046 printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
1047 dev->name);
1048 return;
1046 } 1049 }
1047 1050
1048 if (!netif_carrier_ok(dev)) 1051
1049 genesis_link_up(skge); 1052 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
1053 switch (aux & PHY_B_AS_PAUSE_MSK) {
1054 case PHY_B_AS_PAUSE_MSK:
1055 skge->flow_control = FLOW_MODE_SYMMETRIC;
1056 break;
1057 case PHY_B_AS_PRR:
1058 skge->flow_control = FLOW_MODE_REM_SEND;
1059 break;
1060 case PHY_B_AS_PRT:
1061 skge->flow_control = FLOW_MODE_LOC_SEND;
1062 break;
1063 default:
1064 skge->flow_control = FLOW_MODE_NONE;
1065 }
1066 skge->speed = SPEED_1000;
1050 } 1067 }
1068
1069 if (!netif_carrier_ok(dev))
1070 genesis_link_up(skge);
1051} 1071}
1052 1072
1053/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional 1073/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
1054 * Phy on for 100 or 10Mbit operation 1074 * Phy on for 100 or 10Mbit operation
1055 */ 1075 */
1056static void bcom_phy_init(struct skge_port *skge, int jumbo) 1076static void bcom_phy_init(struct skge_port *skge)
1057{ 1077{
1058 struct skge_hw *hw = skge->hw; 1078 struct skge_hw *hw = skge->hw;
1059 int port = skge->port; 1079 int port = skge->port;
@@ -1144,7 +1164,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1144 phy_pause_map[skge->flow_control] | PHY_AN_CSMA); 1164 phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
1145 1165
1146 /* Handle Jumbo frames */ 1166 /* Handle Jumbo frames */
1147 if (jumbo) { 1167 if (hw->dev[port]->mtu > ETH_DATA_LEN) {
1148 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, 1168 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
1149 PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK); 1169 PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);
1150 1170
@@ -1157,8 +1177,154 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1157 1177
1158 /* Use link status change interrupt */ 1178 /* Use link status change interrupt */
1159 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1179 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1180}
1160 1181
1161 bcom_check_link(hw, port); 1182static void xm_phy_init(struct skge_port *skge)
1183{
1184 struct skge_hw *hw = skge->hw;
1185 int port = skge->port;
1186 u16 ctrl = 0;
1187
1188 if (skge->autoneg == AUTONEG_ENABLE) {
1189 if (skge->advertising & ADVERTISED_1000baseT_Half)
1190 ctrl |= PHY_X_AN_HD;
1191 if (skge->advertising & ADVERTISED_1000baseT_Full)
1192 ctrl |= PHY_X_AN_FD;
1193
1194 switch(skge->flow_control) {
1195 case FLOW_MODE_NONE:
1196 ctrl |= PHY_X_P_NO_PAUSE;
1197 break;
1198 case FLOW_MODE_LOC_SEND:
1199 ctrl |= PHY_X_P_ASYM_MD;
1200 break;
1201 case FLOW_MODE_SYMMETRIC:
1202 ctrl |= PHY_X_P_BOTH_MD;
1203 break;
1204 }
1205
1206 xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl);
1207
1208 /* Restart Auto-negotiation */
1209 ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
1210 } else {
1211 /* Set DuplexMode in Config register */
1212 if (skge->duplex == DUPLEX_FULL)
1213 ctrl |= PHY_CT_DUP_MD;
1214 /*
1215 * Do NOT enable Auto-negotiation here. This would hold
1216 * the link down because no IDLEs are transmitted
1217 */
1218 }
1219
1220 xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl);
1221
1222 /* Poll PHY for status changes */
1223 schedule_delayed_work(&skge->link_thread, LINK_HZ);
1224}
1225
1226static void xm_check_link(struct net_device *dev)
1227{
1228 struct skge_port *skge = netdev_priv(dev);
1229 struct skge_hw *hw = skge->hw;
1230 int port = skge->port;
1231 u16 status;
1232
1233 /* read twice because of latch */
1234 (void) xm_phy_read(hw, port, PHY_XMAC_STAT);
1235 status = xm_phy_read(hw, port, PHY_XMAC_STAT);
1236
1237 if ((status & PHY_ST_LSYNC) == 0) {
1238 u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
1239 cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
1240 xm_write16(hw, port, XM_MMU_CMD, cmd);
1241 /* dummy read to ensure writing */
1242 (void) xm_read16(hw, port, XM_MMU_CMD);
1243
1244 if (netif_carrier_ok(dev))
1245 skge_link_down(skge);
1246 return;
1247 }
1248
1249 if (skge->autoneg == AUTONEG_ENABLE) {
1250 u16 lpa, res;
1251
1252 if (!(status & PHY_ST_AN_OVER))
1253 return;
1254
1255 lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
1256 if (lpa & PHY_B_AN_RF) {
1257 printk(KERN_NOTICE PFX "%s: remote fault\n",
1258 dev->name);
1259 return;
1260 }
1261
1262 res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI);
1263
1264 /* Check Duplex mismatch */
1265 switch (res & (PHY_X_RS_HD | PHY_X_RS_FD)) {
1266 case PHY_X_RS_FD:
1267 skge->duplex = DUPLEX_FULL;
1268 break;
1269 case PHY_X_RS_HD:
1270 skge->duplex = DUPLEX_HALF;
1271 break;
1272 default:
1273 printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
1274 dev->name);
1275 return;
1276 }
1277
1278 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
1279 if (lpa & PHY_X_P_SYM_MD)
1280 skge->flow_control = FLOW_MODE_SYMMETRIC;
1281 else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD)
1282 skge->flow_control = FLOW_MODE_REM_SEND;
1283 else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD)
1284 skge->flow_control = FLOW_MODE_LOC_SEND;
1285 else
1286 skge->flow_control = FLOW_MODE_NONE;
1287
1288
1289 skge->speed = SPEED_1000;
1290 }
1291
1292 if (!netif_carrier_ok(dev))
1293 genesis_link_up(skge);
1294}
1295
1296/* Poll to check for link coming up.
1297 * Since internal PHY is wired to a level triggered pin, can't
1298 * get an interrupt when carrier is detected.
1299 */
1300static void xm_link_timer(void *arg)
1301{
1302 struct net_device *dev = arg;
1303 struct skge_port *skge = netdev_priv(arg);
1304 struct skge_hw *hw = skge->hw;
1305 int port = skge->port;
1306
1307 if (!netif_running(dev))
1308 return;
1309
1310 if (netif_carrier_ok(dev)) {
1311 xm_read16(hw, port, XM_ISRC);
1312 if (!(xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS))
1313 goto nochange;
1314 } else {
1315 if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS)
1316 goto nochange;
1317 xm_read16(hw, port, XM_ISRC);
1318 if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)
1319 goto nochange;
1320 }
1321
1322 mutex_lock(&hw->phy_mutex);
1323 xm_check_link(dev);
1324 mutex_unlock(&hw->phy_mutex);
1325
1326nochange:
1327 schedule_delayed_work(&skge->link_thread, LINK_HZ);
1162} 1328}
1163 1329
1164static void genesis_mac_init(struct skge_hw *hw, int port) 1330static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -1189,20 +1355,29 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1189 * namely for the 1000baseTX cards that use the XMAC's 1355 * namely for the 1000baseTX cards that use the XMAC's
1190 * GMII mode. 1356 * GMII mode.
1191 */ 1357 */
1192 /* Take external Phy out of reset */ 1358 if (hw->phy_type != SK_PHY_XMAC) {
1193 r = skge_read32(hw, B2_GP_IO); 1359 /* Take external Phy out of reset */
1194 if (port == 0) 1360 r = skge_read32(hw, B2_GP_IO);
1195 r |= GP_DIR_0|GP_IO_0; 1361 if (port == 0)
1196 else 1362 r |= GP_DIR_0|GP_IO_0;
1197 r |= GP_DIR_2|GP_IO_2; 1363 else
1364 r |= GP_DIR_2|GP_IO_2;
1198 1365
1199 skge_write32(hw, B2_GP_IO, r); 1366 skge_write32(hw, B2_GP_IO, r);
1200 1367
1368 /* Enable GMII interface */
1369 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1370 }
1201 1371
1202 /* Enable GMII interface */
1203 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1204 1372
1205 bcom_phy_init(skge, jumbo); 1373 switch(hw->phy_type) {
1374 case SK_PHY_XMAC:
1375 xm_phy_init(skge);
1376 break;
1377 case SK_PHY_BCOM:
1378 bcom_phy_init(skge);
1379 bcom_check_link(hw, port);
1380 }
1206 1381
1207 /* Set Station Address */ 1382 /* Set Station Address */
1208 xm_outaddr(hw, port, XM_SA, dev->dev_addr); 1383 xm_outaddr(hw, port, XM_SA, dev->dev_addr);
@@ -1335,16 +1510,18 @@ static void genesis_stop(struct skge_port *skge)
1335 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); 1510 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
1336 1511
1337 /* For external PHYs there must be special handling */ 1512 /* For external PHYs there must be special handling */
1338 reg = skge_read32(hw, B2_GP_IO); 1513 if (hw->phy_type != SK_PHY_XMAC) {
1339 if (port == 0) { 1514 reg = skge_read32(hw, B2_GP_IO);
1340 reg |= GP_DIR_0; 1515 if (port == 0) {
1341 reg &= ~GP_IO_0; 1516 reg |= GP_DIR_0;
1342 } else { 1517 reg &= ~GP_IO_0;
1343 reg |= GP_DIR_2; 1518 } else {
1344 reg &= ~GP_IO_2; 1519 reg |= GP_DIR_2;
1520 reg &= ~GP_IO_2;
1521 }
1522 skge_write32(hw, B2_GP_IO, reg);
1523 skge_read32(hw, B2_GP_IO);
1345 } 1524 }
1346 skge_write32(hw, B2_GP_IO, reg);
1347 skge_read32(hw, B2_GP_IO);
1348 1525
1349 xm_write16(hw, port, XM_MMU_CMD, 1526 xm_write16(hw, port, XM_MMU_CMD,
1350 xm_read16(hw, port, XM_MMU_CMD) 1527 xm_read16(hw, port, XM_MMU_CMD)
@@ -1406,7 +1583,7 @@ static void genesis_link_up(struct skge_port *skge)
1406 struct skge_hw *hw = skge->hw; 1583 struct skge_hw *hw = skge->hw;
1407 int port = skge->port; 1584 int port = skge->port;
1408 u16 cmd; 1585 u16 cmd;
1409 u32 mode, msk; 1586 u32 mode;
1410 1587
1411 cmd = xm_read16(hw, port, XM_MMU_CMD); 1588 cmd = xm_read16(hw, port, XM_MMU_CMD);
1412 1589
@@ -1454,27 +1631,24 @@ static void genesis_link_up(struct skge_port *skge)
1454 } 1631 }
1455 1632
1456 xm_write32(hw, port, XM_MODE, mode); 1633 xm_write32(hw, port, XM_MODE, mode);
1457 1634 xm_write16(hw, port, XM_IMSK, XM_DEF_MSK);
1458 msk = XM_DEF_MSK;
1459 /* disable GP0 interrupt bit for external Phy */
1460 msk |= XM_IS_INP_ASS;
1461
1462 xm_write16(hw, port, XM_IMSK, msk);
1463 xm_read16(hw, port, XM_ISRC); 1635 xm_read16(hw, port, XM_ISRC);
1464 1636
1465 /* get MMU Command Reg. */ 1637 /* get MMU Command Reg. */
1466 cmd = xm_read16(hw, port, XM_MMU_CMD); 1638 cmd = xm_read16(hw, port, XM_MMU_CMD);
1467 if (skge->duplex == DUPLEX_FULL) 1639 if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL)
1468 cmd |= XM_MMU_GMII_FD; 1640 cmd |= XM_MMU_GMII_FD;
1469 1641
1470 /* 1642 /*
1471 * Workaround BCOM Errata (#10523) for all BCom Phys 1643 * Workaround BCOM Errata (#10523) for all BCom Phys
1472 * Enable Power Management after link up 1644 * Enable Power Management after link up
1473 */ 1645 */
1474 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, 1646 if (hw->phy_type == SK_PHY_BCOM) {
1475 xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) 1647 xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
1476 & ~PHY_B_AC_DIS_PM); 1648 xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
1477 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1649 & ~PHY_B_AC_DIS_PM);
1650 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1651 }
1478 1652
1479 /* enable Rx/Tx */ 1653 /* enable Rx/Tx */
1480 xm_write16(hw, port, XM_MMU_CMD, 1654 xm_write16(hw, port, XM_MMU_CMD,
@@ -2240,6 +2414,8 @@ static int skge_down(struct net_device *dev)
2240 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); 2414 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
2241 2415
2242 netif_stop_queue(dev); 2416 netif_stop_queue(dev);
2417 if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
2418 cancel_rearming_delayed_work(&skge->link_thread);
2243 2419
2244 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); 2420 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
2245 if (hw->chip_id == CHIP_ID_GENESIS) 2421 if (hw->chip_id == CHIP_ID_GENESIS)
@@ -2862,7 +3038,7 @@ static void skge_extirq(void *arg)
2862 if (netif_running(dev)) { 3038 if (netif_running(dev)) {
2863 if (hw->chip_id != CHIP_ID_GENESIS) 3039 if (hw->chip_id != CHIP_ID_GENESIS)
2864 yukon_phy_intr(skge); 3040 yukon_phy_intr(skge);
2865 else 3041 else if (hw->phy_type == SK_PHY_BCOM)
2866 bcom_phy_intr(skge); 3042 bcom_phy_intr(skge);
2867 } 3043 }
2868 } 3044 }
@@ -3014,7 +3190,7 @@ static int skge_reset(struct skge_hw *hw)
3014{ 3190{
3015 u32 reg; 3191 u32 reg;
3016 u16 ctst, pci_status; 3192 u16 ctst, pci_status;
3017 u8 t8, mac_cfg, pmd_type, phy_type; 3193 u8 t8, mac_cfg, pmd_type;
3018 int i; 3194 int i;
3019 3195
3020 ctst = skge_read16(hw, B0_CTST); 3196 ctst = skge_read16(hw, B0_CTST);
@@ -3038,19 +3214,22 @@ static int skge_reset(struct skge_hw *hw)
3038 ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); 3214 ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA));
3039 3215
3040 hw->chip_id = skge_read8(hw, B2_CHIP_ID); 3216 hw->chip_id = skge_read8(hw, B2_CHIP_ID);
3041 phy_type = skge_read8(hw, B2_E_1) & 0xf; 3217 hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
3042 pmd_type = skge_read8(hw, B2_PMD_TYP); 3218 pmd_type = skge_read8(hw, B2_PMD_TYP);
3043 hw->copper = (pmd_type == 'T' || pmd_type == '1'); 3219 hw->copper = (pmd_type == 'T' || pmd_type == '1');
3044 3220
3045 switch (hw->chip_id) { 3221 switch (hw->chip_id) {
3046 case CHIP_ID_GENESIS: 3222 case CHIP_ID_GENESIS:
3047 switch (phy_type) { 3223 switch (hw->phy_type) {
3224 case SK_PHY_XMAC:
3225 hw->phy_addr = PHY_ADDR_XMAC;
3226 break;
3048 case SK_PHY_BCOM: 3227 case SK_PHY_BCOM:
3049 hw->phy_addr = PHY_ADDR_BCOM; 3228 hw->phy_addr = PHY_ADDR_BCOM;
3050 break; 3229 break;
3051 default: 3230 default:
3052 printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", 3231 printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n",
3053 pci_name(hw->pdev), phy_type); 3232 pci_name(hw->pdev), hw->phy_type);
3054 return -EOPNOTSUPP; 3233 return -EOPNOTSUPP;
3055 } 3234 }
3056 break; 3235 break;
@@ -3058,7 +3237,7 @@ static int skge_reset(struct skge_hw *hw)
3058 case CHIP_ID_YUKON: 3237 case CHIP_ID_YUKON:
3059 case CHIP_ID_YUKON_LITE: 3238 case CHIP_ID_YUKON_LITE:
3060 case CHIP_ID_YUKON_LP: 3239 case CHIP_ID_YUKON_LP:
3061 if (phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S') 3240 if (hw->phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S')
3062 hw->copper = 1; 3241 hw->copper = 1;
3063 3242
3064 hw->phy_addr = PHY_ADDR_MARV; 3243 hw->phy_addr = PHY_ADDR_MARV;
@@ -3089,10 +3268,13 @@ static int skge_reset(struct skge_hw *hw)
3089 else 3268 else
3090 hw->ram_size = t8 * 4096; 3269 hw->ram_size = t8 * 4096;
3091 3270
3092 hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; 3271 hw->intr_mask = IS_HW_ERR | IS_PORT_1;
3093 if (hw->ports > 1) 3272 if (hw->ports > 1)
3094 hw->intr_mask |= IS_PORT_2; 3273 hw->intr_mask |= IS_PORT_2;
3095 3274
3275 if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC))
3276 hw->intr_mask |= IS_EXT_REG;
3277
3096 if (hw->chip_id == CHIP_ID_GENESIS) 3278 if (hw->chip_id == CHIP_ID_GENESIS)
3097 genesis_init(hw); 3279 genesis_init(hw);
3098 else { 3280 else {
@@ -3226,6 +3408,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
3226 3408
3227 skge->port = port; 3409 skge->port = port;
3228 3410
3411 /* Only used for Genesis XMAC */
3412 INIT_WORK(&skge->link_thread, xm_link_timer, dev);
3413
3229 if (hw->chip_id != CHIP_ID_GENESIS) { 3414 if (hw->chip_id != CHIP_ID_GENESIS) {
3230 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; 3415 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
3231 skge->rx_csum = 1; 3416 skge->rx_csum = 1;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 79e09271bcf9..d0b47d46cf9d 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -934,7 +934,7 @@ enum {
934 PHY_XMAC_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ 934 PHY_XMAC_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */
935 PHY_XMAC_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Abi Reg */ 935 PHY_XMAC_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Abi Reg */
936 PHY_XMAC_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ 936 PHY_XMAC_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */
937 PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */ 937 PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */
938 PHY_XMAC_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */ 938 PHY_XMAC_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */
939 939
940 PHY_XMAC_EXT_STAT = 0x0f,/* 16 bit r/o Ext Status Register */ 940 PHY_XMAC_EXT_STAT = 0x0f,/* 16 bit r/o Ext Status Register */
@@ -1097,13 +1097,36 @@ enum {
1097 1097
1098/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ 1098/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
1099enum { 1099enum {
1100 PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */ 1100 PHY_X_P_NO_PAUSE= 0<<7,/* Bit 8..7: no Pause Mode */
1101 PHY_X_P_SYM_MD = 1<<7, /* Bit 8..7: symmetric Pause Mode */ 1101 PHY_X_P_SYM_MD = 1<<7, /* Bit 8..7: symmetric Pause Mode */
1102 PHY_X_P_ASYM_MD = 2<<7,/* Bit 8..7: asymmetric Pause Mode */ 1102 PHY_X_P_ASYM_MD = 2<<7,/* Bit 8..7: asymmetric Pause Mode */
1103 PHY_X_P_BOTH_MD = 3<<7,/* Bit 8..7: both Pause Mode */ 1103 PHY_X_P_BOTH_MD = 3<<7,/* Bit 8..7: both Pause Mode */
1104}; 1104};
1105 1105
1106 1106
1107/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
1108enum {
1109 PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */
1110 PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */
1111};
1112
1113/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
1114enum {
1115 PHY_X_RS_PAUSE = 3<<7, /* Bit 8..7: selected Pause Mode */
1116 PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */
1117 PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */
1118 PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */
1119 PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */
1120};
1121
1122/* Remote Fault Bits (PHY_X_AN_RFB) encoding */
1123enum {
1124 X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */
1125 X_RFB_LF = 1<<12,/* Bit 13..12 Link Failure */
1126 X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */
1127 X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */
1128};
1129
1107/* Broadcom-Specific */ 1130/* Broadcom-Specific */
1108/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ 1131/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1109enum { 1132enum {
@@ -2158,8 +2181,8 @@ enum {
2158 XM_IS_LNK_AE = 1<<14, /* Bit 14: Link Asynchronous Event */ 2181 XM_IS_LNK_AE = 1<<14, /* Bit 14: Link Asynchronous Event */
2159 XM_IS_TX_ABORT = 1<<13, /* Bit 13: Transmit Abort, late Col. etc */ 2182 XM_IS_TX_ABORT = 1<<13, /* Bit 13: Transmit Abort, late Col. etc */
2160 XM_IS_FRC_INT = 1<<12, /* Bit 12: Force INT bit set in GP */ 2183 XM_IS_FRC_INT = 1<<12, /* Bit 12: Force INT bit set in GP */
2161 XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */ 2184 XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */
2162 XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */ 2185 XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */
2163 XM_IS_RX_PAGE = 1<<9, /* Bit 9: Page Received */ 2186 XM_IS_RX_PAGE = 1<<9, /* Bit 9: Page Received */
2164 XM_IS_TX_PAGE = 1<<8, /* Bit 8: Next Page Loaded for Transmit */ 2187 XM_IS_TX_PAGE = 1<<8, /* Bit 8: Next Page Loaded for Transmit */
2165 XM_IS_AND = 1<<7, /* Bit 7: Auto-Negotiation Done */ 2188 XM_IS_AND = 1<<7, /* Bit 7: Auto-Negotiation Done */
@@ -2172,9 +2195,7 @@ enum {
2172 XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ 2195 XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */
2173}; 2196};
2174 2197
2175#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | \ 2198#define XM_DEF_MSK (~(XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_RXF_OV | XM_IS_TXF_UR))
2176 XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | \
2177 XM_IS_RXF_OV | XM_IS_TXF_UR))
2178 2199
2179 2200
2180/* XM_HW_CFG 16 bit r/w Hardware Config Register */ 2201/* XM_HW_CFG 16 bit r/w Hardware Config Register */
@@ -2396,6 +2417,7 @@ struct skge_hw {
2396 u8 chip_rev; 2417 u8 chip_rev;
2397 u8 copper; 2418 u8 copper;
2398 u8 ports; 2419 u8 ports;
2420 u8 phy_type;
2399 2421
2400 u32 ram_size; 2422 u32 ram_size;
2401 u32 ram_offset; 2423 u32 ram_offset;
@@ -2422,6 +2444,7 @@ struct skge_port {
2422 2444
2423 struct net_device_stats net_stats; 2445 struct net_device_stats net_stats;
2424 2446
2447 struct work_struct link_thread;
2425 u8 rx_csum; 2448 u8 rx_csum;
2426 u8 blink_on; 2449 u8 blink_on;
2427 u8 flow_control; 2450 u8 flow_control;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 7aa7fbac8224..c660e33f43a2 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -379,6 +379,24 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
379 379
380#define SMC_IRQ_FLAGS (0) 380#define SMC_IRQ_FLAGS (0)
381 381
382#elif defined(CONFIG_ARCH_VERSATILE)
383
384#define SMC_CAN_USE_8BIT 1
385#define SMC_CAN_USE_16BIT 1
386#define SMC_CAN_USE_32BIT 1
387#define SMC_NOWAIT 1
388
389#define SMC_inb(a, r) readb((a) + (r))
390#define SMC_inw(a, r) readw((a) + (r))
391#define SMC_inl(a, r) readl((a) + (r))
392#define SMC_outb(v, a, r) writeb(v, (a) + (r))
393#define SMC_outw(v, a, r) writew(v, (a) + (r))
394#define SMC_outl(v, a, r) writel(v, (a) + (r))
395#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
396#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
397
398#define SMC_IRQ_FLAGS (0)
399
382#else 400#else
383 401
384#define SMC_CAN_USE_8BIT 1 402#define SMC_CAN_USE_8BIT 1
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index 0d66700c6ced..bfc8c3eae9a1 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -1876,7 +1876,6 @@ static int sprintf_info(char *buffer, struct net_device *dev)
1876 datap[size+1]=io_word & 0xff; 1876 datap[size+1]=io_word & 0xff;
1877 } 1877 }
1878 1878
1879
1880 size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); 1879 size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name);
1881 1880
1882 size += sprintf(buffer + size, 1881 size += sprintf(buffer + size,
@@ -1932,64 +1931,6 @@ static int sprintf_info(char *buffer, struct net_device *dev)
1932#endif 1931#endif
1933#endif 1932#endif
1934 1933
1935#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1936static int streamer_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1937{
1938 int i;
1939 struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;
1940 u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
1941
1942 switch(cmd) {
1943 case IOCTL_SISR_MASK:
1944 writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
1945 break;
1946 case IOCTL_SPIN_LOCK_TEST:
1947 printk(KERN_INFO "spin_lock() called.\n");
1948 spin_lock(&streamer_priv->streamer_lock);
1949 spin_unlock(&streamer_priv->streamer_lock);
1950 printk(KERN_INFO "spin_unlock() finished.\n");
1951 break;
1952 case IOCTL_PRINT_BDAS:
1953 printk(KERN_INFO "bdas: RXBDA: %x RXLBDA: %x TX2FDA: %x TX2LFDA: %x\n",
1954 readw(streamer_mmio + RXBDA),
1955 readw(streamer_mmio + RXLBDA),
1956 readw(streamer_mmio + TX2FDA),
1957 readw(streamer_mmio + TX2LFDA));
1958 break;
1959 case IOCTL_PRINT_REGISTERS:
1960 printk(KERN_INFO "registers:\n");
1961 printk(KERN_INFO "SISR: %04x MISR: %04x LISR: %04x BCTL: %04x BMCTL: %04x\nmask %04x mask %04x\n",
1962 readw(streamer_mmio + SISR),
1963 readw(streamer_mmio + MISR_RUM),
1964 readw(streamer_mmio + LISR),
1965 readw(streamer_mmio + BCTL),
1966 readw(streamer_mmio + BMCTL_SUM),
1967 readw(streamer_mmio + SISR_MASK),
1968 readw(streamer_mmio + MISR_MASK));
1969 break;
1970 case IOCTL_PRINT_RX_BUFS:
1971 printk(KERN_INFO "Print rx bufs:\n");
1972 for(i=0; i<STREAMER_RX_RING_SIZE; i++)
1973 printk(KERN_INFO "rx_ring %d status: 0x%x\n", i,
1974 streamer_priv->streamer_rx_ring[i].status);
1975 break;
1976 case IOCTL_PRINT_TX_BUFS:
1977 printk(KERN_INFO "Print tx bufs:\n");
1978 for(i=0; i<STREAMER_TX_RING_SIZE; i++)
1979 printk(KERN_INFO "tx_ring %d status: 0x%x\n", i,
1980 streamer_priv->streamer_tx_ring[i].status);
1981 break;
1982 case IOCTL_RX_CMD:
1983 streamer_rx(dev);
1984 printk(KERN_INFO "Sent rx command.\n");
1985 break;
1986 default:
1987 printk(KERN_INFO "Bad ioctl!\n");
1988 }
1989 return 0;
1990}
1991#endif
1992
1993static struct pci_driver streamer_pci_driver = { 1934static struct pci_driver streamer_pci_driver = {
1994 .name = "lanstreamer", 1935 .name = "lanstreamer",
1995 .id_table = streamer_pci_tbl, 1936 .id_table = streamer_pci_tbl,
diff --git a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h
index 5557d8e1e22d..e7bb3494afc7 100644
--- a/drivers/net/tokenring/lanstreamer.h
+++ b/drivers/net/tokenring/lanstreamer.h
@@ -62,18 +62,6 @@
62 62
63#include <linux/version.h> 63#include <linux/version.h>
64 64
65#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
66#include <asm/ioctl.h>
67#define IOCTL_PRINT_RX_BUFS SIOCDEVPRIVATE
68#define IOCTL_PRINT_TX_BUFS SIOCDEVPRIVATE+1
69#define IOCTL_RX_CMD SIOCDEVPRIVATE+2
70#define IOCTL_TX_CMD SIOCDEVPRIVATE+3
71#define IOCTL_PRINT_REGISTERS SIOCDEVPRIVATE+4
72#define IOCTL_PRINT_BDAS SIOCDEVPRIVATE+5
73#define IOCTL_SPIN_LOCK_TEST SIOCDEVPRIVATE+6
74#define IOCTL_SISR_MASK SIOCDEVPRIVATE+7
75#endif
76
77/* MAX_INTR - the maximum number of times we can loop 65/* MAX_INTR - the maximum number of times we can loop
78 * inside the interrupt function before returning 66 * inside the interrupt function before returning
79 * control to the OS (maximum value is 256) 67 * control to the OS (maximum value is 256)
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 8f6f6fd8b87d..d5c32e9caa97 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -333,11 +333,7 @@ enum state_values {
333#define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY) 333#define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY)
334#define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY) 334#define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY)
335 335
336#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28)
337#define typhoon_synchronize_irq(x) synchronize_irq()
338#else
339#define typhoon_synchronize_irq(x) synchronize_irq(x) 336#define typhoon_synchronize_irq(x) synchronize_irq(x)
340#endif
341 337
342#if defined(NETIF_F_TSO) 338#if defined(NETIF_F_TSO)
343#define skb_tso_size(x) (skb_shinfo(x)->gso_size) 339#define skb_tso_size(x) (skb_shinfo(x)->gso_size)
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 54b8e492ef97..58b7efbb0750 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -154,7 +154,7 @@ config HDLC
154 If unsure, say N. 154 If unsure, say N.
155 155
156config HDLC_RAW 156config HDLC_RAW
157 bool "Raw HDLC support" 157 tristate "Raw HDLC support"
158 depends on HDLC 158 depends on HDLC
159 help 159 help
160 Generic HDLC driver supporting raw HDLC over WAN connections. 160 Generic HDLC driver supporting raw HDLC over WAN connections.
@@ -162,7 +162,7 @@ config HDLC_RAW
162 If unsure, say N. 162 If unsure, say N.
163 163
164config HDLC_RAW_ETH 164config HDLC_RAW_ETH
165 bool "Raw HDLC Ethernet device support" 165 tristate "Raw HDLC Ethernet device support"
166 depends on HDLC 166 depends on HDLC
167 help 167 help
168 Generic HDLC driver supporting raw HDLC Ethernet device emulation 168 Generic HDLC driver supporting raw HDLC Ethernet device emulation
@@ -173,7 +173,7 @@ config HDLC_RAW_ETH
173 If unsure, say N. 173 If unsure, say N.
174 174
175config HDLC_CISCO 175config HDLC_CISCO
176 bool "Cisco HDLC support" 176 tristate "Cisco HDLC support"
177 depends on HDLC 177 depends on HDLC
178 help 178 help
179 Generic HDLC driver supporting Cisco HDLC over WAN connections. 179 Generic HDLC driver supporting Cisco HDLC over WAN connections.
@@ -181,7 +181,7 @@ config HDLC_CISCO
181 If unsure, say N. 181 If unsure, say N.
182 182
183config HDLC_FR 183config HDLC_FR
184 bool "Frame Relay support" 184 tristate "Frame Relay support"
185 depends on HDLC 185 depends on HDLC
186 help 186 help
187 Generic HDLC driver supporting Frame Relay over WAN connections. 187 Generic HDLC driver supporting Frame Relay over WAN connections.
@@ -189,7 +189,7 @@ config HDLC_FR
189 If unsure, say N. 189 If unsure, say N.
190 190
191config HDLC_PPP 191config HDLC_PPP
192 bool "Synchronous Point-to-Point Protocol (PPP) support" 192 tristate "Synchronous Point-to-Point Protocol (PPP) support"
193 depends on HDLC 193 depends on HDLC
194 help 194 help
195 Generic HDLC driver supporting PPP over WAN connections. 195 Generic HDLC driver supporting PPP over WAN connections.
@@ -197,7 +197,7 @@ config HDLC_PPP
197 If unsure, say N. 197 If unsure, say N.
198 198
199config HDLC_X25 199config HDLC_X25
200 bool "X.25 protocol support" 200 tristate "X.25 protocol support"
201 depends on HDLC && (LAPB=m && HDLC=m || LAPB=y) 201 depends on HDLC && (LAPB=m && HDLC=m || LAPB=y)
202 help 202 help
203 Generic HDLC driver supporting X.25 over WAN connections. 203 Generic HDLC driver supporting X.25 over WAN connections.
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index 316ca6869d5e..83ec2c87ba3f 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -9,14 +9,13 @@ cyclomx-y := cycx_main.o
9cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o 9cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o
10cyclomx-objs := $(cyclomx-y) 10cyclomx-objs := $(cyclomx-y)
11 11
12hdlc-y := hdlc_generic.o 12obj-$(CONFIG_HDLC) += hdlc.o
13hdlc-$(CONFIG_HDLC_RAW) += hdlc_raw.o 13obj-$(CONFIG_HDLC_RAW) += hdlc_raw.o
14hdlc-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o 14obj-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o
15hdlc-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o 15obj-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o
16hdlc-$(CONFIG_HDLC_FR) += hdlc_fr.o 16obj-$(CONFIG_HDLC_FR) += hdlc_fr.o
17hdlc-$(CONFIG_HDLC_PPP) += hdlc_ppp.o 17obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o syncppp.o
18hdlc-$(CONFIG_HDLC_X25) += hdlc_x25.o 18obj-$(CONFIG_HDLC_X25) += hdlc_x25.o
19hdlc-objs := $(hdlc-y)
20 19
21pc300-y := pc300_drv.o 20pc300-y := pc300_drv.o
22pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o 21pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o
@@ -38,10 +37,6 @@ obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o
38obj-$(CONFIG_LAPBETHER) += lapbether.o 37obj-$(CONFIG_LAPBETHER) += lapbether.o
39obj-$(CONFIG_SBNI) += sbni.o 38obj-$(CONFIG_SBNI) += sbni.o
40obj-$(CONFIG_PC300) += pc300.o 39obj-$(CONFIG_PC300) += pc300.o
41obj-$(CONFIG_HDLC) += hdlc.o
42ifeq ($(CONFIG_HDLC_PPP),y)
43 obj-$(CONFIG_HDLC) += syncppp.o
44endif
45obj-$(CONFIG_N2) += n2.o 40obj-$(CONFIG_N2) += n2.o
46obj-$(CONFIG_C101) += c101.o 41obj-$(CONFIG_C101) += c101.o
47obj-$(CONFIG_WANXL) += wanxl.o 42obj-$(CONFIG_WANXL) += wanxl.o
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc.c
index 04ca1f7b6424..db354e0edbe5 100644
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * 3 *
4 * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> 4 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License 7 * under the terms of version 2 of the GNU General Public License
@@ -17,9 +17,9 @@
17 * Use sethdlc utility to set line parameters, protocol and PVCs 17 * Use sethdlc utility to set line parameters, protocol and PVCs
18 * 18 *
19 * How does it work: 19 * How does it work:
20 * - proto.open(), close(), start(), stop() calls are serialized. 20 * - proto->open(), close(), start(), stop() calls are serialized.
21 * The order is: open, [ start, stop ... ] close ... 21 * The order is: open, [ start, stop ... ] close ...
22 * - proto.start() and stop() are called with spin_lock_irq held. 22 * - proto->start() and stop() are called with spin_lock_irq held.
23 */ 23 */
24 24
25#include <linux/module.h> 25#include <linux/module.h>
@@ -38,10 +38,12 @@
38#include <linux/hdlc.h> 38#include <linux/hdlc.h>
39 39
40 40
41static const char* version = "HDLC support module revision 1.19"; 41static const char* version = "HDLC support module revision 1.20";
42 42
43#undef DEBUG_LINK 43#undef DEBUG_LINK
44 44
45static struct hdlc_proto *first_proto = NULL;
46
45 47
46static int hdlc_change_mtu(struct net_device *dev, int new_mtu) 48static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
47{ 49{
@@ -63,11 +65,11 @@ static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
63static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, 65static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
64 struct packet_type *p, struct net_device *orig_dev) 66 struct packet_type *p, struct net_device *orig_dev)
65{ 67{
66 hdlc_device *hdlc = dev_to_hdlc(dev); 68 struct hdlc_device_desc *desc = dev_to_desc(dev);
67 if (hdlc->proto.netif_rx) 69 if (desc->netif_rx)
68 return hdlc->proto.netif_rx(skb); 70 return desc->netif_rx(skb);
69 71
70 hdlc->stats.rx_dropped++; /* Shouldn't happen */ 72 desc->stats.rx_dropped++; /* Shouldn't happen */
71 dev_kfree_skb(skb); 73 dev_kfree_skb(skb);
72 return NET_RX_DROP; 74 return NET_RX_DROP;
73} 75}
@@ -77,8 +79,8 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
77static inline void hdlc_proto_start(struct net_device *dev) 79static inline void hdlc_proto_start(struct net_device *dev)
78{ 80{
79 hdlc_device *hdlc = dev_to_hdlc(dev); 81 hdlc_device *hdlc = dev_to_hdlc(dev);
80 if (hdlc->proto.start) 82 if (hdlc->proto->start)
81 return hdlc->proto.start(dev); 83 return hdlc->proto->start(dev);
82} 84}
83 85
84 86
@@ -86,8 +88,8 @@ static inline void hdlc_proto_start(struct net_device *dev)
86static inline void hdlc_proto_stop(struct net_device *dev) 88static inline void hdlc_proto_stop(struct net_device *dev)
87{ 89{
88 hdlc_device *hdlc = dev_to_hdlc(dev); 90 hdlc_device *hdlc = dev_to_hdlc(dev);
89 if (hdlc->proto.stop) 91 if (hdlc->proto->stop)
90 return hdlc->proto.stop(dev); 92 return hdlc->proto->stop(dev);
91} 93}
92 94
93 95
@@ -144,15 +146,15 @@ int hdlc_open(struct net_device *dev)
144{ 146{
145 hdlc_device *hdlc = dev_to_hdlc(dev); 147 hdlc_device *hdlc = dev_to_hdlc(dev);
146#ifdef DEBUG_LINK 148#ifdef DEBUG_LINK
147 printk(KERN_DEBUG "hdlc_open() carrier %i open %i\n", 149 printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name,
148 hdlc->carrier, hdlc->open); 150 hdlc->carrier, hdlc->open);
149#endif 151#endif
150 152
151 if (hdlc->proto.id == -1) 153 if (hdlc->proto == NULL)
152 return -ENOSYS; /* no protocol attached */ 154 return -ENOSYS; /* no protocol attached */
153 155
154 if (hdlc->proto.open) { 156 if (hdlc->proto->open) {
155 int result = hdlc->proto.open(dev); 157 int result = hdlc->proto->open(dev);
156 if (result) 158 if (result)
157 return result; 159 return result;
158 } 160 }
@@ -178,7 +180,7 @@ void hdlc_close(struct net_device *dev)
178{ 180{
179 hdlc_device *hdlc = dev_to_hdlc(dev); 181 hdlc_device *hdlc = dev_to_hdlc(dev);
180#ifdef DEBUG_LINK 182#ifdef DEBUG_LINK
181 printk(KERN_DEBUG "hdlc_close() carrier %i open %i\n", 183 printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name,
182 hdlc->carrier, hdlc->open); 184 hdlc->carrier, hdlc->open);
183#endif 185#endif
184 186
@@ -190,68 +192,34 @@ void hdlc_close(struct net_device *dev)
190 192
191 spin_unlock_irq(&hdlc->state_lock); 193 spin_unlock_irq(&hdlc->state_lock);
192 194
193 if (hdlc->proto.close) 195 if (hdlc->proto->close)
194 hdlc->proto.close(dev); 196 hdlc->proto->close(dev);
195} 197}
196 198
197 199
198 200
199#ifndef CONFIG_HDLC_RAW
200#define hdlc_raw_ioctl(dev, ifr) -ENOSYS
201#endif
202
203#ifndef CONFIG_HDLC_RAW_ETH
204#define hdlc_raw_eth_ioctl(dev, ifr) -ENOSYS
205#endif
206
207#ifndef CONFIG_HDLC_PPP
208#define hdlc_ppp_ioctl(dev, ifr) -ENOSYS
209#endif
210
211#ifndef CONFIG_HDLC_CISCO
212#define hdlc_cisco_ioctl(dev, ifr) -ENOSYS
213#endif
214
215#ifndef CONFIG_HDLC_FR
216#define hdlc_fr_ioctl(dev, ifr) -ENOSYS
217#endif
218
219#ifndef CONFIG_HDLC_X25
220#define hdlc_x25_ioctl(dev, ifr) -ENOSYS
221#endif
222
223
224int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 201int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
225{ 202{
226 hdlc_device *hdlc = dev_to_hdlc(dev); 203 struct hdlc_proto *proto = first_proto;
227 unsigned int proto; 204 int result;
228 205
229 if (cmd != SIOCWANDEV) 206 if (cmd != SIOCWANDEV)
230 return -EINVAL; 207 return -EINVAL;
231 208
232 switch(ifr->ifr_settings.type) { 209 if (dev_to_hdlc(dev)->proto) {
233 case IF_PROTO_HDLC: 210 result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr);
234 case IF_PROTO_HDLC_ETH: 211 if (result != -EINVAL)
235 case IF_PROTO_PPP: 212 return result;
236 case IF_PROTO_CISCO:
237 case IF_PROTO_FR:
238 case IF_PROTO_X25:
239 proto = ifr->ifr_settings.type;
240 break;
241
242 default:
243 proto = hdlc->proto.id;
244 } 213 }
245 214
246 switch(proto) { 215 /* Not handled by currently attached protocol (if any) */
247 case IF_PROTO_HDLC: return hdlc_raw_ioctl(dev, ifr); 216
248 case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(dev, ifr); 217 while (proto) {
249 case IF_PROTO_PPP: return hdlc_ppp_ioctl(dev, ifr); 218 if ((result = proto->ioctl(dev, ifr)) != -EINVAL)
250 case IF_PROTO_CISCO: return hdlc_cisco_ioctl(dev, ifr); 219 return result;
251 case IF_PROTO_FR: return hdlc_fr_ioctl(dev, ifr); 220 proto = proto->next;
252 case IF_PROTO_X25: return hdlc_x25_ioctl(dev, ifr);
253 default: return -EINVAL;
254 } 221 }
222 return -EINVAL;
255} 223}
256 224
257void hdlc_setup(struct net_device *dev) 225void hdlc_setup(struct net_device *dev)
@@ -267,8 +235,6 @@ void hdlc_setup(struct net_device *dev)
267 235
268 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 236 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
269 237
270 hdlc->proto.id = -1;
271 hdlc->proto.detach = NULL;
272 hdlc->carrier = 1; 238 hdlc->carrier = 1;
273 hdlc->open = 0; 239 hdlc->open = 0;
274 spin_lock_init(&hdlc->state_lock); 240 spin_lock_init(&hdlc->state_lock);
@@ -277,7 +243,8 @@ void hdlc_setup(struct net_device *dev)
277struct net_device *alloc_hdlcdev(void *priv) 243struct net_device *alloc_hdlcdev(void *priv)
278{ 244{
279 struct net_device *dev; 245 struct net_device *dev;
280 dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup); 246 dev = alloc_netdev(sizeof(struct hdlc_device_desc) +
247 sizeof(hdlc_device), "hdlc%d", hdlc_setup);
281 if (dev) 248 if (dev)
282 dev_to_hdlc(dev)->priv = priv; 249 dev_to_hdlc(dev)->priv = priv;
283 return dev; 250 return dev;
@@ -286,13 +253,71 @@ struct net_device *alloc_hdlcdev(void *priv)
286void unregister_hdlc_device(struct net_device *dev) 253void unregister_hdlc_device(struct net_device *dev)
287{ 254{
288 rtnl_lock(); 255 rtnl_lock();
289 hdlc_proto_detach(dev_to_hdlc(dev));
290 unregister_netdevice(dev); 256 unregister_netdevice(dev);
257 detach_hdlc_protocol(dev);
291 rtnl_unlock(); 258 rtnl_unlock();
292} 259}
293 260
294 261
295 262
263int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
264 int (*rx)(struct sk_buff *skb), size_t size)
265{
266 detach_hdlc_protocol(dev);
267
268 if (!try_module_get(proto->module))
269 return -ENOSYS;
270
271 if (size)
272 if ((dev_to_hdlc(dev)->state = kmalloc(size,
273 GFP_KERNEL)) == NULL) {
274 printk(KERN_WARNING "Memory squeeze on"
275 " hdlc_proto_attach()\n");
276 module_put(proto->module);
277 return -ENOBUFS;
278 }
279 dev_to_hdlc(dev)->proto = proto;
280 dev_to_desc(dev)->netif_rx = rx;
281 return 0;
282}
283
284
285void detach_hdlc_protocol(struct net_device *dev)
286{
287 hdlc_device *hdlc = dev_to_hdlc(dev);
288
289 if (hdlc->proto) {
290 if (hdlc->proto->detach)
291 hdlc->proto->detach(dev);
292 module_put(hdlc->proto->module);
293 hdlc->proto = NULL;
294 }
295 kfree(hdlc->state);
296 hdlc->state = NULL;
297}
298
299
300void register_hdlc_protocol(struct hdlc_proto *proto)
301{
302 proto->next = first_proto;
303 first_proto = proto;
304}
305
306
307void unregister_hdlc_protocol(struct hdlc_proto *proto)
308{
309 struct hdlc_proto **p = &first_proto;
310 while (*p) {
311 if (*p == proto) {
312 *p = proto->next;
313 return;
314 }
315 p = &((*p)->next);
316 }
317}
318
319
320
296MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 321MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
297MODULE_DESCRIPTION("HDLC support module"); 322MODULE_DESCRIPTION("HDLC support module");
298MODULE_LICENSE("GPL v2"); 323MODULE_LICENSE("GPL v2");
@@ -303,6 +328,10 @@ EXPORT_SYMBOL(hdlc_ioctl);
303EXPORT_SYMBOL(hdlc_setup); 328EXPORT_SYMBOL(hdlc_setup);
304EXPORT_SYMBOL(alloc_hdlcdev); 329EXPORT_SYMBOL(alloc_hdlcdev);
305EXPORT_SYMBOL(unregister_hdlc_device); 330EXPORT_SYMBOL(unregister_hdlc_device);
331EXPORT_SYMBOL(register_hdlc_protocol);
332EXPORT_SYMBOL(unregister_hdlc_protocol);
333EXPORT_SYMBOL(attach_hdlc_protocol);
334EXPORT_SYMBOL(detach_hdlc_protocol);
306 335
307static struct packet_type hdlc_packet_type = { 336static struct packet_type hdlc_packet_type = {
308 .type = __constant_htons(ETH_P_HDLC), 337 .type = __constant_htons(ETH_P_HDLC),
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index f289daba0c7b..7ec2b2f9b7ee 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * Cisco HDLC support 3 * Cisco HDLC support
4 * 4 *
5 * Copyright (C) 2000 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 2000 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -34,17 +34,56 @@
34#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ 34#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */
35 35
36 36
37struct hdlc_header {
38 u8 address;
39 u8 control;
40 u16 protocol;
41}__attribute__ ((packed));
42
43
44struct cisco_packet {
45 u32 type; /* code */
46 u32 par1;
47 u32 par2;
48 u16 rel; /* reliability */
49 u32 time;
50}__attribute__ ((packed));
51#define CISCO_PACKET_LEN 18
52#define CISCO_BIG_PACKET_LEN 20
53
54
55struct cisco_state {
56 cisco_proto settings;
57
58 struct timer_list timer;
59 unsigned long last_poll;
60 int up;
61 int request_sent;
62 u32 txseq; /* TX sequence number */
63 u32 rxseq; /* RX sequence number */
64};
65
66
67static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr);
68
69
70static inline struct cisco_state * state(hdlc_device *hdlc)
71{
72 return(struct cisco_state *)(hdlc->state);
73}
74
75
37static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, 76static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev,
38 u16 type, void *daddr, void *saddr, 77 u16 type, void *daddr, void *saddr,
39 unsigned int len) 78 unsigned int len)
40{ 79{
41 hdlc_header *data; 80 struct hdlc_header *data;
42#ifdef DEBUG_HARD_HEADER 81#ifdef DEBUG_HARD_HEADER
43 printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); 82 printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name);
44#endif 83#endif
45 84
46 skb_push(skb, sizeof(hdlc_header)); 85 skb_push(skb, sizeof(struct hdlc_header));
47 data = (hdlc_header*)skb->data; 86 data = (struct hdlc_header*)skb->data;
48 if (type == CISCO_KEEPALIVE) 87 if (type == CISCO_KEEPALIVE)
49 data->address = CISCO_MULTICAST; 88 data->address = CISCO_MULTICAST;
50 else 89 else
@@ -52,7 +91,7 @@ static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev,
52 data->control = 0; 91 data->control = 0;
53 data->protocol = htons(type); 92 data->protocol = htons(type);
54 93
55 return sizeof(hdlc_header); 94 return sizeof(struct hdlc_header);
56} 95}
57 96
58 97
@@ -61,9 +100,10 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
61 u32 par1, u32 par2) 100 u32 par1, u32 par2)
62{ 101{
63 struct sk_buff *skb; 102 struct sk_buff *skb;
64 cisco_packet *data; 103 struct cisco_packet *data;
65 104
66 skb = dev_alloc_skb(sizeof(hdlc_header) + sizeof(cisco_packet)); 105 skb = dev_alloc_skb(sizeof(struct hdlc_header) +
106 sizeof(struct cisco_packet));
67 if (!skb) { 107 if (!skb) {
68 printk(KERN_WARNING 108 printk(KERN_WARNING
69 "%s: Memory squeeze on cisco_keepalive_send()\n", 109 "%s: Memory squeeze on cisco_keepalive_send()\n",
@@ -72,7 +112,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
72 } 112 }
73 skb_reserve(skb, 4); 113 skb_reserve(skb, 4);
74 cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); 114 cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0);
75 data = (cisco_packet*)(skb->data + 4); 115 data = (struct cisco_packet*)(skb->data + 4);
76 116
77 data->type = htonl(type); 117 data->type = htonl(type);
78 data->par1 = htonl(par1); 118 data->par1 = htonl(par1);
@@ -81,7 +121,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
81 /* we will need do_div here if 1000 % HZ != 0 */ 121 /* we will need do_div here if 1000 % HZ != 0 */
82 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); 122 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ));
83 123
84 skb_put(skb, sizeof(cisco_packet)); 124 skb_put(skb, sizeof(struct cisco_packet));
85 skb->priority = TC_PRIO_CONTROL; 125 skb->priority = TC_PRIO_CONTROL;
86 skb->dev = dev; 126 skb->dev = dev;
87 skb->nh.raw = skb->data; 127 skb->nh.raw = skb->data;
@@ -93,9 +133,9 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
93 133
94static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) 134static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
95{ 135{
96 hdlc_header *data = (hdlc_header*)skb->data; 136 struct hdlc_header *data = (struct hdlc_header*)skb->data;
97 137
98 if (skb->len < sizeof(hdlc_header)) 138 if (skb->len < sizeof(struct hdlc_header))
99 return __constant_htons(ETH_P_HDLC); 139 return __constant_htons(ETH_P_HDLC);
100 140
101 if (data->address != CISCO_MULTICAST && 141 if (data->address != CISCO_MULTICAST &&
@@ -106,7 +146,7 @@ static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
106 case __constant_htons(ETH_P_IP): 146 case __constant_htons(ETH_P_IP):
107 case __constant_htons(ETH_P_IPX): 147 case __constant_htons(ETH_P_IPX):
108 case __constant_htons(ETH_P_IPV6): 148 case __constant_htons(ETH_P_IPV6):
109 skb_pull(skb, sizeof(hdlc_header)); 149 skb_pull(skb, sizeof(struct hdlc_header));
110 return data->protocol; 150 return data->protocol;
111 default: 151 default:
112 return __constant_htons(ETH_P_HDLC); 152 return __constant_htons(ETH_P_HDLC);
@@ -118,12 +158,12 @@ static int cisco_rx(struct sk_buff *skb)
118{ 158{
119 struct net_device *dev = skb->dev; 159 struct net_device *dev = skb->dev;
120 hdlc_device *hdlc = dev_to_hdlc(dev); 160 hdlc_device *hdlc = dev_to_hdlc(dev);
121 hdlc_header *data = (hdlc_header*)skb->data; 161 struct hdlc_header *data = (struct hdlc_header*)skb->data;
122 cisco_packet *cisco_data; 162 struct cisco_packet *cisco_data;
123 struct in_device *in_dev; 163 struct in_device *in_dev;
124 u32 addr, mask; 164 u32 addr, mask;
125 165
126 if (skb->len < sizeof(hdlc_header)) 166 if (skb->len < sizeof(struct hdlc_header))
127 goto rx_error; 167 goto rx_error;
128 168
129 if (data->address != CISCO_MULTICAST && 169 if (data->address != CISCO_MULTICAST &&
@@ -137,15 +177,17 @@ static int cisco_rx(struct sk_buff *skb)
137 return NET_RX_SUCCESS; 177 return NET_RX_SUCCESS;
138 178
139 case CISCO_KEEPALIVE: 179 case CISCO_KEEPALIVE:
140 if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN && 180 if ((skb->len != sizeof(struct hdlc_header) +
141 skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) { 181 CISCO_PACKET_LEN) &&
142 printk(KERN_INFO "%s: Invalid length of Cisco " 182 (skb->len != sizeof(struct hdlc_header) +
143 "control packet (%d bytes)\n", 183 CISCO_BIG_PACKET_LEN)) {
144 dev->name, skb->len); 184 printk(KERN_INFO "%s: Invalid length of Cisco control"
185 " packet (%d bytes)\n", dev->name, skb->len);
145 goto rx_error; 186 goto rx_error;
146 } 187 }
147 188
148 cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header)); 189 cisco_data = (struct cisco_packet*)(skb->data + sizeof
190 (struct hdlc_header));
149 191
150 switch(ntohl (cisco_data->type)) { 192 switch(ntohl (cisco_data->type)) {
151 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ 193 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
@@ -178,11 +220,11 @@ static int cisco_rx(struct sk_buff *skb)
178 goto rx_error; 220 goto rx_error;
179 221
180 case CISCO_KEEPALIVE_REQ: 222 case CISCO_KEEPALIVE_REQ:
181 hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); 223 state(hdlc)->rxseq = ntohl(cisco_data->par1);
182 if (hdlc->state.cisco.request_sent && 224 if (state(hdlc)->request_sent &&
183 ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { 225 ntohl(cisco_data->par2) == state(hdlc)->txseq) {
184 hdlc->state.cisco.last_poll = jiffies; 226 state(hdlc)->last_poll = jiffies;
185 if (!hdlc->state.cisco.up) { 227 if (!state(hdlc)->up) {
186 u32 sec, min, hrs, days; 228 u32 sec, min, hrs, days;
187 sec = ntohl(cisco_data->time) / 1000; 229 sec = ntohl(cisco_data->time) / 1000;
188 min = sec / 60; sec -= min * 60; 230 min = sec / 60; sec -= min * 60;
@@ -193,7 +235,7 @@ static int cisco_rx(struct sk_buff *skb)
193 dev->name, days, hrs, 235 dev->name, days, hrs,
194 min, sec); 236 min, sec);
195 netif_dormant_off(dev); 237 netif_dormant_off(dev);
196 hdlc->state.cisco.up = 1; 238 state(hdlc)->up = 1;
197 } 239 }
198 } 240 }
199 241
@@ -208,7 +250,7 @@ static int cisco_rx(struct sk_buff *skb)
208 return NET_RX_DROP; 250 return NET_RX_DROP;
209 251
210 rx_error: 252 rx_error:
211 hdlc->stats.rx_errors++; /* Mark error */ 253 dev_to_desc(dev)->stats.rx_errors++; /* Mark error */
212 dev_kfree_skb_any(skb); 254 dev_kfree_skb_any(skb);
213 return NET_RX_DROP; 255 return NET_RX_DROP;
214} 256}
@@ -220,23 +262,22 @@ static void cisco_timer(unsigned long arg)
220 struct net_device *dev = (struct net_device *)arg; 262 struct net_device *dev = (struct net_device *)arg;
221 hdlc_device *hdlc = dev_to_hdlc(dev); 263 hdlc_device *hdlc = dev_to_hdlc(dev);
222 264
223 if (hdlc->state.cisco.up && 265 if (state(hdlc)->up &&
224 time_after(jiffies, hdlc->state.cisco.last_poll + 266 time_after(jiffies, state(hdlc)->last_poll +
225 hdlc->state.cisco.settings.timeout * HZ)) { 267 state(hdlc)->settings.timeout * HZ)) {
226 hdlc->state.cisco.up = 0; 268 state(hdlc)->up = 0;
227 printk(KERN_INFO "%s: Link down\n", dev->name); 269 printk(KERN_INFO "%s: Link down\n", dev->name);
228 netif_dormant_on(dev); 270 netif_dormant_on(dev);
229 } 271 }
230 272
231 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, 273 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, ++state(hdlc)->txseq,
232 ++hdlc->state.cisco.txseq, 274 state(hdlc)->rxseq);
233 hdlc->state.cisco.rxseq); 275 state(hdlc)->request_sent = 1;
234 hdlc->state.cisco.request_sent = 1; 276 state(hdlc)->timer.expires = jiffies +
235 hdlc->state.cisco.timer.expires = jiffies + 277 state(hdlc)->settings.interval * HZ;
236 hdlc->state.cisco.settings.interval * HZ; 278 state(hdlc)->timer.function = cisco_timer;
237 hdlc->state.cisco.timer.function = cisco_timer; 279 state(hdlc)->timer.data = arg;
238 hdlc->state.cisco.timer.data = arg; 280 add_timer(&state(hdlc)->timer);
239 add_timer(&hdlc->state.cisco.timer);
240} 281}
241 282
242 283
@@ -244,15 +285,15 @@ static void cisco_timer(unsigned long arg)
244static void cisco_start(struct net_device *dev) 285static void cisco_start(struct net_device *dev)
245{ 286{
246 hdlc_device *hdlc = dev_to_hdlc(dev); 287 hdlc_device *hdlc = dev_to_hdlc(dev);
247 hdlc->state.cisco.up = 0; 288 state(hdlc)->up = 0;
248 hdlc->state.cisco.request_sent = 0; 289 state(hdlc)->request_sent = 0;
249 hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; 290 state(hdlc)->txseq = state(hdlc)->rxseq = 0;
250 291
251 init_timer(&hdlc->state.cisco.timer); 292 init_timer(&state(hdlc)->timer);
252 hdlc->state.cisco.timer.expires = jiffies + HZ; /*First poll after 1s*/ 293 state(hdlc)->timer.expires = jiffies + HZ; /*First poll after 1s*/
253 hdlc->state.cisco.timer.function = cisco_timer; 294 state(hdlc)->timer.function = cisco_timer;
254 hdlc->state.cisco.timer.data = (unsigned long)dev; 295 state(hdlc)->timer.data = (unsigned long)dev;
255 add_timer(&hdlc->state.cisco.timer); 296 add_timer(&state(hdlc)->timer);
256} 297}
257 298
258 299
@@ -260,15 +301,24 @@ static void cisco_start(struct net_device *dev)
260static void cisco_stop(struct net_device *dev) 301static void cisco_stop(struct net_device *dev)
261{ 302{
262 hdlc_device *hdlc = dev_to_hdlc(dev); 303 hdlc_device *hdlc = dev_to_hdlc(dev);
263 del_timer_sync(&hdlc->state.cisco.timer); 304 del_timer_sync(&state(hdlc)->timer);
264 netif_dormant_on(dev); 305 netif_dormant_on(dev);
265 hdlc->state.cisco.up = 0; 306 state(hdlc)->up = 0;
266 hdlc->state.cisco.request_sent = 0; 307 state(hdlc)->request_sent = 0;
267} 308}
268 309
269 310
270 311
271int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 312static struct hdlc_proto proto = {
313 .start = cisco_start,
314 .stop = cisco_stop,
315 .type_trans = cisco_type_trans,
316 .ioctl = cisco_ioctl,
317 .module = THIS_MODULE,
318};
319
320
321static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
272{ 322{
273 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; 323 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco;
274 const size_t size = sizeof(cisco_proto); 324 const size_t size = sizeof(cisco_proto);
@@ -278,12 +328,14 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
278 328
279 switch (ifr->ifr_settings.type) { 329 switch (ifr->ifr_settings.type) {
280 case IF_GET_PROTO: 330 case IF_GET_PROTO:
331 if (dev_to_hdlc(dev)->proto != &proto)
332 return -EINVAL;
281 ifr->ifr_settings.type = IF_PROTO_CISCO; 333 ifr->ifr_settings.type = IF_PROTO_CISCO;
282 if (ifr->ifr_settings.size < size) { 334 if (ifr->ifr_settings.size < size) {
283 ifr->ifr_settings.size = size; /* data size wanted */ 335 ifr->ifr_settings.size = size; /* data size wanted */
284 return -ENOBUFS; 336 return -ENOBUFS;
285 } 337 }
286 if (copy_to_user(cisco_s, &hdlc->state.cisco.settings, size)) 338 if (copy_to_user(cisco_s, &state(hdlc)->settings, size))
287 return -EFAULT; 339 return -EFAULT;
288 return 0; 340 return 0;
289 341
@@ -302,19 +354,15 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
302 return -EINVAL; 354 return -EINVAL;
303 355
304 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); 356 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
305
306 if (result) 357 if (result)
307 return result; 358 return result;
308 359
309 hdlc_proto_detach(hdlc); 360 result = attach_hdlc_protocol(dev, &proto, cisco_rx,
310 memcpy(&hdlc->state.cisco.settings, &new_settings, size); 361 sizeof(struct cisco_state));
311 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 362 if (result)
363 return result;
312 364
313 hdlc->proto.start = cisco_start; 365 memcpy(&state(hdlc)->settings, &new_settings, size);
314 hdlc->proto.stop = cisco_stop;
315 hdlc->proto.netif_rx = cisco_rx;
316 hdlc->proto.type_trans = cisco_type_trans;
317 hdlc->proto.id = IF_PROTO_CISCO;
318 dev->hard_start_xmit = hdlc->xmit; 366 dev->hard_start_xmit = hdlc->xmit;
319 dev->hard_header = cisco_hard_header; 367 dev->hard_header = cisco_hard_header;
320 dev->hard_header_cache = NULL; 368 dev->hard_header_cache = NULL;
@@ -327,3 +375,25 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
327 375
328 return -EINVAL; 376 return -EINVAL;
329} 377}
378
379
380static int __init mod_init(void)
381{
382 register_hdlc_protocol(&proto);
383 return 0;
384}
385
386
387
388static void __exit mod_exit(void)
389{
390 unregister_hdlc_protocol(&proto);
391}
392
393
394module_init(mod_init);
395module_exit(mod_exit);
396
397MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
398MODULE_DESCRIPTION("Cisco HDLC protocol support for generic HDLC");
399MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 7bb737bbdeb9..b45ab680d2d6 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * Frame Relay support 3 * Frame Relay support
4 * 4 *
5 * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -52,6 +52,8 @@
52#undef DEBUG_PKT 52#undef DEBUG_PKT
53#undef DEBUG_ECN 53#undef DEBUG_ECN
54#undef DEBUG_LINK 54#undef DEBUG_LINK
55#undef DEBUG_PROTO
56#undef DEBUG_PVC
55 57
56#define FR_UI 0x03 58#define FR_UI 0x03
57#define FR_PAD 0x00 59#define FR_PAD 0x00
@@ -115,13 +117,53 @@ typedef struct {
115}__attribute__ ((packed)) fr_hdr; 117}__attribute__ ((packed)) fr_hdr;
116 118
117 119
120typedef struct pvc_device_struct {
121 struct net_device *frad;
122 struct net_device *main;
123 struct net_device *ether; /* bridged Ethernet interface */
124 struct pvc_device_struct *next; /* Sorted in ascending DLCI order */
125 int dlci;
126 int open_count;
127
128 struct {
129 unsigned int new: 1;
130 unsigned int active: 1;
131 unsigned int exist: 1;
132 unsigned int deleted: 1;
133 unsigned int fecn: 1;
134 unsigned int becn: 1;
135 unsigned int bandwidth; /* Cisco LMI reporting only */
136 }state;
137}pvc_device;
138
139
140struct frad_state {
141 fr_proto settings;
142 pvc_device *first_pvc;
143 int dce_pvc_count;
144
145 struct timer_list timer;
146 unsigned long last_poll;
147 int reliable;
148 int dce_changed;
149 int request;
150 int fullrep_sent;
151 u32 last_errors; /* last errors bit list */
152 u8 n391cnt;
153 u8 txseq; /* TX sequence number */
154 u8 rxseq; /* RX sequence number */
155};
156
157
158static int fr_ioctl(struct net_device *dev, struct ifreq *ifr);
159
160
118static inline u16 q922_to_dlci(u8 *hdr) 161static inline u16 q922_to_dlci(u8 *hdr)
119{ 162{
120 return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); 163 return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4);
121} 164}
122 165
123 166
124
125static inline void dlci_to_q922(u8 *hdr, u16 dlci) 167static inline void dlci_to_q922(u8 *hdr, u16 dlci)
126{ 168{
127 hdr[0] = (dlci >> 2) & 0xFC; 169 hdr[0] = (dlci >> 2) & 0xFC;
@@ -129,10 +171,21 @@ static inline void dlci_to_q922(u8 *hdr, u16 dlci)
129} 171}
130 172
131 173
174static inline struct frad_state * state(hdlc_device *hdlc)
175{
176 return(struct frad_state *)(hdlc->state);
177}
178
179
180static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
181{
182 return dev->priv;
183}
184
132 185
133static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) 186static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
134{ 187{
135 pvc_device *pvc = hdlc->state.fr.first_pvc; 188 pvc_device *pvc = state(hdlc)->first_pvc;
136 189
137 while (pvc) { 190 while (pvc) {
138 if (pvc->dlci == dlci) 191 if (pvc->dlci == dlci)
@@ -146,10 +199,10 @@ static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
146} 199}
147 200
148 201
149static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci) 202static pvc_device* add_pvc(struct net_device *dev, u16 dlci)
150{ 203{
151 hdlc_device *hdlc = dev_to_hdlc(dev); 204 hdlc_device *hdlc = dev_to_hdlc(dev);
152 pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; 205 pvc_device *pvc, **pvc_p = &state(hdlc)->first_pvc;
153 206
154 while (*pvc_p) { 207 while (*pvc_p) {
155 if ((*pvc_p)->dlci == dlci) 208 if ((*pvc_p)->dlci == dlci)
@@ -160,12 +213,15 @@ static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci)
160 } 213 }
161 214
162 pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); 215 pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC);
216#ifdef DEBUG_PVC
217 printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev);
218#endif
163 if (!pvc) 219 if (!pvc)
164 return NULL; 220 return NULL;
165 221
166 memset(pvc, 0, sizeof(pvc_device)); 222 memset(pvc, 0, sizeof(pvc_device));
167 pvc->dlci = dlci; 223 pvc->dlci = dlci;
168 pvc->master = dev; 224 pvc->frad = dev;
169 pvc->next = *pvc_p; /* Put it in the chain */ 225 pvc->next = *pvc_p; /* Put it in the chain */
170 *pvc_p = pvc; 226 *pvc_p = pvc;
171 return pvc; 227 return pvc;
@@ -174,7 +230,7 @@ static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci)
174 230
175static inline int pvc_is_used(pvc_device *pvc) 231static inline int pvc_is_used(pvc_device *pvc)
176{ 232{
177 return pvc->main != NULL || pvc->ether != NULL; 233 return pvc->main || pvc->ether;
178} 234}
179 235
180 236
@@ -200,11 +256,14 @@ static inline void pvc_carrier(int on, pvc_device *pvc)
200 256
201static inline void delete_unused_pvcs(hdlc_device *hdlc) 257static inline void delete_unused_pvcs(hdlc_device *hdlc)
202{ 258{
203 pvc_device **pvc_p = &hdlc->state.fr.first_pvc; 259 pvc_device **pvc_p = &state(hdlc)->first_pvc;
204 260
205 while (*pvc_p) { 261 while (*pvc_p) {
206 if (!pvc_is_used(*pvc_p)) { 262 if (!pvc_is_used(*pvc_p)) {
207 pvc_device *pvc = *pvc_p; 263 pvc_device *pvc = *pvc_p;
264#ifdef DEBUG_PVC
265 printk(KERN_DEBUG "freeing unused pvc: %p\n", pvc);
266#endif
208 *pvc_p = pvc->next; 267 *pvc_p = pvc->next;
209 kfree(pvc); 268 kfree(pvc);
210 continue; 269 continue;
@@ -295,16 +354,16 @@ static int pvc_open(struct net_device *dev)
295{ 354{
296 pvc_device *pvc = dev_to_pvc(dev); 355 pvc_device *pvc = dev_to_pvc(dev);
297 356
298 if ((pvc->master->flags & IFF_UP) == 0) 357 if ((pvc->frad->flags & IFF_UP) == 0)
299 return -EIO; /* Master must be UP in order to activate PVC */ 358 return -EIO; /* Frad must be UP in order to activate PVC */
300 359
301 if (pvc->open_count++ == 0) { 360 if (pvc->open_count++ == 0) {
302 hdlc_device *hdlc = dev_to_hdlc(pvc->master); 361 hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
303 if (hdlc->state.fr.settings.lmi == LMI_NONE) 362 if (state(hdlc)->settings.lmi == LMI_NONE)
304 pvc->state.active = netif_carrier_ok(pvc->master); 363 pvc->state.active = netif_carrier_ok(pvc->frad);
305 364
306 pvc_carrier(pvc->state.active, pvc); 365 pvc_carrier(pvc->state.active, pvc);
307 hdlc->state.fr.dce_changed = 1; 366 state(hdlc)->dce_changed = 1;
308 } 367 }
309 return 0; 368 return 0;
310} 369}
@@ -316,12 +375,12 @@ static int pvc_close(struct net_device *dev)
316 pvc_device *pvc = dev_to_pvc(dev); 375 pvc_device *pvc = dev_to_pvc(dev);
317 376
318 if (--pvc->open_count == 0) { 377 if (--pvc->open_count == 0) {
319 hdlc_device *hdlc = dev_to_hdlc(pvc->master); 378 hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
320 if (hdlc->state.fr.settings.lmi == LMI_NONE) 379 if (state(hdlc)->settings.lmi == LMI_NONE)
321 pvc->state.active = 0; 380 pvc->state.active = 0;
322 381
323 if (hdlc->state.fr.settings.dce) { 382 if (state(hdlc)->settings.dce) {
324 hdlc->state.fr.dce_changed = 1; 383 state(hdlc)->dce_changed = 1;
325 pvc->state.active = 0; 384 pvc->state.active = 0;
326 } 385 }
327 } 386 }
@@ -348,7 +407,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
348 } 407 }
349 408
350 info.dlci = pvc->dlci; 409 info.dlci = pvc->dlci;
351 memcpy(info.master, pvc->master->name, IFNAMSIZ); 410 memcpy(info.master, pvc->frad->name, IFNAMSIZ);
352 if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, 411 if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info,
353 &info, sizeof(info))) 412 &info, sizeof(info)))
354 return -EFAULT; 413 return -EFAULT;
@@ -361,7 +420,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
361 420
362static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) 421static inline struct net_device_stats *pvc_get_stats(struct net_device *dev)
363{ 422{
364 return netdev_priv(dev); 423 return &dev_to_desc(dev)->stats;
365} 424}
366 425
367 426
@@ -393,7 +452,7 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
393 stats->tx_packets++; 452 stats->tx_packets++;
394 if (pvc->state.fecn) /* TX Congestion counter */ 453 if (pvc->state.fecn) /* TX Congestion counter */
395 stats->tx_compressed++; 454 stats->tx_compressed++;
396 skb->dev = pvc->master; 455 skb->dev = pvc->frad;
397 dev_queue_xmit(skb); 456 dev_queue_xmit(skb);
398 return 0; 457 return 0;
399 } 458 }
@@ -419,7 +478,7 @@ static int pvc_change_mtu(struct net_device *dev, int new_mtu)
419static inline void fr_log_dlci_active(pvc_device *pvc) 478static inline void fr_log_dlci_active(pvc_device *pvc)
420{ 479{
421 printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", 480 printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n",
422 pvc->master->name, 481 pvc->frad->name,
423 pvc->dlci, 482 pvc->dlci,
424 pvc->main ? pvc->main->name : "", 483 pvc->main ? pvc->main->name : "",
425 pvc->main && pvc->ether ? " " : "", 484 pvc->main && pvc->ether ? " " : "",
@@ -438,21 +497,20 @@ static inline u8 fr_lmi_nextseq(u8 x)
438} 497}
439 498
440 499
441
442static void fr_lmi_send(struct net_device *dev, int fullrep) 500static void fr_lmi_send(struct net_device *dev, int fullrep)
443{ 501{
444 hdlc_device *hdlc = dev_to_hdlc(dev); 502 hdlc_device *hdlc = dev_to_hdlc(dev);
445 struct sk_buff *skb; 503 struct sk_buff *skb;
446 pvc_device *pvc = hdlc->state.fr.first_pvc; 504 pvc_device *pvc = state(hdlc)->first_pvc;
447 int lmi = hdlc->state.fr.settings.lmi; 505 int lmi = state(hdlc)->settings.lmi;
448 int dce = hdlc->state.fr.settings.dce; 506 int dce = state(hdlc)->settings.dce;
449 int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; 507 int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH;
450 int stat_len = (lmi == LMI_CISCO) ? 6 : 3; 508 int stat_len = (lmi == LMI_CISCO) ? 6 : 3;
451 u8 *data; 509 u8 *data;
452 int i = 0; 510 int i = 0;
453 511
454 if (dce && fullrep) { 512 if (dce && fullrep) {
455 len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); 513 len += state(hdlc)->dce_pvc_count * (2 + stat_len);
456 if (len > HDLC_MAX_MRU) { 514 if (len > HDLC_MAX_MRU) {
457 printk(KERN_WARNING "%s: Too many PVCs while sending " 515 printk(KERN_WARNING "%s: Too many PVCs while sending "
458 "LMI full report\n", dev->name); 516 "LMI full report\n", dev->name);
@@ -486,8 +544,9 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
486 data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; 544 data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
487 data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; 545 data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE;
488 data[i++] = LMI_INTEG_LEN; 546 data[i++] = LMI_INTEG_LEN;
489 data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); 547 data[i++] = state(hdlc)->txseq =
490 data[i++] = hdlc->state.fr.rxseq; 548 fr_lmi_nextseq(state(hdlc)->txseq);
549 data[i++] = state(hdlc)->rxseq;
491 550
492 if (dce && fullrep) { 551 if (dce && fullrep) {
493 while (pvc) { 552 while (pvc) {
@@ -496,7 +555,7 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
496 data[i++] = stat_len; 555 data[i++] = stat_len;
497 556
498 /* LMI start/restart */ 557 /* LMI start/restart */
499 if (hdlc->state.fr.reliable && !pvc->state.exist) { 558 if (state(hdlc)->reliable && !pvc->state.exist) {
500 pvc->state.exist = pvc->state.new = 1; 559 pvc->state.exist = pvc->state.new = 1;
501 fr_log_dlci_active(pvc); 560 fr_log_dlci_active(pvc);
502 } 561 }
@@ -541,15 +600,15 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
541static void fr_set_link_state(int reliable, struct net_device *dev) 600static void fr_set_link_state(int reliable, struct net_device *dev)
542{ 601{
543 hdlc_device *hdlc = dev_to_hdlc(dev); 602 hdlc_device *hdlc = dev_to_hdlc(dev);
544 pvc_device *pvc = hdlc->state.fr.first_pvc; 603 pvc_device *pvc = state(hdlc)->first_pvc;
545 604
546 hdlc->state.fr.reliable = reliable; 605 state(hdlc)->reliable = reliable;
547 if (reliable) { 606 if (reliable) {
548 netif_dormant_off(dev); 607 netif_dormant_off(dev);
549 hdlc->state.fr.n391cnt = 0; /* Request full status */ 608 state(hdlc)->n391cnt = 0; /* Request full status */
550 hdlc->state.fr.dce_changed = 1; 609 state(hdlc)->dce_changed = 1;
551 610
552 if (hdlc->state.fr.settings.lmi == LMI_NONE) { 611 if (state(hdlc)->settings.lmi == LMI_NONE) {
553 while (pvc) { /* Activate all PVCs */ 612 while (pvc) { /* Activate all PVCs */
554 pvc_carrier(1, pvc); 613 pvc_carrier(1, pvc);
555 pvc->state.exist = pvc->state.active = 1; 614 pvc->state.exist = pvc->state.active = 1;
@@ -563,7 +622,7 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
563 pvc_carrier(0, pvc); 622 pvc_carrier(0, pvc);
564 pvc->state.exist = pvc->state.active = 0; 623 pvc->state.exist = pvc->state.active = 0;
565 pvc->state.new = 0; 624 pvc->state.new = 0;
566 if (!hdlc->state.fr.settings.dce) 625 if (!state(hdlc)->settings.dce)
567 pvc->state.bandwidth = 0; 626 pvc->state.bandwidth = 0;
568 pvc = pvc->next; 627 pvc = pvc->next;
569 } 628 }
@@ -571,7 +630,6 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
571} 630}
572 631
573 632
574
575static void fr_timer(unsigned long arg) 633static void fr_timer(unsigned long arg)
576{ 634{
577 struct net_device *dev = (struct net_device *)arg; 635 struct net_device *dev = (struct net_device *)arg;
@@ -579,62 +637,61 @@ static void fr_timer(unsigned long arg)
579 int i, cnt = 0, reliable; 637 int i, cnt = 0, reliable;
580 u32 list; 638 u32 list;
581 639
582 if (hdlc->state.fr.settings.dce) { 640 if (state(hdlc)->settings.dce) {
583 reliable = hdlc->state.fr.request && 641 reliable = state(hdlc)->request &&
584 time_before(jiffies, hdlc->state.fr.last_poll + 642 time_before(jiffies, state(hdlc)->last_poll +
585 hdlc->state.fr.settings.t392 * HZ); 643 state(hdlc)->settings.t392 * HZ);
586 hdlc->state.fr.request = 0; 644 state(hdlc)->request = 0;
587 } else { 645 } else {
588 hdlc->state.fr.last_errors <<= 1; /* Shift the list */ 646 state(hdlc)->last_errors <<= 1; /* Shift the list */
589 if (hdlc->state.fr.request) { 647 if (state(hdlc)->request) {
590 if (hdlc->state.fr.reliable) 648 if (state(hdlc)->reliable)
591 printk(KERN_INFO "%s: No LMI status reply " 649 printk(KERN_INFO "%s: No LMI status reply "
592 "received\n", dev->name); 650 "received\n", dev->name);
593 hdlc->state.fr.last_errors |= 1; 651 state(hdlc)->last_errors |= 1;
594 } 652 }
595 653
596 list = hdlc->state.fr.last_errors; 654 list = state(hdlc)->last_errors;
597 for (i = 0; i < hdlc->state.fr.settings.n393; i++, list >>= 1) 655 for (i = 0; i < state(hdlc)->settings.n393; i++, list >>= 1)
598 cnt += (list & 1); /* errors count */ 656 cnt += (list & 1); /* errors count */
599 657
600 reliable = (cnt < hdlc->state.fr.settings.n392); 658 reliable = (cnt < state(hdlc)->settings.n392);
601 } 659 }
602 660
603 if (hdlc->state.fr.reliable != reliable) { 661 if (state(hdlc)->reliable != reliable) {
604 printk(KERN_INFO "%s: Link %sreliable\n", dev->name, 662 printk(KERN_INFO "%s: Link %sreliable\n", dev->name,
605 reliable ? "" : "un"); 663 reliable ? "" : "un");
606 fr_set_link_state(reliable, dev); 664 fr_set_link_state(reliable, dev);
607 } 665 }
608 666
609 if (hdlc->state.fr.settings.dce) 667 if (state(hdlc)->settings.dce)
610 hdlc->state.fr.timer.expires = jiffies + 668 state(hdlc)->timer.expires = jiffies +
611 hdlc->state.fr.settings.t392 * HZ; 669 state(hdlc)->settings.t392 * HZ;
612 else { 670 else {
613 if (hdlc->state.fr.n391cnt) 671 if (state(hdlc)->n391cnt)
614 hdlc->state.fr.n391cnt--; 672 state(hdlc)->n391cnt--;
615 673
616 fr_lmi_send(dev, hdlc->state.fr.n391cnt == 0); 674 fr_lmi_send(dev, state(hdlc)->n391cnt == 0);
617 675
618 hdlc->state.fr.last_poll = jiffies; 676 state(hdlc)->last_poll = jiffies;
619 hdlc->state.fr.request = 1; 677 state(hdlc)->request = 1;
620 hdlc->state.fr.timer.expires = jiffies + 678 state(hdlc)->timer.expires = jiffies +
621 hdlc->state.fr.settings.t391 * HZ; 679 state(hdlc)->settings.t391 * HZ;
622 } 680 }
623 681
624 hdlc->state.fr.timer.function = fr_timer; 682 state(hdlc)->timer.function = fr_timer;
625 hdlc->state.fr.timer.data = arg; 683 state(hdlc)->timer.data = arg;
626 add_timer(&hdlc->state.fr.timer); 684 add_timer(&state(hdlc)->timer);
627} 685}
628 686
629 687
630
631static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) 688static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
632{ 689{
633 hdlc_device *hdlc = dev_to_hdlc(dev); 690 hdlc_device *hdlc = dev_to_hdlc(dev);
634 pvc_device *pvc; 691 pvc_device *pvc;
635 u8 rxseq, txseq; 692 u8 rxseq, txseq;
636 int lmi = hdlc->state.fr.settings.lmi; 693 int lmi = state(hdlc)->settings.lmi;
637 int dce = hdlc->state.fr.settings.dce; 694 int dce = state(hdlc)->settings.dce;
638 int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; 695 int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i;
639 696
640 if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : 697 if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH :
@@ -645,8 +702,8 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
645 702
646 if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : 703 if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI :
647 NLPID_CCITT_ANSI_LMI)) { 704 NLPID_CCITT_ANSI_LMI)) {
648 printk(KERN_INFO "%s: Received non-LMI frame with LMI" 705 printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n",
649 " DLCI\n", dev->name); 706 dev->name);
650 return 1; 707 return 1;
651 } 708 }
652 709
@@ -706,53 +763,53 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
706 } 763 }
707 i++; 764 i++;
708 765
709 hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ 766 state(hdlc)->rxseq = skb->data[i++]; /* TX sequence from peer */
710 rxseq = skb->data[i++]; /* Should confirm our sequence */ 767 rxseq = skb->data[i++]; /* Should confirm our sequence */
711 768
712 txseq = hdlc->state.fr.txseq; 769 txseq = state(hdlc)->txseq;
713 770
714 if (dce) 771 if (dce)
715 hdlc->state.fr.last_poll = jiffies; 772 state(hdlc)->last_poll = jiffies;
716 773
717 error = 0; 774 error = 0;
718 if (!hdlc->state.fr.reliable) 775 if (!state(hdlc)->reliable)
719 error = 1; 776 error = 1;
720 777
721 if (rxseq == 0 || rxseq != txseq) { 778 if (rxseq == 0 || rxseq != txseq) { /* Ask for full report next time */
722 hdlc->state.fr.n391cnt = 0; /* Ask for full report next time */ 779 state(hdlc)->n391cnt = 0;
723 error = 1; 780 error = 1;
724 } 781 }
725 782
726 if (dce) { 783 if (dce) {
727 if (hdlc->state.fr.fullrep_sent && !error) { 784 if (state(hdlc)->fullrep_sent && !error) {
728/* Stop sending full report - the last one has been confirmed by DTE */ 785/* Stop sending full report - the last one has been confirmed by DTE */
729 hdlc->state.fr.fullrep_sent = 0; 786 state(hdlc)->fullrep_sent = 0;
730 pvc = hdlc->state.fr.first_pvc; 787 pvc = state(hdlc)->first_pvc;
731 while (pvc) { 788 while (pvc) {
732 if (pvc->state.new) { 789 if (pvc->state.new) {
733 pvc->state.new = 0; 790 pvc->state.new = 0;
734 791
735/* Tell DTE that new PVC is now active */ 792/* Tell DTE that new PVC is now active */
736 hdlc->state.fr.dce_changed = 1; 793 state(hdlc)->dce_changed = 1;
737 } 794 }
738 pvc = pvc->next; 795 pvc = pvc->next;
739 } 796 }
740 } 797 }
741 798
742 if (hdlc->state.fr.dce_changed) { 799 if (state(hdlc)->dce_changed) {
743 reptype = LMI_FULLREP; 800 reptype = LMI_FULLREP;
744 hdlc->state.fr.fullrep_sent = 1; 801 state(hdlc)->fullrep_sent = 1;
745 hdlc->state.fr.dce_changed = 0; 802 state(hdlc)->dce_changed = 0;
746 } 803 }
747 804
748 hdlc->state.fr.request = 1; /* got request */ 805 state(hdlc)->request = 1; /* got request */
749 fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); 806 fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
750 return 0; 807 return 0;
751 } 808 }
752 809
753 /* DTE */ 810 /* DTE */
754 811
755 hdlc->state.fr.request = 0; /* got response, no request pending */ 812 state(hdlc)->request = 0; /* got response, no request pending */
756 813
757 if (error) 814 if (error)
758 return 0; 815 return 0;
@@ -760,7 +817,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
760 if (reptype != LMI_FULLREP) 817 if (reptype != LMI_FULLREP)
761 return 0; 818 return 0;
762 819
763 pvc = hdlc->state.fr.first_pvc; 820 pvc = state(hdlc)->first_pvc;
764 821
765 while (pvc) { 822 while (pvc) {
766 pvc->state.deleted = 1; 823 pvc->state.deleted = 1;
@@ -827,7 +884,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
827 i += stat_len; 884 i += stat_len;
828 } 885 }
829 886
830 pvc = hdlc->state.fr.first_pvc; 887 pvc = state(hdlc)->first_pvc;
831 888
832 while (pvc) { 889 while (pvc) {
833 if (pvc->state.deleted && pvc->state.exist) { 890 if (pvc->state.deleted && pvc->state.exist) {
@@ -841,17 +898,16 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
841 } 898 }
842 899
843 /* Next full report after N391 polls */ 900 /* Next full report after N391 polls */
844 hdlc->state.fr.n391cnt = hdlc->state.fr.settings.n391; 901 state(hdlc)->n391cnt = state(hdlc)->settings.n391;
845 902
846 return 0; 903 return 0;
847} 904}
848 905
849 906
850
851static int fr_rx(struct sk_buff *skb) 907static int fr_rx(struct sk_buff *skb)
852{ 908{
853 struct net_device *ndev = skb->dev; 909 struct net_device *frad = skb->dev;
854 hdlc_device *hdlc = dev_to_hdlc(ndev); 910 hdlc_device *hdlc = dev_to_hdlc(frad);
855 fr_hdr *fh = (fr_hdr*)skb->data; 911 fr_hdr *fh = (fr_hdr*)skb->data;
856 u8 *data = skb->data; 912 u8 *data = skb->data;
857 u16 dlci; 913 u16 dlci;
@@ -864,11 +920,11 @@ static int fr_rx(struct sk_buff *skb)
864 dlci = q922_to_dlci(skb->data); 920 dlci = q922_to_dlci(skb->data);
865 921
866 if ((dlci == LMI_CCITT_ANSI_DLCI && 922 if ((dlci == LMI_CCITT_ANSI_DLCI &&
867 (hdlc->state.fr.settings.lmi == LMI_ANSI || 923 (state(hdlc)->settings.lmi == LMI_ANSI ||
868 hdlc->state.fr.settings.lmi == LMI_CCITT)) || 924 state(hdlc)->settings.lmi == LMI_CCITT)) ||
869 (dlci == LMI_CISCO_DLCI && 925 (dlci == LMI_CISCO_DLCI &&
870 hdlc->state.fr.settings.lmi == LMI_CISCO)) { 926 state(hdlc)->settings.lmi == LMI_CISCO)) {
871 if (fr_lmi_recv(ndev, skb)) 927 if (fr_lmi_recv(frad, skb))
872 goto rx_error; 928 goto rx_error;
873 dev_kfree_skb_any(skb); 929 dev_kfree_skb_any(skb);
874 return NET_RX_SUCCESS; 930 return NET_RX_SUCCESS;
@@ -878,7 +934,7 @@ static int fr_rx(struct sk_buff *skb)
878 if (!pvc) { 934 if (!pvc) {
879#ifdef DEBUG_PKT 935#ifdef DEBUG_PKT
880 printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", 936 printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n",
881 ndev->name, dlci); 937 frad->name, dlci);
882#endif 938#endif
883 dev_kfree_skb_any(skb); 939 dev_kfree_skb_any(skb);
884 return NET_RX_DROP; 940 return NET_RX_DROP;
@@ -886,7 +942,7 @@ static int fr_rx(struct sk_buff *skb)
886 942
887 if (pvc->state.fecn != fh->fecn) { 943 if (pvc->state.fecn != fh->fecn) {
888#ifdef DEBUG_ECN 944#ifdef DEBUG_ECN
889 printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", ndev->name, 945 printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", frad->name,
890 dlci, fh->fecn ? "N" : "FF"); 946 dlci, fh->fecn ? "N" : "FF");
891#endif 947#endif
892 pvc->state.fecn ^= 1; 948 pvc->state.fecn ^= 1;
@@ -894,7 +950,7 @@ static int fr_rx(struct sk_buff *skb)
894 950
895 if (pvc->state.becn != fh->becn) { 951 if (pvc->state.becn != fh->becn) {
896#ifdef DEBUG_ECN 952#ifdef DEBUG_ECN
897 printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", ndev->name, 953 printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", frad->name,
898 dlci, fh->becn ? "N" : "FF"); 954 dlci, fh->becn ? "N" : "FF");
899#endif 955#endif
900 pvc->state.becn ^= 1; 956 pvc->state.becn ^= 1;
@@ -902,7 +958,7 @@ static int fr_rx(struct sk_buff *skb)
902 958
903 959
904 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 960 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
905 hdlc->stats.rx_dropped++; 961 dev_to_desc(frad)->stats.rx_dropped++;
906 return NET_RX_DROP; 962 return NET_RX_DROP;
907 } 963 }
908 964
@@ -938,13 +994,13 @@ static int fr_rx(struct sk_buff *skb)
938 994
939 default: 995 default:
940 printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " 996 printk(KERN_INFO "%s: Unsupported protocol, OUI=%x "
941 "PID=%x\n", ndev->name, oui, pid); 997 "PID=%x\n", frad->name, oui, pid);
942 dev_kfree_skb_any(skb); 998 dev_kfree_skb_any(skb);
943 return NET_RX_DROP; 999 return NET_RX_DROP;
944 } 1000 }
945 } else { 1001 } else {
946 printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " 1002 printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x "
947 "length = %i\n", ndev->name, data[3], skb->len); 1003 "length = %i\n", frad->name, data[3], skb->len);
948 dev_kfree_skb_any(skb); 1004 dev_kfree_skb_any(skb);
949 return NET_RX_DROP; 1005 return NET_RX_DROP;
950 } 1006 }
@@ -964,7 +1020,7 @@ static int fr_rx(struct sk_buff *skb)
964 } 1020 }
965 1021
966 rx_error: 1022 rx_error:
967 hdlc->stats.rx_errors++; /* Mark error */ 1023 dev_to_desc(frad)->stats.rx_errors++; /* Mark error */
968 dev_kfree_skb_any(skb); 1024 dev_kfree_skb_any(skb);
969 return NET_RX_DROP; 1025 return NET_RX_DROP;
970} 1026}
@@ -977,44 +1033,42 @@ static void fr_start(struct net_device *dev)
977#ifdef DEBUG_LINK 1033#ifdef DEBUG_LINK
978 printk(KERN_DEBUG "fr_start\n"); 1034 printk(KERN_DEBUG "fr_start\n");
979#endif 1035#endif
980 if (hdlc->state.fr.settings.lmi != LMI_NONE) { 1036 if (state(hdlc)->settings.lmi != LMI_NONE) {
981 hdlc->state.fr.reliable = 0; 1037 state(hdlc)->reliable = 0;
982 hdlc->state.fr.dce_changed = 1; 1038 state(hdlc)->dce_changed = 1;
983 hdlc->state.fr.request = 0; 1039 state(hdlc)->request = 0;
984 hdlc->state.fr.fullrep_sent = 0; 1040 state(hdlc)->fullrep_sent = 0;
985 hdlc->state.fr.last_errors = 0xFFFFFFFF; 1041 state(hdlc)->last_errors = 0xFFFFFFFF;
986 hdlc->state.fr.n391cnt = 0; 1042 state(hdlc)->n391cnt = 0;
987 hdlc->state.fr.txseq = hdlc->state.fr.rxseq = 0; 1043 state(hdlc)->txseq = state(hdlc)->rxseq = 0;
988 1044
989 init_timer(&hdlc->state.fr.timer); 1045 init_timer(&state(hdlc)->timer);
990 /* First poll after 1 s */ 1046 /* First poll after 1 s */
991 hdlc->state.fr.timer.expires = jiffies + HZ; 1047 state(hdlc)->timer.expires = jiffies + HZ;
992 hdlc->state.fr.timer.function = fr_timer; 1048 state(hdlc)->timer.function = fr_timer;
993 hdlc->state.fr.timer.data = (unsigned long)dev; 1049 state(hdlc)->timer.data = (unsigned long)dev;
994 add_timer(&hdlc->state.fr.timer); 1050 add_timer(&state(hdlc)->timer);
995 } else 1051 } else
996 fr_set_link_state(1, dev); 1052 fr_set_link_state(1, dev);
997} 1053}
998 1054
999 1055
1000
1001static void fr_stop(struct net_device *dev) 1056static void fr_stop(struct net_device *dev)
1002{ 1057{
1003 hdlc_device *hdlc = dev_to_hdlc(dev); 1058 hdlc_device *hdlc = dev_to_hdlc(dev);
1004#ifdef DEBUG_LINK 1059#ifdef DEBUG_LINK
1005 printk(KERN_DEBUG "fr_stop\n"); 1060 printk(KERN_DEBUG "fr_stop\n");
1006#endif 1061#endif
1007 if (hdlc->state.fr.settings.lmi != LMI_NONE) 1062 if (state(hdlc)->settings.lmi != LMI_NONE)
1008 del_timer_sync(&hdlc->state.fr.timer); 1063 del_timer_sync(&state(hdlc)->timer);
1009 fr_set_link_state(0, dev); 1064 fr_set_link_state(0, dev);
1010} 1065}
1011 1066
1012 1067
1013
1014static void fr_close(struct net_device *dev) 1068static void fr_close(struct net_device *dev)
1015{ 1069{
1016 hdlc_device *hdlc = dev_to_hdlc(dev); 1070 hdlc_device *hdlc = dev_to_hdlc(dev);
1017 pvc_device *pvc = hdlc->state.fr.first_pvc; 1071 pvc_device *pvc = state(hdlc)->first_pvc;
1018 1072
1019 while (pvc) { /* Shutdown all PVCs for this FRAD */ 1073 while (pvc) { /* Shutdown all PVCs for this FRAD */
1020 if (pvc->main) 1074 if (pvc->main)
@@ -1025,7 +1079,8 @@ static void fr_close(struct net_device *dev)
1025 } 1079 }
1026} 1080}
1027 1081
1028static void dlci_setup(struct net_device *dev) 1082
1083static void pvc_setup(struct net_device *dev)
1029{ 1084{
1030 dev->type = ARPHRD_DLCI; 1085 dev->type = ARPHRD_DLCI;
1031 dev->flags = IFF_POINTOPOINT; 1086 dev->flags = IFF_POINTOPOINT;
@@ -1033,9 +1088,9 @@ static void dlci_setup(struct net_device *dev)
1033 dev->addr_len = 2; 1088 dev->addr_len = 2;
1034} 1089}
1035 1090
1036static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) 1091static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
1037{ 1092{
1038 hdlc_device *hdlc = dev_to_hdlc(master); 1093 hdlc_device *hdlc = dev_to_hdlc(frad);
1039 pvc_device *pvc = NULL; 1094 pvc_device *pvc = NULL;
1040 struct net_device *dev; 1095 struct net_device *dev;
1041 int result, used; 1096 int result, used;
@@ -1044,9 +1099,9 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
1044 if (type == ARPHRD_ETHER) 1099 if (type == ARPHRD_ETHER)
1045 prefix = "pvceth%d"; 1100 prefix = "pvceth%d";
1046 1101
1047 if ((pvc = add_pvc(master, dlci)) == NULL) { 1102 if ((pvc = add_pvc(frad, dlci)) == NULL) {
1048 printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", 1103 printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
1049 master->name); 1104 frad->name);
1050 return -ENOBUFS; 1105 return -ENOBUFS;
1051 } 1106 }
1052 1107
@@ -1060,11 +1115,11 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
1060 "pvceth%d", ether_setup); 1115 "pvceth%d", ether_setup);
1061 else 1116 else
1062 dev = alloc_netdev(sizeof(struct net_device_stats), 1117 dev = alloc_netdev(sizeof(struct net_device_stats),
1063 "pvc%d", dlci_setup); 1118 "pvc%d", pvc_setup);
1064 1119
1065 if (!dev) { 1120 if (!dev) {
1066 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", 1121 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1067 master->name); 1122 frad->name);
1068 delete_unused_pvcs(hdlc); 1123 delete_unused_pvcs(hdlc);
1069 return -ENOBUFS; 1124 return -ENOBUFS;
1070 } 1125 }
@@ -1102,8 +1157,8 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
1102 dev->destructor = free_netdev; 1157 dev->destructor = free_netdev;
1103 *get_dev_p(pvc, type) = dev; 1158 *get_dev_p(pvc, type) = dev;
1104 if (!used) { 1159 if (!used) {
1105 hdlc->state.fr.dce_changed = 1; 1160 state(hdlc)->dce_changed = 1;
1106 hdlc->state.fr.dce_pvc_count++; 1161 state(hdlc)->dce_pvc_count++;
1107 } 1162 }
1108 return 0; 1163 return 0;
1109} 1164}
@@ -1128,8 +1183,8 @@ static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1128 *get_dev_p(pvc, type) = NULL; 1183 *get_dev_p(pvc, type) = NULL;
1129 1184
1130 if (!pvc_is_used(pvc)) { 1185 if (!pvc_is_used(pvc)) {
1131 hdlc->state.fr.dce_pvc_count--; 1186 state(hdlc)->dce_pvc_count--;
1132 hdlc->state.fr.dce_changed = 1; 1187 state(hdlc)->dce_changed = 1;
1133 } 1188 }
1134 delete_unused_pvcs(hdlc); 1189 delete_unused_pvcs(hdlc);
1135 return 0; 1190 return 0;
@@ -1137,14 +1192,13 @@ static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1137 1192
1138 1193
1139 1194
1140static void fr_destroy(hdlc_device *hdlc) 1195static void fr_destroy(struct net_device *frad)
1141{ 1196{
1142 pvc_device *pvc; 1197 hdlc_device *hdlc = dev_to_hdlc(frad);
1143 1198 pvc_device *pvc = state(hdlc)->first_pvc;
1144 pvc = hdlc->state.fr.first_pvc; 1199 state(hdlc)->first_pvc = NULL; /* All PVCs destroyed */
1145 hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */ 1200 state(hdlc)->dce_pvc_count = 0;
1146 hdlc->state.fr.dce_pvc_count = 0; 1201 state(hdlc)->dce_changed = 1;
1147 hdlc->state.fr.dce_changed = 1;
1148 1202
1149 while (pvc) { 1203 while (pvc) {
1150 pvc_device *next = pvc->next; 1204 pvc_device *next = pvc->next;
@@ -1161,8 +1215,17 @@ static void fr_destroy(hdlc_device *hdlc)
1161} 1215}
1162 1216
1163 1217
1218static struct hdlc_proto proto = {
1219 .close = fr_close,
1220 .start = fr_start,
1221 .stop = fr_stop,
1222 .detach = fr_destroy,
1223 .ioctl = fr_ioctl,
1224 .module = THIS_MODULE,
1225};
1226
1164 1227
1165int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) 1228static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1166{ 1229{
1167 fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; 1230 fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr;
1168 const size_t size = sizeof(fr_proto); 1231 const size_t size = sizeof(fr_proto);
@@ -1173,12 +1236,14 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1173 1236
1174 switch (ifr->ifr_settings.type) { 1237 switch (ifr->ifr_settings.type) {
1175 case IF_GET_PROTO: 1238 case IF_GET_PROTO:
1239 if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1240 return -EINVAL;
1176 ifr->ifr_settings.type = IF_PROTO_FR; 1241 ifr->ifr_settings.type = IF_PROTO_FR;
1177 if (ifr->ifr_settings.size < size) { 1242 if (ifr->ifr_settings.size < size) {
1178 ifr->ifr_settings.size = size; /* data size wanted */ 1243 ifr->ifr_settings.size = size; /* data size wanted */
1179 return -ENOBUFS; 1244 return -ENOBUFS;
1180 } 1245 }
1181 if (copy_to_user(fr_s, &hdlc->state.fr.settings, size)) 1246 if (copy_to_user(fr_s, &state(hdlc)->settings, size))
1182 return -EFAULT; 1247 return -EFAULT;
1183 return 0; 1248 return 0;
1184 1249
@@ -1213,20 +1278,16 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1213 if (result) 1278 if (result)
1214 return result; 1279 return result;
1215 1280
1216 if (hdlc->proto.id != IF_PROTO_FR) { 1281 if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */
1217 hdlc_proto_detach(hdlc); 1282 result = attach_hdlc_protocol(dev, &proto, fr_rx,
1218 hdlc->state.fr.first_pvc = NULL; 1283 sizeof(struct frad_state));
1219 hdlc->state.fr.dce_pvc_count = 0; 1284 if (result)
1285 return result;
1286 state(hdlc)->first_pvc = NULL;
1287 state(hdlc)->dce_pvc_count = 0;
1220 } 1288 }
1221 memcpy(&hdlc->state.fr.settings, &new_settings, size); 1289 memcpy(&state(hdlc)->settings, &new_settings, size);
1222 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 1290
1223
1224 hdlc->proto.close = fr_close;
1225 hdlc->proto.start = fr_start;
1226 hdlc->proto.stop = fr_stop;
1227 hdlc->proto.detach = fr_destroy;
1228 hdlc->proto.netif_rx = fr_rx;
1229 hdlc->proto.id = IF_PROTO_FR;
1230 dev->hard_start_xmit = hdlc->xmit; 1291 dev->hard_start_xmit = hdlc->xmit;
1231 dev->hard_header = NULL; 1292 dev->hard_header = NULL;
1232 dev->type = ARPHRD_FRAD; 1293 dev->type = ARPHRD_FRAD;
@@ -1238,6 +1299,9 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1238 case IF_PROTO_FR_DEL_PVC: 1299 case IF_PROTO_FR_DEL_PVC:
1239 case IF_PROTO_FR_ADD_ETH_PVC: 1300 case IF_PROTO_FR_ADD_ETH_PVC:
1240 case IF_PROTO_FR_DEL_ETH_PVC: 1301 case IF_PROTO_FR_DEL_ETH_PVC:
1302 if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1303 return -EINVAL;
1304
1241 if(!capable(CAP_NET_ADMIN)) 1305 if(!capable(CAP_NET_ADMIN))
1242 return -EPERM; 1306 return -EPERM;
1243 1307
@@ -1263,3 +1327,24 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1263 1327
1264 return -EINVAL; 1328 return -EINVAL;
1265} 1329}
1330
1331
1332static int __init mod_init(void)
1333{
1334 register_hdlc_protocol(&proto);
1335 return 0;
1336}
1337
1338
1339static void __exit mod_exit(void)
1340{
1341 unregister_hdlc_protocol(&proto);
1342}
1343
1344
1345module_init(mod_init);
1346module_exit(mod_exit);
1347
1348MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
1349MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC");
1350MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index fbaab5bf71eb..e9f717070fde 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * Point-to-point protocol support 3 * Point-to-point protocol support
4 * 4 *
5 * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -22,6 +22,21 @@
22#include <linux/lapb.h> 22#include <linux/lapb.h>
23#include <linux/rtnetlink.h> 23#include <linux/rtnetlink.h>
24#include <linux/hdlc.h> 24#include <linux/hdlc.h>
25#include <net/syncppp.h>
26
27struct ppp_state {
28 struct ppp_device pppdev;
29 struct ppp_device *syncppp_ptr;
30 int (*old_change_mtu)(struct net_device *dev, int new_mtu);
31};
32
33static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr);
34
35
36static inline struct ppp_state* state(hdlc_device *hdlc)
37{
38 return(struct ppp_state *)(hdlc->state);
39}
25 40
26 41
27static int ppp_open(struct net_device *dev) 42static int ppp_open(struct net_device *dev)
@@ -30,16 +45,16 @@ static int ppp_open(struct net_device *dev)
30 void *old_ioctl; 45 void *old_ioctl;
31 int result; 46 int result;
32 47
33 dev->priv = &hdlc->state.ppp.syncppp_ptr; 48 dev->priv = &state(hdlc)->syncppp_ptr;
34 hdlc->state.ppp.syncppp_ptr = &hdlc->state.ppp.pppdev; 49 state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev;
35 hdlc->state.ppp.pppdev.dev = dev; 50 state(hdlc)->pppdev.dev = dev;
36 51
37 old_ioctl = dev->do_ioctl; 52 old_ioctl = dev->do_ioctl;
38 hdlc->state.ppp.old_change_mtu = dev->change_mtu; 53 state(hdlc)->old_change_mtu = dev->change_mtu;
39 sppp_attach(&hdlc->state.ppp.pppdev); 54 sppp_attach(&state(hdlc)->pppdev);
40 /* sppp_attach nukes them. We don't need syncppp's ioctl */ 55 /* sppp_attach nukes them. We don't need syncppp's ioctl */
41 dev->do_ioctl = old_ioctl; 56 dev->do_ioctl = old_ioctl;
42 hdlc->state.ppp.pppdev.sppp.pp_flags &= ~PP_CISCO; 57 state(hdlc)->pppdev.sppp.pp_flags &= ~PP_CISCO;
43 dev->type = ARPHRD_PPP; 58 dev->type = ARPHRD_PPP;
44 result = sppp_open(dev); 59 result = sppp_open(dev);
45 if (result) { 60 if (result) {
@@ -59,7 +74,7 @@ static void ppp_close(struct net_device *dev)
59 sppp_close(dev); 74 sppp_close(dev);
60 sppp_detach(dev); 75 sppp_detach(dev);
61 dev->rebuild_header = NULL; 76 dev->rebuild_header = NULL;
62 dev->change_mtu = hdlc->state.ppp.old_change_mtu; 77 dev->change_mtu = state(hdlc)->old_change_mtu;
63 dev->mtu = HDLC_MAX_MTU; 78 dev->mtu = HDLC_MAX_MTU;
64 dev->hard_header_len = 16; 79 dev->hard_header_len = 16;
65} 80}
@@ -73,13 +88,24 @@ static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
73 88
74 89
75 90
76int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) 91static struct hdlc_proto proto = {
92 .open = ppp_open,
93 .close = ppp_close,
94 .type_trans = ppp_type_trans,
95 .ioctl = ppp_ioctl,
96 .module = THIS_MODULE,
97};
98
99
100static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
77{ 101{
78 hdlc_device *hdlc = dev_to_hdlc(dev); 102 hdlc_device *hdlc = dev_to_hdlc(dev);
79 int result; 103 int result;
80 104
81 switch (ifr->ifr_settings.type) { 105 switch (ifr->ifr_settings.type) {
82 case IF_GET_PROTO: 106 case IF_GET_PROTO:
107 if (dev_to_hdlc(dev)->proto != &proto)
108 return -EINVAL;
83 ifr->ifr_settings.type = IF_PROTO_PPP; 109 ifr->ifr_settings.type = IF_PROTO_PPP;
84 return 0; /* return protocol only, no settable parameters */ 110 return 0; /* return protocol only, no settable parameters */
85 111
@@ -96,13 +122,10 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
96 if (result) 122 if (result)
97 return result; 123 return result;
98 124
99 hdlc_proto_detach(hdlc); 125 result = attach_hdlc_protocol(dev, &proto, NULL,
100 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 126 sizeof(struct ppp_state));
101 127 if (result)
102 hdlc->proto.open = ppp_open; 128 return result;
103 hdlc->proto.close = ppp_close;
104 hdlc->proto.type_trans = ppp_type_trans;
105 hdlc->proto.id = IF_PROTO_PPP;
106 dev->hard_start_xmit = hdlc->xmit; 129 dev->hard_start_xmit = hdlc->xmit;
107 dev->hard_header = NULL; 130 dev->hard_header = NULL;
108 dev->type = ARPHRD_PPP; 131 dev->type = ARPHRD_PPP;
@@ -113,3 +136,25 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
113 136
114 return -EINVAL; 137 return -EINVAL;
115} 138}
139
140
141static int __init mod_init(void)
142{
143 register_hdlc_protocol(&proto);
144 return 0;
145}
146
147
148
149static void __exit mod_exit(void)
150{
151 unregister_hdlc_protocol(&proto);
152}
153
154
155module_init(mod_init);
156module_exit(mod_exit);
157
158MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
159MODULE_DESCRIPTION("PPP protocol support for generic HDLC");
160MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index f15aa6ba77f1..fe3cae5c6b9d 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * HDLC support 3 * HDLC support
4 * 4 *
5 * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -24,6 +24,8 @@
24#include <linux/hdlc.h> 24#include <linux/hdlc.h>
25 25
26 26
27static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
28
27static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) 29static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
28{ 30{
29 return __constant_htons(ETH_P_IP); 31 return __constant_htons(ETH_P_IP);
@@ -31,7 +33,14 @@ static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
31 33
32 34
33 35
34int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) 36static struct hdlc_proto proto = {
37 .type_trans = raw_type_trans,
38 .ioctl = raw_ioctl,
39 .module = THIS_MODULE,
40};
41
42
43static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
35{ 44{
36 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 45 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
37 const size_t size = sizeof(raw_hdlc_proto); 46 const size_t size = sizeof(raw_hdlc_proto);
@@ -41,12 +50,14 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
41 50
42 switch (ifr->ifr_settings.type) { 51 switch (ifr->ifr_settings.type) {
43 case IF_GET_PROTO: 52 case IF_GET_PROTO:
53 if (dev_to_hdlc(dev)->proto != &proto)
54 return -EINVAL;
44 ifr->ifr_settings.type = IF_PROTO_HDLC; 55 ifr->ifr_settings.type = IF_PROTO_HDLC;
45 if (ifr->ifr_settings.size < size) { 56 if (ifr->ifr_settings.size < size) {
46 ifr->ifr_settings.size = size; /* data size wanted */ 57 ifr->ifr_settings.size = size; /* data size wanted */
47 return -ENOBUFS; 58 return -ENOBUFS;
48 } 59 }
49 if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) 60 if (copy_to_user(raw_s, hdlc->state, size))
50 return -EFAULT; 61 return -EFAULT;
51 return 0; 62 return 0;
52 63
@@ -71,12 +82,11 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
71 if (result) 82 if (result)
72 return result; 83 return result;
73 84
74 hdlc_proto_detach(hdlc); 85 result = attach_hdlc_protocol(dev, &proto, NULL,
75 memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); 86 sizeof(raw_hdlc_proto));
76 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 87 if (result)
77 88 return result;
78 hdlc->proto.type_trans = raw_type_trans; 89 memcpy(hdlc->state, &new_settings, size);
79 hdlc->proto.id = IF_PROTO_HDLC;
80 dev->hard_start_xmit = hdlc->xmit; 90 dev->hard_start_xmit = hdlc->xmit;
81 dev->hard_header = NULL; 91 dev->hard_header = NULL;
82 dev->type = ARPHRD_RAWHDLC; 92 dev->type = ARPHRD_RAWHDLC;
@@ -88,3 +98,25 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
88 98
89 return -EINVAL; 99 return -EINVAL;
90} 100}
101
102
103static int __init mod_init(void)
104{
105 register_hdlc_protocol(&proto);
106 return 0;
107}
108
109
110
111static void __exit mod_exit(void)
112{
113 unregister_hdlc_protocol(&proto);
114}
115
116
117module_init(mod_init);
118module_exit(mod_exit);
119
120MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
121MODULE_DESCRIPTION("Raw HDLC protocol support for generic HDLC");
122MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index d1884987f94e..1a69a9aaa9b9 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * HDLC Ethernet emulation support 3 * HDLC Ethernet emulation support
4 * 4 *
5 * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 2002-2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -25,6 +25,7 @@
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <linux/hdlc.h> 26#include <linux/hdlc.h>
27 27
28static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
28 29
29static int eth_tx(struct sk_buff *skb, struct net_device *dev) 30static int eth_tx(struct sk_buff *skb, struct net_device *dev)
30{ 31{
@@ -44,7 +45,14 @@ static int eth_tx(struct sk_buff *skb, struct net_device *dev)
44} 45}
45 46
46 47
47int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) 48static struct hdlc_proto proto = {
49 .type_trans = eth_type_trans,
50 .ioctl = raw_eth_ioctl,
51 .module = THIS_MODULE,
52};
53
54
55static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
48{ 56{
49 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 57 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
50 const size_t size = sizeof(raw_hdlc_proto); 58 const size_t size = sizeof(raw_hdlc_proto);
@@ -56,12 +64,14 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
56 64
57 switch (ifr->ifr_settings.type) { 65 switch (ifr->ifr_settings.type) {
58 case IF_GET_PROTO: 66 case IF_GET_PROTO:
67 if (dev_to_hdlc(dev)->proto != &proto)
68 return -EINVAL;
59 ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; 69 ifr->ifr_settings.type = IF_PROTO_HDLC_ETH;
60 if (ifr->ifr_settings.size < size) { 70 if (ifr->ifr_settings.size < size) {
61 ifr->ifr_settings.size = size; /* data size wanted */ 71 ifr->ifr_settings.size = size; /* data size wanted */
62 return -ENOBUFS; 72 return -ENOBUFS;
63 } 73 }
64 if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) 74 if (copy_to_user(raw_s, hdlc->state, size))
65 return -EFAULT; 75 return -EFAULT;
66 return 0; 76 return 0;
67 77
@@ -86,12 +96,11 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
86 if (result) 96 if (result)
87 return result; 97 return result;
88 98
89 hdlc_proto_detach(hdlc); 99 result = attach_hdlc_protocol(dev, &proto, NULL,
90 memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); 100 sizeof(raw_hdlc_proto));
91 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 101 if (result)
92 102 return result;
93 hdlc->proto.type_trans = eth_type_trans; 103 memcpy(hdlc->state, &new_settings, size);
94 hdlc->proto.id = IF_PROTO_HDLC_ETH;
95 dev->hard_start_xmit = eth_tx; 104 dev->hard_start_xmit = eth_tx;
96 old_ch_mtu = dev->change_mtu; 105 old_ch_mtu = dev->change_mtu;
97 old_qlen = dev->tx_queue_len; 106 old_qlen = dev->tx_queue_len;
@@ -106,3 +115,25 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
106 115
107 return -EINVAL; 116 return -EINVAL;
108} 117}
118
119
120static int __init mod_init(void)
121{
122 register_hdlc_protocol(&proto);
123 return 0;
124}
125
126
127
128static void __exit mod_exit(void)
129{
130 unregister_hdlc_protocol(&proto);
131}
132
133
134module_init(mod_init);
135module_exit(mod_exit);
136
137MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
138MODULE_DESCRIPTION("Ethernet encapsulation support for generic HDLC");
139MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index a867fb411f89..e4bb9f8ad433 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * X.25 support 3 * X.25 support
4 * 4 *
5 * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -25,6 +25,8 @@
25 25
26#include <net/x25device.h> 26#include <net/x25device.h>
27 27
28static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
29
28/* These functions are callbacks called by LAPB layer */ 30/* These functions are callbacks called by LAPB layer */
29 31
30static void x25_connect_disconnect(struct net_device *dev, int reason, int code) 32static void x25_connect_disconnect(struct net_device *dev, int reason, int code)
@@ -162,30 +164,39 @@ static void x25_close(struct net_device *dev)
162 164
163static int x25_rx(struct sk_buff *skb) 165static int x25_rx(struct sk_buff *skb)
164{ 166{
165 hdlc_device *hdlc = dev_to_hdlc(skb->dev); 167 struct hdlc_device_desc *desc = dev_to_desc(skb->dev);
166 168
167 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 169 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
168 hdlc->stats.rx_dropped++; 170 desc->stats.rx_dropped++;
169 return NET_RX_DROP; 171 return NET_RX_DROP;
170 } 172 }
171 173
172 if (lapb_data_received(skb->dev, skb) == LAPB_OK) 174 if (lapb_data_received(skb->dev, skb) == LAPB_OK)
173 return NET_RX_SUCCESS; 175 return NET_RX_SUCCESS;
174 176
175 hdlc->stats.rx_errors++; 177 desc->stats.rx_errors++;
176 dev_kfree_skb_any(skb); 178 dev_kfree_skb_any(skb);
177 return NET_RX_DROP; 179 return NET_RX_DROP;
178} 180}
179 181
180 182
183static struct hdlc_proto proto = {
184 .open = x25_open,
185 .close = x25_close,
186 .ioctl = x25_ioctl,
187 .module = THIS_MODULE,
188};
189
181 190
182int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) 191static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
183{ 192{
184 hdlc_device *hdlc = dev_to_hdlc(dev); 193 hdlc_device *hdlc = dev_to_hdlc(dev);
185 int result; 194 int result;
186 195
187 switch (ifr->ifr_settings.type) { 196 switch (ifr->ifr_settings.type) {
188 case IF_GET_PROTO: 197 case IF_GET_PROTO:
198 if (dev_to_hdlc(dev)->proto != &proto)
199 return -EINVAL;
189 ifr->ifr_settings.type = IF_PROTO_X25; 200 ifr->ifr_settings.type = IF_PROTO_X25;
190 return 0; /* return protocol only, no settable parameters */ 201 return 0; /* return protocol only, no settable parameters */
191 202
@@ -200,14 +211,9 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
200 if (result) 211 if (result)
201 return result; 212 return result;
202 213
203 hdlc_proto_detach(hdlc); 214 if ((result = attach_hdlc_protocol(dev, &proto,
204 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 215 x25_rx, 0)) != 0)
205 216 return result;
206 hdlc->proto.open = x25_open;
207 hdlc->proto.close = x25_close;
208 hdlc->proto.netif_rx = x25_rx;
209 hdlc->proto.type_trans = NULL;
210 hdlc->proto.id = IF_PROTO_X25;
211 dev->hard_start_xmit = x25_xmit; 217 dev->hard_start_xmit = x25_xmit;
212 dev->hard_header = NULL; 218 dev->hard_header = NULL;
213 dev->type = ARPHRD_X25; 219 dev->type = ARPHRD_X25;
@@ -218,3 +224,25 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
218 224
219 return -EINVAL; 225 return -EINVAL;
220} 226}
227
228
229static int __init mod_init(void)
230{
231 register_hdlc_protocol(&proto);
232 return 0;
233}
234
235
236
237static void __exit mod_exit(void)
238{
239 unregister_hdlc_protocol(&proto);
240}
241
242
243module_init(mod_init);
244module_exit(mod_exit);
245
246MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
247MODULE_DESCRIPTION("X.25 protocol support for generic HDLC");
248MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h
index 2024b26b99e6..63e9fcf31fb8 100644
--- a/drivers/net/wan/pc300.h
+++ b/drivers/net/wan/pc300.h
@@ -100,6 +100,7 @@
100#define _PC300_H 100#define _PC300_H
101 101
102#include <linux/hdlc.h> 102#include <linux/hdlc.h>
103#include <net/syncppp.h>
103#include "hd64572.h" 104#include "hd64572.h"
104#include "pc300-falc-lh.h" 105#include "pc300-falc-lh.h"
105 106
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 56e69403d178..8d9b959bf15b 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -2016,7 +2016,6 @@ static void sca_intr(pc300_t * card)
2016 pc300ch_t *chan = &card->chan[ch]; 2016 pc300ch_t *chan = &card->chan[ch];
2017 pc300dev_t *d = &chan->d; 2017 pc300dev_t *d = &chan->d;
2018 struct net_device *dev = d->dev; 2018 struct net_device *dev = d->dev;
2019 hdlc_device *hdlc = dev_to_hdlc(dev);
2020 2019
2021 spin_lock(&card->card_lock); 2020 spin_lock(&card->card_lock);
2022 2021
@@ -2049,8 +2048,8 @@ static void sca_intr(pc300_t * card)
2049 } 2048 }
2050 cpc_net_rx(dev); 2049 cpc_net_rx(dev);
2051 /* Discard invalid frames */ 2050 /* Discard invalid frames */
2052 hdlc->stats.rx_errors++; 2051 hdlc_stats(dev)->rx_errors++;
2053 hdlc->stats.rx_over_errors++; 2052 hdlc_stats(dev)->rx_over_errors++;
2054 chan->rx_first_bd = 0; 2053 chan->rx_first_bd = 0;
2055 chan->rx_last_bd = N_DMA_RX_BUF - 1; 2054 chan->rx_last_bd = N_DMA_RX_BUF - 1;
2056 rx_dma_start(card, ch); 2055 rx_dma_start(card, ch);
@@ -2116,8 +2115,8 @@ static void sca_intr(pc300_t * card)
2116 card->hw.cpld_reg2) & 2115 card->hw.cpld_reg2) &
2117 ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); 2116 ~ (CPLD_REG2_FALC_LED1 << (2 * ch)));
2118 } 2117 }
2119 hdlc->stats.tx_errors++; 2118 hdlc_stats(dev)->tx_errors++;
2120 hdlc->stats.tx_fifo_errors++; 2119 hdlc_stats(dev)->tx_fifo_errors++;
2121 sca_tx_intr(d); 2120 sca_tx_intr(d);
2122 } 2121 }
2123 } 2122 }
@@ -2534,7 +2533,6 @@ static int cpc_change_mtu(struct net_device *dev, int new_mtu)
2534 2533
2535static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 2534static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2536{ 2535{
2537 hdlc_device *hdlc = dev_to_hdlc(dev);
2538 pc300dev_t *d = (pc300dev_t *) dev->priv; 2536 pc300dev_t *d = (pc300dev_t *) dev->priv;
2539 pc300ch_t *chan = (pc300ch_t *) d->chan; 2537 pc300ch_t *chan = (pc300ch_t *) d->chan;
2540 pc300_t *card = (pc300_t *) chan->card; 2538 pc300_t *card = (pc300_t *) chan->card;
@@ -2552,10 +2550,10 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2552 case SIOCGPC300CONF: 2550 case SIOCGPC300CONF:
2553#ifdef CONFIG_PC300_MLPPP 2551#ifdef CONFIG_PC300_MLPPP
2554 if (conf->proto != PC300_PROTO_MLPPP) { 2552 if (conf->proto != PC300_PROTO_MLPPP) {
2555 conf->proto = hdlc->proto.id; 2553 conf->proto = /* FIXME hdlc->proto.id */ 0;
2556 } 2554 }
2557#else 2555#else
2558 conf->proto = hdlc->proto.id; 2556 conf->proto = /* FIXME hdlc->proto.id */ 0;
2559#endif 2557#endif
2560 memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t)); 2558 memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t));
2561 memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t)); 2559 memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t));
@@ -2588,12 +2586,12 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2588 } 2586 }
2589 } else { 2587 } else {
2590 memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); 2588 memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t));
2591 hdlc->proto.id = conf->proto; 2589 /* FIXME hdlc->proto.id = conf->proto; */
2592 } 2590 }
2593 } 2591 }
2594#else 2592#else
2595 memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); 2593 memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t));
2596 hdlc->proto.id = conf->proto; 2594 /* FIXME hdlc->proto.id = conf->proto; */
2597#endif 2595#endif
2598 return 0; 2596 return 0;
2599 case SIOCGPC300STATUS: 2597 case SIOCGPC300STATUS:
@@ -2606,7 +2604,7 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2606 case SIOCGPC300UTILSTATS: 2604 case SIOCGPC300UTILSTATS:
2607 { 2605 {
2608 if (!arg) { /* clear statistics */ 2606 if (!arg) { /* clear statistics */
2609 memset(&hdlc->stats, 0, sizeof(struct net_device_stats)); 2607 memset(hdlc_stats(dev), 0, sizeof(struct net_device_stats));
2610 if (card->hw.type == PC300_TE) { 2608 if (card->hw.type == PC300_TE) {
2611 memset(&chan->falc, 0, sizeof(falc_t)); 2609 memset(&chan->falc, 0, sizeof(falc_t));
2612 } 2610 }
@@ -2617,7 +2615,7 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2617 pc300stats.hw_type = card->hw.type; 2615 pc300stats.hw_type = card->hw.type;
2618 pc300stats.line_on = card->chan[ch].d.line_on; 2616 pc300stats.line_on = card->chan[ch].d.line_on;
2619 pc300stats.line_off = card->chan[ch].d.line_off; 2617 pc300stats.line_off = card->chan[ch].d.line_off;
2620 memcpy(&pc300stats.gen_stats, &hdlc->stats, 2618 memcpy(&pc300stats.gen_stats, hdlc_stats(dev),
2621 sizeof(struct net_device_stats)); 2619 sizeof(struct net_device_stats));
2622 if (card->hw.type == PC300_TE) 2620 if (card->hw.type == PC300_TE)
2623 memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); 2621 memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t));
@@ -3147,7 +3145,6 @@ static void cpc_closech(pc300dev_t * d)
3147 3145
3148int cpc_open(struct net_device *dev) 3146int cpc_open(struct net_device *dev)
3149{ 3147{
3150 hdlc_device *hdlc = dev_to_hdlc(dev);
3151 pc300dev_t *d = (pc300dev_t *) dev->priv; 3148 pc300dev_t *d = (pc300dev_t *) dev->priv;
3152 struct ifreq ifr; 3149 struct ifreq ifr;
3153 int result; 3150 int result;
@@ -3156,12 +3153,14 @@ int cpc_open(struct net_device *dev)
3156 printk("pc300: cpc_open"); 3153 printk("pc300: cpc_open");
3157#endif 3154#endif
3158 3155
3156#ifdef FIXME
3159 if (hdlc->proto.id == IF_PROTO_PPP) { 3157 if (hdlc->proto.id == IF_PROTO_PPP) {
3160 d->if_ptr = &hdlc->state.ppp.pppdev; 3158 d->if_ptr = &hdlc->state.ppp.pppdev;
3161 } 3159 }
3160#endif
3162 3161
3163 result = hdlc_open(dev); 3162 result = hdlc_open(dev);
3164 if (hdlc->proto.id == IF_PROTO_PPP) { 3163 if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) {
3165 dev->priv = d; 3164 dev->priv = d;
3166 } 3165 }
3167 if (result) { 3166 if (result) {
@@ -3176,7 +3175,6 @@ int cpc_open(struct net_device *dev)
3176 3175
3177static int cpc_close(struct net_device *dev) 3176static int cpc_close(struct net_device *dev)
3178{ 3177{
3179 hdlc_device *hdlc = dev_to_hdlc(dev);
3180 pc300dev_t *d = (pc300dev_t *) dev->priv; 3178 pc300dev_t *d = (pc300dev_t *) dev->priv;
3181 pc300ch_t *chan = (pc300ch_t *) d->chan; 3179 pc300ch_t *chan = (pc300ch_t *) d->chan;
3182 pc300_t *card = (pc300_t *) chan->card; 3180 pc300_t *card = (pc300_t *) chan->card;
@@ -3193,7 +3191,7 @@ static int cpc_close(struct net_device *dev)
3193 CPC_UNLOCK(card, flags); 3191 CPC_UNLOCK(card, flags);
3194 3192
3195 hdlc_close(dev); 3193 hdlc_close(dev);
3196 if (hdlc->proto.id == IF_PROTO_PPP) { 3194 if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) {
3197 d->if_ptr = NULL; 3195 d->if_ptr = NULL;
3198 } 3196 }
3199#ifdef CONFIG_PC300_MLPPP 3197#ifdef CONFIG_PC300_MLPPP
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index bff04cba3fed..ba737c6cebec 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5868,7 +5868,7 @@ static int airo_set_essid(struct net_device *dev,
5868 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 5868 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5869 5869
5870 /* Check the size of the string */ 5870 /* Check the size of the string */
5871 if(dwrq->length > IW_ESSID_MAX_SIZE+1) { 5871 if(dwrq->length > IW_ESSID_MAX_SIZE) {
5872 return -E2BIG ; 5872 return -E2BIG ;
5873 } 5873 }
5874 /* Check if index is valid */ 5874 /* Check if index is valid */
@@ -5880,7 +5880,7 @@ static int airo_set_essid(struct net_device *dev,
5880 memset(SSID_rid.ssids[index].ssid, 0, 5880 memset(SSID_rid.ssids[index].ssid, 0,
5881 sizeof(SSID_rid.ssids[index].ssid)); 5881 sizeof(SSID_rid.ssids[index].ssid));
5882 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length); 5882 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5883 SSID_rid.ssids[index].len = dwrq->length - 1; 5883 SSID_rid.ssids[index].len = dwrq->length;
5884 } 5884 }
5885 SSID_rid.len = sizeof(SSID_rid); 5885 SSID_rid.len = sizeof(SSID_rid);
5886 /* Write it to the card */ 5886 /* Write it to the card */
@@ -5990,7 +5990,7 @@ static int airo_set_nick(struct net_device *dev,
5990 struct airo_info *local = dev->priv; 5990 struct airo_info *local = dev->priv;
5991 5991
5992 /* Check the size of the string */ 5992 /* Check the size of the string */
5993 if(dwrq->length > 16 + 1) { 5993 if(dwrq->length > 16) {
5994 return -E2BIG; 5994 return -E2BIG;
5995 } 5995 }
5996 readConfigRid(local, 1); 5996 readConfigRid(local, 1);
@@ -6015,7 +6015,7 @@ static int airo_get_nick(struct net_device *dev,
6015 readConfigRid(local, 1); 6015 readConfigRid(local, 1);
6016 strncpy(extra, local->config.nodeName, 16); 6016 strncpy(extra, local->config.nodeName, 16);
6017 extra[16] = '\0'; 6017 extra[16] = '\0';
6018 dwrq->length = strlen(extra) + 1; 6018 dwrq->length = strlen(extra);
6019 6019
6020 return 0; 6020 return 0;
6021} 6021}
@@ -6767,9 +6767,9 @@ static int airo_set_retry(struct net_device *dev,
6767 } 6767 }
6768 readConfigRid(local, 1); 6768 readConfigRid(local, 1);
6769 if(vwrq->flags & IW_RETRY_LIMIT) { 6769 if(vwrq->flags & IW_RETRY_LIMIT) {
6770 if(vwrq->flags & IW_RETRY_MAX) 6770 if(vwrq->flags & IW_RETRY_LONG)
6771 local->config.longRetryLimit = vwrq->value; 6771 local->config.longRetryLimit = vwrq->value;
6772 else if (vwrq->flags & IW_RETRY_MIN) 6772 else if (vwrq->flags & IW_RETRY_SHORT)
6773 local->config.shortRetryLimit = vwrq->value; 6773 local->config.shortRetryLimit = vwrq->value;
6774 else { 6774 else {
6775 /* No modifier : set both */ 6775 /* No modifier : set both */
@@ -6805,14 +6805,14 @@ static int airo_get_retry(struct net_device *dev,
6805 if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { 6805 if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6806 vwrq->flags = IW_RETRY_LIFETIME; 6806 vwrq->flags = IW_RETRY_LIFETIME;
6807 vwrq->value = (int)local->config.txLifetime * 1024; 6807 vwrq->value = (int)local->config.txLifetime * 1024;
6808 } else if((vwrq->flags & IW_RETRY_MAX)) { 6808 } else if((vwrq->flags & IW_RETRY_LONG)) {
6809 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 6809 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
6810 vwrq->value = (int)local->config.longRetryLimit; 6810 vwrq->value = (int)local->config.longRetryLimit;
6811 } else { 6811 } else {
6812 vwrq->flags = IW_RETRY_LIMIT; 6812 vwrq->flags = IW_RETRY_LIMIT;
6813 vwrq->value = (int)local->config.shortRetryLimit; 6813 vwrq->value = (int)local->config.shortRetryLimit;
6814 if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit) 6814 if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
6815 vwrq->flags |= IW_RETRY_MIN; 6815 vwrq->flags |= IW_RETRY_SHORT;
6816 } 6816 }
6817 6817
6818 return 0; 6818 return 0;
@@ -6990,6 +6990,7 @@ static int airo_set_power(struct net_device *dev,
6990 local->config.rmode |= RXMODE_BC_MC_ADDR; 6990 local->config.rmode |= RXMODE_BC_MC_ADDR;
6991 set_bit (FLAG_COMMIT, &local->flags); 6991 set_bit (FLAG_COMMIT, &local->flags);
6992 case IW_POWER_ON: 6992 case IW_POWER_ON:
6993 /* This is broken, fixme ;-) */
6993 break; 6994 break;
6994 default: 6995 default:
6995 return -EINVAL; 6996 return -EINVAL;
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 995c7bea5897..0fc267d626dc 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1656,13 +1656,13 @@ static int atmel_set_essid(struct net_device *dev,
1656 priv->connect_to_any_BSS = 0; 1656 priv->connect_to_any_BSS = 0;
1657 1657
1658 /* Check the size of the string */ 1658 /* Check the size of the string */
1659 if (dwrq->length > MAX_SSID_LENGTH + 1) 1659 if (dwrq->length > MAX_SSID_LENGTH)
1660 return -E2BIG; 1660 return -E2BIG;
1661 if (index != 0) 1661 if (index != 0)
1662 return -EINVAL; 1662 return -EINVAL;
1663 1663
1664 memcpy(priv->new_SSID, extra, dwrq->length - 1); 1664 memcpy(priv->new_SSID, extra, dwrq->length);
1665 priv->new_SSID_size = dwrq->length - 1; 1665 priv->new_SSID_size = dwrq->length;
1666 } 1666 }
1667 1667
1668 return -EINPROGRESS; 1668 return -EINPROGRESS;
@@ -2120,9 +2120,9 @@ static int atmel_set_retry(struct net_device *dev,
2120 struct atmel_private *priv = netdev_priv(dev); 2120 struct atmel_private *priv = netdev_priv(dev);
2121 2121
2122 if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) { 2122 if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2123 if (vwrq->flags & IW_RETRY_MAX) 2123 if (vwrq->flags & IW_RETRY_LONG)
2124 priv->long_retry = vwrq->value; 2124 priv->long_retry = vwrq->value;
2125 else if (vwrq->flags & IW_RETRY_MIN) 2125 else if (vwrq->flags & IW_RETRY_SHORT)
2126 priv->short_retry = vwrq->value; 2126 priv->short_retry = vwrq->value;
2127 else { 2127 else {
2128 /* No modifier : set both */ 2128 /* No modifier : set both */
@@ -2144,15 +2144,15 @@ static int atmel_get_retry(struct net_device *dev,
2144 2144
2145 vwrq->disabled = 0; /* Can't be disabled */ 2145 vwrq->disabled = 0; /* Can't be disabled */
2146 2146
2147 /* Note : by default, display the min retry number */ 2147 /* Note : by default, display the short retry number */
2148 if (vwrq->flags & IW_RETRY_MAX) { 2148 if (vwrq->flags & IW_RETRY_LONG) {
2149 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 2149 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2150 vwrq->value = priv->long_retry; 2150 vwrq->value = priv->long_retry;
2151 } else { 2151 } else {
2152 vwrq->flags = IW_RETRY_LIMIT; 2152 vwrq->flags = IW_RETRY_LIMIT;
2153 vwrq->value = priv->short_retry; 2153 vwrq->value = priv->short_retry;
2154 if (priv->long_retry != priv->short_retry) 2154 if (priv->long_retry != priv->short_retry)
2155 vwrq->flags |= IW_RETRY_MIN; 2155 vwrq->flags |= IW_RETRY_SHORT;
2156 } 2156 }
2157 2157
2158 return 0; 2158 return 0;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 6d4ea36bc564..d6a8bf09878e 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -666,7 +666,6 @@ struct bcm43xx_noise_calculation {
666}; 666};
667 667
668struct bcm43xx_stats { 668struct bcm43xx_stats {
669 u8 link_quality;
670 u8 noise; 669 u8 noise;
671 struct iw_statistics wstats; 670 struct iw_statistics wstats;
672 /* Store the last TX/RX times here for updating the leds. */ 671 /* Store the last TX/RX times here for updating the leds. */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index cb9a3ae8463a..eb65db7393ba 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -2405,9 +2405,10 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2405 BCM43xx_UCODE_TIME) & 0x1f); 2405 BCM43xx_UCODE_TIME) & 0x1f);
2406 2406
2407 if ( value16 > 0x128 ) { 2407 if ( value16 > 0x128 ) {
2408 dprintk(KERN_ERR PFX 2408 printk(KERN_ERR PFX
2409 "Firmware: no support for microcode rev > 0x128\n"); 2409 "Firmware: no support for microcode extracted "
2410 err = -1; 2410 "from version 4.x binary drivers.\n");
2411 err = -EOPNOTSUPP;
2411 goto err_release_fw; 2412 goto err_release_fw;
2412 } 2413 }
2413 2414
@@ -3169,8 +3170,7 @@ static void bcm43xx_periodic_work_handler(void *d)
3169 * be preemtible. 3170 * be preemtible.
3170 */ 3171 */
3171 mutex_lock(&bcm->mutex); 3172 mutex_lock(&bcm->mutex);
3172 netif_stop_queue(bcm->net_dev); 3173 netif_tx_disable(bcm->net_dev);
3173 synchronize_net();
3174 spin_lock_irqsave(&bcm->irq_lock, flags); 3174 spin_lock_irqsave(&bcm->irq_lock, flags);
3175 bcm43xx_mac_suspend(bcm); 3175 bcm43xx_mac_suspend(bcm);
3176 if (bcm43xx_using_pio(bcm)) 3176 if (bcm43xx_using_pio(bcm))
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index eafd0f662686..52ce2a9334fb 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -361,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
361 if (phy->rev <= 2) 361 if (phy->rev <= 2)
362 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) 362 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
363 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]); 363 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]);
364 else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200)) 364 else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
365 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) 365 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
366 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]); 366 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]);
367 else 367 else
@@ -371,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
371 if (phy->rev == 2) 371 if (phy->rev == 2)
372 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) 372 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
373 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); 373 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
374 else if ((phy->rev > 2) && (phy->rev <= 7)) 374 else if ((phy->rev > 2) && (phy->rev <= 8))
375 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) 375 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
376 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]); 376 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]);
377 377
@@ -1197,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
1197 1197
1198 if (phy->rev == 1) 1198 if (phy->rev == 1)
1199 bcm43xx_phy_initb5(bcm); 1199 bcm43xx_phy_initb5(bcm);
1200 else if (phy->rev >= 2 && phy->rev <= 7) 1200 else
1201 bcm43xx_phy_initb6(bcm); 1201 bcm43xx_phy_initb6(bcm);
1202 if (phy->rev >= 2 || phy->connected) 1202 if (phy->rev >= 2 || phy->connected)
1203 bcm43xx_phy_inita(bcm); 1203 bcm43xx_phy_inita(bcm);
@@ -1241,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
1241 bcm43xx_phy_lo_g_measure(bcm); 1241 bcm43xx_phy_lo_g_measure(bcm);
1242 } else { 1242 } else {
1243 if (radio->version == 0x2050 && radio->revision == 8) { 1243 if (radio->version == 0x2050 && radio->revision == 8) {
1244 //FIXME 1244 bcm43xx_radio_write16(bcm, 0x0052,
1245 (radio->txctl1 << 4) | radio->txctl2);
1245 } else { 1246 } else {
1246 bcm43xx_radio_write16(bcm, 0x0052, 1247 bcm43xx_radio_write16(bcm, 0x0052,
1247 (bcm43xx_radio_read16(bcm, 0x0052) 1248 (bcm43xx_radio_read16(bcm, 0x0052)
1248 & 0xFFF0) | radio->txctl1); 1249 & 0xFFF0) | radio->txctl1);
1249 } 1250 }
1250 if (phy->rev >= 6) { 1251 if (phy->rev >= 6) {
1251 /*
1252 bcm43xx_phy_write(bcm, 0x0036, 1252 bcm43xx_phy_write(bcm, 0x0036,
1253 (bcm43xx_phy_read(bcm, 0x0036) 1253 (bcm43xx_phy_read(bcm, 0x0036)
1254 & 0xF000) | (FIXME << 12)); 1254 & 0xF000) | (radio->txctl2 << 12));
1255 */
1256 } 1255 }
1257 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) 1256 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
1258 bcm43xx_phy_write(bcm, 0x002E, 0x8075); 1257 bcm43xx_phy_write(bcm, 0x002E, 0x8075);
1259 else 1258 else
1260 bcm43xx_phy_write(bcm, 0x003E, 0x807F); 1259 bcm43xx_phy_write(bcm, 0x002E, 0x807F);
1261 if (phy->rev < 2) 1260 if (phy->rev < 2)
1262 bcm43xx_phy_write(bcm, 0x002F, 0x0101); 1261 bcm43xx_phy_write(bcm, 0x002F, 0x0101);
1263 else 1262 else
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 888077fc14c4..9b7b15cf6561 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -334,7 +334,7 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev,
334 size_t len; 334 size_t len;
335 335
336 mutex_lock(&bcm->mutex); 336 mutex_lock(&bcm->mutex);
337 len = strlen(bcm->nick) + 1; 337 len = strlen(bcm->nick);
338 memcpy(extra, bcm->nick, len); 338 memcpy(extra, bcm->nick, len);
339 data->data.length = (__u16)len; 339 data->data.length = (__u16)len;
340 data->data.flags = 1; 340 data->data.flags = 1;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
index c0efbfe605a5..0159e4e93201 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
@@ -496,15 +496,14 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
496 stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm, 496 stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
497 !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), 497 !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
498 !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); 498 !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
499//TODO stats.noise = 499 stats.noise = bcm->stats.noise;
500 if (is_ofdm) 500 if (is_ofdm)
501 stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); 501 stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);
502 else 502 else
503 stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); 503 stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);
504 stats.received_channel = radio->channel; 504 stats.received_channel = radio->channel;
505//TODO stats.control =
506 stats.mask = IEEE80211_STATMASK_SIGNAL | 505 stats.mask = IEEE80211_STATMASK_SIGNAL |
507//TODO IEEE80211_STATMASK_NOISE | 506 IEEE80211_STATMASK_NOISE |
508 IEEE80211_STATMASK_RATE | 507 IEEE80211_STATMASK_RATE |
509 IEEE80211_STATMASK_RSSI; 508 IEEE80211_STATMASK_RSSI;
510 if (phy->type == BCM43xx_PHYTYPE_A) 509 if (phy->type == BCM43xx_PHYTYPE_A)
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 7a4978516eac..d061fb3443ff 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1412,9 +1412,9 @@ static int prism2_ioctl_siwretry(struct net_device *dev,
1412 /* what could be done, if firmware would support this.. */ 1412 /* what could be done, if firmware would support this.. */
1413 1413
1414 if (rrq->flags & IW_RETRY_LIMIT) { 1414 if (rrq->flags & IW_RETRY_LIMIT) {
1415 if (rrq->flags & IW_RETRY_MAX) 1415 if (rrq->flags & IW_RETRY_LONG)
1416 HFA384X_RID_LONGRETRYLIMIT = rrq->value; 1416 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1417 else if (rrq->flags & IW_RETRY_MIN) 1417 else if (rrq->flags & IW_RETRY_SHORT)
1418 HFA384X_RID_SHORTRETRYLIMIT = rrq->value; 1418 HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1419 else { 1419 else {
1420 HFA384X_RID_LONGRETRYLIMIT = rrq->value; 1420 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
@@ -1468,14 +1468,14 @@ static int prism2_ioctl_giwretry(struct net_device *dev,
1468 rrq->value = le16_to_cpu(altretry); 1468 rrq->value = le16_to_cpu(altretry);
1469 else 1469 else
1470 rrq->value = local->manual_retry_count; 1470 rrq->value = local->manual_retry_count;
1471 } else if ((rrq->flags & IW_RETRY_MAX)) { 1471 } else if ((rrq->flags & IW_RETRY_LONG)) {
1472 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 1472 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1473 rrq->value = longretry; 1473 rrq->value = longretry;
1474 } else { 1474 } else {
1475 rrq->flags = IW_RETRY_LIMIT; 1475 rrq->flags = IW_RETRY_LIMIT;
1476 rrq->value = shortretry; 1476 rrq->value = shortretry;
1477 if (shortretry != longretry) 1477 if (shortretry != longretry)
1478 rrq->flags |= IW_RETRY_MIN; 1478 rrq->flags |= IW_RETRY_SHORT;
1479 } 1479 }
1480 } 1480 }
1481 return 0; 1481 return 0;
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index b4d81a04c895..6c5add701a6f 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6958,7 +6958,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
6958 } 6958 }
6959 6959
6960 if (wrqu->essid.flags && wrqu->essid.length) { 6960 if (wrqu->essid.flags && wrqu->essid.length) {
6961 length = wrqu->essid.length - 1; 6961 length = wrqu->essid.length;
6962 essid = extra; 6962 essid = extra;
6963 } 6963 }
6964 6964
@@ -7051,7 +7051,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
7051 7051
7052 struct ipw2100_priv *priv = ieee80211_priv(dev); 7052 struct ipw2100_priv *priv = ieee80211_priv(dev);
7053 7053
7054 wrqu->data.length = strlen(priv->nick) + 1; 7054 wrqu->data.length = strlen(priv->nick);
7055 memcpy(extra, priv->nick, wrqu->data.length); 7055 memcpy(extra, priv->nick, wrqu->data.length);
7056 wrqu->data.flags = 1; /* active */ 7056 wrqu->data.flags = 1; /* active */
7057 7057
@@ -7343,14 +7343,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7343 goto done; 7343 goto done;
7344 } 7344 }
7345 7345
7346 if (wrqu->retry.flags & IW_RETRY_MIN) { 7346 if (wrqu->retry.flags & IW_RETRY_SHORT) {
7347 err = ipw2100_set_short_retry(priv, wrqu->retry.value); 7347 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7348 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", 7348 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7349 wrqu->retry.value); 7349 wrqu->retry.value);
7350 goto done; 7350 goto done;
7351 } 7351 }
7352 7352
7353 if (wrqu->retry.flags & IW_RETRY_MAX) { 7353 if (wrqu->retry.flags & IW_RETRY_LONG) {
7354 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7354 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7355 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", 7355 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7356 wrqu->retry.value); 7356 wrqu->retry.value);
@@ -7383,14 +7383,14 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7383 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) 7383 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
7384 return -EINVAL; 7384 return -EINVAL;
7385 7385
7386 if (wrqu->retry.flags & IW_RETRY_MAX) { 7386 if (wrqu->retry.flags & IW_RETRY_LONG) {
7387 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 7387 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
7388 wrqu->retry.value = priv->long_retry_limit; 7388 wrqu->retry.value = priv->long_retry_limit;
7389 } else { 7389 } else {
7390 wrqu->retry.flags = 7390 wrqu->retry.flags =
7391 (priv->short_retry_limit != 7391 (priv->short_retry_limit !=
7392 priv->long_retry_limit) ? 7392 priv->long_retry_limit) ?
7393 IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT; 7393 IW_RETRY_LIMIT | IW_RETRY_SHORT : IW_RETRY_LIMIT;
7394 7394
7395 wrqu->retry.value = priv->short_retry_limit; 7395 wrqu->retry.value = priv->short_retry_limit;
7396 } 7396 }
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 7358664e0908..5685d7ba55bb 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8875,8 +8875,6 @@ static int ipw_wx_set_essid(struct net_device *dev,
8875 } 8875 }
8876 8876
8877 length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE); 8877 length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
8878 if (!extra[length - 1])
8879 length--;
8880 8878
8881 priv->config |= CFG_STATIC_ESSID; 8879 priv->config |= CFG_STATIC_ESSID;
8882 8880
@@ -8953,7 +8951,7 @@ static int ipw_wx_get_nick(struct net_device *dev,
8953 struct ipw_priv *priv = ieee80211_priv(dev); 8951 struct ipw_priv *priv = ieee80211_priv(dev);
8954 IPW_DEBUG_WX("Getting nick\n"); 8952 IPW_DEBUG_WX("Getting nick\n");
8955 mutex_lock(&priv->mutex); 8953 mutex_lock(&priv->mutex);
8956 wrqu->data.length = strlen(priv->nick) + 1; 8954 wrqu->data.length = strlen(priv->nick);
8957 memcpy(extra, priv->nick, wrqu->data.length); 8955 memcpy(extra, priv->nick, wrqu->data.length);
8958 wrqu->data.flags = 1; /* active */ 8956 wrqu->data.flags = 1; /* active */
8959 mutex_unlock(&priv->mutex); 8957 mutex_unlock(&priv->mutex);
@@ -9276,9 +9274,9 @@ static int ipw_wx_set_retry(struct net_device *dev,
9276 return -EINVAL; 9274 return -EINVAL;
9277 9275
9278 mutex_lock(&priv->mutex); 9276 mutex_lock(&priv->mutex);
9279 if (wrqu->retry.flags & IW_RETRY_MIN) 9277 if (wrqu->retry.flags & IW_RETRY_SHORT)
9280 priv->short_retry_limit = (u8) wrqu->retry.value; 9278 priv->short_retry_limit = (u8) wrqu->retry.value;
9281 else if (wrqu->retry.flags & IW_RETRY_MAX) 9279 else if (wrqu->retry.flags & IW_RETRY_LONG)
9282 priv->long_retry_limit = (u8) wrqu->retry.value; 9280 priv->long_retry_limit = (u8) wrqu->retry.value;
9283 else { 9281 else {
9284 priv->short_retry_limit = (u8) wrqu->retry.value; 9282 priv->short_retry_limit = (u8) wrqu->retry.value;
@@ -9307,11 +9305,11 @@ static int ipw_wx_get_retry(struct net_device *dev,
9307 return -EINVAL; 9305 return -EINVAL;
9308 } 9306 }
9309 9307
9310 if (wrqu->retry.flags & IW_RETRY_MAX) { 9308 if (wrqu->retry.flags & IW_RETRY_LONG) {
9311 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 9309 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
9312 wrqu->retry.value = priv->long_retry_limit; 9310 wrqu->retry.value = priv->long_retry_limit;
9313 } else if (wrqu->retry.flags & IW_RETRY_MIN) { 9311 } else if (wrqu->retry.flags & IW_RETRY_SHORT) {
9314 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; 9312 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
9315 wrqu->retry.value = priv->short_retry_limit; 9313 wrqu->retry.value = priv->short_retry_limit;
9316 } else { 9314 } else {
9317 wrqu->retry.flags = IW_RETRY_LIMIT; 9315 wrqu->retry.flags = IW_RETRY_LIMIT;
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 1840b69e3cb5..9e19a963febc 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -3037,7 +3037,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
3037 } 3037 }
3038 3038
3039 erq->flags = 1; 3039 erq->flags = 1;
3040 erq->length = strlen(essidbuf) + 1; 3040 erq->length = strlen(essidbuf);
3041 3041
3042 return 0; 3042 return 0;
3043} 3043}
@@ -3078,7 +3078,7 @@ static int orinoco_ioctl_getnick(struct net_device *dev,
3078 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); 3078 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
3079 orinoco_unlock(priv, &flags); 3079 orinoco_unlock(priv, &flags);
3080 3080
3081 nrq->length = strlen(nickbuf)+1; 3081 nrq->length = strlen(nickbuf);
3082 3082
3083 return 0; 3083 return 0;
3084} 3084}
@@ -3575,14 +3575,14 @@ static int orinoco_ioctl_getretry(struct net_device *dev,
3575 rrq->value = lifetime * 1000; /* ??? */ 3575 rrq->value = lifetime * 1000; /* ??? */
3576 } else { 3576 } else {
3577 /* By default, display the min number */ 3577 /* By default, display the min number */
3578 if ((rrq->flags & IW_RETRY_MAX)) { 3578 if ((rrq->flags & IW_RETRY_LONG)) {
3579 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 3579 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
3580 rrq->value = long_limit; 3580 rrq->value = long_limit;
3581 } else { 3581 } else {
3582 rrq->flags = IW_RETRY_LIMIT; 3582 rrq->flags = IW_RETRY_LIMIT;
3583 rrq->value = short_limit; 3583 rrq->value = short_limit;
3584 if(short_limit != long_limit) 3584 if(short_limit != long_limit)
3585 rrq->flags |= IW_RETRY_MIN; 3585 rrq->flags |= IW_RETRY_SHORT;
3586 } 3586 }
3587 } 3587 }
3588 3588
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index c09fbf733b3a..286325ca3293 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -742,9 +742,9 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info,
742 742
743 /* Check if we were asked for `any' */ 743 /* Check if we were asked for `any' */
744 if (dwrq->flags && dwrq->length) { 744 if (dwrq->flags && dwrq->length) {
745 if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1)) 745 if (dwrq->length > 32)
746 return -E2BIG; 746 return -E2BIG;
747 essid.length = dwrq->length - 1; 747 essid.length = dwrq->length;
748 memcpy(essid.octets, extra, dwrq->length); 748 memcpy(essid.octets, extra, dwrq->length);
749 } else 749 } else
750 essid.length = 0; 750 essid.length = 0;
@@ -814,7 +814,7 @@ prism54_get_nick(struct net_device *ndev, struct iw_request_info *info,
814 dwrq->length = 0; 814 dwrq->length = 0;
815 815
816 down_read(&priv->mib_sem); 816 down_read(&priv->mib_sem);
817 dwrq->length = strlen(priv->nickname) + 1; 817 dwrq->length = strlen(priv->nickname);
818 memcpy(extra, priv->nickname, dwrq->length); 818 memcpy(extra, priv->nickname, dwrq->length);
819 up_read(&priv->mib_sem); 819 up_read(&priv->mib_sem);
820 820
@@ -992,9 +992,9 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info,
992 return -EINVAL; 992 return -EINVAL;
993 993
994 if (vwrq->flags & IW_RETRY_LIMIT) { 994 if (vwrq->flags & IW_RETRY_LIMIT) {
995 if (vwrq->flags & IW_RETRY_MIN) 995 if (vwrq->flags & IW_RETRY_SHORT)
996 slimit = vwrq->value; 996 slimit = vwrq->value;
997 else if (vwrq->flags & IW_RETRY_MAX) 997 else if (vwrq->flags & IW_RETRY_LONG)
998 llimit = vwrq->value; 998 llimit = vwrq->value;
999 else { 999 else {
1000 /* we are asked to set both */ 1000 /* we are asked to set both */
@@ -1035,18 +1035,18 @@ prism54_get_retry(struct net_device *ndev, struct iw_request_info *info,
1035 mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r); 1035 mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r);
1036 vwrq->value = r.u * 1024; 1036 vwrq->value = r.u * 1024;
1037 vwrq->flags = IW_RETRY_LIFETIME; 1037 vwrq->flags = IW_RETRY_LIFETIME;
1038 } else if ((vwrq->flags & IW_RETRY_MAX)) { 1038 } else if ((vwrq->flags & IW_RETRY_LONG)) {
1039 /* we are asked for the long retry limit */ 1039 /* we are asked for the long retry limit */
1040 rvalue |= 1040 rvalue |=
1041 mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r); 1041 mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r);
1042 vwrq->value = r.u; 1042 vwrq->value = r.u;
1043 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 1043 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1044 } else { 1044 } else {
1045 /* default. get the short retry limit */ 1045 /* default. get the short retry limit */
1046 rvalue |= 1046 rvalue |=
1047 mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r); 1047 mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r);
1048 vwrq->value = r.u; 1048 vwrq->value = r.u;
1049 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN; 1049 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
1050 } 1050 }
1051 1051
1052 return rvalue; 1052 return rvalue;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 4574290f971f..e82548ea609a 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1173,7 +1173,7 @@ static int ray_set_essid(struct net_device *dev,
1173 return -EOPNOTSUPP; 1173 return -EOPNOTSUPP;
1174 } else { 1174 } else {
1175 /* Check the size of the string */ 1175 /* Check the size of the string */
1176 if(dwrq->length > IW_ESSID_MAX_SIZE + 1) { 1176 if(dwrq->length > IW_ESSID_MAX_SIZE) {
1177 return -E2BIG; 1177 return -E2BIG;
1178 } 1178 }
1179 1179
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index e0d294c12970..e3ae5f60d5be 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1802,15 +1802,15 @@ static int wl3501_get_retry(struct net_device *dev,
1802 &retry, sizeof(retry)); 1802 &retry, sizeof(retry));
1803 if (rc) 1803 if (rc)
1804 goto out; 1804 goto out;
1805 if (wrqu->retry.flags & IW_RETRY_MAX) { 1805 if (wrqu->retry.flags & IW_RETRY_LONG) {
1806 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 1806 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1807 goto set_value; 1807 goto set_value;
1808 } 1808 }
1809 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT, 1809 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT,
1810 &retry, sizeof(retry)); 1810 &retry, sizeof(retry));
1811 if (rc) 1811 if (rc)
1812 goto out; 1812 goto out;
1813 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; 1813 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
1814set_value: 1814set_value:
1815 wrqu->retry.value = retry; 1815 wrqu->retry.value = retry;
1816 wrqu->retry.disabled = 0; 1816 wrqu->retry.disabled = 0;
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index f50ec10675d1..80af9a9fcbb3 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1218,7 +1218,7 @@ static int zd1201_set_essid(struct net_device *dev,
1218 return -EINVAL; 1218 return -EINVAL;
1219 if (data->length < 1) 1219 if (data->length < 1)
1220 data->length = 1; 1220 data->length = 1;
1221 zd->essidlen = data->length-1; 1221 zd->essidlen = data->length;
1222 memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1); 1222 memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1);
1223 memcpy(zd->essid, essid, data->length); 1223 memcpy(zd->essid, essid, data->length);
1224 return zd1201_join(zd, zd->essid, zd->essidlen); 1224 return zd1201_join(zd, zd->essid, zd->essidlen);
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 7c4e32cf0d47..aa661b2b76c7 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -249,7 +249,6 @@ int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
249{ 249{
250 int r; 250 int r;
251 251
252 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
253 mutex_lock(&chip->mutex); 252 mutex_lock(&chip->mutex);
254 r = zd_ioread16_locked(chip, value, addr); 253 r = zd_ioread16_locked(chip, value, addr);
255 mutex_unlock(&chip->mutex); 254 mutex_unlock(&chip->mutex);
@@ -260,7 +259,6 @@ int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
260{ 259{
261 int r; 260 int r;
262 261
263 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
264 mutex_lock(&chip->mutex); 262 mutex_lock(&chip->mutex);
265 r = zd_ioread32_locked(chip, value, addr); 263 r = zd_ioread32_locked(chip, value, addr);
266 mutex_unlock(&chip->mutex); 264 mutex_unlock(&chip->mutex);
@@ -271,7 +269,6 @@ int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
271{ 269{
272 int r; 270 int r;
273 271
274 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
275 mutex_lock(&chip->mutex); 272 mutex_lock(&chip->mutex);
276 r = zd_iowrite16_locked(chip, value, addr); 273 r = zd_iowrite16_locked(chip, value, addr);
277 mutex_unlock(&chip->mutex); 274 mutex_unlock(&chip->mutex);
@@ -282,7 +279,6 @@ int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
282{ 279{
283 int r; 280 int r;
284 281
285 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
286 mutex_lock(&chip->mutex); 282 mutex_lock(&chip->mutex);
287 r = zd_iowrite32_locked(chip, value, addr); 283 r = zd_iowrite32_locked(chip, value, addr);
288 mutex_unlock(&chip->mutex); 284 mutex_unlock(&chip->mutex);
@@ -294,7 +290,6 @@ int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
294{ 290{
295 int r; 291 int r;
296 292
297 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
298 mutex_lock(&chip->mutex); 293 mutex_lock(&chip->mutex);
299 r = zd_ioread32v_locked(chip, values, addresses, count); 294 r = zd_ioread32v_locked(chip, values, addresses, count);
300 mutex_unlock(&chip->mutex); 295 mutex_unlock(&chip->mutex);
@@ -306,7 +301,6 @@ int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
306{ 301{
307 int r; 302 int r;
308 303
309 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
310 mutex_lock(&chip->mutex); 304 mutex_lock(&chip->mutex);
311 r = zd_iowrite32a_locked(chip, ioreqs, count); 305 r = zd_iowrite32a_locked(chip, ioreqs, count);
312 mutex_unlock(&chip->mutex); 306 mutex_unlock(&chip->mutex);
@@ -331,13 +325,22 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type)
331 chip->patch_cr157 = (value >> 13) & 0x1; 325 chip->patch_cr157 = (value >> 13) & 0x1;
332 chip->patch_6m_band_edge = (value >> 21) & 0x1; 326 chip->patch_6m_band_edge = (value >> 21) & 0x1;
333 chip->new_phy_layout = (value >> 31) & 0x1; 327 chip->new_phy_layout = (value >> 31) & 0x1;
328 chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
329 chip->supports_tx_led = 1;
330 if (value & (1 << 24)) { /* LED scenario */
331 if (value & (1 << 29))
332 chip->supports_tx_led = 0;
333 }
334 334
335 dev_dbg_f(zd_chip_dev(chip), 335 dev_dbg_f(zd_chip_dev(chip),
336 "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d " 336 "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
337 "patch 6M %d new PHY %d\n", 337 "patch 6M %d new PHY %d link LED%d tx led %d\n",
338 zd_rf_name(*rf_type), *rf_type, 338 zd_rf_name(*rf_type), *rf_type,
339 chip->pa_type, chip->patch_cck_gain, 339 chip->pa_type, chip->patch_cck_gain,
340 chip->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout); 340 chip->patch_cr157, chip->patch_6m_band_edge,
341 chip->new_phy_layout,
342 chip->link_led == LED1 ? 1 : 2,
343 chip->supports_tx_led);
341 return 0; 344 return 0;
342error: 345error:
343 *rf_type = 0; 346 *rf_type = 0;
@@ -1181,7 +1184,7 @@ static int update_pwr_int(struct zd_chip *chip, u8 channel)
1181 u8 value = chip->pwr_int_values[channel - 1]; 1184 u8 value = chip->pwr_int_values[channel - 1];
1182 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n", 1185 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n",
1183 channel, value); 1186 channel, value);
1184 return zd_iowrite32_locked(chip, value, CR31); 1187 return zd_iowrite16_locked(chip, value, CR31);
1185} 1188}
1186 1189
1187static int update_pwr_cal(struct zd_chip *chip, u8 channel) 1190static int update_pwr_cal(struct zd_chip *chip, u8 channel)
@@ -1189,12 +1192,12 @@ static int update_pwr_cal(struct zd_chip *chip, u8 channel)
1189 u8 value = chip->pwr_cal_values[channel-1]; 1192 u8 value = chip->pwr_cal_values[channel-1];
1190 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n", 1193 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n",
1191 channel, value); 1194 channel, value);
1192 return zd_iowrite32_locked(chip, value, CR68); 1195 return zd_iowrite16_locked(chip, value, CR68);
1193} 1196}
1194 1197
1195static int update_ofdm_cal(struct zd_chip *chip, u8 channel) 1198static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
1196{ 1199{
1197 struct zd_ioreq32 ioreqs[3]; 1200 struct zd_ioreq16 ioreqs[3];
1198 1201
1199 ioreqs[0].addr = CR67; 1202 ioreqs[0].addr = CR67;
1200 ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; 1203 ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
@@ -1206,7 +1209,7 @@ static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
1206 dev_dbg_f(zd_chip_dev(chip), 1209 dev_dbg_f(zd_chip_dev(chip),
1207 "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n", 1210 "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n",
1208 channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value); 1211 channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value);
1209 return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 1212 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1210} 1213}
1211 1214
1212static int update_channel_integration_and_calibration(struct zd_chip *chip, 1215static int update_channel_integration_and_calibration(struct zd_chip *chip,
@@ -1218,7 +1221,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
1218 if (r) 1221 if (r)
1219 return r; 1222 return r;
1220 if (chip->is_zd1211b) { 1223 if (chip->is_zd1211b) {
1221 static const struct zd_ioreq32 ioreqs[] = { 1224 static const struct zd_ioreq16 ioreqs[] = {
1222 { CR69, 0x28 }, 1225 { CR69, 0x28 },
1223 {}, 1226 {},
1224 { CR69, 0x2a }, 1227 { CR69, 0x2a },
@@ -1230,7 +1233,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
1230 r = update_pwr_cal(chip, channel); 1233 r = update_pwr_cal(chip, channel);
1231 if (r) 1234 if (r)
1232 return r; 1235 return r;
1233 r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 1236 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1234 if (r) 1237 if (r)
1235 return r; 1238 return r;
1236 } 1239 }
@@ -1252,7 +1255,7 @@ static int patch_cck_gain(struct zd_chip *chip)
1252 if (r) 1255 if (r)
1253 return r; 1256 return r;
1254 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); 1257 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
1255 return zd_iowrite32_locked(chip, value & 0xff, CR47); 1258 return zd_iowrite16_locked(chip, value & 0xff, CR47);
1256} 1259}
1257 1260
1258int zd_chip_set_channel(struct zd_chip *chip, u8 channel) 1261int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
@@ -1295,89 +1298,60 @@ u8 zd_chip_get_channel(struct zd_chip *chip)
1295 return channel; 1298 return channel;
1296} 1299}
1297 1300
1298static u16 led_mask(int led) 1301int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
1299{ 1302{
1300 switch (led) { 1303 static const zd_addr_t a[] = {
1301 case 1: 1304 FW_LINK_STATUS,
1302 return LED1; 1305 CR_LED,
1303 case 2: 1306 };
1304 return LED2;
1305 default:
1306 return 0;
1307 }
1308}
1309
1310static int read_led_reg(struct zd_chip *chip, u16 *status)
1311{
1312 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1313 return zd_ioread16_locked(chip, status, CR_LED);
1314}
1315
1316static int write_led_reg(struct zd_chip *chip, u16 status)
1317{
1318 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1319 return zd_iowrite16_locked(chip, status, CR_LED);
1320}
1321 1307
1322int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status) 1308 int r;
1323{ 1309 u16 v[ARRAY_SIZE(a)];
1324 int r, ret; 1310 struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
1325 u16 mask = led_mask(led); 1311 [0] = { FW_LINK_STATUS },
1326 u16 reg; 1312 [1] = { CR_LED },
1313 };
1314 u16 other_led;
1327 1315
1328 if (!mask)
1329 return -EINVAL;
1330 mutex_lock(&chip->mutex); 1316 mutex_lock(&chip->mutex);
1331 r = read_led_reg(chip, &reg); 1317 r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));
1332 if (r) 1318 if (r)
1333 return r; 1319 goto out;
1320
1321 other_led = chip->link_led == LED1 ? LED2 : LED1;
1322
1334 switch (status) { 1323 switch (status) {
1335 case LED_STATUS:
1336 return (reg & mask) ? LED_ON : LED_OFF;
1337 case LED_OFF: 1324 case LED_OFF:
1338 reg &= ~mask; 1325 ioreqs[0].value = FW_LINK_OFF;
1339 ret = LED_OFF; 1326 ioreqs[1].value = v[1] & ~(LED1|LED2);
1340 break; 1327 break;
1341 case LED_FLIP: 1328 case LED_SCANNING:
1342 reg ^= mask; 1329 ioreqs[0].value = FW_LINK_OFF;
1343 ret = (reg&mask) ? LED_ON : LED_OFF; 1330 ioreqs[1].value = v[1] & ~other_led;
1331 if (get_seconds() % 3 == 0) {
1332 ioreqs[1].value &= ~chip->link_led;
1333 } else {
1334 ioreqs[1].value |= chip->link_led;
1335 }
1344 break; 1336 break;
1345 case LED_ON: 1337 case LED_ASSOCIATED:
1346 reg |= mask; 1338 ioreqs[0].value = FW_LINK_TX;
1347 ret = LED_ON; 1339 ioreqs[1].value = v[1] & ~other_led;
1340 ioreqs[1].value |= chip->link_led;
1348 break; 1341 break;
1349 default: 1342 default:
1350 return -EINVAL; 1343 r = -EINVAL;
1351 }
1352 r = write_led_reg(chip, reg);
1353 if (r) {
1354 ret = r;
1355 goto out; 1344 goto out;
1356 } 1345 }
1357out:
1358 mutex_unlock(&chip->mutex);
1359 return r;
1360}
1361
1362int zd_chip_led_flip(struct zd_chip *chip, int led,
1363 const unsigned int *phases_msecs, unsigned int count)
1364{
1365 int i, r;
1366 enum led_status status;
1367 1346
1368 r = zd_chip_led_status(chip, led, LED_STATUS); 1347 if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {
1369 if (r) 1348 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1370 return r; 1349 if (r)
1371 status = r;
1372 for (i = 0; i < count; i++) {
1373 r = zd_chip_led_status(chip, led, LED_FLIP);
1374 if (r < 0)
1375 goto out; 1350 goto out;
1376 msleep(phases_msecs[i]);
1377 } 1351 }
1378 1352 r = 0;
1379out: 1353out:
1380 zd_chip_led_status(chip, led, status); 1354 mutex_unlock(&chip->mutex);
1381 return r; 1355 return r;
1382} 1356}
1383 1357
@@ -1679,4 +1653,3 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip,
1679 1653
1680 return 0; 1654 return 0;
1681} 1655}
1682
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 4b1250859897..ae59597ce4e1 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -428,6 +428,7 @@
428/* masks for controlling LEDs */ 428/* masks for controlling LEDs */
429#define LED1 0x0100 429#define LED1 0x0100
430#define LED2 0x0200 430#define LED2 0x0200
431#define LED_SW 0x0400
431 432
432/* Seems to indicate that the configuration is over. 433/* Seems to indicate that the configuration is over.
433 */ 434 */
@@ -629,6 +630,10 @@
629#define FW_SOFT_RESET FW_REG(4) 630#define FW_SOFT_RESET FW_REG(4)
630#define FW_FLASH_CHK FW_REG(5) 631#define FW_FLASH_CHK FW_REG(5)
631 632
633#define FW_LINK_OFF 0x0
634#define FW_LINK_TX 0x1
635/* 0x2 - link led on? */
636
632enum { 637enum {
633 CR_BASE_OFFSET = 0x9000, 638 CR_BASE_OFFSET = 0x9000,
634 FW_START_OFFSET = 0xee00, 639 FW_START_OFFSET = 0xee00,
@@ -663,8 +668,11 @@ struct zd_chip {
663 u8 pwr_int_values[E2P_CHANNEL_COUNT]; 668 u8 pwr_int_values[E2P_CHANNEL_COUNT];
664 /* SetPointOFDM in the vendor driver */ 669 /* SetPointOFDM in the vendor driver */
665 u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT]; 670 u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT];
666 u8 pa_type:4, patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1, 671 u16 link_led;
667 new_phy_layout:1, is_zd1211b:1; 672 unsigned int pa_type:4,
673 patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
674 new_phy_layout:1,
675 is_zd1211b:1, supports_tx_led:1;
668}; 676};
669 677
670static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) 678static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
@@ -812,15 +820,12 @@ int zd_chip_lock_phy_regs(struct zd_chip *chip);
812int zd_chip_unlock_phy_regs(struct zd_chip *chip); 820int zd_chip_unlock_phy_regs(struct zd_chip *chip);
813 821
814enum led_status { 822enum led_status {
815 LED_OFF = 0, 823 LED_OFF = 0,
816 LED_ON = 1, 824 LED_SCANNING = 1,
817 LED_FLIP = 2, 825 LED_ASSOCIATED = 2,
818 LED_STATUS = 3,
819}; 826};
820 827
821int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status); 828int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
822int zd_chip_led_flip(struct zd_chip *chip, int led,
823 const unsigned int *phases_msecs, unsigned int count);
824 829
825int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); 830int zd_set_beacon_interval(struct zd_chip *chip, u32 interval);
826 831
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 1989f1c05fbe..2d12837052b0 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -33,6 +33,10 @@
33static void ieee_init(struct ieee80211_device *ieee); 33static void ieee_init(struct ieee80211_device *ieee);
34static void softmac_init(struct ieee80211softmac_device *sm); 34static void softmac_init(struct ieee80211softmac_device *sm);
35 35
36static void housekeeping_init(struct zd_mac *mac);
37static void housekeeping_enable(struct zd_mac *mac);
38static void housekeeping_disable(struct zd_mac *mac);
39
36int zd_mac_init(struct zd_mac *mac, 40int zd_mac_init(struct zd_mac *mac,
37 struct net_device *netdev, 41 struct net_device *netdev,
38 struct usb_interface *intf) 42 struct usb_interface *intf)
@@ -46,6 +50,7 @@ int zd_mac_init(struct zd_mac *mac,
46 ieee_init(ieee); 50 ieee_init(ieee);
47 softmac_init(ieee80211_priv(netdev)); 51 softmac_init(ieee80211_priv(netdev));
48 zd_chip_init(&mac->chip, netdev, intf); 52 zd_chip_init(&mac->chip, netdev, intf);
53 housekeeping_init(mac);
49 return 0; 54 return 0;
50} 55}
51 56
@@ -178,6 +183,7 @@ int zd_mac_open(struct net_device *netdev)
178 if (r < 0) 183 if (r < 0)
179 goto disable_rx; 184 goto disable_rx;
180 185
186 housekeeping_enable(mac);
181 ieee80211softmac_start(netdev); 187 ieee80211softmac_start(netdev);
182 return 0; 188 return 0;
183disable_rx: 189disable_rx:
@@ -204,6 +210,7 @@ int zd_mac_stop(struct net_device *netdev)
204 */ 210 */
205 211
206 zd_chip_disable_rx(chip); 212 zd_chip_disable_rx(chip);
213 housekeeping_disable(mac);
207 ieee80211softmac_stop(netdev); 214 ieee80211softmac_stop(netdev);
208 215
209 zd_chip_disable_hwint(chip); 216 zd_chip_disable_hwint(chip);
@@ -1080,3 +1087,46 @@ void zd_dump_rx_status(const struct rx_status *status)
1080 } 1087 }
1081} 1088}
1082#endif /* DEBUG */ 1089#endif /* DEBUG */
1090
1091#define LINK_LED_WORK_DELAY HZ
1092
1093static void link_led_handler(void *p)
1094{
1095 struct zd_mac *mac = p;
1096 struct zd_chip *chip = &mac->chip;
1097 struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev);
1098 int is_associated;
1099 int r;
1100
1101 spin_lock_irq(&mac->lock);
1102 is_associated = sm->associated != 0;
1103 spin_unlock_irq(&mac->lock);
1104
1105 r = zd_chip_control_leds(chip,
1106 is_associated ? LED_ASSOCIATED : LED_SCANNING);
1107 if (r)
1108 dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
1109
1110 queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
1111 LINK_LED_WORK_DELAY);
1112}
1113
1114static void housekeeping_init(struct zd_mac *mac)
1115{
1116 INIT_WORK(&mac->housekeeping.link_led_work, link_led_handler, mac);
1117}
1118
1119static void housekeeping_enable(struct zd_mac *mac)
1120{
1121 dev_dbg_f(zd_mac_dev(mac), "\n");
1122 queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
1123 0);
1124}
1125
1126static void housekeeping_disable(struct zd_mac *mac)
1127{
1128 dev_dbg_f(zd_mac_dev(mac), "\n");
1129 cancel_rearming_delayed_workqueue(zd_workqueue,
1130 &mac->housekeeping.link_led_work);
1131 zd_chip_control_leds(&mac->chip, LED_OFF);
1132}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 29b51fd7d4e5..b8ea3de7924a 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -120,6 +120,10 @@ enum mac_flags {
120 MAC_FIXED_CHANNEL = 0x01, 120 MAC_FIXED_CHANNEL = 0x01,
121}; 121};
122 122
123struct housekeeping {
124 struct work_struct link_led_work;
125};
126
123#define ZD_MAC_STATS_BUFFER_SIZE 16 127#define ZD_MAC_STATS_BUFFER_SIZE 16
124 128
125struct zd_mac { 129struct zd_mac {
@@ -128,6 +132,7 @@ struct zd_mac {
128 struct net_device *netdev; 132 struct net_device *netdev;
129 /* Unlocked reading possible */ 133 /* Unlocked reading possible */
130 struct iw_statistics iw_stats; 134 struct iw_statistics iw_stats;
135 struct housekeeping housekeeping;
131 unsigned int stats_count; 136 unsigned int stats_count;
132 u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; 137 u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
133 u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; 138 u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c
index 440ef24b5fd1..af3a7b36d078 100644
--- a/drivers/net/wireless/zd1211rw/zd_netdev.c
+++ b/drivers/net/wireless/zd1211rw/zd_netdev.c
@@ -82,7 +82,7 @@ static int iw_get_nick(struct net_device *netdev,
82 union iwreq_data *req, char *extra) 82 union iwreq_data *req, char *extra)
83{ 83{
84 strcpy(extra, "zd1211"); 84 strcpy(extra, "zd1211");
85 req->data.length = strlen(extra) + 1; 85 req->data.length = strlen(extra);
86 req->data.flags = 1; 86 req->data.flags = 1;
87 return 0; 87 return 0;
88} 88}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 31027e52b04b..5c265ad0485a 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -24,6 +24,7 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/skbuff.h> 25#include <linux/skbuff.h>
26#include <linux/usb.h> 26#include <linux/usb.h>
27#include <linux/workqueue.h>
27#include <net/ieee80211.h> 28#include <net/ieee80211.h>
28 29
29#include "zd_def.h" 30#include "zd_def.h"
@@ -1112,12 +1113,20 @@ static struct usb_driver driver = {
1112 .disconnect = disconnect, 1113 .disconnect = disconnect,
1113}; 1114};
1114 1115
1116struct workqueue_struct *zd_workqueue;
1117
1115static int __init usb_init(void) 1118static int __init usb_init(void)
1116{ 1119{
1117 int r; 1120 int r;
1118 1121
1119 pr_debug("usb_init()\n"); 1122 pr_debug("usb_init()\n");
1120 1123
1124 zd_workqueue = create_singlethread_workqueue(driver.name);
1125 if (zd_workqueue == NULL) {
1126 printk(KERN_ERR "%s: couldn't create workqueue\n", driver.name);
1127 return -ENOMEM;
1128 }
1129
1121 r = usb_register(&driver); 1130 r = usb_register(&driver);
1122 if (r) { 1131 if (r) {
1123 printk(KERN_ERR "usb_register() failed. Error number %d\n", r); 1132 printk(KERN_ERR "usb_register() failed. Error number %d\n", r);
@@ -1132,6 +1141,7 @@ static void __exit usb_exit(void)
1132{ 1141{
1133 pr_debug("usb_exit()\n"); 1142 pr_debug("usb_exit()\n");
1134 usb_deregister(&driver); 1143 usb_deregister(&driver);
1144 destroy_workqueue(zd_workqueue);
1135} 1145}
1136 1146
1137module_init(usb_init); 1147module_init(usb_init);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index ded39de5f72d..e81a2d3cfffd 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -238,4 +238,6 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
238 238
239int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); 239int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits);
240 240
241extern struct workqueue_struct *zd_workqueue;
242
241#endif /* _ZD_USB_H */ 243#endif /* _ZD_USB_H */
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index d5ebbb29aeae..d4b333938f73 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -11,95 +11,46 @@
11#ifndef __HDLC_H 11#ifndef __HDLC_H
12#define __HDLC_H 12#define __HDLC_H
13 13
14#define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */
15
16#define CLOCK_DEFAULT 0 /* Default setting */
17#define CLOCK_EXT 1 /* External TX and RX clock - DTE */
18#define CLOCK_INT 2 /* Internal TX and RX clock - DCE */
19#define CLOCK_TXINT 3 /* Internal TX and external RX clock */
20#define CLOCK_TXFROMRX 4 /* TX clock derived from external RX clock */
21
22
23#define ENCODING_DEFAULT 0 /* Default setting */
24#define ENCODING_NRZ 1
25#define ENCODING_NRZI 2
26#define ENCODING_FM_MARK 3
27#define ENCODING_FM_SPACE 4
28#define ENCODING_MANCHESTER 5
29
30
31#define PARITY_DEFAULT 0 /* Default setting */
32#define PARITY_NONE 1 /* No parity */
33#define PARITY_CRC16_PR0 2 /* CRC16, initial value 0x0000 */
34#define PARITY_CRC16_PR1 3 /* CRC16, initial value 0xFFFF */
35#define PARITY_CRC16_PR0_CCITT 4 /* CRC16, initial 0x0000, ITU-T version */
36#define PARITY_CRC16_PR1_CCITT 5 /* CRC16, initial 0xFFFF, ITU-T version */
37#define PARITY_CRC32_PR0_CCITT 6 /* CRC32, initial value 0x00000000 */
38#define PARITY_CRC32_PR1_CCITT 7 /* CRC32, initial value 0xFFFFFFFF */
39
40#define LMI_DEFAULT 0 /* Default setting */
41#define LMI_NONE 1 /* No LMI, all PVCs are static */
42#define LMI_ANSI 2 /* ANSI Annex D */
43#define LMI_CCITT 3 /* ITU-T Annex A */
44#define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */
45 14
46#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ 15#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */
16#if 0
47#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ 17#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
18#else
19#define HDLC_MAX_MRU 1600 /* as required for FR network */
20#endif
48 21
49 22
50#ifdef __KERNEL__ 23#ifdef __KERNEL__
51 24
52#include <linux/skbuff.h> 25#include <linux/skbuff.h>
53#include <linux/netdevice.h> 26#include <linux/netdevice.h>
54#include <net/syncppp.h>
55#include <linux/hdlc/ioctl.h> 27#include <linux/hdlc/ioctl.h>
56 28
57 29
58typedef struct { /* Used in Cisco and PPP mode */ 30/* Used by all network devices here, pointed to by netdev_priv(dev) */
59 u8 address; 31struct hdlc_device_desc {
60 u8 control; 32 int (*netif_rx)(struct sk_buff *skb);
61 u16 protocol;
62}__attribute__ ((packed)) hdlc_header;
63
64
65
66typedef struct {
67 u32 type; /* code */
68 u32 par1;
69 u32 par2;
70 u16 rel; /* reliability */
71 u32 time;
72}__attribute__ ((packed)) cisco_packet;
73#define CISCO_PACKET_LEN 18
74#define CISCO_BIG_PACKET_LEN 20
75
76
77
78typedef struct pvc_device_struct {
79 struct net_device *master;
80 struct net_device *main;
81 struct net_device *ether; /* bridged Ethernet interface */
82 struct pvc_device_struct *next; /* Sorted in ascending DLCI order */
83 int dlci;
84 int open_count;
85
86 struct {
87 unsigned int new: 1;
88 unsigned int active: 1;
89 unsigned int exist: 1;
90 unsigned int deleted: 1;
91 unsigned int fecn: 1;
92 unsigned int becn: 1;
93 unsigned int bandwidth; /* Cisco LMI reporting only */
94 }state;
95}pvc_device;
96
97
98
99typedef struct hdlc_device_struct {
100 /* To be initialized by hardware driver */
101 struct net_device_stats stats; 33 struct net_device_stats stats;
102 34};
35
36/* This structure is a private property of HDLC protocols.
37 Hardware drivers have no interest here */
38
39struct hdlc_proto {
40 int (*open)(struct net_device *dev);
41 void (*close)(struct net_device *dev);
42 void (*start)(struct net_device *dev); /* if open & DCD */
43 void (*stop)(struct net_device *dev); /* if open & !DCD */
44 void (*detach)(struct net_device *dev);
45 int (*ioctl)(struct net_device *dev, struct ifreq *ifr);
46 unsigned short (*type_trans)(struct sk_buff *skb,
47 struct net_device *dev);
48 struct module *module;
49 struct hdlc_proto *next; /* next protocol in the list */
50};
51
52
53typedef struct hdlc_device {
103 /* used by HDLC layer to take control over HDLC device from hw driver*/ 54 /* used by HDLC layer to take control over HDLC device from hw driver*/
104 int (*attach)(struct net_device *dev, 55 int (*attach)(struct net_device *dev,
105 unsigned short encoding, unsigned short parity); 56 unsigned short encoding, unsigned short parity);
@@ -107,82 +58,18 @@ typedef struct hdlc_device_struct {
107 /* hardware driver must handle this instead of dev->hard_start_xmit */ 58 /* hardware driver must handle this instead of dev->hard_start_xmit */
108 int (*xmit)(struct sk_buff *skb, struct net_device *dev); 59 int (*xmit)(struct sk_buff *skb, struct net_device *dev);
109 60
110
111 /* Things below are for HDLC layer internal use only */ 61 /* Things below are for HDLC layer internal use only */
112 struct { 62 const struct hdlc_proto *proto;
113 int (*open)(struct net_device *dev);
114 void (*close)(struct net_device *dev);
115
116 /* if open & DCD */
117 void (*start)(struct net_device *dev);
118 /* if open & !DCD */
119 void (*stop)(struct net_device *dev);
120
121 void (*detach)(struct hdlc_device_struct *hdlc);
122 int (*netif_rx)(struct sk_buff *skb);
123 unsigned short (*type_trans)(struct sk_buff *skb,
124 struct net_device *dev);
125 int id; /* IF_PROTO_HDLC/CISCO/FR/etc. */
126 }proto;
127
128 int carrier; 63 int carrier;
129 int open; 64 int open;
130 spinlock_t state_lock; 65 spinlock_t state_lock;
131 66 void *state;
132 union {
133 struct {
134 fr_proto settings;
135 pvc_device *first_pvc;
136 int dce_pvc_count;
137
138 struct timer_list timer;
139 unsigned long last_poll;
140 int reliable;
141 int dce_changed;
142 int request;
143 int fullrep_sent;
144 u32 last_errors; /* last errors bit list */
145 u8 n391cnt;
146 u8 txseq; /* TX sequence number */
147 u8 rxseq; /* RX sequence number */
148 }fr;
149
150 struct {
151 cisco_proto settings;
152
153 struct timer_list timer;
154 unsigned long last_poll;
155 int up;
156 int request_sent;
157 u32 txseq; /* TX sequence number */
158 u32 rxseq; /* RX sequence number */
159 }cisco;
160
161 struct {
162 raw_hdlc_proto settings;
163 }raw_hdlc;
164
165 struct {
166 struct ppp_device pppdev;
167 struct ppp_device *syncppp_ptr;
168 int (*old_change_mtu)(struct net_device *dev,
169 int new_mtu);
170 }ppp;
171 }state;
172 void *priv; 67 void *priv;
173}hdlc_device; 68}hdlc_device;
174 69
175 70
176 71
177int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr); 72/* Exported from hdlc module */
178int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
179int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr);
180int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr);
181int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr);
182int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr);
183
184
185/* Exported from hdlc.o */
186 73
187/* Called by hardware driver when a user requests HDLC service */ 74/* Called by hardware driver when a user requests HDLC service */
188int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 75int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
@@ -191,17 +78,21 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
191#define register_hdlc_device(dev) register_netdev(dev) 78#define register_hdlc_device(dev) register_netdev(dev)
192void unregister_hdlc_device(struct net_device *dev); 79void unregister_hdlc_device(struct net_device *dev);
193 80
81
82void register_hdlc_protocol(struct hdlc_proto *proto);
83void unregister_hdlc_protocol(struct hdlc_proto *proto);
84
194struct net_device *alloc_hdlcdev(void *priv); 85struct net_device *alloc_hdlcdev(void *priv);
195 86
196static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) 87
88static __inline__ struct hdlc_device_desc* dev_to_desc(struct net_device *dev)
197{ 89{
198 return netdev_priv(dev); 90 return netdev_priv(dev);
199} 91}
200 92
201 93static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev)
202static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
203{ 94{
204 return (pvc_device*)dev->priv; 95 return netdev_priv(dev) + sizeof(struct hdlc_device_desc);
205} 96}
206 97
207 98
@@ -225,18 +116,14 @@ int hdlc_open(struct net_device *dev);
225/* Must be called by hardware driver when HDLC device is being closed */ 116/* Must be called by hardware driver when HDLC device is being closed */
226void hdlc_close(struct net_device *dev); 117void hdlc_close(struct net_device *dev);
227 118
119int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
120 int (*rx)(struct sk_buff *skb), size_t size);
228/* May be used by hardware driver to gain control over HDLC device */ 121/* May be used by hardware driver to gain control over HDLC device */
229static __inline__ void hdlc_proto_detach(hdlc_device *hdlc) 122void detach_hdlc_protocol(struct net_device *dev);
230{
231 if (hdlc->proto.detach)
232 hdlc->proto.detach(hdlc);
233 hdlc->proto.detach = NULL;
234}
235
236 123
237static __inline__ struct net_device_stats *hdlc_stats(struct net_device *dev) 124static __inline__ struct net_device_stats *hdlc_stats(struct net_device *dev)
238{ 125{
239 return &dev_to_hdlc(dev)->stats; 126 return &dev_to_desc(dev)->stats;
240} 127}
241 128
242 129
@@ -248,8 +135,8 @@ static __inline__ __be16 hdlc_type_trans(struct sk_buff *skb,
248 skb->mac.raw = skb->data; 135 skb->mac.raw = skb->data;
249 skb->dev = dev; 136 skb->dev = dev;
250 137
251 if (hdlc->proto.type_trans) 138 if (hdlc->proto->type_trans)
252 return hdlc->proto.type_trans(skb, dev); 139 return hdlc->proto->type_trans(skb, dev);
253 else 140 else
254 return htons(ETH_P_HDLC); 141 return htons(ETH_P_HDLC);
255} 142}
diff --git a/include/linux/hdlc/ioctl.h b/include/linux/hdlc/ioctl.h
index 78430ba3ea69..583972364357 100644
--- a/include/linux/hdlc/ioctl.h
+++ b/include/linux/hdlc/ioctl.h
@@ -1,6 +1,39 @@
1#ifndef __HDLC_IOCTL_H__ 1#ifndef __HDLC_IOCTL_H__
2#define __HDLC_IOCTL_H__ 2#define __HDLC_IOCTL_H__
3 3
4
5#define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */
6
7#define CLOCK_DEFAULT 0 /* Default setting */
8#define CLOCK_EXT 1 /* External TX and RX clock - DTE */
9#define CLOCK_INT 2 /* Internal TX and RX clock - DCE */
10#define CLOCK_TXINT 3 /* Internal TX and external RX clock */
11#define CLOCK_TXFROMRX 4 /* TX clock derived from external RX clock */
12
13
14#define ENCODING_DEFAULT 0 /* Default setting */
15#define ENCODING_NRZ 1
16#define ENCODING_NRZI 2
17#define ENCODING_FM_MARK 3
18#define ENCODING_FM_SPACE 4
19#define ENCODING_MANCHESTER 5
20
21
22#define PARITY_DEFAULT 0 /* Default setting */
23#define PARITY_NONE 1 /* No parity */
24#define PARITY_CRC16_PR0 2 /* CRC16, initial value 0x0000 */
25#define PARITY_CRC16_PR1 3 /* CRC16, initial value 0xFFFF */
26#define PARITY_CRC16_PR0_CCITT 4 /* CRC16, initial 0x0000, ITU-T version */
27#define PARITY_CRC16_PR1_CCITT 5 /* CRC16, initial 0xFFFF, ITU-T version */
28#define PARITY_CRC32_PR0_CCITT 6 /* CRC32, initial value 0x00000000 */
29#define PARITY_CRC32_PR1_CCITT 7 /* CRC32, initial value 0xFFFFFFFF */
30
31#define LMI_DEFAULT 0 /* Default setting */
32#define LMI_NONE 1 /* No LMI, all PVCs are static */
33#define LMI_ANSI 2 /* ANSI Annex D */
34#define LMI_CCITT 3 /* ITU-T Annex A */
35#define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */
36
4typedef struct { 37typedef struct {
5 unsigned int clock_rate; /* bits per second */ 38 unsigned int clock_rate; /* bits per second */
6 unsigned int clock_type; /* internal, external, TX-internal etc. */ 39 unsigned int clock_type; /* internal, external, TX-internal etc. */
diff --git a/include/linux/if.h b/include/linux/if.h
index cd080d765324..8018c2e22c0c 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -59,6 +59,8 @@
59#define IFF_SLAVE_INACTIVE 0x4 /* bonding slave not the curr. active */ 59#define IFF_SLAVE_INACTIVE 0x4 /* bonding slave not the curr. active */
60#define IFF_MASTER_8023AD 0x8 /* bonding master, 802.3ad. */ 60#define IFF_MASTER_8023AD 0x8 /* bonding master, 802.3ad. */
61#define IFF_MASTER_ALB 0x10 /* bonding master, balance-alb. */ 61#define IFF_MASTER_ALB 0x10 /* bonding master, balance-alb. */
62#define IFF_BONDING 0x20 /* bonding master or slave */
63#define IFF_SLAVE_NEEDARP 0x40 /* need ARPs for validation */
62 64
63#define IF_GET_IFACE 0x0001 /* for querying only */ 65#define IF_GET_IFACE 0x0001 /* for querying only */
64#define IF_GET_PROTO 0x0002 66#define IF_GET_PROTO 0x0002
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 43289127b458..13d6d4eb8b3a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -334,7 +334,6 @@ struct net_device
334 334
335 335
336 struct net_device_stats* (*get_stats)(struct net_device *dev); 336 struct net_device_stats* (*get_stats)(struct net_device *dev);
337 struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
338 337
339 /* List of functions to handle Wireless Extensions (instead of ioctl). 338 /* List of functions to handle Wireless Extensions (instead of ioctl).
340 * See <net/iw_handler.h> for details. Jean II */ 339 * See <net/iw_handler.h> for details. Jean II */
@@ -1016,7 +1015,8 @@ static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
1016} 1015}
1017 1016
1018/* On bonding slaves other than the currently active slave, suppress 1017/* On bonding slaves other than the currently active slave, suppress
1019 * duplicates except for 802.3ad ETH_P_SLOW and alb non-mcast/bcast. 1018 * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
1019 * ARP on active-backup slaves with arp_validate enabled.
1020 */ 1020 */
1021static inline int skb_bond_should_drop(struct sk_buff *skb) 1021static inline int skb_bond_should_drop(struct sk_buff *skb)
1022{ 1022{
@@ -1025,6 +1025,10 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
1025 1025
1026 if (master && 1026 if (master &&
1027 (dev->priv_flags & IFF_SLAVE_INACTIVE)) { 1027 (dev->priv_flags & IFF_SLAVE_INACTIVE)) {
1028 if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
1029 skb->protocol == __constant_htons(ETH_P_ARP))
1030 return 0;
1031
1028 if (master->priv_flags & IFF_MASTER_ALB) { 1032 if (master->priv_flags & IFF_MASTER_ALB) {
1029 if (skb->pkt_type != PACKET_BROADCAST && 1033 if (skb->pkt_type != PACKET_BROADCAST &&
1030 skb->pkt_type != PACKET_MULTICAST) 1034 skb->pkt_type != PACKET_MULTICAST)
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 13588564b42b..a50a0130fd9e 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file define a set of standard wireless extensions 2 * This file define a set of standard wireless extensions
3 * 3 *
4 * Version : 20 17.2.06 4 * Version : 21 14.3.06
5 * 5 *
6 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> 6 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
7 * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved. 7 * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
@@ -69,9 +69,14 @@
69 69
70/***************************** INCLUDES *****************************/ 70/***************************** INCLUDES *****************************/
71 71
72/* This header is used in user-space, therefore need to be sanitised
73 * for that purpose. Those includes are usually not compatible with glibc.
74 * To know which includes to use in user-space, check iwlib.h. */
75#ifdef __KERNEL__
72#include <linux/types.h> /* for "caddr_t" et al */ 76#include <linux/types.h> /* for "caddr_t" et al */
73#include <linux/socket.h> /* for "struct sockaddr" et al */ 77#include <linux/socket.h> /* for "struct sockaddr" et al */
74#include <linux/if.h> /* for IFNAMSIZ and co... */ 78#include <linux/if.h> /* for IFNAMSIZ and co... */
79#endif /* __KERNEL__ */
75 80
76/***************************** VERSION *****************************/ 81/***************************** VERSION *****************************/
77/* 82/*
@@ -80,7 +85,7 @@
80 * (there is some stuff that will be added in the future...) 85 * (there is some stuff that will be added in the future...)
81 * I just plan to increment with each new version. 86 * I just plan to increment with each new version.
82 */ 87 */
83#define WIRELESS_EXT 20 88#define WIRELESS_EXT 21
84 89
85/* 90/*
86 * Changes : 91 * Changes :
@@ -208,6 +213,14 @@
208 * V19 to V20 213 * V19 to V20
209 * ---------- 214 * ----------
210 * - RtNetlink requests support (SET/GET) 215 * - RtNetlink requests support (SET/GET)
216 *
217 * V20 to V21
218 * ----------
219 * - Remove (struct net_device *)->get_wireless_stats()
220 * - Change length in ESSID and NICK to strlen() instead of strlen()+1
221 * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
222 * - Power/Retry relative values no longer * 100000
223 * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
211 */ 224 */
212 225
213/**************************** CONSTANTS ****************************/ 226/**************************** CONSTANTS ****************************/
@@ -448,6 +461,7 @@
448#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ 461#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
449#define IW_QUAL_LEVEL_INVALID 0x20 462#define IW_QUAL_LEVEL_INVALID 0x20
450#define IW_QUAL_NOISE_INVALID 0x40 463#define IW_QUAL_NOISE_INVALID 0x40
464#define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */
451#define IW_QUAL_ALL_INVALID 0x70 465#define IW_QUAL_ALL_INVALID 0x70
452 466
453/* Frequency flags */ 467/* Frequency flags */
@@ -500,10 +514,12 @@
500#define IW_RETRY_TYPE 0xF000 /* Type of parameter */ 514#define IW_RETRY_TYPE 0xF000 /* Type of parameter */
501#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ 515#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/
502#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ 516#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */
503#define IW_RETRY_MODIFIER 0x000F /* Modify a parameter */ 517#define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */
504#define IW_RETRY_MIN 0x0001 /* Value is a minimum */ 518#define IW_RETRY_MIN 0x0001 /* Value is a minimum */
505#define IW_RETRY_MAX 0x0002 /* Value is a maximum */ 519#define IW_RETRY_MAX 0x0002 /* Value is a maximum */
506#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ 520#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
521#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */
522#define IW_RETRY_LONG 0x0020 /* Value is for long packets */
507 523
508/* Scanning request flags */ 524/* Scanning request flags */
509#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ 525#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
@@ -1017,7 +1033,7 @@ struct iw_range
1017 /* Note : this frequency list doesn't need to fit channel numbers, 1033 /* Note : this frequency list doesn't need to fit channel numbers,
1018 * because each entry contain its channel index */ 1034 * because each entry contain its channel index */
1019 1035
1020 __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ 1036 __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
1021}; 1037};
1022 1038
1023/* 1039/*
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 13472762b18b..f47f319bb7dc 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -344,8 +344,6 @@ static ssize_t wireless_show(struct class_device *cd, char *buf,
344 if(dev->wireless_handlers && 344 if(dev->wireless_handlers &&
345 dev->wireless_handlers->get_wireless_stats) 345 dev->wireless_handlers->get_wireless_stats)
346 iw = dev->wireless_handlers->get_wireless_stats(dev); 346 iw = dev->wireless_handlers->get_wireless_stats(dev);
347 else if (dev->get_wireless_stats)
348 iw = dev->get_wireless_stats(dev);
349 if (iw != NULL) 347 if (iw != NULL)
350 ret = (*format)(iw, buf); 348 ret = (*format)(iw, buf);
351 } 349 }
@@ -465,8 +463,7 @@ int netdev_register_sysfs(struct net_device *net)
465 *groups++ = &netstat_group; 463 *groups++ = &netstat_group;
466 464
467#ifdef WIRELESS_EXT 465#ifdef WIRELESS_EXT
468 if (net->get_wireless_stats 466 if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)
469 || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats))
470 *groups++ = &wireless_group; 467 *groups++ = &wireless_group;
471#endif 468#endif
472 469
diff --git a/net/core/wireless.c b/net/core/wireless.c
index 3168fca312f7..ffff0da46c6e 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -68,6 +68,14 @@
68 * 68 *
69 * v8 - 17.02.06 - Jean II 69 * v8 - 17.02.06 - Jean II
70 * o RtNetlink requests support (SET/GET) 70 * o RtNetlink requests support (SET/GET)
71 *
72 * v8b - 03.08.06 - Herbert Xu
73 * o Fix Wireless Event locking issues.
74 *
75 * v9 - 14.3.06 - Jean II
76 * o Change length in ESSID and NICK to strlen() instead of strlen()+1
77 * o Make standard_ioctl_num and standard_event_num unsigned
78 * o Remove (struct net_device *)->get_wireless_stats()
71 */ 79 */
72 80
73/***************************** INCLUDES *****************************/ 81/***************************** INCLUDES *****************************/
@@ -234,24 +242,24 @@ static const struct iw_ioctl_description standard_ioctl[] = {
234 [SIOCSIWESSID - SIOCIWFIRST] = { 242 [SIOCSIWESSID - SIOCIWFIRST] = {
235 .header_type = IW_HEADER_TYPE_POINT, 243 .header_type = IW_HEADER_TYPE_POINT,
236 .token_size = 1, 244 .token_size = 1,
237 .max_tokens = IW_ESSID_MAX_SIZE + 1, 245 .max_tokens = IW_ESSID_MAX_SIZE,
238 .flags = IW_DESCR_FLAG_EVENT, 246 .flags = IW_DESCR_FLAG_EVENT,
239 }, 247 },
240 [SIOCGIWESSID - SIOCIWFIRST] = { 248 [SIOCGIWESSID - SIOCIWFIRST] = {
241 .header_type = IW_HEADER_TYPE_POINT, 249 .header_type = IW_HEADER_TYPE_POINT,
242 .token_size = 1, 250 .token_size = 1,
243 .max_tokens = IW_ESSID_MAX_SIZE + 1, 251 .max_tokens = IW_ESSID_MAX_SIZE,
244 .flags = IW_DESCR_FLAG_DUMP, 252 .flags = IW_DESCR_FLAG_DUMP,
245 }, 253 },
246 [SIOCSIWNICKN - SIOCIWFIRST] = { 254 [SIOCSIWNICKN - SIOCIWFIRST] = {
247 .header_type = IW_HEADER_TYPE_POINT, 255 .header_type = IW_HEADER_TYPE_POINT,
248 .token_size = 1, 256 .token_size = 1,
249 .max_tokens = IW_ESSID_MAX_SIZE + 1, 257 .max_tokens = IW_ESSID_MAX_SIZE,
250 }, 258 },
251 [SIOCGIWNICKN - SIOCIWFIRST] = { 259 [SIOCGIWNICKN - SIOCIWFIRST] = {
252 .header_type = IW_HEADER_TYPE_POINT, 260 .header_type = IW_HEADER_TYPE_POINT,
253 .token_size = 1, 261 .token_size = 1,
254 .max_tokens = IW_ESSID_MAX_SIZE + 1, 262 .max_tokens = IW_ESSID_MAX_SIZE,
255 }, 263 },
256 [SIOCSIWRATE - SIOCIWFIRST] = { 264 [SIOCSIWRATE - SIOCIWFIRST] = {
257 .header_type = IW_HEADER_TYPE_PARAM, 265 .header_type = IW_HEADER_TYPE_PARAM,
@@ -338,8 +346,8 @@ static const struct iw_ioctl_description standard_ioctl[] = {
338 .max_tokens = sizeof(struct iw_pmksa), 346 .max_tokens = sizeof(struct iw_pmksa),
339 }, 347 },
340}; 348};
341static const int standard_ioctl_num = (sizeof(standard_ioctl) / 349static const unsigned standard_ioctl_num = (sizeof(standard_ioctl) /
342 sizeof(struct iw_ioctl_description)); 350 sizeof(struct iw_ioctl_description));
343 351
344/* 352/*
345 * Meta-data about all the additional standard Wireless Extension events 353 * Meta-data about all the additional standard Wireless Extension events
@@ -389,8 +397,8 @@ static const struct iw_ioctl_description standard_event[] = {
389 .max_tokens = sizeof(struct iw_pmkid_cand), 397 .max_tokens = sizeof(struct iw_pmkid_cand),
390 }, 398 },
391}; 399};
392static const int standard_event_num = (sizeof(standard_event) / 400static const unsigned standard_event_num = (sizeof(standard_event) /
393 sizeof(struct iw_ioctl_description)); 401 sizeof(struct iw_ioctl_description));
394 402
395/* Size (in bytes) of the various private data types */ 403/* Size (in bytes) of the various private data types */
396static const char iw_priv_type_size[] = { 404static const char iw_priv_type_size[] = {
@@ -465,17 +473,6 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
465 (dev->wireless_handlers->get_wireless_stats != NULL)) 473 (dev->wireless_handlers->get_wireless_stats != NULL))
466 return dev->wireless_handlers->get_wireless_stats(dev); 474 return dev->wireless_handlers->get_wireless_stats(dev);
467 475
468 /* Old location, field to be removed in next WE */
469 if(dev->get_wireless_stats) {
470 static int printed_message;
471
472 if (!printed_message++)
473 printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n",
474 dev->name);
475
476 return dev->get_wireless_stats(dev);
477 }
478
479 /* Not found */ 476 /* Not found */
480 return (struct iw_statistics *) NULL; 477 return (struct iw_statistics *) NULL;
481} 478}
@@ -1843,8 +1840,33 @@ int wireless_rtnetlink_set(struct net_device * dev,
1843 */ 1840 */
1844 1841
1845#ifdef WE_EVENT_RTNETLINK 1842#ifdef WE_EVENT_RTNETLINK
1843/* ---------------------------------------------------------------- */
1844/*
1845 * Locking...
1846 * ----------
1847 *
1848 * Thanks to Herbert Xu <herbert@gondor.apana.org.au> for fixing
1849 * the locking issue in here and implementing this code !
1850 *
1851 * The issue : wireless_send_event() is often called in interrupt context,
1852 * while the Netlink layer can never be called in interrupt context.
1853 * The fully formed RtNetlink events are queued, and then a tasklet is run
1854 * to feed those to Netlink.
1855 * The skb_queue is interrupt safe, and its lock is not held while calling
1856 * Netlink, so there is no possibility of dealock.
1857 * Jean II
1858 */
1859
1846static struct sk_buff_head wireless_nlevent_queue; 1860static struct sk_buff_head wireless_nlevent_queue;
1847 1861
1862static int __init wireless_nlevent_init(void)
1863{
1864 skb_queue_head_init(&wireless_nlevent_queue);
1865 return 0;
1866}
1867
1868subsys_initcall(wireless_nlevent_init);
1869
1848static void wireless_nlevent_process(unsigned long data) 1870static void wireless_nlevent_process(unsigned long data)
1849{ 1871{
1850 struct sk_buff *skb; 1872 struct sk_buff *skb;
@@ -1921,13 +1943,6 @@ static inline void rtmsg_iwinfo(struct net_device * dev,
1921 tasklet_schedule(&wireless_nlevent_tasklet); 1943 tasklet_schedule(&wireless_nlevent_tasklet);
1922} 1944}
1923 1945
1924static int __init wireless_nlevent_init(void)
1925{
1926 skb_queue_head_init(&wireless_nlevent_queue);
1927 return 0;
1928}
1929
1930subsys_initcall(wireless_nlevent_init);
1931#endif /* WE_EVENT_RTNETLINK */ 1946#endif /* WE_EVENT_RTNETLINK */
1932 1947
1933/* ---------------------------------------------------------------- */ 1948/* ---------------------------------------------------------------- */
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 75320b6842ab..2aa779d18f38 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -80,10 +80,10 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
80 * If it's our network, ignore the change, we're already doing it! 80 * If it's our network, ignore the change, we're already doing it!
81 */ 81 */
82 if((sm->associnfo.associating || sm->associated) && 82 if((sm->associnfo.associating || sm->associated) &&
83 (data->essid.flags && data->essid.length && extra)) { 83 (data->essid.flags && data->essid.length)) {
84 /* Get the associating network */ 84 /* Get the associating network */
85 n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); 85 n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
86 if(n && n->essid.len == (data->essid.length - 1) && 86 if(n && n->essid.len == data->essid.length &&
87 !memcmp(n->essid.data, extra, n->essid.len)) { 87 !memcmp(n->essid.data, extra, n->essid.len)) {
88 dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", 88 dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
89 MAC_ARG(sm->associnfo.bssid)); 89 MAC_ARG(sm->associnfo.bssid));
@@ -109,8 +109,8 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
109 sm->associnfo.static_essid = 0; 109 sm->associnfo.static_essid = 0;
110 sm->associnfo.assoc_wait = 0; 110 sm->associnfo.assoc_wait = 0;
111 111
112 if (data->essid.flags && data->essid.length && extra /*required?*/) { 112 if (data->essid.flags && data->essid.length) {
113 length = min(data->essid.length - 1, IW_ESSID_MAX_SIZE); 113 length = min((int)data->essid.length, IW_ESSID_MAX_SIZE);
114 if (length) { 114 if (length) {
115 memcpy(sm->associnfo.req_essid.data, extra, length); 115 memcpy(sm->associnfo.req_essid.data, extra, length);
116 sm->associnfo.static_essid = 1; 116 sm->associnfo.static_essid = 1;