mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits)
  qlcnic: adding co maintainer
  ixgbe: add support for active DA cables
  ixgbe: dcb, do not tag tc_prio_control frames
  ixgbe: fix ixgbe_tx_is_paused logic
  ixgbe: always enable vlan strip/insert when DCB is enabled
  ixgbe: remove some redundant code in setting FCoE FIP filter
  ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp
  ixgbe: fix header len when unsplit packet overflows to data buffer
  ipv6: Never schedule DAD timer on dead address
  ipv6: Use POSTDAD state
  ipv6: Use state_lock to protect ifa state
  ipv6: Replace inet6_ifaddr->dead with state
  cxgb4: notify upper drivers if the device is already up when they load
  cxgb4: keep interrupts available when the ports are brought down
  cxgb4: fix initial addition of MAC address
  cnic: Return SPQ credit to bnx2x after ring setup and shutdown.
  cnic: Convert cnic_local_flags to atomic ops.
  can: Fix SJA1000 command register writes on SMP systems
  bridge: fix build for CONFIG_SYSFS disabled
  ARCNET: Limit com20020 PCI ID matches for SOHARD cards
  ...
Fix up various conflicts with pcmcia tree drivers/net/
{pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and
wireless/orinoco/spectrum_cs.c} and feature removal
(Documentation/feature-removal-schedule.txt).
Also fix a non-content conflict due to pm_qos_requirement getting
renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
			
			
This commit is contained in:
		
						commit
						f8965467f3
					
				
					 1455 changed files with 95973 additions and 48342 deletions
				
			
		
							
								
								
									
										29
									
								
								Documentation/ABI/obsolete/sysfs-class-rfkill
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Documentation/ABI/obsolete/sysfs-class-rfkill
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					rfkill - radio frequency (RF) connector kill switch support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For details to this subsystem look at Documentation/rfkill.txt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:		/sys/class/rfkill/rfkill[0-9]+/state
 | 
				
			||||||
 | 
					Date:		09-Jul-2007
 | 
				
			||||||
 | 
					KernelVersion	v2.6.22
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org
 | 
				
			||||||
 | 
					Description: 	Current state of the transmitter.
 | 
				
			||||||
 | 
							This file is deprecated and sheduled to be removed in 2014,
 | 
				
			||||||
 | 
							because its not possible to express the 'soft and hard block'
 | 
				
			||||||
 | 
							state of the rfkill driver.
 | 
				
			||||||
 | 
					Values: 	A numeric value.
 | 
				
			||||||
 | 
							0: RFKILL_STATE_SOFT_BLOCKED
 | 
				
			||||||
 | 
								transmitter is turned off by software
 | 
				
			||||||
 | 
							1: RFKILL_STATE_UNBLOCKED
 | 
				
			||||||
 | 
								transmitter is (potentially) active
 | 
				
			||||||
 | 
							2: RFKILL_STATE_HARD_BLOCKED
 | 
				
			||||||
 | 
								transmitter is forced off by something outside of
 | 
				
			||||||
 | 
								the driver's control.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:		/sys/class/rfkill/rfkill[0-9]+/claim
 | 
				
			||||||
 | 
					Date:		09-Jul-2007
 | 
				
			||||||
 | 
					KernelVersion	v2.6.22
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org
 | 
				
			||||||
 | 
					Description:	This file is deprecated because there no longer is a way to
 | 
				
			||||||
 | 
							claim just control over a single rfkill instance.
 | 
				
			||||||
 | 
							This file is scheduled to be removed in 2012.
 | 
				
			||||||
 | 
					Values: 	0: Kernel handles events
 | 
				
			||||||
							
								
								
									
										67
									
								
								Documentation/ABI/stable/sysfs-class-rfkill
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Documentation/ABI/stable/sysfs-class-rfkill
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,67 @@
 | 
				
			||||||
 | 
					rfkill - radio frequency (RF) connector kill switch support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For details to this subsystem look at Documentation/rfkill.txt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the deprecated /sys/class/rfkill/*/state and
 | 
				
			||||||
 | 
					/sys/class/rfkill/*/claim knobs of this interface look in
 | 
				
			||||||
 | 
					Documentation/ABI/obsolete/sysfs-class-rfkill.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What: 		/sys/class/rfkill
 | 
				
			||||||
 | 
					Date:		09-Jul-2007
 | 
				
			||||||
 | 
					KernelVersion:	v2.6.22
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org,
 | 
				
			||||||
 | 
					Description: 	The rfkill class subsystem folder.
 | 
				
			||||||
 | 
							Each registered rfkill driver is represented by an rfkillX
 | 
				
			||||||
 | 
							subfolder (X being an integer > 0).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:		/sys/class/rfkill/rfkill[0-9]+/name
 | 
				
			||||||
 | 
					Date:		09-Jul-2007
 | 
				
			||||||
 | 
					KernelVersion	v2.6.22
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org
 | 
				
			||||||
 | 
					Description: 	Name assigned by driver to this key (interface or driver name).
 | 
				
			||||||
 | 
					Values: 	arbitrary string.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What: 		/sys/class/rfkill/rfkill[0-9]+/type
 | 
				
			||||||
 | 
					Date:		09-Jul-2007
 | 
				
			||||||
 | 
					KernelVersion	v2.6.22
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org
 | 
				
			||||||
 | 
					Description: 	Driver type string ("wlan", "bluetooth", etc).
 | 
				
			||||||
 | 
					Values: 	See include/linux/rfkill.h.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:		/sys/class/rfkill/rfkill[0-9]+/persistent
 | 
				
			||||||
 | 
					Date:		09-Jul-2007
 | 
				
			||||||
 | 
					KernelVersion	v2.6.22
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org
 | 
				
			||||||
 | 
					Description: 	Whether the soft blocked state is initialised from non-volatile
 | 
				
			||||||
 | 
							storage at startup.
 | 
				
			||||||
 | 
					Values: 	A numeric value.
 | 
				
			||||||
 | 
							0: false
 | 
				
			||||||
 | 
							1: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:		/sys/class/rfkill/rfkill[0-9]+/hard
 | 
				
			||||||
 | 
					Date:		12-March-2010
 | 
				
			||||||
 | 
					KernelVersion	v2.6.34
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org
 | 
				
			||||||
 | 
					Description: 	Current hardblock state. This file is read only.
 | 
				
			||||||
 | 
					Values: 	A numeric value.
 | 
				
			||||||
 | 
							0: inactive
 | 
				
			||||||
 | 
								The transmitter is (potentially) active.
 | 
				
			||||||
 | 
							1: active
 | 
				
			||||||
 | 
								The transmitter is forced off by something outside of
 | 
				
			||||||
 | 
								the driver's control.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:		/sys/class/rfkill/rfkill[0-9]+/soft
 | 
				
			||||||
 | 
					Date:		12-March-2010
 | 
				
			||||||
 | 
					KernelVersion	v2.6.34
 | 
				
			||||||
 | 
					Contact:	linux-wireless@vger.kernel.org
 | 
				
			||||||
 | 
					Description:	Current softblock state. This file is read and write.
 | 
				
			||||||
 | 
					Values: 	A numeric value.
 | 
				
			||||||
 | 
							0: inactive
 | 
				
			||||||
 | 
								The transmitter is (potentially) active.
 | 
				
			||||||
 | 
							1: active
 | 
				
			||||||
 | 
								The transmitter is turned off by software.
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ o  oprofile               0.9                     # oprofiled --version
 | 
				
			||||||
o  udev                   081                     # udevinfo -V
 | 
					o  udev                   081                     # udevinfo -V
 | 
				
			||||||
o  grub                   0.93                    # grub --version
 | 
					o  grub                   0.93                    # grub --version
 | 
				
			||||||
o  mcelog		  0.6
 | 
					o  mcelog		  0.6
 | 
				
			||||||
o  iptables               1.4.1                   # iptables -V
 | 
					o  iptables               1.4.2                   # iptables -V
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Kernel compilation
 | 
					Kernel compilation
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -241,16 +241,6 @@ Who:	Thomas Gleixner <tglx@linutronix.de>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---------------------------
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
What (Why):
 | 
					 | 
				
			||||||
	- xt_recent: the old ipt_recent proc dir
 | 
					 | 
				
			||||||
	  (superseded by /proc/net/xt_recent)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When:	January 2009 or Linux 2.7.0, whichever comes first
 | 
					 | 
				
			||||||
Why:	Superseded by newer revisions or modules
 | 
					 | 
				
			||||||
Who:	Jan Engelhardt <jengelh@computergmbh.de>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
What:	GPIO autorequest on gpio_direction_{input,output}() in gpiolib
 | 
					What:	GPIO autorequest on gpio_direction_{input,output}() in gpiolib
 | 
				
			||||||
When:	February 2010
 | 
					When:	February 2010
 | 
				
			||||||
Why:	All callers should use explicit gpio_request()/gpio_free().
 | 
					Why:	All callers should use explicit gpio_request()/gpio_free().
 | 
				
			||||||
| 
						 | 
					@ -520,6 +510,24 @@ Who:	Hans de Goede <hdegoede@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
----------------------------
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:	sysfs-class-rfkill state file
 | 
				
			||||||
 | 
					When:	Feb 2014
 | 
				
			||||||
 | 
					Files:	net/rfkill/core.c
 | 
				
			||||||
 | 
					Why: 	Documented as obsolete since Feb 2010. This file is limited to 3
 | 
				
			||||||
 | 
						states while the rfkill drivers can have 4 states.
 | 
				
			||||||
 | 
					Who: 	anybody or Florian Mickler <florian@mickler.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What: 	sysfs-class-rfkill claim file
 | 
				
			||||||
 | 
					When:	Feb 2012
 | 
				
			||||||
 | 
					Files:	net/rfkill/core.c
 | 
				
			||||||
 | 
					Why:	It is not possible to claim an rfkill driver since 2007. This is
 | 
				
			||||||
 | 
						Documented as obsolete since Feb 2010.
 | 
				
			||||||
 | 
					Who: 	anybody or Florian Mickler <florian@mickler.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
What:	capifs
 | 
					What:	capifs
 | 
				
			||||||
When:	February 2011
 | 
					When:	February 2011
 | 
				
			||||||
Files:	drivers/isdn/capi/capifs.*
 | 
					Files:	drivers/isdn/capi/capifs.*
 | 
				
			||||||
| 
						 | 
					@ -579,6 +587,35 @@ Who:	Len Brown <len.brown@intel.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
----------------------------
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:	iwlwifi 50XX module parameters
 | 
				
			||||||
 | 
					When:	2.6.40
 | 
				
			||||||
 | 
					Why:	The "..50" modules parameters were used to configure 5000 series and
 | 
				
			||||||
 | 
						up devices; different set of module parameters also available for 4965
 | 
				
			||||||
 | 
						with same functionalities. Consolidate both set into single place
 | 
				
			||||||
 | 
						in drivers/net/wireless/iwlwifi/iwl-agn.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Who:	Wey-Yi Guy <wey-yi.w.guy@intel.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:	iwl4965 alias support
 | 
				
			||||||
 | 
					When:	2.6.40
 | 
				
			||||||
 | 
					Why:	Internal alias support has been present in module-init-tools for some
 | 
				
			||||||
 | 
						time, the MODULE_ALIAS("iwl4965") boilerplate aliases can be removed
 | 
				
			||||||
 | 
						with no impact.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Who:	Wey-Yi Guy <wey-yi.w.guy@intel.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:	xt_NOTRACK
 | 
				
			||||||
 | 
					Files:	net/netfilter/xt_NOTRACK.c
 | 
				
			||||||
 | 
					When:	April 2011
 | 
				
			||||||
 | 
					Why:	Superseded by xt_CT
 | 
				
			||||||
 | 
					Who:	Netfilter developer team <netfilter-devel@vger.kernel.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
What:	video4linux /dev/vtx teletext API support
 | 
					What:	video4linux /dev/vtx teletext API support
 | 
				
			||||||
When:	2.6.35
 | 
					When:	2.6.35
 | 
				
			||||||
Files:	drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
 | 
					Files:	drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										212
									
								
								Documentation/networking/caif/Linux-CAIF.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								Documentation/networking/caif/Linux-CAIF.txt
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,212 @@
 | 
				
			||||||
 | 
					Linux CAIF
 | 
				
			||||||
 | 
					===========
 | 
				
			||||||
 | 
					copyright (C) ST-Ericsson AB 2010
 | 
				
			||||||
 | 
					Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
 | 
				
			||||||
 | 
					License terms: GNU General Public License (GPL) version 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Introduction
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					CAIF is a MUX protocol used by ST-Ericsson cellular modems for
 | 
				
			||||||
 | 
					communication between Modem and host. The host processes can open virtual AT
 | 
				
			||||||
 | 
					channels, initiate GPRS Data connections, Video channels and Utility Channels.
 | 
				
			||||||
 | 
					The Utility Channels are general purpose pipes between modem and host.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ST-Ericsson modems support a number of transports between modem
 | 
				
			||||||
 | 
					and host. Currently, UART and Loopback are available for Linux.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Architecture:
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					The implementation of CAIF is divided into:
 | 
				
			||||||
 | 
					* CAIF Socket Layer, Kernel API, and  Net Device.
 | 
				
			||||||
 | 
					* CAIF Core Protocol Implementation
 | 
				
			||||||
 | 
					* CAIF Link Layer, implemented as NET devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  RTNL
 | 
				
			||||||
 | 
					   !
 | 
				
			||||||
 | 
					   !	 +------+   +------+   +------+
 | 
				
			||||||
 | 
					   !	+------+!  +------+!  +------+!
 | 
				
			||||||
 | 
					   !	! Sock !!  !Kernel!!  ! Net  !!
 | 
				
			||||||
 | 
					   !	! API  !+  ! API  !+  ! Dev  !+	  <- CAIF Client APIs
 | 
				
			||||||
 | 
					   !	+------+   +------!   +------+
 | 
				
			||||||
 | 
					   !	   !	      !		 !
 | 
				
			||||||
 | 
					   !	   +----------!----------+
 | 
				
			||||||
 | 
					   !		   +------+		  <- CAIF Protocol Implementation
 | 
				
			||||||
 | 
					   +------->	   ! CAIF !
 | 
				
			||||||
 | 
							   ! Core !
 | 
				
			||||||
 | 
							   +------+
 | 
				
			||||||
 | 
						     +--------!--------+
 | 
				
			||||||
 | 
						     !		       !
 | 
				
			||||||
 | 
						  +------+	    +-----+
 | 
				
			||||||
 | 
						  !    	 !	    ! TTY !	  <- Link Layer (Net Devices)
 | 
				
			||||||
 | 
						  +------+	    +-----+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Using the Kernel API
 | 
				
			||||||
 | 
					----------------------
 | 
				
			||||||
 | 
					The Kernel API is used for accessing CAIF channels from the
 | 
				
			||||||
 | 
					kernel.
 | 
				
			||||||
 | 
					The user of the API has to implement two callbacks for receive
 | 
				
			||||||
 | 
					and control.
 | 
				
			||||||
 | 
					The receive callback gives a CAIF packet as a SKB. The control
 | 
				
			||||||
 | 
					callback will
 | 
				
			||||||
 | 
					notify of channel initialization complete, and flow-on/flow-
 | 
				
			||||||
 | 
					off.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct caif_device caif_dev = {
 | 
				
			||||||
 | 
					    .caif_config = {
 | 
				
			||||||
 | 
					     .name = "MYDEV"
 | 
				
			||||||
 | 
					     .type = CAIF_CHTY_AT
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					   .receive_cb = my_receive,
 | 
				
			||||||
 | 
					   .control_cb = my_control,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  caif_add_device(&caif_dev);
 | 
				
			||||||
 | 
					  caif_transmit(&caif_dev, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the caif_kernel.h for details about the CAIF kernel API.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I M P L E M E N T A T I O N
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CAIF Core Protocol Layer
 | 
				
			||||||
 | 
					=========================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson.
 | 
				
			||||||
 | 
					It implements the CAIF protocol stack in a layered approach, where
 | 
				
			||||||
 | 
					each layer described in the specification is implemented as a separate layer.
 | 
				
			||||||
 | 
					The architecture is inspired by the design patterns "Protocol Layer" and
 | 
				
			||||||
 | 
					"Protocol Packet".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== CAIF structure ==
 | 
				
			||||||
 | 
					The Core CAIF implementation contains:
 | 
				
			||||||
 | 
					      -	Simple implementation of CAIF.
 | 
				
			||||||
 | 
					      -	Layered architecture (a la Streams), each layer in the CAIF
 | 
				
			||||||
 | 
						specification is implemented in a separate c-file.
 | 
				
			||||||
 | 
					      -	Clients must implement PHY layer to access physical HW
 | 
				
			||||||
 | 
						with receive and transmit functions.
 | 
				
			||||||
 | 
					      -	Clients must call configuration function to add PHY layer.
 | 
				
			||||||
 | 
					      -	Clients must implement CAIF layer to consume/produce
 | 
				
			||||||
 | 
						CAIF payload with receive and transmit functions.
 | 
				
			||||||
 | 
					      -	Clients must call configuration function to add and connect the
 | 
				
			||||||
 | 
						Client layer.
 | 
				
			||||||
 | 
					      - When receiving / transmitting CAIF Packets (cfpkt), ownership is passed
 | 
				
			||||||
 | 
						to the called function (except for framing layers' receive functions
 | 
				
			||||||
 | 
						or if a transmit function returns an error, in which case the caller
 | 
				
			||||||
 | 
						must free the packet).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Layered Architecture
 | 
				
			||||||
 | 
					--------------------
 | 
				
			||||||
 | 
					The CAIF protocol can be divided into two parts: Support functions and Protocol
 | 
				
			||||||
 | 
					Implementation. The support functions include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFPKT CAIF Packet. Implementation of CAIF Protocol Packet. The
 | 
				
			||||||
 | 
						CAIF Packet has functions for creating, destroying and adding content
 | 
				
			||||||
 | 
						and for adding/extracting header and trailers to protocol packets.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFLST CAIF list implementation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFGLUE CAIF Glue. Contains OS Specifics, such as memory
 | 
				
			||||||
 | 
						allocation, endianness, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The CAIF Protocol implementation contains:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFCNFG CAIF Configuration layer. Configures the CAIF Protocol
 | 
				
			||||||
 | 
						Stack and provides a Client interface for adding Link-Layer and
 | 
				
			||||||
 | 
						Driver interfaces on top of the CAIF Stack.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFCTRL CAIF Control layer. Encodes and Decodes control messages
 | 
				
			||||||
 | 
						such as enumeration and channel setup. Also matches request and
 | 
				
			||||||
 | 
						response messages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFSERVL General CAIF Service Layer functionality; handles flow
 | 
				
			||||||
 | 
						control and remote shutdown requests.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual
 | 
				
			||||||
 | 
					        External Interface). This layer encodes/decodes VEI frames.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP
 | 
				
			||||||
 | 
						traffic), encodes/decodes Datagram frames.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFMUX CAIF Mux layer. Handles multiplexing between multiple
 | 
				
			||||||
 | 
						physical bearers and multiple channels such as VEI, Datagram, etc.
 | 
				
			||||||
 | 
						The MUX keeps track of the existing CAIF Channels and
 | 
				
			||||||
 | 
						Physical Instances and selects the apropriate instance based
 | 
				
			||||||
 | 
						on Channel-Id and Physical-ID.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFFRML CAIF Framing layer. Handles Framing i.e. Frame length
 | 
				
			||||||
 | 
						and frame checksum.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - CFSERL CAIF Serial layer. Handles concatenation/split of frames
 | 
				
			||||||
 | 
						into CAIF Frames with correct length.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							    +---------+
 | 
				
			||||||
 | 
							    | Config  |
 | 
				
			||||||
 | 
							    | CFCNFG  |
 | 
				
			||||||
 | 
							    +---------+
 | 
				
			||||||
 | 
								 !
 | 
				
			||||||
 | 
					    +---------+	    +---------+	    +---------+
 | 
				
			||||||
 | 
					    |	AT    |	    | Control |	    | Datagram|
 | 
				
			||||||
 | 
					    | CFVEIL  |	    | CFCTRL  |	    | CFDGML  |
 | 
				
			||||||
 | 
					    +---------+	    +---------+	    +---------+
 | 
				
			||||||
 | 
						   \_____________!______________/
 | 
				
			||||||
 | 
								 !
 | 
				
			||||||
 | 
							    +---------+
 | 
				
			||||||
 | 
							    |	MUX   |
 | 
				
			||||||
 | 
							    |	      |
 | 
				
			||||||
 | 
							    +---------+
 | 
				
			||||||
 | 
							    _____!_____
 | 
				
			||||||
 | 
							   /	       \
 | 
				
			||||||
 | 
						    +---------+	    +---------+
 | 
				
			||||||
 | 
						    | CFFRML  |	    | CFFRML  |
 | 
				
			||||||
 | 
						    | Framing |	    | Framing |
 | 
				
			||||||
 | 
						    +---------+	    +---------+
 | 
				
			||||||
 | 
							 !		!
 | 
				
			||||||
 | 
						    +---------+	    +---------+
 | 
				
			||||||
 | 
						    |         |	    | Serial  |
 | 
				
			||||||
 | 
						    |	      |	    | CFSERL  |
 | 
				
			||||||
 | 
						    +---------+	    +---------+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In this layered approach the following "rules" apply.
 | 
				
			||||||
 | 
					      - All layers embed the same structure "struct cflayer"
 | 
				
			||||||
 | 
					      - A layer does not depend on any other layer's private data.
 | 
				
			||||||
 | 
					      - Layers are stacked by setting the pointers
 | 
				
			||||||
 | 
							  layer->up , layer->dn
 | 
				
			||||||
 | 
					      -	In order to send data upwards, each layer should do
 | 
				
			||||||
 | 
							 layer->up->receive(layer->up, packet);
 | 
				
			||||||
 | 
					      - In order to send data downwards, each layer should do
 | 
				
			||||||
 | 
							 layer->dn->transmit(layer->dn, packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Linux Driver Implementation
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Linux GPRS Net Device and CAIF socket are implemented on top of the
 | 
				
			||||||
 | 
					CAIF Core protocol. The Net device and CAIF socket have an instance of
 | 
				
			||||||
 | 
					'struct cflayer', just like the CAIF Core protocol stack.
 | 
				
			||||||
 | 
					Net device and Socket implement the 'receive()' function defined by
 | 
				
			||||||
 | 
					'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and
 | 
				
			||||||
 | 
					receive of packets is handled as by the rest of the layers: the 'dn->transmit()'
 | 
				
			||||||
 | 
					function is called in order to transmit data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The layer on top of the CAIF Core implementation is
 | 
				
			||||||
 | 
					sometimes referred to as the "Client layer".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Configuration of Link Layer
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					The Link Layer is implemented as Linux net devices (struct net_device).
 | 
				
			||||||
 | 
					Payload handling and registration is done using standard Linux mechanisms.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The CAIF Protocol relies on a loss-less link layer without implementing
 | 
				
			||||||
 | 
					retransmission. This implies that packet drops must not happen.
 | 
				
			||||||
 | 
					Therefore a flow-control mechanism is implemented where the physical
 | 
				
			||||||
 | 
					interface can initiate flow stop for all CAIF Channels.
 | 
				
			||||||
							
								
								
									
										109
									
								
								Documentation/networking/caif/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								Documentation/networking/caif/README
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,109 @@
 | 
				
			||||||
 | 
					Copyright (C) ST-Ericsson AB 2010
 | 
				
			||||||
 | 
					Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
 | 
				
			||||||
 | 
					License terms: GNU General Public License (GPL) version 2
 | 
				
			||||||
 | 
					---------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Start ===
 | 
				
			||||||
 | 
					If you have compiled CAIF for modules do:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$modprobe crc_ccitt
 | 
				
			||||||
 | 
					$modprobe caif
 | 
				
			||||||
 | 
					$modprobe caif_socket
 | 
				
			||||||
 | 
					$modprobe chnl_net
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Preparing the setup with a STE modem ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are working on integration of CAIF you should make sure
 | 
				
			||||||
 | 
					that the kernel is built with module support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are some things that need to be tweaked to get the host TTY correctly
 | 
				
			||||||
 | 
					set up to talk to the modem.
 | 
				
			||||||
 | 
					Since the CAIF stack is running in the kernel and we want to use the existing
 | 
				
			||||||
 | 
					TTY, we are installing our physical serial driver as a line discipline above
 | 
				
			||||||
 | 
					the TTY device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To achieve this we need to install the N_CAIF ldisc from user space.
 | 
				
			||||||
 | 
					The benefit is that we can hook up to any TTY.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The use of Start-of-frame-extension (STX) must also be set as
 | 
				
			||||||
 | 
					module parameter "ser_use_stx".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Normally Frame Checksum is always used on UART, but this is also provided as a
 | 
				
			||||||
 | 
					module parameter "ser_use_fcs".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes
 | 
				
			||||||
 | 
					$ ifconfig caif_ttyS0 up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PLEASE NOTE: 	There is a limitation in Android shell.
 | 
				
			||||||
 | 
							It only accepts one argument to insmod/modprobe!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Trouble shooting ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are debugfs parameters provided for serial communication.
 | 
				
			||||||
 | 
					/sys/kernel/debug/caif_serial/<tty-name>/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* ser_state:   Prints the bit-mask status where
 | 
				
			||||||
 | 
					  - 0x02 means SENDING, this is a transient state.
 | 
				
			||||||
 | 
					  - 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent
 | 
				
			||||||
 | 
						and is blocking further send operation. Flow OFF has been propagated
 | 
				
			||||||
 | 
						to all CAIF Channels using this TTY.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* tty_status: Prints the bit-mask tty status information
 | 
				
			||||||
 | 
					  - 0x01 - tty->warned is on.
 | 
				
			||||||
 | 
					  - 0x02 - tty->low_latency is on.
 | 
				
			||||||
 | 
					  - 0x04 - tty->packed is on.
 | 
				
			||||||
 | 
					  - 0x08 - tty->flow_stopped is on.
 | 
				
			||||||
 | 
					  - 0x10 - tty->hw_stopped is on.
 | 
				
			||||||
 | 
					  - 0x20 - tty->stopped is on.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* last_tx_msg: Binary blob Prints the last transmitted frame.
 | 
				
			||||||
 | 
						This can be printed with
 | 
				
			||||||
 | 
						$od --format=x1 /sys/kernel/debug/caif_serial/<tty>/last_rx_msg.
 | 
				
			||||||
 | 
						The first two tx messages sent look like this. Note: The initial
 | 
				
			||||||
 | 
						byte 02 is start of frame extension (STX) used for re-syncing
 | 
				
			||||||
 | 
						upon errors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - Enumeration:
 | 
				
			||||||
 | 
					        0000000  02 05 00 00 03 01 d2 02
 | 
				
			||||||
 | 
					                 |  |     |  |  |  |
 | 
				
			||||||
 | 
					                 STX(1)   |  |  |  |
 | 
				
			||||||
 | 
					                    Length(2)|  |  |
 | 
				
			||||||
 | 
					                          Control Channel(1)
 | 
				
			||||||
 | 
					                             Command:Enumeration(1)
 | 
				
			||||||
 | 
					                                Link-ID(1)
 | 
				
			||||||
 | 
					                                    Checksum(2)
 | 
				
			||||||
 | 
					  - Channel Setup:
 | 
				
			||||||
 | 
					        0000000  02 07 00 00 00 21 a1 00 48 df
 | 
				
			||||||
 | 
					                 |  |     |  |  |  |  |  |
 | 
				
			||||||
 | 
					                 STX(1)   |  |  |  |  |  |
 | 
				
			||||||
 | 
					                    Length(2)|  |  |  |  |
 | 
				
			||||||
 | 
					                          Control Channel(1)
 | 
				
			||||||
 | 
					                             Command:Channel Setup(1)
 | 
				
			||||||
 | 
					                                Channel Type(1)
 | 
				
			||||||
 | 
					                                    Priority and Link-ID(1)
 | 
				
			||||||
 | 
									      Endpoint(1)
 | 
				
			||||||
 | 
										  Checksum(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* last_rx_msg: Prints the last transmitted frame.
 | 
				
			||||||
 | 
						The RX messages for LinkSetup look almost identical but they have the
 | 
				
			||||||
 | 
						bit 0x20 set in the command bit, and Channel Setup has added one byte
 | 
				
			||||||
 | 
						before Checksum containing Channel ID.
 | 
				
			||||||
 | 
						NOTE: Several CAIF Messages might be concatenated. The maximum debug
 | 
				
			||||||
 | 
						buffer size is 128 bytes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Error Scenarios:
 | 
				
			||||||
 | 
					- last_tx_msg contains channel setup message and last_rx_msg is empty ->
 | 
				
			||||||
 | 
					  The host seems to be able to send over the UART, at least the CAIF ldisc get
 | 
				
			||||||
 | 
					  notified that sending is completed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- last_tx_msg contains enumeration message and last_rx_msg is empty ->
 | 
				
			||||||
 | 
					  The host is not able to send the message from UART, the tty has not been
 | 
				
			||||||
 | 
					  able to complete the transmit operation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- if /sys/kernel/debug/caif_serial/<tty>/tty_status is non-zero there
 | 
				
			||||||
 | 
					  might be problems transmitting over UART.
 | 
				
			||||||
 | 
					  E.g. host and modem wiring is not correct you will typically see
 | 
				
			||||||
 | 
					  tty_status = 0x10 (hw_stopped) and ser_state = 0x10 (FLOW_OFF_SENT).
 | 
				
			||||||
 | 
					  You will probably see the enumeration message in last_tx_message
 | 
				
			||||||
 | 
					  and empty last_rx_message.
 | 
				
			||||||
| 
						 | 
					@ -588,6 +588,37 @@ ip_local_port_range - 2 INTEGERS
 | 
				
			||||||
	(i.e. by default) range 1024-4999 is enough to issue up to
 | 
						(i.e. by default) range 1024-4999 is enough to issue up to
 | 
				
			||||||
	2000 connections per second to systems supporting timestamps.
 | 
						2000 connections per second to systems supporting timestamps.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ip_local_reserved_ports - list of comma separated ranges
 | 
				
			||||||
 | 
						Specify the ports which are reserved for known third-party
 | 
				
			||||||
 | 
						applications. These ports will not be used by automatic port
 | 
				
			||||||
 | 
						assignments (e.g. when calling connect() or bind() with port
 | 
				
			||||||
 | 
						number 0). Explicit port allocation behavior is unchanged.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						The format used for both input and output is a comma separated
 | 
				
			||||||
 | 
						list of ranges (e.g. "1,2-4,10-10" for ports 1, 2, 3, 4 and
 | 
				
			||||||
 | 
						10). Writing to the file will clear all previously reserved
 | 
				
			||||||
 | 
						ports and update the current list with the one given in the
 | 
				
			||||||
 | 
						input.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Note that ip_local_port_range and ip_local_reserved_ports
 | 
				
			||||||
 | 
						settings are independent and both are considered by the kernel
 | 
				
			||||||
 | 
						when determining which ports are available for automatic port
 | 
				
			||||||
 | 
						assignments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						You can reserve ports which are not in the current
 | 
				
			||||||
 | 
						ip_local_port_range, e.g.:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						$ cat /proc/sys/net/ipv4/ip_local_port_range
 | 
				
			||||||
 | 
						32000	61000
 | 
				
			||||||
 | 
						$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
 | 
				
			||||||
 | 
						8080,9148
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						although this is redundant. However such a setting is useful
 | 
				
			||||||
 | 
						if later the port range is changed to a value that will
 | 
				
			||||||
 | 
						include the reserved ports.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Default: Empty
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ip_nonlocal_bind - BOOLEAN
 | 
					ip_nonlocal_bind - BOOLEAN
 | 
				
			||||||
	If set, allows processes to bind() to non-local IP addresses,
 | 
						If set, allows processes to bind() to non-local IP addresses,
 | 
				
			||||||
	which can be quite useful - but may break some applications.
 | 
						which can be quite useful - but may break some applications.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,44 +1,95 @@
 | 
				
			||||||
This brief document describes how to use the kernel's PPPoL2TP driver
 | 
					This document describes how to use the kernel's L2TP drivers to
 | 
				
			||||||
to provide L2TP functionality. L2TP is a protocol that tunnels one or
 | 
					provide L2TP functionality. L2TP is a protocol that tunnels one or
 | 
				
			||||||
more PPP sessions over a UDP tunnel. It is commonly used for VPNs
 | 
					more sessions over an IP tunnel. It is commonly used for VPNs
 | 
				
			||||||
(L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
 | 
					(L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
 | 
				
			||||||
network infrastructure.
 | 
					network infrastructure. With L2TPv3, it is also useful as a Layer-2
 | 
				
			||||||
 | 
					tunneling infrastructure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Features
 | 
				
			||||||
 | 
					========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					L2TPv2 (PPP over L2TP (UDP tunnels)).
 | 
				
			||||||
 | 
					L2TPv3 ethernet pseudowires.
 | 
				
			||||||
 | 
					L2TPv3 PPP pseudowires.
 | 
				
			||||||
 | 
					L2TPv3 IP encapsulation.
 | 
				
			||||||
 | 
					Netlink sockets for L2TPv3 configuration management.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					History
 | 
				
			||||||
 | 
					=======
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The original pppol2tp driver was introduced in 2.6.23 and provided
 | 
				
			||||||
 | 
					L2TPv2 functionality (rfc2661). L2TPv2 is used to tunnel one or more PPP
 | 
				
			||||||
 | 
					sessions over a UDP tunnel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					L2TPv3 (rfc3931) changes the protocol to allow different frame types
 | 
				
			||||||
 | 
					to be passed over an L2TP tunnel by moving the PPP-specific parts of
 | 
				
			||||||
 | 
					the protocol out of the core L2TP packet headers. Each frame type is
 | 
				
			||||||
 | 
					known as a pseudowire type. Ethernet, PPP, HDLC, Frame Relay and ATM
 | 
				
			||||||
 | 
					pseudowires for L2TP are defined in separate RFC standards. Another
 | 
				
			||||||
 | 
					change for L2TPv3 is that it can be carried directly over IP with no
 | 
				
			||||||
 | 
					UDP header (UDP is optional). It is also possible to create static
 | 
				
			||||||
 | 
					unmanaged L2TPv3 tunnels manually without a control protocol
 | 
				
			||||||
 | 
					(userspace daemon) to manage them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To support L2TPv3, the original pppol2tp driver was split up to
 | 
				
			||||||
 | 
					separate the L2TP and PPP functionality. Existing L2TPv2 userspace
 | 
				
			||||||
 | 
					apps should be unaffected as the original pppol2tp sockets API is
 | 
				
			||||||
 | 
					retained. L2TPv3, however, uses netlink to manage L2TPv3 tunnels and
 | 
				
			||||||
 | 
					sessions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Design
 | 
					Design
 | 
				
			||||||
======
 | 
					======
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The PPPoL2TP driver, drivers/net/pppol2tp.c, provides a mechanism by
 | 
					The L2TP protocol separates control and data frames.  The L2TP kernel
 | 
				
			||||||
which PPP frames carried through an L2TP session are passed through
 | 
					drivers handle only L2TP data frames; control frames are always
 | 
				
			||||||
the kernel's PPP subsystem. The standard PPP daemon, pppd, handles all
 | 
					handled by userspace. L2TP control frames carry messages between L2TP
 | 
				
			||||||
PPP interaction with the peer. PPP network interfaces are created for
 | 
					clients/servers and are used to setup / teardown tunnels and
 | 
				
			||||||
each local PPP endpoint.
 | 
					sessions. An L2TP client or server is implemented in userspace.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The L2TP protocol http://www.faqs.org/rfcs/rfc2661.html defines L2TP
 | 
					Each L2TP tunnel is implemented using a UDP or L2TPIP socket; L2TPIP
 | 
				
			||||||
control and data frames. L2TP control frames carry messages between
 | 
					provides L2TPv3 IP encapsulation (no UDP) and is implemented using a
 | 
				
			||||||
L2TP clients/servers and are used to setup / teardown tunnels and
 | 
					new l2tpip socket family. The tunnel socket is typically created by
 | 
				
			||||||
sessions. An L2TP client or server is implemented in userspace and
 | 
					userspace, though for unmanaged L2TPv3 tunnels, the socket can also be
 | 
				
			||||||
will use a regular UDP socket per tunnel. L2TP data frames carry PPP
 | 
					created by the kernel. Each L2TP session (pseudowire) gets a network
 | 
				
			||||||
frames, which may be PPP control or PPP data. The kernel's PPP
 | 
					interface instance. In the case of PPP, these interfaces are created
 | 
				
			||||||
 | 
					indirectly by pppd using a pppol2tp socket. In the case of ethernet,
 | 
				
			||||||
 | 
					the netdevice is created upon a netlink request to create an L2TPv3
 | 
				
			||||||
 | 
					ethernet pseudowire.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For PPP, the PPPoL2TP driver, net/l2tp/l2tp_ppp.c, provides a
 | 
				
			||||||
 | 
					mechanism by which PPP frames carried through an L2TP session are
 | 
				
			||||||
 | 
					passed through the kernel's PPP subsystem. The standard PPP daemon,
 | 
				
			||||||
 | 
					pppd, handles all PPP interaction with the peer. PPP network
 | 
				
			||||||
 | 
					interfaces are created for each local PPP endpoint. The kernel's PPP
 | 
				
			||||||
subsystem arranges for PPP control frames to be delivered to pppd,
 | 
					subsystem arranges for PPP control frames to be delivered to pppd,
 | 
				
			||||||
while data frames are forwarded as usual.
 | 
					while data frames are forwarded as usual.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For ethernet, the L2TPETH driver, net/l2tp/l2tp_eth.c, implements a
 | 
				
			||||||
 | 
					netdevice driver, managing virtual ethernet devices, one per
 | 
				
			||||||
 | 
					pseudowire. These interfaces can be managed using standard Linux tools
 | 
				
			||||||
 | 
					such as "ip" and "ifconfig". If only IP frames are passed over the
 | 
				
			||||||
 | 
					tunnel, the interface can be given an IP addresses of itself and its
 | 
				
			||||||
 | 
					peer. If non-IP frames are to be passed over the tunnel, the interface
 | 
				
			||||||
 | 
					can be added to a bridge using brctl. All L2TP datapath protocol
 | 
				
			||||||
 | 
					functions are handled by the L2TP core driver.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Each tunnel and session within a tunnel is assigned a unique tunnel_id
 | 
					Each tunnel and session within a tunnel is assigned a unique tunnel_id
 | 
				
			||||||
and session_id. These ids are carried in the L2TP header of every
 | 
					and session_id. These ids are carried in the L2TP header of every
 | 
				
			||||||
control and data packet. The pppol2tp driver uses them to lookup
 | 
					control and data packet. (Actually, in L2TPv3, the tunnel_id isn't
 | 
				
			||||||
internal tunnel and/or session contexts. Zero tunnel / session ids are
 | 
					present in data frames - it is inferred from the IP connection on
 | 
				
			||||||
treated specially - zero ids are never assigned to tunnels or sessions
 | 
					which the packet was received.) The L2TP driver uses the ids to lookup
 | 
				
			||||||
in the network. In the driver, the tunnel context keeps a pointer to
 | 
					internal tunnel and/or session contexts to determine how to handle the
 | 
				
			||||||
the tunnel UDP socket. The session context keeps a pointer to the
 | 
					packet. Zero tunnel / session ids are treated specially - zero ids are
 | 
				
			||||||
PPPoL2TP socket, as well as other data that lets the driver interface
 | 
					never assigned to tunnels or sessions in the network. In the driver,
 | 
				
			||||||
to the kernel PPP subsystem.
 | 
					the tunnel context keeps a reference to the tunnel UDP or L2TPIP
 | 
				
			||||||
 | 
					socket. The session context holds data that lets the driver interface
 | 
				
			||||||
 | 
					to the kernel's network frame type subsystems, i.e. PPP, ethernet.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Note that the pppol2tp kernel driver handles only L2TP data frames;
 | 
					Userspace Programming
 | 
				
			||||||
L2TP control frames are simply passed up to userspace in the UDP
 | 
					=====================
 | 
				
			||||||
tunnel socket. The kernel handles all datapath aspects of the
 | 
					 | 
				
			||||||
protocol, including data packet resequencing (if enabled).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are a number of requirements on the userspace L2TP daemon in
 | 
					For L2TPv2, there are a number of requirements on the userspace L2TP
 | 
				
			||||||
order to use the pppol2tp driver.
 | 
					daemon in order to use the pppol2tp driver.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Use a UDP socket per tunnel.
 | 
					1. Use a UDP socket per tunnel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,6 +137,35 @@ In addition to the standard PPP ioctls, a PPPIOCGL2TPSTATS is provided
 | 
				
			||||||
to retrieve tunnel and session statistics from the kernel using the
 | 
					to retrieve tunnel and session statistics from the kernel using the
 | 
				
			||||||
PPPoX socket of the appropriate tunnel or session.
 | 
					PPPoX socket of the appropriate tunnel or session.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For L2TPv3, userspace must use the netlink API defined in
 | 
				
			||||||
 | 
					include/linux/l2tp.h to manage tunnel and session contexts. The
 | 
				
			||||||
 | 
					general procedure to create a new L2TP tunnel with one session is:-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Open a GENL socket using L2TP_GENL_NAME for configuring the kernel
 | 
				
			||||||
 | 
					   using netlink.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Create a UDP or L2TPIP socket for the tunnel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Create a new L2TP tunnel using a L2TP_CMD_TUNNEL_CREATE
 | 
				
			||||||
 | 
					   request. Set attributes according to desired tunnel parameters,
 | 
				
			||||||
 | 
					   referencing the UDP or L2TPIP socket created in the previous step.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. Create a new L2TP session in the tunnel using a
 | 
				
			||||||
 | 
					   L2TP_CMD_SESSION_CREATE request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The tunnel and all of its sessions are closed when the tunnel socket
 | 
				
			||||||
 | 
					is closed. The netlink API may also be used to delete sessions and
 | 
				
			||||||
 | 
					tunnels. Configuration and status info may be set or read using netlink.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The L2TP driver also supports static (unmanaged) L2TPv3 tunnels. These
 | 
				
			||||||
 | 
					are where there is no L2TP control message exchange with the peer to
 | 
				
			||||||
 | 
					setup the tunnel; the tunnel is configured manually at each end of the
 | 
				
			||||||
 | 
					tunnel. There is no need for an L2TP userspace application in this
 | 
				
			||||||
 | 
					case -- the tunnel socket is created by the kernel and configured
 | 
				
			||||||
 | 
					using parameters sent in the L2TP_CMD_TUNNEL_CREATE netlink
 | 
				
			||||||
 | 
					request. The "ip" utility of iproute2 has commands for managing static
 | 
				
			||||||
 | 
					L2TPv3 tunnels; do "ip l2tp help" for more information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Debugging
 | 
					Debugging
 | 
				
			||||||
=========
 | 
					=========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,6 +182,69 @@ PPPOL2TP_MSG_CONTROL  userspace - kernel interface
 | 
				
			||||||
PPPOL2TP_MSG_SEQ      sequence numbers handling
 | 
					PPPOL2TP_MSG_SEQ      sequence numbers handling
 | 
				
			||||||
PPPOL2TP_MSG_DATA     data packets
 | 
					PPPOL2TP_MSG_DATA     data packets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If enabled, files under a l2tp debugfs directory can be used to dump
 | 
				
			||||||
 | 
					kernel state about L2TP tunnels and sessions. To access it, the
 | 
				
			||||||
 | 
					debugfs filesystem must first be mounted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# mount -t debugfs debugfs /debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Files under the l2tp directory can then be accessed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# cat /debug/l2tp/tunnels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The debugfs files should not be used by applications to obtain L2TP
 | 
				
			||||||
 | 
					state information because the file format is subject to change. It is
 | 
				
			||||||
 | 
					implemented to provide extra debug information to help diagnose
 | 
				
			||||||
 | 
					problems.) Users should use the netlink API.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/proc/net/pppol2tp is also provided for backwards compaibility with
 | 
				
			||||||
 | 
					the original pppol2tp driver. It lists information about L2TPv2
 | 
				
			||||||
 | 
					tunnels and sessions only. Its use is discouraged.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unmanaged L2TPv3 Tunnels
 | 
				
			||||||
 | 
					========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some commercial L2TP products support unmanaged L2TPv3 ethernet
 | 
				
			||||||
 | 
					tunnels, where there is no L2TP control protocol; tunnels are
 | 
				
			||||||
 | 
					configured at each side manually. New commands are available in
 | 
				
			||||||
 | 
					iproute2's ip utility to support this.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To create an L2TPv3 ethernet pseudowire between local host 192.168.1.1
 | 
				
			||||||
 | 
					and peer 192.168.1.2, using IP addresses 10.5.1.1 and 10.5.1.2 for the
 | 
				
			||||||
 | 
					tunnel endpoints:-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# modprobe l2tp_eth
 | 
				
			||||||
 | 
					# modprobe l2tp_netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ip l2tp add tunnel tunnel_id 1 peer_tunnel_id 1 udp_sport 5000 \
 | 
				
			||||||
 | 
					  udp_dport 5000 encap udp local 192.168.1.1 remote 192.168.1.2
 | 
				
			||||||
 | 
					# ip l2tp add session tunnel_id 1 session_id 1 peer_session_id 1
 | 
				
			||||||
 | 
					# ifconfig -a
 | 
				
			||||||
 | 
					# ip addr add 10.5.1.2/32 peer 10.5.1.1/32 dev l2tpeth0
 | 
				
			||||||
 | 
					# ifconfig l2tpeth0 up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Choose IP addresses to be the address of a local IP interface and that
 | 
				
			||||||
 | 
					of the remote system. The IP addresses of the l2tpeth0 interface can be
 | 
				
			||||||
 | 
					anything suitable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Repeat the above at the peer, with ports, tunnel/session ids and IP
 | 
				
			||||||
 | 
					addresses reversed.  The tunnel and session IDs can be any non-zero
 | 
				
			||||||
 | 
					32-bit number, but the values must be reversed at the peer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Host 1                         Host2
 | 
				
			||||||
 | 
					udp_sport=5000                 udp_sport=5001
 | 
				
			||||||
 | 
					udp_dport=5001                 udp_dport=5000
 | 
				
			||||||
 | 
					tunnel_id=42                   tunnel_id=45
 | 
				
			||||||
 | 
					peer_tunnel_id=45              peer_tunnel_id=42
 | 
				
			||||||
 | 
					session_id=128                 session_id=5196755
 | 
				
			||||||
 | 
					peer_session_id=5196755        peer_session_id=128
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When done at both ends of the tunnel, it should be possible to send
 | 
				
			||||||
 | 
					data over the network. e.g.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ping 10.5.1.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Sample Userspace Code
 | 
					Sample Userspace Code
 | 
				
			||||||
=====================
 | 
					=====================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -158,12 +301,48 @@ Sample Userspace Code
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Miscellaneous
 | 
					Internal Implementation
 | 
				
			||||||
============
 | 
					=======================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The PPPoL2TP driver was developed as part of the OpenL2TP project by
 | 
					The driver keeps a struct l2tp_tunnel context per L2TP tunnel and a
 | 
				
			||||||
 | 
					struct l2tp_session context for each session. The l2tp_tunnel is
 | 
				
			||||||
 | 
					always associated with a UDP or L2TP/IP socket and keeps a list of
 | 
				
			||||||
 | 
					sessions in the tunnel. The l2tp_session context keeps kernel state
 | 
				
			||||||
 | 
					about the session. It has private data which is used for data specific
 | 
				
			||||||
 | 
					to the session type. With L2TPv2, the session always carried PPP
 | 
				
			||||||
 | 
					traffic. With L2TPv3, the session can also carry ethernet frames
 | 
				
			||||||
 | 
					(ethernet pseudowire) or other data types such as ATM, HDLC or Frame
 | 
				
			||||||
 | 
					Relay.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When a tunnel is first opened, the reference count on the socket is
 | 
				
			||||||
 | 
					increased using sock_hold(). This ensures that the kernel socket
 | 
				
			||||||
 | 
					cannot be removed while L2TP's data structures reference it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some L2TP sessions also have a socket (PPP pseudowires) while others
 | 
				
			||||||
 | 
					do not (ethernet pseudowires). We can't use the socket reference count
 | 
				
			||||||
 | 
					as the reference count for session contexts. The L2TP implementation
 | 
				
			||||||
 | 
					therefore has its own internal reference counts on the session
 | 
				
			||||||
 | 
					contexts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To Do
 | 
				
			||||||
 | 
					=====
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Add L2TP tunnel switching support. This would route tunneled traffic
 | 
				
			||||||
 | 
					from one L2TP tunnel into another. Specified in
 | 
				
			||||||
 | 
					http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Add L2TPv3 VLAN pseudowire support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Add L2TPv3 IP pseudowire support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Add L2TPv3 ATM pseudowire support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Miscellaneous
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The L2TP drivers were developed as part of the OpenL2TP project by
 | 
				
			||||||
Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
 | 
					Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
 | 
				
			||||||
designed from the ground up to have the L2TP datapath in the
 | 
					designed from the ground up to have the L2TP datapath in the
 | 
				
			||||||
kernel. The project also implemented the pppol2tp plugin for pppd
 | 
					kernel. The project also implemented the pppol2tp plugin for pppd
 | 
				
			||||||
which allows pppd to use the kernel driver. Details can be found at
 | 
					which allows pppd to use the kernel driver. Details can be found at
 | 
				
			||||||
http://openl2tp.sourceforge.net.
 | 
					http://www.openl2tp.org.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,23 +20,23 @@ the rest of the skbuff, if any more information does exist.
 | 
				
			||||||
Packet Layer to Device Driver
 | 
					Packet Layer to Device Driver
 | 
				
			||||||
-----------------------------
 | 
					-----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x00
 | 
					First Byte = 0x00 (X25_IFACE_DATA)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This indicates that the rest of the skbuff contains data to be transmitted
 | 
					This indicates that the rest of the skbuff contains data to be transmitted
 | 
				
			||||||
over the LAPB link. The LAPB link should already exist before any data is
 | 
					over the LAPB link. The LAPB link should already exist before any data is
 | 
				
			||||||
passed down.
 | 
					passed down.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x01
 | 
					First Byte = 0x01 (X25_IFACE_CONNECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Establish the LAPB link. If the link is already established then the connect
 | 
					Establish the LAPB link. If the link is already established then the connect
 | 
				
			||||||
confirmation message should be returned as soon as possible.
 | 
					confirmation message should be returned as soon as possible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x02
 | 
					First Byte = 0x02 (X25_IFACE_DISCONNECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Terminate the LAPB link. If it is already disconnected then the disconnect
 | 
					Terminate the LAPB link. If it is already disconnected then the disconnect
 | 
				
			||||||
confirmation message should be returned as soon as possible.
 | 
					confirmation message should be returned as soon as possible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x03
 | 
					First Byte = 0x03 (X25_IFACE_PARAMS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LAPB parameters. To be defined.
 | 
					LAPB parameters. To be defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,22 +44,22 @@ LAPB parameters. To be defined.
 | 
				
			||||||
Device Driver to Packet Layer
 | 
					Device Driver to Packet Layer
 | 
				
			||||||
-----------------------------
 | 
					-----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x00
 | 
					First Byte = 0x00 (X25_IFACE_DATA)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This indicates that the rest of the skbuff contains data that has been
 | 
					This indicates that the rest of the skbuff contains data that has been
 | 
				
			||||||
received over the LAPB link.
 | 
					received over the LAPB link.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x01
 | 
					First Byte = 0x01 (X25_IFACE_CONNECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LAPB link has been established. The same message is used for both a LAPB
 | 
					LAPB link has been established. The same message is used for both a LAPB
 | 
				
			||||||
link connect_confirmation and a connect_indication.
 | 
					link connect_confirmation and a connect_indication.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x02
 | 
					First Byte = 0x02 (X25_IFACE_DISCONNECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LAPB link has been terminated. This same message is used for both a LAPB
 | 
					LAPB link has been terminated. This same message is used for both a LAPB
 | 
				
			||||||
link disconnect_confirmation and a disconnect_indication.
 | 
					link disconnect_confirmation and a disconnect_indication.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First Byte = 0x03
 | 
					First Byte = 0x03 (X25_IFACE_PARAMS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LAPB parameters. To be defined.
 | 
					LAPB parameters. To be defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,37 +99,15 @@ system. Also, it is possible to switch all rfkill drivers (or all drivers of
 | 
				
			||||||
a specified type) into a state which also updates the default state for
 | 
					a specified type) into a state which also updates the default state for
 | 
				
			||||||
hotplugged devices.
 | 
					hotplugged devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
After an application opens /dev/rfkill, it can read the current state of
 | 
					After an application opens /dev/rfkill, it can read the current state of all
 | 
				
			||||||
all devices, and afterwards can poll the descriptor for hotplug or state
 | 
					devices. Changes can be either obtained by either polling the descriptor for
 | 
				
			||||||
change events.
 | 
					hotplug or state change events or by listening for uevents emitted by the
 | 
				
			||||||
 | 
					rfkill core framework.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Applications must ignore operations (the "op" field) they do not handle,
 | 
					Additionally, each rfkill device is registered in sysfs and emits uevents.
 | 
				
			||||||
this allows the API to be extended in the future.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Additionally, each rfkill device is registered in sysfs and there has the
 | 
					rfkill devices issue uevents (with an action of "change"), with the following
 | 
				
			||||||
following attributes:
 | 
					environment variables set:
 | 
				
			||||||
 | 
					 | 
				
			||||||
	name: Name assigned by driver to this key (interface or driver name).
 | 
					 | 
				
			||||||
	type: Driver type string ("wlan", "bluetooth", etc).
 | 
					 | 
				
			||||||
	persistent: Whether the soft blocked state is initialised from
 | 
					 | 
				
			||||||
	            non-volatile storage at startup.
 | 
					 | 
				
			||||||
	state: Current state of the transmitter
 | 
					 | 
				
			||||||
		0: RFKILL_STATE_SOFT_BLOCKED
 | 
					 | 
				
			||||||
			transmitter is turned off by software
 | 
					 | 
				
			||||||
		1: RFKILL_STATE_UNBLOCKED
 | 
					 | 
				
			||||||
			transmitter is (potentially) active
 | 
					 | 
				
			||||||
		2: RFKILL_STATE_HARD_BLOCKED
 | 
					 | 
				
			||||||
			transmitter is forced off by something outside of
 | 
					 | 
				
			||||||
			the driver's control.
 | 
					 | 
				
			||||||
	       This file is deprecated because it can only properly show
 | 
					 | 
				
			||||||
	       three of the four possible states, soft-and-hard-blocked is
 | 
					 | 
				
			||||||
	       missing.
 | 
					 | 
				
			||||||
	claim: 0: Kernel handles events
 | 
					 | 
				
			||||||
	       This file is deprecated because there no longer is a way to
 | 
					 | 
				
			||||||
	       claim just control over a single rfkill instance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rfkill devices also issue uevents (with an action of "change"), with the
 | 
					 | 
				
			||||||
following environment variables set:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
RFKILL_NAME
 | 
					RFKILL_NAME
 | 
				
			||||||
RFKILL_STATE
 | 
					RFKILL_STATE
 | 
				
			||||||
| 
						 | 
					@ -137,3 +115,7 @@ RFKILL_TYPE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The contents of these variables corresponds to the "name", "state" and
 | 
					The contents of these variables corresponds to the "name", "state" and
 | 
				
			||||||
"type" sysfs files explained above.
 | 
					"type" sysfs files explained above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For further details consult Documentation/ABI/stable/dev-rfkill and
 | 
				
			||||||
 | 
					Documentation/ABI/stable/sysfs-class-rfkill.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,16 @@ netdev_max_backlog
 | 
				
			||||||
Maximum number  of  packets,  queued  on  the  INPUT  side, when the interface
 | 
					Maximum number  of  packets,  queued  on  the  INPUT  side, when the interface
 | 
				
			||||||
receives packets faster than kernel can process them.
 | 
					receives packets faster than kernel can process them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					netdev_tstamp_prequeue
 | 
				
			||||||
 | 
					----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If set to 0, RX packet timestamps can be sampled after RPS processing, when
 | 
				
			||||||
 | 
					the target CPU processes packets. It might give some delay on timestamps, but
 | 
				
			||||||
 | 
					permit to distribute the load on several cpus.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If set to 1 (default), timestamps are sampled as soon as possible, before
 | 
				
			||||||
 | 
					queueing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
optmem_max
 | 
					optmem_max
 | 
				
			||||||
----------
 | 
					----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								MAINTAINERS
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								MAINTAINERS
									
									
									
									
									
								
							| 
						 | 
					@ -1521,9 +1521,10 @@ M:	Andy Whitcroft <apw@canonical.com>
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
F:	scripts/checkpatch.pl
 | 
					F:	scripts/checkpatch.pl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CISCO 10G ETHERNET DRIVER
 | 
					CISCO VIC ETHERNET NIC DRIVER
 | 
				
			||||||
M:	Scott Feldman <scofeldm@cisco.com>
 | 
					M:	Scott Feldman <scofeldm@cisco.com>
 | 
				
			||||||
M:	Joe Eykholt <jeykholt@cisco.com>
 | 
					M:	Vasanthy Kolluri <vkolluri@cisco.com>
 | 
				
			||||||
 | 
					M:	Roopa Prabhu <roprabhu@cisco.com>
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
F:	drivers/net/enic/
 | 
					F:	drivers/net/enic/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3044,10 +3045,9 @@ F:	net/ipv4/netfilter/ipt_MASQUERADE.c
 | 
				
			||||||
IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER
 | 
					IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER
 | 
				
			||||||
M:	Francois Romieu <romieu@fr.zoreil.com>
 | 
					M:	Francois Romieu <romieu@fr.zoreil.com>
 | 
				
			||||||
M:	Sorbica Shieh <sorbica@icplus.com.tw>
 | 
					M:	Sorbica Shieh <sorbica@icplus.com.tw>
 | 
				
			||||||
M:	Jesse Huang <jesse@icplus.com.tw>
 | 
					 | 
				
			||||||
L:	netdev@vger.kernel.org
 | 
					L:	netdev@vger.kernel.org
 | 
				
			||||||
S:	Maintained
 | 
					S:	Maintained
 | 
				
			||||||
F:	drivers/net/ipg.c
 | 
					F:	drivers/net/ipg.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IPATH DRIVER
 | 
					IPATH DRIVER
 | 
				
			||||||
M:	Ralph Campbell <infinipath@qlogic.com>
 | 
					M:	Ralph Campbell <infinipath@qlogic.com>
 | 
				
			||||||
| 
						 | 
					@ -3895,7 +3895,6 @@ M:	Ramkrishna Vepa <ram.vepa@neterion.com>
 | 
				
			||||||
M:	Rastapur Santosh <santosh.rastapur@neterion.com>
 | 
					M:	Rastapur Santosh <santosh.rastapur@neterion.com>
 | 
				
			||||||
M:	Sivakumar Subramani <sivakumar.subramani@neterion.com>
 | 
					M:	Sivakumar Subramani <sivakumar.subramani@neterion.com>
 | 
				
			||||||
M:	Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
 | 
					M:	Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
 | 
				
			||||||
M:	Anil Murthy <anil.murthy@neterion.com>
 | 
					 | 
				
			||||||
L:	netdev@vger.kernel.org
 | 
					L:	netdev@vger.kernel.org
 | 
				
			||||||
W:	http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
 | 
					W:	http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
 | 
				
			||||||
W:	http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
 | 
					W:	http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
 | 
				
			||||||
| 
						 | 
					@ -4000,6 +3999,7 @@ F:	net/rfkill/
 | 
				
			||||||
F:	net/wireless/
 | 
					F:	net/wireless/
 | 
				
			||||||
F:	include/net/ieee80211*
 | 
					F:	include/net/ieee80211*
 | 
				
			||||||
F:	include/linux/wireless.h
 | 
					F:	include/linux/wireless.h
 | 
				
			||||||
 | 
					F:	include/linux/iw_handler.h
 | 
				
			||||||
F:	drivers/net/wireless/
 | 
					F:	drivers/net/wireless/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NETWORKING DRIVERS
 | 
					NETWORKING DRIVERS
 | 
				
			||||||
| 
						 | 
					@ -4631,6 +4631,7 @@ F:	drivers/net/qla3xxx.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
 | 
					QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
 | 
				
			||||||
M:	Amit Kumar Salecha <amit.salecha@qlogic.com>
 | 
					M:	Amit Kumar Salecha <amit.salecha@qlogic.com>
 | 
				
			||||||
 | 
					M:	Anirban Chakraborty <anirban.chakraborty@qlogic.com>
 | 
				
			||||||
M:	linux-driver@qlogic.com
 | 
					M:	linux-driver@qlogic.com
 | 
				
			||||||
L:	netdev@vger.kernel.org
 | 
					L:	netdev@vger.kernel.org
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,9 +201,9 @@ static struct resource pcm970_sja1000_resources[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sja1000_platform_data pcm970_sja1000_platform_data = {
 | 
					struct sja1000_platform_data pcm970_sja1000_platform_data = {
 | 
				
			||||||
	.clock		= 16000000 / 2,
 | 
						.osc_freq	= 16000000,
 | 
				
			||||||
	.ocr		= 0x40 | 0x18,
 | 
						.ocr		= OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
 | 
				
			||||||
	.cdr		= 0x40,
 | 
						.cdr		= CDR_CBP,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct platform_device pcm970_sja1000 = {
 | 
					static struct platform_device pcm970_sja1000 = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -530,9 +530,9 @@ static struct resource pcm970_sja1000_resources[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sja1000_platform_data pcm970_sja1000_platform_data = {
 | 
					struct sja1000_platform_data pcm970_sja1000_platform_data = {
 | 
				
			||||||
	.clock		= 16000000 / 2,
 | 
						.osc_freq	= 16000000,
 | 
				
			||||||
	.ocr		= 0x40 | 0x18,
 | 
						.ocr		= OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
 | 
				
			||||||
	.cdr		= 0x40,
 | 
						.cdr		= CDR_CBP,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct platform_device pcm970_sja1000 = {
 | 
					static struct platform_device pcm970_sja1000 = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mcp251x_platform_data mcp251x_info = {
 | 
					static struct mcp251x_platform_data mcp251x_info = {
 | 
				
			||||||
	.oscillator_frequency = 16E6,
 | 
						.oscillator_frequency = 16E6,
 | 
				
			||||||
	.model                = CAN_MCP251X_MCP2515,
 | 
					 | 
				
			||||||
	.board_specific_setup = NULL,
 | 
						.board_specific_setup = NULL,
 | 
				
			||||||
	.power_enable         = NULL,
 | 
						.power_enable         = NULL,
 | 
				
			||||||
	.transceiver_enable   = NULL
 | 
						.transceiver_enable   = NULL
 | 
				
			||||||
| 
						 | 
					@ -81,7 +80,7 @@ static struct mcp251x_platform_data mcp251x_info = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spi_board_info mcp251x_board_info[] = {
 | 
					static struct spi_board_info mcp251x_board_info[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.modalias        = "mcp251x",
 | 
							.modalias        = "mcp2515",
 | 
				
			||||||
		.max_speed_hz    = 6500000,
 | 
							.max_speed_hz    = 6500000,
 | 
				
			||||||
		.bus_num         = 3,
 | 
							.bus_num         = 3,
 | 
				
			||||||
		.chip_select     = 0,
 | 
							.chip_select     = 0,
 | 
				
			||||||
| 
						 | 
					@ -90,7 +89,7 @@ static struct spi_board_info mcp251x_board_info[] = {
 | 
				
			||||||
		.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ1)
 | 
							.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ1)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.modalias        = "mcp251x",
 | 
							.modalias        = "mcp2515",
 | 
				
			||||||
		.max_speed_hz    = 6500000,
 | 
							.max_speed_hz    = 6500000,
 | 
				
			||||||
		.bus_num         = 3,
 | 
							.bus_num         = 3,
 | 
				
			||||||
		.chip_select     = 1,
 | 
							.chip_select     = 1,
 | 
				
			||||||
| 
						 | 
					@ -99,7 +98,7 @@ static struct spi_board_info mcp251x_board_info[] = {
 | 
				
			||||||
		.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ2)
 | 
							.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ2)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.modalias        = "mcp251x",
 | 
							.modalias        = "mcp2515",
 | 
				
			||||||
		.max_speed_hz    = 6500000,
 | 
							.max_speed_hz    = 6500000,
 | 
				
			||||||
		.bus_num         = 4,
 | 
							.bus_num         = 4,
 | 
				
			||||||
		.chip_select     = 0,
 | 
							.chip_select     = 0,
 | 
				
			||||||
| 
						 | 
					@ -108,7 +107,7 @@ static struct spi_board_info mcp251x_board_info[] = {
 | 
				
			||||||
		.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ3)
 | 
							.irq             = gpio_to_irq(ICONTROL_MCP251x_nIRQ3)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.modalias        = "mcp251x",
 | 
							.modalias        = "mcp2515",
 | 
				
			||||||
		.max_speed_hz    = 6500000,
 | 
							.max_speed_hz    = 6500000,
 | 
				
			||||||
		.bus_num         = 4,
 | 
							.bus_num         = 4,
 | 
				
			||||||
		.chip_select     = 1,
 | 
							.chip_select     = 1,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -414,15 +414,13 @@ static int zeus_mcp2515_transceiver_enable(int enable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mcp251x_platform_data zeus_mcp2515_pdata = {
 | 
					static struct mcp251x_platform_data zeus_mcp2515_pdata = {
 | 
				
			||||||
	.oscillator_frequency	= 16*1000*1000,
 | 
						.oscillator_frequency	= 16*1000*1000,
 | 
				
			||||||
	.model			= CAN_MCP251X_MCP2515,
 | 
					 | 
				
			||||||
	.board_specific_setup	= zeus_mcp2515_setup,
 | 
						.board_specific_setup	= zeus_mcp2515_setup,
 | 
				
			||||||
	.transceiver_enable	= zeus_mcp2515_transceiver_enable,
 | 
					 | 
				
			||||||
	.power_enable		= zeus_mcp2515_transceiver_enable,
 | 
						.power_enable		= zeus_mcp2515_transceiver_enable,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spi_board_info zeus_spi_board_info[] = {
 | 
					static struct spi_board_info zeus_spi_board_info[] = {
 | 
				
			||||||
	[0] = {
 | 
						[0] = {
 | 
				
			||||||
		.modalias	= "mcp251x",
 | 
							.modalias	= "mcp2515",
 | 
				
			||||||
		.platform_data	= &zeus_mcp2515_pdata,
 | 
							.platform_data	= &zeus_mcp2515_pdata,
 | 
				
			||||||
		.irq		= gpio_to_irq(ZEUS_CAN_GPIO),
 | 
							.irq		= gpio_to_irq(ZEUS_CAN_GPIO),
 | 
				
			||||||
		.max_speed_hz	= 1*1000*1000,
 | 
							.max_speed_hz	= 1*1000*1000,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@
 | 
				
			||||||
#include <asm/registers.h>
 | 
					#include <asm/registers.h>
 | 
				
			||||||
#include <asm/setup.h>
 | 
					#include <asm/setup.h>
 | 
				
			||||||
#include <asm/irqflags.h>
 | 
					#include <asm/irqflags.h>
 | 
				
			||||||
 | 
					#include <asm/cache.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm-generic/cmpxchg.h>
 | 
					#include <asm-generic/cmpxchg.h>
 | 
				
			||||||
#include <asm-generic/cmpxchg-local.h>
 | 
					#include <asm-generic/cmpxchg-local.h>
 | 
				
			||||||
| 
						 | 
					@ -96,4 +97,14 @@ extern struct dentry *of_debugfs_root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define arch_align_stack(x) (x)
 | 
					#define arch_align_stack(x) (x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * MicroBlaze doesn't handle unaligned accesses in hardware.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Based on this we force the IP header alignment in network drivers.
 | 
				
			||||||
 | 
					 * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining
 | 
				
			||||||
 | 
					 * cacheline alignment of buffers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define NET_IP_ALIGN	2
 | 
				
			||||||
 | 
					#define NET_SKB_PAD	L1_CACHE_BYTES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _ASM_MICROBLAZE_SYSTEM_H */
 | 
					#endif /* _ASM_MICROBLAZE_SYSTEM_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,3 +83,57 @@ static int __init swarm_pata_init(void)
 | 
				
			||||||
device_initcall(swarm_pata_init);
 | 
					device_initcall(swarm_pata_init);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) */
 | 
					#endif /* defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define sb1250_dev_struct(num) \
 | 
				
			||||||
 | 
						static struct resource sb1250_res##num = {		\
 | 
				
			||||||
 | 
							.name = "SB1250 MAC " __stringify(num),		\
 | 
				
			||||||
 | 
							.flags = IORESOURCE_MEM,		\
 | 
				
			||||||
 | 
							.start = A_MAC_CHANNEL_BASE(num),	\
 | 
				
			||||||
 | 
							.end = A_MAC_CHANNEL_BASE(num + 1) -1,	\
 | 
				
			||||||
 | 
						};\
 | 
				
			||||||
 | 
						static struct platform_device sb1250_dev##num = {	\
 | 
				
			||||||
 | 
							.name = "sb1250-mac",			\
 | 
				
			||||||
 | 
						.id = num,					\
 | 
				
			||||||
 | 
						.resource = &sb1250_res##num,			\
 | 
				
			||||||
 | 
						.num_resources = 1,				\
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sb1250_dev_struct(0);
 | 
				
			||||||
 | 
					sb1250_dev_struct(1);
 | 
				
			||||||
 | 
					sb1250_dev_struct(2);
 | 
				
			||||||
 | 
					sb1250_dev_struct(3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct platform_device *sb1250_devs[] __initdata = {
 | 
				
			||||||
 | 
						&sb1250_dev0,
 | 
				
			||||||
 | 
						&sb1250_dev1,
 | 
				
			||||||
 | 
						&sb1250_dev2,
 | 
				
			||||||
 | 
						&sb1250_dev3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int __init sb1250_device_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Set the number of available units based on the SOC type.  */
 | 
				
			||||||
 | 
						switch (soc_type) {
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1250:
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1250_ALT:
 | 
				
			||||||
 | 
							ret = platform_add_devices(sb1250_devs, 3);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1120:
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1125:
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1125H:
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1250_ALT2:       /* Hybrid */
 | 
				
			||||||
 | 
							ret = platform_add_devices(sb1250_devs, 2);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1x55:
 | 
				
			||||||
 | 
						case K_SYS_SOC_TYPE_BCM1x80:
 | 
				
			||||||
 | 
							ret = platform_add_devices(sb1250_devs, 4);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ret = -ENODEV;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					device_initcall(sb1250_device_init);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -394,6 +394,7 @@ config ATM_HE_USE_SUNI
 | 
				
			||||||
config ATM_SOLOS
 | 
					config ATM_SOLOS
 | 
				
			||||||
	tristate "Solos ADSL2+ PCI Multiport card driver"
 | 
						tristate "Solos ADSL2+ PCI Multiport card driver"
 | 
				
			||||||
	depends on PCI
 | 
						depends on PCI
 | 
				
			||||||
 | 
						select FW_LOADER
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Support for the Solos multiport ADSL2+ card.
 | 
						  Support for the Solos multiport ADSL2+ card.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ static int atmtcp_send_control(struct atm_vcc *vcc,int type,
 | 
				
			||||||
	*(struct atm_vcc **) &new_msg->vcc = vcc;
 | 
						*(struct atm_vcc **) &new_msg->vcc = vcc;
 | 
				
			||||||
	old_test = test_bit(flag,&vcc->flags);
 | 
						old_test = test_bit(flag,&vcc->flags);
 | 
				
			||||||
	out_vcc->push(out_vcc,skb);
 | 
						out_vcc->push(out_vcc,skb);
 | 
				
			||||||
	add_wait_queue(sk_atm(vcc)->sk_sleep, &wait);
 | 
						add_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
 | 
				
			||||||
	while (test_bit(flag,&vcc->flags) == old_test) {
 | 
						while (test_bit(flag,&vcc->flags) == old_test) {
 | 
				
			||||||
		mb();
 | 
							mb();
 | 
				
			||||||
		out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
 | 
							out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@ static int atmtcp_send_control(struct atm_vcc *vcc,int type,
 | 
				
			||||||
		schedule();
 | 
							schedule();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	set_current_state(TASK_RUNNING);
 | 
						set_current_state(TASK_RUNNING);
 | 
				
			||||||
	remove_wait_queue(sk_atm(vcc)->sk_sleep, &wait);
 | 
						remove_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
 | 
				
			||||||
	return error;
 | 
						return error;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,7 +105,7 @@ static int atmtcp_recv_control(const struct atmtcp_control *msg)
 | 
				
			||||||
		    msg->type);
 | 
							    msg->type);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wake_up(sk_atm(vcc)->sk_sleep);
 | 
						wake_up(sk_sleep(sk_atm(vcc)));
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1131,7 +1131,7 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
 | 
				
			||||||
			if (i == -1)
 | 
								if (i == -1)
 | 
				
			||||||
				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
 | 
									put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
 | 
				
			||||||
				    skb->data,
 | 
									    skb->data,
 | 
				
			||||||
				    skb->len - skb->data_len);
 | 
									    skb_headlen(skb));
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
 | 
									put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
 | 
				
			||||||
				    skb_shinfo(skb)->frags[i].page + skb_shinfo(skb)->frags[i].page_offset,
 | 
									    skb_shinfo(skb)->frags[i].page + skb_shinfo(skb)->frags[i].page_offset,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2664,8 +2664,8 @@ he_send(struct atm_vcc *vcc, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_SCATTERGATHER
 | 
					#ifdef USE_SCATTERGATHER
 | 
				
			||||||
	tpd->iovec[slot].addr = pci_map_single(he_dev->pci_dev, skb->data,
 | 
						tpd->iovec[slot].addr = pci_map_single(he_dev->pci_dev, skb->data,
 | 
				
			||||||
				skb->len - skb->data_len, PCI_DMA_TODEVICE);
 | 
									skb_headlen(skb), PCI_DMA_TODEVICE);
 | 
				
			||||||
	tpd->iovec[slot].len = skb->len - skb->data_len;
 | 
						tpd->iovec[slot].len = skb_headlen(skb);
 | 
				
			||||||
	++slot;
 | 
						++slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 | 
						for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,8 @@ struct btmrvl_device {
 | 
				
			||||||
	void *card;
 | 
						void *card;
 | 
				
			||||||
	struct hci_dev *hcidev;
 | 
						struct hci_dev *hcidev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u8 dev_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u8 tx_dnld_rdy;
 | 
						u8 tx_dnld_rdy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u8 psmode;
 | 
						u8 psmode;
 | 
				
			||||||
| 
						 | 
					@ -88,8 +90,11 @@ struct btmrvl_private {
 | 
				
			||||||
#define BT_CMD_HOST_SLEEP_ENABLE	0x5A
 | 
					#define BT_CMD_HOST_SLEEP_ENABLE	0x5A
 | 
				
			||||||
#define BT_CMD_MODULE_CFG_REQ		0x5B
 | 
					#define BT_CMD_MODULE_CFG_REQ		0x5B
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Sub-commands: Module Bringup/Shutdown Request */
 | 
					/* Sub-commands: Module Bringup/Shutdown Request/Response */
 | 
				
			||||||
#define MODULE_BRINGUP_REQ		0xF1
 | 
					#define MODULE_BRINGUP_REQ		0xF1
 | 
				
			||||||
 | 
					#define MODULE_BROUGHT_UP		0x00
 | 
				
			||||||
 | 
					#define MODULE_ALREADY_UP		0x0C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MODULE_SHUTDOWN_REQ		0xF2
 | 
					#define MODULE_SHUTDOWN_REQ		0xF2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BT_EVENT_POWER_STATE		0x20
 | 
					#define BT_EVENT_POWER_STATE		0x20
 | 
				
			||||||
| 
						 | 
					@ -123,6 +128,7 @@ struct btmrvl_event {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Prototype of global function */
 | 
					/* Prototype of global function */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int btmrvl_register_hdev(struct btmrvl_private *priv);
 | 
				
			||||||
struct btmrvl_private *btmrvl_add_card(void *card);
 | 
					struct btmrvl_private *btmrvl_add_card(void *card);
 | 
				
			||||||
int btmrvl_remove_card(struct btmrvl_private *priv);
 | 
					int btmrvl_remove_card(struct btmrvl_private *priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,7 +66,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct btmrvl_adapter *adapter = priv->adapter;
 | 
						struct btmrvl_adapter *adapter = priv->adapter;
 | 
				
			||||||
	struct btmrvl_event *event;
 | 
						struct btmrvl_event *event;
 | 
				
			||||||
	u8 ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	event = (struct btmrvl_event *) skb->data;
 | 
						event = (struct btmrvl_event *) skb->data;
 | 
				
			||||||
	if (event->ec != 0xff) {
 | 
						if (event->ec != 0xff) {
 | 
				
			||||||
| 
						 | 
					@ -112,8 +112,17 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
 | 
				
			||||||
	case BT_CMD_MODULE_CFG_REQ:
 | 
						case BT_CMD_MODULE_CFG_REQ:
 | 
				
			||||||
		if (priv->btmrvl_dev.sendcmdflag &&
 | 
							if (priv->btmrvl_dev.sendcmdflag &&
 | 
				
			||||||
				event->data[1] == MODULE_BRINGUP_REQ) {
 | 
									event->data[1] == MODULE_BRINGUP_REQ) {
 | 
				
			||||||
			BT_DBG("EVENT:%s", (event->data[2]) ?
 | 
								BT_DBG("EVENT:%s",
 | 
				
			||||||
				"Bring-up failed" : "Bring-up succeed");
 | 
									((event->data[2] == MODULE_BROUGHT_UP) ||
 | 
				
			||||||
 | 
									(event->data[2] == MODULE_ALREADY_UP)) ?
 | 
				
			||||||
 | 
									"Bring-up succeed" : "Bring-up failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (event->length > 3)
 | 
				
			||||||
 | 
									priv->btmrvl_dev.dev_type = event->data[3];
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									priv->btmrvl_dev.dev_type = HCI_BREDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type);
 | 
				
			||||||
		} else if (priv->btmrvl_dev.sendcmdflag &&
 | 
							} else if (priv->btmrvl_dev.sendcmdflag &&
 | 
				
			||||||
				event->data[1] == MODULE_SHUTDOWN_REQ) {
 | 
									event->data[1] == MODULE_SHUTDOWN_REQ) {
 | 
				
			||||||
			BT_DBG("EVENT:%s", (event->data[2]) ?
 | 
								BT_DBG("EVENT:%s", (event->data[2]) ?
 | 
				
			||||||
| 
						 | 
					@ -522,12 +531,63 @@ static int btmrvl_service_main_thread(void *data)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct btmrvl_private *btmrvl_add_card(void *card)
 | 
					int btmrvl_register_hdev(struct btmrvl_private *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct hci_dev *hdev = NULL;
 | 
						struct hci_dev *hdev = NULL;
 | 
				
			||||||
	struct btmrvl_private *priv;
 | 
					 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdev = hci_alloc_dev();
 | 
				
			||||||
 | 
						if (!hdev) {
 | 
				
			||||||
 | 
							BT_ERR("Can not allocate HCI device");
 | 
				
			||||||
 | 
							goto err_hdev;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv->btmrvl_dev.hcidev = hdev;
 | 
				
			||||||
 | 
						hdev->driver_data = priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdev->bus = HCI_SDIO;
 | 
				
			||||||
 | 
						hdev->open = btmrvl_open;
 | 
				
			||||||
 | 
						hdev->close = btmrvl_close;
 | 
				
			||||||
 | 
						hdev->flush = btmrvl_flush;
 | 
				
			||||||
 | 
						hdev->send = btmrvl_send_frame;
 | 
				
			||||||
 | 
						hdev->destruct = btmrvl_destruct;
 | 
				
			||||||
 | 
						hdev->ioctl = btmrvl_ioctl;
 | 
				
			||||||
 | 
						hdev->owner = THIS_MODULE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdev->dev_type = priv->btmrvl_dev.dev_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = hci_register_dev(hdev);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							BT_ERR("Can not register HCI device");
 | 
				
			||||||
 | 
							goto err_hci_register_dev;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
 | 
						btmrvl_debugfs_init(hdev);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err_hci_register_dev:
 | 
				
			||||||
 | 
						hci_free_dev(hdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err_hdev:
 | 
				
			||||||
 | 
						/* Stop the thread servicing the interrupts */
 | 
				
			||||||
 | 
						kthread_stop(priv->main_thread.task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						btmrvl_free_adapter(priv);
 | 
				
			||||||
 | 
						kfree(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return -ENOMEM;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(btmrvl_register_hdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct btmrvl_private *btmrvl_add_card(void *card)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct btmrvl_private *priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 | 
						priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 | 
				
			||||||
	if (!priv) {
 | 
						if (!priv) {
 | 
				
			||||||
		BT_ERR("Can not allocate priv");
 | 
							BT_ERR("Can not allocate priv");
 | 
				
			||||||
| 
						 | 
					@ -542,12 +602,6 @@ struct btmrvl_private *btmrvl_add_card(void *card)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	btmrvl_init_adapter(priv);
 | 
						btmrvl_init_adapter(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hdev = hci_alloc_dev();
 | 
					 | 
				
			||||||
	if (!hdev) {
 | 
					 | 
				
			||||||
		BT_ERR("Can not allocate HCI device");
 | 
					 | 
				
			||||||
		goto err_hdev;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	BT_DBG("Starting kthread...");
 | 
						BT_DBG("Starting kthread...");
 | 
				
			||||||
	priv->main_thread.priv = priv;
 | 
						priv->main_thread.priv = priv;
 | 
				
			||||||
	spin_lock_init(&priv->driver_lock);
 | 
						spin_lock_init(&priv->driver_lock);
 | 
				
			||||||
| 
						 | 
					@ -556,43 +610,11 @@ struct btmrvl_private *btmrvl_add_card(void *card)
 | 
				
			||||||
	priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
 | 
						priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
 | 
				
			||||||
				&priv->main_thread, "btmrvl_main_service");
 | 
									&priv->main_thread, "btmrvl_main_service");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->btmrvl_dev.hcidev = hdev;
 | 
					 | 
				
			||||||
	priv->btmrvl_dev.card = card;
 | 
						priv->btmrvl_dev.card = card;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	hdev->driver_data = priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	priv->btmrvl_dev.tx_dnld_rdy = true;
 | 
						priv->btmrvl_dev.tx_dnld_rdy = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hdev->bus = HCI_SDIO;
 | 
					 | 
				
			||||||
	hdev->open = btmrvl_open;
 | 
					 | 
				
			||||||
	hdev->close = btmrvl_close;
 | 
					 | 
				
			||||||
	hdev->flush = btmrvl_flush;
 | 
					 | 
				
			||||||
	hdev->send = btmrvl_send_frame;
 | 
					 | 
				
			||||||
	hdev->destruct = btmrvl_destruct;
 | 
					 | 
				
			||||||
	hdev->ioctl = btmrvl_ioctl;
 | 
					 | 
				
			||||||
	hdev->owner = THIS_MODULE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = hci_register_dev(hdev);
 | 
					 | 
				
			||||||
	if (ret < 0) {
 | 
					 | 
				
			||||||
		BT_ERR("Can not register HCI device");
 | 
					 | 
				
			||||||
		goto err_hci_register_dev;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					 | 
				
			||||||
	btmrvl_debugfs_init(hdev);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return priv;
 | 
						return priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_hci_register_dev:
 | 
					 | 
				
			||||||
	/* Stop the thread servicing the interrupts */
 | 
					 | 
				
			||||||
	kthread_stop(priv->main_thread.task);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hci_free_dev(hdev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
err_hdev:
 | 
					 | 
				
			||||||
	btmrvl_free_adapter(priv);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
err_adapter:
 | 
					err_adapter:
 | 
				
			||||||
	kfree(priv);
 | 
						kfree(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -931,7 +931,12 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
 | 
				
			||||||
	priv->hw_host_to_card = btmrvl_sdio_host_to_card;
 | 
						priv->hw_host_to_card = btmrvl_sdio_host_to_card;
 | 
				
			||||||
	priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
 | 
						priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
 | 
						if (btmrvl_register_hdev(priv)) {
 | 
				
			||||||
 | 
							BT_ERR("Register hdev failed!");
 | 
				
			||||||
 | 
							ret = -ENODEV;
 | 
				
			||||||
 | 
							goto disable_host_int;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->btmrvl_dev.psmode = 1;
 | 
						priv->btmrvl_dev.psmode = 1;
 | 
				
			||||||
	btmrvl_enable_ps(priv);
 | 
						btmrvl_enable_ps(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,7 +246,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
 | 
				
			||||||
			BT_ERR("Can't allocate mem for new packet");
 | 
								BT_ERR("Can't allocate mem for new packet");
 | 
				
			||||||
			h4->rx_state = H4_W4_PACKET_TYPE;
 | 
								h4->rx_state = H4_W4_PACKET_TYPE;
 | 
				
			||||||
			h4->rx_count = 0;
 | 
								h4->rx_count = 0;
 | 
				
			||||||
			return 0;
 | 
								return -ENOMEM;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		h4->rx_skb->dev = (void *) hu->hdev;
 | 
							h4->rx_skb->dev = (void *) hu->hdev;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,7 +402,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case HCILL_W4_EVENT_HDR:
 | 
								case HCILL_W4_EVENT_HDR:
 | 
				
			||||||
				eh = (struct hci_event_hdr *) ll->rx_skb->data;
 | 
									eh = hci_event_hdr(ll->rx_skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
 | 
									BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -410,7 +410,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case HCILL_W4_ACL_HDR:
 | 
								case HCILL_W4_ACL_HDR:
 | 
				
			||||||
				ah = (struct hci_acl_hdr *) ll->rx_skb->data;
 | 
									ah = hci_acl_hdr(ll->rx_skb);
 | 
				
			||||||
				dlen = __le16_to_cpu(ah->dlen);
 | 
									dlen = __le16_to_cpu(ah->dlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				BT_DBG("ACL header: dlen %d", dlen);
 | 
									BT_DBG("ACL header: dlen %d", dlen);
 | 
				
			||||||
| 
						 | 
					@ -419,7 +419,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case HCILL_W4_SCO_HDR:
 | 
								case HCILL_W4_SCO_HDR:
 | 
				
			||||||
				sh = (struct hci_sco_hdr *) ll->rx_skb->data;
 | 
									sh = hci_sco_hdr(ll->rx_skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				BT_DBG("SCO header: dlen %d", sh->dlen);
 | 
									BT_DBG("SCO header: dlen %d", sh->dlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -491,7 +491,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
 | 
				
			||||||
			BT_ERR("Can't allocate mem for new packet");
 | 
								BT_ERR("Can't allocate mem for new packet");
 | 
				
			||||||
			ll->rx_state = HCILL_W4_PACKET_TYPE;
 | 
								ll->rx_state = HCILL_W4_PACKET_TYPE;
 | 
				
			||||||
			ll->rx_count = 0;
 | 
								ll->rx_count = 0;
 | 
				
			||||||
			return 0;
 | 
								return -ENOMEM;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ll->rx_skb->dev = (void *) hu->hdev;
 | 
							ll->rx_skb->dev = (void *) hu->hdev;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,7 +157,7 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case HCI_SCODATA_PKT:
 | 
						case HCI_SCODATA_PKT:
 | 
				
			||||||
		data->hdev->stat.cmd_tx++;
 | 
							data->hdev->stat.sco_tx++;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -877,7 +877,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
 | 
				
			||||||
	if (!mc_all_on) {
 | 
						if (!mc_all_on) {
 | 
				
			||||||
		char *addrs;
 | 
							char *addrs;
 | 
				
			||||||
		int i;
 | 
							int i;
 | 
				
			||||||
		struct dev_mc_list *mcaddr;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		addrs = kmalloc(ETH_ALEN * mc_count, GFP_ATOMIC);
 | 
							addrs = kmalloc(ETH_ALEN * mc_count, GFP_ATOMIC);
 | 
				
			||||||
		if (!addrs) {
 | 
							if (!addrs) {
 | 
				
			||||||
| 
						 | 
					@ -885,9 +885,8 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
 | 
				
			||||||
			goto unlock;
 | 
								goto unlock;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		i = 0;
 | 
							i = 0;
 | 
				
			||||||
		netdev_for_each_mc_addr(mcaddr, netdev)
 | 
							netdev_for_each_mc_addr(ha, netdev)
 | 
				
			||||||
			memcpy(get_addr(addrs, i++),
 | 
								memcpy(get_addr(addrs, i++), ha->addr, ETH_ALEN);
 | 
				
			||||||
			       mcaddr->dmi_addr, ETH_ALEN);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
 | 
							perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
 | 
				
			||||||
						pft_entries_preallocated * 0x8;
 | 
											pft_entries_preallocated * 0x8;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -768,11 +768,8 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ipoib_mcast_addr_is_valid(const u8 *addr, unsigned int addrlen,
 | 
					static int ipoib_mcast_addr_is_valid(const u8 *addr, const u8 *broadcast)
 | 
				
			||||||
				     const u8 *broadcast)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (addrlen != INFINIBAND_ALEN)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	/* reserved QPN, prefix, scope */
 | 
						/* reserved QPN, prefix, scope */
 | 
				
			||||||
	if (memcmp(addr, broadcast, 6))
 | 
						if (memcmp(addr, broadcast, 6))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -787,7 +784,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
 | 
				
			||||||
	struct ipoib_dev_priv *priv =
 | 
						struct ipoib_dev_priv *priv =
 | 
				
			||||||
		container_of(work, struct ipoib_dev_priv, restart_task);
 | 
							container_of(work, struct ipoib_dev_priv, restart_task);
 | 
				
			||||||
	struct net_device *dev = priv->dev;
 | 
						struct net_device *dev = priv->dev;
 | 
				
			||||||
	struct dev_mc_list *mclist;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	struct ipoib_mcast *mcast, *tmcast;
 | 
						struct ipoib_mcast *mcast, *tmcast;
 | 
				
			||||||
	LIST_HEAD(remove_list);
 | 
						LIST_HEAD(remove_list);
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
| 
						 | 
					@ -812,15 +809,13 @@ void ipoib_mcast_restart_task(struct work_struct *work)
 | 
				
			||||||
		clear_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags);
 | 
							clear_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Mark all of the entries that are found or don't exist */
 | 
						/* Mark all of the entries that are found or don't exist */
 | 
				
			||||||
	netdev_for_each_mc_addr(mclist, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		union ib_gid mgid;
 | 
							union ib_gid mgid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!ipoib_mcast_addr_is_valid(mclist->dmi_addr,
 | 
							if (!ipoib_mcast_addr_is_valid(ha->addr, dev->broadcast))
 | 
				
			||||||
					       mclist->dmi_addrlen,
 | 
					 | 
				
			||||||
					       dev->broadcast))
 | 
					 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
 | 
							memcpy(mgid.raw, ha->addr + 4, sizeof mgid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		mcast = __ipoib_mcast_find(dev, &mgid);
 | 
							mcast = __ipoib_mcast_find(dev, &mgid);
 | 
				
			||||||
		if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
 | 
							if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -194,7 +194,7 @@ static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb
 | 
				
			||||||
	if ( ( (ix25_pdata_t*) (cprot->proto_data) ) 
 | 
						if ( ( (ix25_pdata_t*) (cprot->proto_data) ) 
 | 
				
			||||||
	     -> state == WAN_CONNECTED ){
 | 
						     -> state == WAN_CONNECTED ){
 | 
				
			||||||
		if( skb_push(skb, 1)){
 | 
							if( skb_push(skb, 1)){
 | 
				
			||||||
			skb -> data[0]=0x00;
 | 
								skb->data[0] = X25_IFACE_DATA;
 | 
				
			||||||
			skb->protocol = x25_type_trans(skb, cprot->net_dev);
 | 
								skb->protocol = x25_type_trans(skb, cprot->net_dev);
 | 
				
			||||||
			netif_rx(skb);
 | 
								netif_rx(skb);
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
| 
						 | 
					@ -224,7 +224,7 @@ static int isdn_x25iface_connect_ind(struct concap_proto *cprot)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb = dev_alloc_skb(1);
 | 
						skb = dev_alloc_skb(1);
 | 
				
			||||||
	if( skb ){
 | 
						if( skb ){
 | 
				
			||||||
		*( skb_put(skb, 1) ) = 0x01;
 | 
							*(skb_put(skb, 1)) = X25_IFACE_CONNECT;
 | 
				
			||||||
		skb->protocol = x25_type_trans(skb, cprot->net_dev);
 | 
							skb->protocol = x25_type_trans(skb, cprot->net_dev);
 | 
				
			||||||
		netif_rx(skb);
 | 
							netif_rx(skb);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -253,7 +253,7 @@ static int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
 | 
				
			||||||
	*state_p = WAN_DISCONNECTED;
 | 
						*state_p = WAN_DISCONNECTED;
 | 
				
			||||||
	skb = dev_alloc_skb(1);
 | 
						skb = dev_alloc_skb(1);
 | 
				
			||||||
	if( skb ){
 | 
						if( skb ){
 | 
				
			||||||
		*( skb_put(skb, 1) ) = 0x02;
 | 
							*(skb_put(skb, 1)) = X25_IFACE_DISCONNECT;
 | 
				
			||||||
		skb->protocol = x25_type_trans(skb, cprot->net_dev);
 | 
							skb->protocol = x25_type_trans(skb, cprot->net_dev);
 | 
				
			||||||
		netif_rx(skb);
 | 
							netif_rx(skb);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -272,9 +272,10 @@ static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
 | 
				
			||||||
	unsigned char firstbyte = skb->data[0];
 | 
						unsigned char firstbyte = skb->data[0];
 | 
				
			||||||
	enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state;
 | 
						enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
	IX25DEBUG( "isdn_x25iface_xmit: %s first=%x state=%d \n", MY_DEVNAME(cprot -> net_dev), firstbyte, *state );
 | 
						IX25DEBUG("isdn_x25iface_xmit: %s first=%x state=%d\n",
 | 
				
			||||||
 | 
							MY_DEVNAME(cprot->net_dev), firstbyte, *state);
 | 
				
			||||||
	switch ( firstbyte ){
 | 
						switch ( firstbyte ){
 | 
				
			||||||
	case 0x00: /* dl_data request */
 | 
						case X25_IFACE_DATA:
 | 
				
			||||||
		if( *state == WAN_CONNECTED ){
 | 
							if( *state == WAN_CONNECTED ){
 | 
				
			||||||
			skb_pull(skb, 1);
 | 
								skb_pull(skb, 1);
 | 
				
			||||||
			cprot -> net_dev -> trans_start = jiffies;
 | 
								cprot -> net_dev -> trans_start = jiffies;
 | 
				
			||||||
| 
						 | 
					@ -285,7 +286,7 @@ static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		illegal_state_warn( *state, firstbyte ); 
 | 
							illegal_state_warn( *state, firstbyte ); 
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 0x01: /* dl_connect request */
 | 
						case X25_IFACE_CONNECT:
 | 
				
			||||||
		if( *state == WAN_DISCONNECTED ){
 | 
							if( *state == WAN_DISCONNECTED ){
 | 
				
			||||||
			*state = WAN_CONNECTING;
 | 
								*state = WAN_CONNECTING;
 | 
				
			||||||
		        ret = cprot -> dops -> connect_req(cprot);
 | 
							        ret = cprot -> dops -> connect_req(cprot);
 | 
				
			||||||
| 
						 | 
					@ -298,7 +299,7 @@ static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
 | 
				
			||||||
			illegal_state_warn( *state, firstbyte );
 | 
								illegal_state_warn( *state, firstbyte );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 0x02: /* dl_disconnect request */
 | 
						case X25_IFACE_DISCONNECT:
 | 
				
			||||||
		switch ( *state ){
 | 
							switch ( *state ){
 | 
				
			||||||
		case WAN_DISCONNECTED: 
 | 
							case WAN_DISCONNECTED: 
 | 
				
			||||||
			/* Should not happen. However, give upper layer a
 | 
								/* Should not happen. However, give upper layer a
 | 
				
			||||||
| 
						 | 
					@ -318,7 +319,7 @@ static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
 | 
				
			||||||
			illegal_state_warn( *state, firstbyte );
 | 
								illegal_state_warn( *state, firstbyte );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 0x03: /* changing lapb parameters requested */
 | 
						case X25_IFACE_PARAMS:
 | 
				
			||||||
		printk(KERN_WARNING "isdn_x25iface_xmit: setting of lapb"
 | 
							printk(KERN_WARNING "isdn_x25iface_xmit: setting of lapb"
 | 
				
			||||||
		       " options not yet supported\n");
 | 
							       " options not yet supported\n");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1109,14 +1109,14 @@ static int dvb_net_feed_stop(struct net_device *dev)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
 | 
					static int dvb_set_mc_filter(struct net_device *dev, unsigned char *addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dvb_net_priv *priv = netdev_priv(dev);
 | 
						struct dvb_net_priv *priv = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->multi_num == DVB_NET_MULTICAST_MAX)
 | 
						if (priv->multi_num == DVB_NET_MULTICAST_MAX)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
 | 
						memcpy(priv->multi_macs[priv->multi_num], addr, ETH_ALEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->multi_num++;
 | 
						priv->multi_num++;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -1140,8 +1140,7 @@ static void wq_set_multicast_list (struct work_struct *work)
 | 
				
			||||||
		dprintk("%s: allmulti mode\n", dev->name);
 | 
							dprintk("%s: allmulti mode\n", dev->name);
 | 
				
			||||||
		priv->rx_mode = RX_MODE_ALL_MULTI;
 | 
							priv->rx_mode = RX_MODE_ALL_MULTI;
 | 
				
			||||||
	} else if (!netdev_mc_empty(dev)) {
 | 
						} else if (!netdev_mc_empty(dev)) {
 | 
				
			||||||
		int mci;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
		struct dev_mc_list *mc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dprintk("%s: set_mc_list, %d entries\n",
 | 
							dprintk("%s: set_mc_list, %d entries\n",
 | 
				
			||||||
			dev->name, netdev_mc_count(dev));
 | 
								dev->name, netdev_mc_count(dev));
 | 
				
			||||||
| 
						 | 
					@ -1149,11 +1148,8 @@ static void wq_set_multicast_list (struct work_struct *work)
 | 
				
			||||||
		priv->rx_mode = RX_MODE_MULTI;
 | 
							priv->rx_mode = RX_MODE_MULTI;
 | 
				
			||||||
		priv->multi_num = 0;
 | 
							priv->multi_num = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (mci = 0, mc=dev->mc_list;
 | 
							netdev_for_each_mc_addr(ha, dev)
 | 
				
			||||||
		     mci < netdev_mc_count(dev);
 | 
								dvb_set_mc_filter(dev, ha->addr);
 | 
				
			||||||
		     mc = mc->next, mci++) {
 | 
					 | 
				
			||||||
			dvb_set_mc_filter(dev, mc);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_addr_unlock_bh(dev);
 | 
						netif_addr_unlock_bh(dev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -480,7 +480,6 @@ static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
			/* fire ... Trigger xmit.  */
 | 
								/* fire ... Trigger xmit.  */
 | 
				
			||||||
			outb(AX_XMIT, AX_CMD);
 | 
								outb(AX_XMIT, AX_CMD);
 | 
				
			||||||
			lp->loading = 0;
 | 
								lp->loading = 0;
 | 
				
			||||||
			dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
			if (el_debug > 2)
 | 
								if (el_debug > 2)
 | 
				
			||||||
				pr_debug(" queued xmit.\n");
 | 
									pr_debug(" queued xmit.\n");
 | 
				
			||||||
			dev_kfree_skb(skb);
 | 
								dev_kfree_skb(skb);
 | 
				
			||||||
| 
						 | 
					@ -727,7 +726,6 @@ static void el_receive(struct net_device *dev)
 | 
				
			||||||
		dev->stats.rx_packets++;
 | 
							dev->stats.rx_packets++;
 | 
				
			||||||
		dev->stats.rx_bytes += pkt_len;
 | 
							dev->stats.rx_bytes += pkt_len;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -380,6 +380,12 @@ el2_probe1(struct net_device *dev, int ioaddr)
 | 
				
			||||||
    return retval;
 | 
					    return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static irqreturn_t el2_probe_interrupt(int irq, void *seen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*(bool *)seen = true;
 | 
				
			||||||
 | 
						return IRQ_HANDLED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
el2_open(struct net_device *dev)
 | 
					el2_open(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -391,23 +397,35 @@ el2_open(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	outb(EGACFR_NORM, E33G_GACFR);	/* Enable RAM and interrupts. */
 | 
						outb(EGACFR_NORM, E33G_GACFR);	/* Enable RAM and interrupts. */
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
	    retval = request_irq(*irqp, NULL, 0, "bogus", dev);
 | 
							bool seen;
 | 
				
			||||||
	    if (retval >= 0) {
 | 
					
 | 
				
			||||||
 | 
							retval = request_irq(*irqp, el2_probe_interrupt, 0,
 | 
				
			||||||
 | 
									     dev->name, &seen);
 | 
				
			||||||
 | 
							if (retval == -EBUSY)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (retval < 0)
 | 
				
			||||||
 | 
								goto err_disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Twinkle the interrupt, and check if it's seen. */
 | 
							/* Twinkle the interrupt, and check if it's seen. */
 | 
				
			||||||
		unsigned long cookie = probe_irq_on();
 | 
							seen = false;
 | 
				
			||||||
 | 
							smp_wmb();
 | 
				
			||||||
		outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
 | 
							outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
 | 
				
			||||||
		outb_p(0x00, E33G_IDCFR);
 | 
							outb_p(0x00, E33G_IDCFR);
 | 
				
			||||||
		if (*irqp == probe_irq_off(cookie) &&	/* It's a good IRQ line! */
 | 
							msleep(1);
 | 
				
			||||||
		    ((retval = request_irq(dev->irq = *irqp,
 | 
							free_irq(*irqp, el2_probe_interrupt);
 | 
				
			||||||
					   eip_interrupt, 0,
 | 
							if (!seen)
 | 
				
			||||||
					   dev->name, dev)) == 0))
 | 
								continue;
 | 
				
			||||||
		    break;
 | 
					
 | 
				
			||||||
	    } else {
 | 
							retval = request_irq(dev->irq = *irqp, eip_interrupt, 0,
 | 
				
			||||||
		    if (retval != -EBUSY)
 | 
									     dev->name, dev);
 | 
				
			||||||
			    return retval;
 | 
							if (retval == -EBUSY)
 | 
				
			||||||
	    }
 | 
								continue;
 | 
				
			||||||
 | 
							if (retval < 0)
 | 
				
			||||||
 | 
								goto err_disable;
 | 
				
			||||||
	} while (*++irqp);
 | 
						} while (*++irqp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (*irqp == 0) {
 | 
						if (*irqp == 0) {
 | 
				
			||||||
 | 
						err_disable:
 | 
				
			||||||
	    outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */
 | 
						    outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */
 | 
				
			||||||
	    return -EAGAIN;
 | 
						    return -EAGAIN;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -555,7 +573,6 @@ el2_block_output(struct net_device *dev, int count,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    blocked:;
 | 
					    blocked:;
 | 
				
			||||||
    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 | 
					    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Read the 4 byte, page aligned 8390 specific header. */
 | 
					/* Read the 4 byte, page aligned 8390 specific header. */
 | 
				
			||||||
| 
						 | 
					@ -671,7 +688,6 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    blocked:;
 | 
					    blocked:;
 | 
				
			||||||
    outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 | 
					    outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1055,7 +1055,7 @@ static void elp_timeout(struct net_device *dev)
 | 
				
			||||||
		   (stat & ACRF) ? "interrupt" : "command");
 | 
							   (stat & ACRF) ? "interrupt" : "command");
 | 
				
			||||||
	if (elp_debug >= 1)
 | 
						if (elp_debug >= 1)
 | 
				
			||||||
		pr_debug("%s: status %#02x\n", dev->name, stat);
 | 
							pr_debug("%s: status %#02x\n", dev->name, stat);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	dev->stats.tx_dropped++;
 | 
						dev->stats.tx_dropped++;
 | 
				
			||||||
	netif_wake_queue(dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1093,11 +1093,6 @@ static netdev_tx_t elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	if (elp_debug >= 3)
 | 
						if (elp_debug >= 3)
 | 
				
			||||||
		pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
 | 
							pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * start the transmit timeout
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prime_rx(dev);
 | 
						prime_rx(dev);
 | 
				
			||||||
	spin_unlock_irqrestore(&adapter->lock, flags);
 | 
						spin_unlock_irqrestore(&adapter->lock, flags);
 | 
				
			||||||
	netif_start_queue(dev);
 | 
						netif_start_queue(dev);
 | 
				
			||||||
| 
						 | 
					@ -1216,7 +1211,7 @@ static int elp_close(struct net_device *dev)
 | 
				
			||||||
static void elp_set_mc_list(struct net_device *dev)
 | 
					static void elp_set_mc_list(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	elp_device *adapter = netdev_priv(dev);
 | 
						elp_device *adapter = netdev_priv(dev);
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1231,8 +1226,9 @@ static void elp_set_mc_list(struct net_device *dev)
 | 
				
			||||||
		adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
 | 
							adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
 | 
				
			||||||
		adapter->tx_pcb.length = 6 * netdev_mc_count(dev);
 | 
							adapter->tx_pcb.length = 6 * netdev_mc_count(dev);
 | 
				
			||||||
		i = 0;
 | 
							i = 0;
 | 
				
			||||||
		netdev_for_each_mc_addr(dmi, dev)
 | 
							netdev_for_each_mc_addr(ha, dev)
 | 
				
			||||||
			memcpy(adapter->tx_pcb.data.multicast[i++], dmi->dmi_addr, 6);
 | 
								memcpy(adapter->tx_pcb.data.multicast[i++],
 | 
				
			||||||
 | 
								       ha->addr, 6);
 | 
				
			||||||
		adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
 | 
							adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
 | 
				
			||||||
		if (!send_pcb(dev, &adapter->tx_pcb))
 | 
							if (!send_pcb(dev, &adapter->tx_pcb))
 | 
				
			||||||
			pr_err("%s: couldn't send set_multicast command\n", dev->name);
 | 
								pr_err("%s: couldn't send set_multicast command\n", dev->name);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -449,7 +449,6 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
 | 
				
			||||||
		pr_debug("%s", version);
 | 
							pr_debug("%s", version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lp = netdev_priv(dev);
 | 
						lp = netdev_priv(dev);
 | 
				
			||||||
 	memset(lp, 0, sizeof(*lp));
 | 
					 | 
				
			||||||
	spin_lock_init(&lp->lock);
 | 
						spin_lock_init(&lp->lock);
 | 
				
			||||||
	lp->base = ioremap(dev->mem_start, RX_BUF_END);
 | 
						lp->base = ioremap(dev->mem_start, RX_BUF_END);
 | 
				
			||||||
	if (!lp->base) {
 | 
						if (!lp->base) {
 | 
				
			||||||
| 
						 | 
					@ -505,7 +504,7 @@ static void el16_tx_timeout (struct net_device *dev)
 | 
				
			||||||
		outb (0, ioaddr + SIGNAL_CA);	/* Issue channel-attn. */
 | 
							outb (0, ioaddr + SIGNAL_CA);	/* Issue channel-attn. */
 | 
				
			||||||
		lp->last_restart = dev->stats.tx_packets;
 | 
							lp->last_restart = dev->stats.tx_packets;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue (dev);
 | 
						netif_wake_queue (dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,7 +528,6 @@ static netdev_tx_t el16_send_packet (struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hardware_send_packet (dev, buf, skb->len, length - skb->len);
 | 
						hardware_send_packet (dev, buf, skb->len, length - skb->len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	/* Enable the 82586 interrupt input. */
 | 
						/* Enable the 82586 interrupt input. */
 | 
				
			||||||
	outb (0x84, ioaddr + MISC_CTRL);
 | 
						outb (0x84, ioaddr + MISC_CTRL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -766,7 +764,6 @@ static void init_82586_mem(struct net_device *dev)
 | 
				
			||||||
	if (net_debug > 4)
 | 
						if (net_debug > 4)
 | 
				
			||||||
		pr_debug("%s: Initialized 82586, status %04x.\n", dev->name,
 | 
							pr_debug("%s: Initialized 82586, status %04x.\n", dev->name,
 | 
				
			||||||
			   readw(shmem+iSCB_STATUS));
 | 
								   readw(shmem+iSCB_STATUS));
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad)
 | 
					static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -807,7 +807,7 @@ el3_tx_timeout (struct net_device *dev)
 | 
				
			||||||
		   dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
 | 
							   dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
 | 
				
			||||||
		   inw(ioaddr + TX_FREE));
 | 
							   inw(ioaddr + TX_FREE));
 | 
				
			||||||
	dev->stats.tx_errors++;
 | 
						dev->stats.tx_errors++;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	/* Issue TX_RESET and TX_START commands. */
 | 
						/* Issue TX_RESET and TX_START commands. */
 | 
				
			||||||
	outw(TxReset, ioaddr + EL3_CMD);
 | 
						outw(TxReset, ioaddr + EL3_CMD);
 | 
				
			||||||
	outw(TxEnable, ioaddr + EL3_CMD);
 | 
						outw(TxEnable, ioaddr + EL3_CMD);
 | 
				
			||||||
| 
						 | 
					@ -868,7 +868,6 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	/* ... and the packet rounded to a doubleword. */
 | 
						/* ... and the packet rounded to a doubleword. */
 | 
				
			||||||
	outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 | 
						outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	if (inw(ioaddr + TX_FREE) > 1536)
 | 
						if (inw(ioaddr + TX_FREE) > 1536)
 | 
				
			||||||
		netif_start_queue(dev);
 | 
							netif_start_queue(dev);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -1038,7 +1037,6 @@ static void update_stats(struct net_device *dev)
 | 
				
			||||||
	/* Back to window 1, and turn statistics back on. */
 | 
						/* Back to window 1, and turn statistics back on. */
 | 
				
			||||||
	EL3WINDOW(1);
 | 
						EL3WINDOW(1);
 | 
				
			||||||
	outw(StatsEnable, ioaddr + EL3_CMD);
 | 
						outw(StatsEnable, ioaddr + EL3_CMD);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -958,7 +958,6 @@ static void corkscrew_timer(unsigned long data)
 | 
				
			||||||
		       dev->name, media_tbl[dev->if_port].name);
 | 
							       dev->name, media_tbl[dev->if_port].name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif				/* AUTOMEDIA */
 | 
					#endif				/* AUTOMEDIA */
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void corkscrew_timeout(struct net_device *dev)
 | 
					static void corkscrew_timeout(struct net_device *dev)
 | 
				
			||||||
| 
						 | 
					@ -992,7 +991,7 @@ static void corkscrew_timeout(struct net_device *dev)
 | 
				
			||||||
		if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
 | 
							if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	outw(TxEnable, ioaddr + EL3_CMD);
 | 
						outw(TxEnable, ioaddr + EL3_CMD);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	dev->stats.tx_errors++;
 | 
						dev->stats.tx_errors++;
 | 
				
			||||||
	dev->stats.tx_dropped++;
 | 
						dev->stats.tx_dropped++;
 | 
				
			||||||
	netif_wake_queue(dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
| 
						 | 
					@ -1055,7 +1054,6 @@ static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
				prev_entry->status &= ~0x80000000;
 | 
									prev_entry->status &= ~0x80000000;
 | 
				
			||||||
			netif_wake_queue(dev);
 | 
								netif_wake_queue(dev);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
		return NETDEV_TX_OK;
 | 
							return NETDEV_TX_OK;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* Put out the doubleword header... */
 | 
						/* Put out the doubleword header... */
 | 
				
			||||||
| 
						 | 
					@ -1091,7 +1089,6 @@ static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
		outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
 | 
							outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
 | 
				
			||||||
#endif				/* bus master */
 | 
					#endif				/* bus master */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Clear the Tx status stack. */
 | 
						/* Clear the Tx status stack. */
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -1518,7 +1515,6 @@ static void update_stats(int ioaddr, struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We change back to window 7 (not 1) with the Vortex. */
 | 
						/* We change back to window 7 (not 1) with the Vortex. */
 | 
				
			||||||
	EL3WINDOW(7);
 | 
						EL3WINDOW(7);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This new version of set_rx_mode() supports v1.4 kernels.
 | 
					/* This new version of set_rx_mode() supports v1.4 kernels.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -503,7 +503,6 @@ static int __init do_elmc_probe(struct net_device *dev)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(pr, 0, sizeof(struct priv));
 | 
					 | 
				
			||||||
	pr->slot = slot;
 | 
						pr->slot = slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
 | 
						pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
 | 
				
			||||||
| 
						 | 
					@ -624,7 +623,7 @@ static int init586(struct net_device *dev)
 | 
				
			||||||
	volatile struct iasetup_cmd_struct *ias_cmd;
 | 
						volatile struct iasetup_cmd_struct *ias_cmd;
 | 
				
			||||||
	volatile struct tdr_cmd_struct *tdr_cmd;
 | 
						volatile struct tdr_cmd_struct *tdr_cmd;
 | 
				
			||||||
	volatile struct mcsetup_cmd_struct *mc_cmd;
 | 
						volatile struct mcsetup_cmd_struct *mc_cmd;
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	int num_addrs = netdev_mc_count(dev);
 | 
						int num_addrs = netdev_mc_count(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct));
 | 
						ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct));
 | 
				
			||||||
| 
						 | 
					@ -787,8 +786,9 @@ static int init586(struct net_device *dev)
 | 
				
			||||||
			mc_cmd->cmd_link = 0xffff;
 | 
								mc_cmd->cmd_link = 0xffff;
 | 
				
			||||||
			mc_cmd->mc_cnt = num_addrs * 6;
 | 
								mc_cmd->mc_cnt = num_addrs * 6;
 | 
				
			||||||
			i = 0;
 | 
								i = 0;
 | 
				
			||||||
			netdev_for_each_mc_addr(dmi, dev)
 | 
								netdev_for_each_mc_addr(ha, dev)
 | 
				
			||||||
				memcpy((char *) mc_cmd->mc_list[i++], dmi->dmi_addr, 6);
 | 
									memcpy((char *) mc_cmd->mc_list[i++],
 | 
				
			||||||
 | 
									       ha->addr, 6);
 | 
				
			||||||
			p->scb->cbl_offset = make16(mc_cmd);
 | 
								p->scb->cbl_offset = make16(mc_cmd);
 | 
				
			||||||
			p->scb->cmd = CUC_START;
 | 
								p->scb->cmd = CUC_START;
 | 
				
			||||||
			elmc_id_attn586();
 | 
								elmc_id_attn586();
 | 
				
			||||||
| 
						 | 
					@ -1152,7 +1152,6 @@ static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		p->scb->cmd = CUC_START;
 | 
							p->scb->cmd = CUC_START;
 | 
				
			||||||
		p->xmit_cmds[0]->cmd_status = 0;
 | 
							p->xmit_cmds[0]->cmd_status = 0;
 | 
				
			||||||
			elmc_attn586();
 | 
								elmc_attn586();
 | 
				
			||||||
		dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
		if (!i) {
 | 
							if (!i) {
 | 
				
			||||||
			dev_kfree_skb(skb);
 | 
								dev_kfree_skb(skb);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1176,7 +1175,6 @@ static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 | 
						p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
 | 
						p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	p->nop_point = next_nop;
 | 
						p->nop_point = next_nop;
 | 
				
			||||||
	dev_kfree_skb(skb);
 | 
						dev_kfree_skb(skb);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -1190,7 +1188,6 @@ static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	    = make16((p->nop_cmds[next_nop]));
 | 
						    = make16((p->nop_cmds[next_nop]));
 | 
				
			||||||
	p->nop_cmds[next_nop]->cmd_status = 0;
 | 
						p->nop_cmds[next_nop]->cmd_status = 0;
 | 
				
			||||||
		p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
 | 
							p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	p->xmit_count = next_nop;
 | 
						p->xmit_count = next_nop;
 | 
				
			||||||
	if (p->xmit_count != p->xmit_last)
 | 
						if (p->xmit_count != p->xmit_last)
 | 
				
			||||||
		netif_wake_queue(dev);
 | 
							netif_wake_queue(dev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1533,7 +1533,7 @@ static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		unsigned char block[62];
 | 
							unsigned char block[62];
 | 
				
			||||||
		unsigned char *bp;
 | 
							unsigned char *bp;
 | 
				
			||||||
		struct dev_mc_list *dmc;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(retry==0)
 | 
							if(retry==0)
 | 
				
			||||||
			lp->mc_list_valid = 0;
 | 
								lp->mc_list_valid = 0;
 | 
				
			||||||
| 
						 | 
					@ -1543,8 +1543,8 @@ static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
 | 
				
			||||||
			block[0]=netdev_mc_count(dev);
 | 
								block[0]=netdev_mc_count(dev);
 | 
				
			||||||
			bp=block+2;
 | 
								bp=block+2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			netdev_for_each_mc_addr(dmc, dev) {
 | 
								netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
				memcpy(bp, dmc->dmi_addr, 6);
 | 
									memcpy(bp, ha->addr, 6);
 | 
				
			||||||
				bp+=6;
 | 
									bp+=6;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if(mc32_command_nowait(dev, 2, block,
 | 
								if(mc32_command_nowait(dev, 2, block,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1855,7 +1855,6 @@ vortex_timer(unsigned long data)
 | 
				
			||||||
	mod_timer(&vp->timer, RUN_AT(next_tick));
 | 
						mod_timer(&vp->timer, RUN_AT(next_tick));
 | 
				
			||||||
	if (vp->deferred)
 | 
						if (vp->deferred)
 | 
				
			||||||
		iowrite16(FakeIntr, ioaddr + EL3_CMD);
 | 
							iowrite16(FakeIntr, ioaddr + EL3_CMD);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vortex_tx_timeout(struct net_device *dev)
 | 
					static void vortex_tx_timeout(struct net_device *dev)
 | 
				
			||||||
| 
						 | 
					@ -1917,7 +1916,7 @@ static void vortex_tx_timeout(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Issue Tx Enable */
 | 
						/* Issue Tx Enable */
 | 
				
			||||||
	iowrite16(TxEnable, ioaddr + EL3_CMD);
 | 
						iowrite16(TxEnable, ioaddr + EL3_CMD);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Switch to register set 7 for normal use. */
 | 
						/* Switch to register set 7 for normal use. */
 | 
				
			||||||
	EL3WINDOW(7);
 | 
						EL3WINDOW(7);
 | 
				
			||||||
| 
						 | 
					@ -2063,7 +2062,6 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Clear the Tx status stack. */
 | 
						/* Clear the Tx status stack. */
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -2129,8 +2127,8 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		int i;
 | 
							int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 | 
							vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 | 
				
			||||||
										skb->len-skb->data_len, PCI_DMA_TODEVICE));
 | 
															skb_headlen(skb), PCI_DMA_TODEVICE));
 | 
				
			||||||
		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len-skb->data_len);
 | 
							vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 | 
							for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 | 
				
			||||||
			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 | 
								skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 | 
				
			||||||
| 
						 | 
					@ -2174,7 +2172,6 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	iowrite16(DownUnstall, ioaddr + EL3_CMD);
 | 
						iowrite16(DownUnstall, ioaddr + EL3_CMD);
 | 
				
			||||||
	spin_unlock_irqrestore(&vp->lock, flags);
 | 
						spin_unlock_irqrestore(&vp->lock, flags);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2800,7 +2797,6 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EL3WINDOW(old_window >> 13);
 | 
						EL3WINDOW(old_window >> 13);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int vortex_nway_reset(struct net_device *dev)
 | 
					static int vortex_nway_reset(struct net_device *dev)
 | 
				
			||||||
| 
						 | 
					@ -3122,7 +3118,6 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 | 
				
			||||||
		iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 | 
							iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 | 
				
			||||||
		mdio_delay();
 | 
							mdio_delay();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ACPI: Advanced Configuration and Power Interface. */
 | 
					/* ACPI: Advanced Configuration and Power Interface. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,7 +262,7 @@ static int lance_reset (struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        load_csrs (lp);
 | 
					        load_csrs (lp);
 | 
				
			||||||
        lance_init_ring (dev);
 | 
					        lance_init_ring (dev);
 | 
				
			||||||
        dev->trans_start = jiffies;
 | 
					        dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
        status = init_restart_lance (lp);
 | 
					        status = init_restart_lance (lp);
 | 
				
			||||||
#ifdef DEBUG_DRIVER
 | 
					#ifdef DEBUG_DRIVER
 | 
				
			||||||
        printk ("Lance restart=%d\n", status);
 | 
					        printk ("Lance restart=%d\n", status);
 | 
				
			||||||
| 
						 | 
					@ -526,7 +526,7 @@ void lance_tx_timeout(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printk("lance_tx_timeout\n");
 | 
						printk("lance_tx_timeout\n");
 | 
				
			||||||
	lance_reset(dev);
 | 
						lance_reset(dev);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue (dev);
 | 
						netif_wake_queue (dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(lance_tx_timeout);
 | 
					EXPORT_SYMBOL_GPL(lance_tx_timeout);
 | 
				
			||||||
| 
						 | 
					@ -574,7 +574,6 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
        outs++;
 | 
					        outs++;
 | 
				
			||||||
        /* Kick the lance: transmit now */
 | 
					        /* Kick the lance: transmit now */
 | 
				
			||||||
        WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD);
 | 
					        WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD);
 | 
				
			||||||
        dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
        dev_kfree_skb (skb);
 | 
					        dev_kfree_skb (skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave (&lp->devlock, flags);
 | 
						spin_lock_irqsave (&lp->devlock, flags);
 | 
				
			||||||
| 
						 | 
					@ -594,7 +593,7 @@ static void lance_load_multicast (struct net_device *dev)
 | 
				
			||||||
        struct lance_private *lp = netdev_priv(dev);
 | 
					        struct lance_private *lp = netdev_priv(dev);
 | 
				
			||||||
        volatile struct lance_init_block *ib = lp->init_block;
 | 
					        volatile struct lance_init_block *ib = lp->init_block;
 | 
				
			||||||
        volatile u16 *mcast_table = (u16 *)&ib->filter;
 | 
					        volatile u16 *mcast_table = (u16 *)&ib->filter;
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
        char *addrs;
 | 
					        char *addrs;
 | 
				
			||||||
        u32 crc;
 | 
					        u32 crc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -609,8 +608,8 @@ static void lance_load_multicast (struct net_device *dev)
 | 
				
			||||||
        ib->filter [1] = 0;
 | 
					        ib->filter [1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Add addresses */
 | 
					        /* Add addresses */
 | 
				
			||||||
	netdev_for_each_mc_addr(dmi, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
                addrs = dmi->dmi_addr;
 | 
							addrs = ha->addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /* multicast address? */
 | 
					                /* multicast address? */
 | 
				
			||||||
                if (!(*addrs & 1))
 | 
					                if (!(*addrs & 1))
 | 
				
			||||||
| 
						 | 
					@ -620,7 +619,6 @@ static void lance_load_multicast (struct net_device *dev)
 | 
				
			||||||
                crc = crc >> 26;
 | 
					                crc = crc >> 26;
 | 
				
			||||||
                mcast_table [crc >> 4] |= 1 << (crc & 0xf);
 | 
					                mcast_table [crc >> 4] |= 1 << (crc & 0xf);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -882,7 +882,6 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
 | 
				
			||||||
	spin_unlock_irqrestore(&cp->lock, intr_flags);
 | 
						spin_unlock_irqrestore(&cp->lock, intr_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cpw8(TxPoll, NormalTxPoll);
 | 
						cpw8(TxPoll, NormalTxPoll);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -910,11 +909,11 @@ static void __cp_set_rx_mode (struct net_device *dev)
 | 
				
			||||||
		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 | 
							rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 | 
				
			||||||
		mc_filter[1] = mc_filter[0] = 0xffffffff;
 | 
							mc_filter[1] = mc_filter[0] = 0xffffffff;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct dev_mc_list *mclist;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
		rx_mode = AcceptBroadcast | AcceptMyPhys;
 | 
							rx_mode = AcceptBroadcast | AcceptMyPhys;
 | 
				
			||||||
		mc_filter[1] = mc_filter[0] = 0;
 | 
							mc_filter[1] = mc_filter[0] = 0;
 | 
				
			||||||
		netdev_for_each_mc_addr(mclist, dev) {
 | 
							netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 | 
								int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 | 
								mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 | 
				
			||||||
			rx_mode |= AcceptMulticast;
 | 
								rx_mode |= AcceptMulticast;
 | 
				
			||||||
| 
						 | 
					@ -1225,8 +1224,6 @@ static void cp_tx_timeout(struct net_device *dev)
 | 
				
			||||||
	netif_wake_queue(dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irqrestore(&cp->lock, flags);
 | 
						spin_unlock_irqrestore(&cp->lock, flags);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef BROKEN
 | 
					#ifdef BROKEN
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1716,8 +1716,6 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
 | 
				
			||||||
	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
 | 
						RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
 | 
				
			||||||
		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 | 
							   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tp->cur_tx++;
 | 
						tp->cur_tx++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 | 
						if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 | 
				
			||||||
| 
						 | 
					@ -2503,11 +2501,11 @@ static void __set_rx_mode (struct net_device *dev)
 | 
				
			||||||
		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 | 
							rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 | 
				
			||||||
		mc_filter[1] = mc_filter[0] = 0xffffffff;
 | 
							mc_filter[1] = mc_filter[0] = 0xffffffff;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct dev_mc_list *mclist;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
		rx_mode = AcceptBroadcast | AcceptMyPhys;
 | 
							rx_mode = AcceptBroadcast | AcceptMyPhys;
 | 
				
			||||||
		mc_filter[1] = mc_filter[0] = 0;
 | 
							mc_filter[1] = mc_filter[0] = 0;
 | 
				
			||||||
		netdev_for_each_mc_addr(mclist, dev) {
 | 
							netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 | 
								int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 | 
								mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 | 
				
			||||||
			rx_mode |= AcceptMulticast;
 | 
								rx_mode |= AcceptMulticast;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1050,7 +1050,7 @@ static void i596_tx_timeout (struct net_device *dev)
 | 
				
			||||||
		lp->last_restart = dev->stats.tx_packets;
 | 
							lp->last_restart = dev->stats.tx_packets;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue (dev);
 | 
						netif_wake_queue (dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1060,7 +1060,6 @@ static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	struct tx_cmd *tx_cmd;
 | 
						struct tx_cmd *tx_cmd;
 | 
				
			||||||
	struct i596_tbd *tbd;
 | 
						struct i596_tbd *tbd;
 | 
				
			||||||
	short length = skb->len;
 | 
						short length = skb->len;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%p) called\n",
 | 
						DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%p) called\n",
 | 
				
			||||||
				dev->name, skb->len, skb->data));
 | 
									dev->name, skb->len, skb->data));
 | 
				
			||||||
| 
						 | 
					@ -1542,7 +1541,7 @@ static void set_multicast_list(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!netdev_mc_empty(dev)) {
 | 
						if (!netdev_mc_empty(dev)) {
 | 
				
			||||||
		struct dev_mc_list *dmi;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
		unsigned char *cp;
 | 
							unsigned char *cp;
 | 
				
			||||||
		struct mc_cmd *cmd;
 | 
							struct mc_cmd *cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1552,10 +1551,10 @@ static void set_multicast_list(struct net_device *dev)
 | 
				
			||||||
		cmd->cmd.command = CmdMulticastList;
 | 
							cmd->cmd.command = CmdMulticastList;
 | 
				
			||||||
		cmd->mc_cnt = cnt * ETH_ALEN;
 | 
							cmd->mc_cnt = cnt * ETH_ALEN;
 | 
				
			||||||
		cp = cmd->mc_addrs;
 | 
							cp = cmd->mc_addrs;
 | 
				
			||||||
		netdev_for_each_mc_addr(dmi, dev) {
 | 
							netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
			if (!cnt--)
 | 
								if (!cnt--)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			memcpy(cp, dmi->dmi_addr, ETH_ALEN);
 | 
								memcpy(cp, ha->addr, ETH_ALEN);
 | 
				
			||||||
			if (i596_debug > 1)
 | 
								if (i596_debug > 1)
 | 
				
			||||||
				DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %pM\n",
 | 
									DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %pM\n",
 | 
				
			||||||
						dev->name, cp));
 | 
											dev->name, cp));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -483,7 +483,7 @@ config XTENSA_XT2000_SONIC
 | 
				
			||||||
	  This is the driver for the onboard card of the Xtensa XT2000 board.
 | 
						  This is the driver for the onboard card of the Xtensa XT2000 board.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config MIPS_AU1X00_ENET
 | 
					config MIPS_AU1X00_ENET
 | 
				
			||||||
	bool "MIPS AU1000 Ethernet support"
 | 
						tristate "MIPS AU1000 Ethernet support"
 | 
				
			||||||
	depends on SOC_AU1X00
 | 
						depends on SOC_AU1X00
 | 
				
			||||||
	select PHYLIB
 | 
						select PHYLIB
 | 
				
			||||||
	select CRC32
 | 
						select CRC32
 | 
				
			||||||
| 
						 | 
					@ -887,6 +887,13 @@ config BFIN_MAC_RMII
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Use Reduced PHY MII Interface
 | 
						  Use Reduced PHY MII Interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config BFIN_MAC_USE_HWSTAMP
 | 
				
			||||||
 | 
						bool "Use IEEE 1588 hwstamp"
 | 
				
			||||||
 | 
						depends on BFIN_MAC && BF518
 | 
				
			||||||
 | 
						default y
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  To support the IEEE 1588 Precision Time Protocol (PTP), select y here
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SMC9194
 | 
					config SMC9194
 | 
				
			||||||
	tristate "SMC 9194 support"
 | 
						tristate "SMC 9194 support"
 | 
				
			||||||
	depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
 | 
						depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
 | 
				
			||||||
| 
						 | 
					@ -1453,20 +1460,6 @@ config FORCEDETH
 | 
				
			||||||
	  To compile this driver as a module, choose M here. The module
 | 
						  To compile this driver as a module, choose M here. The module
 | 
				
			||||||
	  will be called forcedeth.
 | 
						  will be called forcedeth.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config FORCEDETH_NAPI
 | 
					 | 
				
			||||||
	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
 | 
					 | 
				
			||||||
	depends on FORCEDETH && EXPERIMENTAL
 | 
					 | 
				
			||||||
	help
 | 
					 | 
				
			||||||
	  NAPI is a new driver API designed to reduce CPU and interrupt load
 | 
					 | 
				
			||||||
	  when the driver is receiving lots of packets from the card. It is
 | 
					 | 
				
			||||||
	  still somewhat experimental and thus not yet enabled by default.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  If your estimated Rx load is 10kpps or more, or if the card will be
 | 
					 | 
				
			||||||
	  deployed on potentially unfriendly networks (e.g. in a firewall),
 | 
					 | 
				
			||||||
	  then say Y here.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  If in doubt, say N.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
config CS89x0
 | 
					config CS89x0
 | 
				
			||||||
	tristate "CS89x0 support"
 | 
						tristate "CS89x0 support"
 | 
				
			||||||
	depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \
 | 
						depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \
 | 
				
			||||||
| 
						 | 
					@ -1916,6 +1909,7 @@ config FEC
 | 
				
			||||||
	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 | 
						bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 | 
				
			||||||
	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
 | 
						depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
 | 
				
			||||||
		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
 | 
							MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
 | 
				
			||||||
 | 
						select PHYLIB
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 | 
						  Say Y here if you want to use the built-in 10/100 Fast ethernet
 | 
				
			||||||
	  controller on some Motorola ColdFire and Freescale i.MX processors.
 | 
						  controller on some Motorola ColdFire and Freescale i.MX processors.
 | 
				
			||||||
| 
						 | 
					@ -2434,8 +2428,8 @@ config MV643XX_ETH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config XILINX_LL_TEMAC
 | 
					config XILINX_LL_TEMAC
 | 
				
			||||||
	tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
 | 
						tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
 | 
				
			||||||
 | 
						depends on PPC || MICROBLAZE
 | 
				
			||||||
	select PHYLIB
 | 
						select PHYLIB
 | 
				
			||||||
	depends on PPC_DCR_NATIVE
 | 
					 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
 | 
						  This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
 | 
				
			||||||
	  core used in Xilinx Spartan and Virtex FPGAs
 | 
						  core used in Xilinx Spartan and Virtex FPGAs
 | 
				
			||||||
| 
						 | 
					@ -2618,11 +2612,11 @@ config EHEA
 | 
				
			||||||
	  will be called ehea.
 | 
						  will be called ehea.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config ENIC
 | 
					config ENIC
 | 
				
			||||||
	tristate "Cisco 10G Ethernet NIC support"
 | 
						tristate "Cisco VIC Ethernet NIC Support"
 | 
				
			||||||
	depends on PCI && INET
 | 
						depends on PCI && INET
 | 
				
			||||||
	select INET_LRO
 | 
						select INET_LRO
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  This enables the support for the Cisco 10G Ethernet card.
 | 
						  This enables the support for the Cisco VIC Ethernet card.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config IXGBE
 | 
					config IXGBE
 | 
				
			||||||
	tristate "Intel(R) 10GbE PCI Express adapters support"
 | 
						tristate "Intel(R) 10GbE PCI Express adapters support"
 | 
				
			||||||
| 
						 | 
					@ -2862,6 +2856,8 @@ source "drivers/ieee802154/Kconfig"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source "drivers/s390/net/Kconfig"
 | 
					source "drivers/s390/net/Kconfig"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source "drivers/net/caif/Kconfig"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config XEN_NETDEV_FRONTEND
 | 
					config XEN_NETDEV_FRONTEND
 | 
				
			||||||
	tristate "Xen network device frontend driver"
 | 
						tristate "Xen network device frontend driver"
 | 
				
			||||||
	depends on XEN
 | 
						depends on XEN
 | 
				
			||||||
| 
						 | 
					@ -3180,17 +3176,12 @@ config PPPOATM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config PPPOL2TP
 | 
					config PPPOL2TP
 | 
				
			||||||
	tristate "PPP over L2TP (EXPERIMENTAL)"
 | 
						tristate "PPP over L2TP (EXPERIMENTAL)"
 | 
				
			||||||
	depends on EXPERIMENTAL && PPP && INET
 | 
						depends on EXPERIMENTAL && L2TP && PPP
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Support for PPP-over-L2TP socket family. L2TP is a protocol
 | 
						  Support for PPP-over-L2TP socket family. L2TP is a protocol
 | 
				
			||||||
	  used by ISPs and enterprises to tunnel PPP traffic over UDP
 | 
						  used by ISPs and enterprises to tunnel PPP traffic over UDP
 | 
				
			||||||
	  tunnels. L2TP is replacing PPTP for VPN uses.
 | 
						  tunnels. L2TP is replacing PPTP for VPN uses.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  This kernel component handles only L2TP data packets: a
 | 
					 | 
				
			||||||
	  userland daemon handles L2TP the control protocol (tunnel
 | 
					 | 
				
			||||||
	  and session setup). One such daemon is OpenL2TP
 | 
					 | 
				
			||||||
	  (http://openl2tp.sourceforge.net/).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
config SLIP
 | 
					config SLIP
 | 
				
			||||||
	tristate "SLIP (serial line) support"
 | 
						tristate "SLIP (serial line) support"
 | 
				
			||||||
	---help---
 | 
						---help---
 | 
				
			||||||
| 
						 | 
					@ -3277,15 +3268,14 @@ config NET_FC
 | 
				
			||||||
	  "SCSI generic support".
 | 
						  "SCSI generic support".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config NETCONSOLE
 | 
					config NETCONSOLE
 | 
				
			||||||
	tristate "Network console logging support (EXPERIMENTAL)"
 | 
						tristate "Network console logging support"
 | 
				
			||||||
	depends on EXPERIMENTAL
 | 
					 | 
				
			||||||
	---help---
 | 
						---help---
 | 
				
			||||||
	If you want to log kernel messages over the network, enable this.
 | 
						If you want to log kernel messages over the network, enable this.
 | 
				
			||||||
	See <file:Documentation/networking/netconsole.txt> for details.
 | 
						See <file:Documentation/networking/netconsole.txt> for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config NETCONSOLE_DYNAMIC
 | 
					config NETCONSOLE_DYNAMIC
 | 
				
			||||||
	bool "Dynamic reconfiguration of logging targets (EXPERIMENTAL)"
 | 
						bool "Dynamic reconfiguration of logging targets"
 | 
				
			||||||
	depends on NETCONSOLE && SYSFS && EXPERIMENTAL
 | 
						depends on NETCONSOLE && SYSFS
 | 
				
			||||||
	select CONFIGFS_FS
 | 
						select CONFIGFS_FS
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  This option enables the ability to dynamically reconfigure target
 | 
						  This option enables the ability to dynamically reconfigure target
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,7 +161,7 @@ obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
 | 
				
			||||||
obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
 | 
					obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
 | 
				
			||||||
obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
 | 
					obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
 | 
				
			||||||
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
 | 
					obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
 | 
				
			||||||
obj-$(CONFIG_PPPOL2TP) += pppox.o pppol2tp.o
 | 
					obj-$(CONFIG_PPPOL2TP) += pppox.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_SLIP) += slip.o
 | 
					obj-$(CONFIG_SLIP) += slip.o
 | 
				
			||||||
obj-$(CONFIG_SLHC) += slhc.o
 | 
					obj-$(CONFIG_SLHC) += slhc.o
 | 
				
			||||||
| 
						 | 
					@ -292,5 +292,6 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
 | 
				
			||||||
obj-$(CONFIG_SFC) += sfc/
 | 
					obj-$(CONFIG_SFC) += sfc/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_WIMAX) += wimax/
 | 
					obj-$(CONFIG_WIMAX) += wimax/
 | 
				
			||||||
 | 
					obj-$(CONFIG_CAIF) += caif/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
 | 
					obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -525,7 +525,7 @@ static inline int lance_reset (struct net_device *dev)
 | 
				
			||||||
	load_csrs (lp);
 | 
						load_csrs (lp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lance_init_ring (dev);
 | 
						lance_init_ring (dev);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_start_queue(dev);
 | 
						netif_start_queue(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = init_restart_lance (lp);
 | 
						status = init_restart_lance (lp);
 | 
				
			||||||
| 
						 | 
					@ -588,7 +588,6 @@ static netdev_tx_t lance_start_xmit (struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Kick the lance: transmit now */
 | 
						/* Kick the lance: transmit now */
 | 
				
			||||||
	ll->rdp = LE_C0_INEA | LE_C0_TDMD;
 | 
						ll->rdp = LE_C0_INEA | LE_C0_TDMD;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	dev_kfree_skb (skb);
 | 
						dev_kfree_skb (skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local_irq_restore(flags);
 | 
						local_irq_restore(flags);
 | 
				
			||||||
| 
						 | 
					@ -602,7 +601,7 @@ static void lance_load_multicast (struct net_device *dev)
 | 
				
			||||||
	struct lance_private *lp = netdev_priv(dev);
 | 
						struct lance_private *lp = netdev_priv(dev);
 | 
				
			||||||
	volatile struct lance_init_block *ib = lp->init_block;
 | 
						volatile struct lance_init_block *ib = lp->init_block;
 | 
				
			||||||
	volatile u16 *mcast_table = (u16 *)&ib->filter;
 | 
						volatile u16 *mcast_table = (u16 *)&ib->filter;
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	char *addrs;
 | 
						char *addrs;
 | 
				
			||||||
	u32 crc;
 | 
						u32 crc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -617,8 +616,8 @@ static void lance_load_multicast (struct net_device *dev)
 | 
				
			||||||
	ib->filter [1] = 0;
 | 
						ib->filter [1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Add addresses */
 | 
						/* Add addresses */
 | 
				
			||||||
	netdev_for_each_mc_addr(dmi, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		addrs = dmi->dmi_addr;
 | 
							addrs = ha->addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* multicast address? */
 | 
							/* multicast address? */
 | 
				
			||||||
		if (!(*addrs & 1))
 | 
							if (!(*addrs & 1))
 | 
				
			||||||
| 
						 | 
					@ -628,7 +627,6 @@ static void lance_load_multicast (struct net_device *dev)
 | 
				
			||||||
		crc = crc >> 26;
 | 
							crc = crc >> 26;
 | 
				
			||||||
		mcast_table [crc >> 4] |= 1 << (crc & 0xf);
 | 
							mcast_table [crc >> 4] |= 1 << (crc & 0xf);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void lance_set_multicast (struct net_device *dev)
 | 
					static void lance_set_multicast (struct net_device *dev)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -307,8 +307,6 @@ static void ac_reset_8390(struct net_device *dev)
 | 
				
			||||||
	ei_status.txing = 0;
 | 
						ei_status.txing = 0;
 | 
				
			||||||
	outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
 | 
						outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
 | 
				
			||||||
	if (ei_debug > 1) printk("reset done\n");
 | 
						if (ei_debug > 1) printk("reset done\n");
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Grab the 8390 specific header. Similar to the block_input routine, but
 | 
					/* Grab the 8390 specific header. Similar to the block_input routine, but
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -661,7 +661,7 @@ static void __devexit acenic_remove_one(struct pci_dev *pdev)
 | 
				
			||||||
			dma_addr_t mapping;
 | 
								dma_addr_t mapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ringp = &ap->skb->rx_std_skbuff[i];
 | 
								ringp = &ap->skb->rx_std_skbuff[i];
 | 
				
			||||||
			mapping = pci_unmap_addr(ringp, mapping);
 | 
								mapping = dma_unmap_addr(ringp, mapping);
 | 
				
			||||||
			pci_unmap_page(ap->pdev, mapping,
 | 
								pci_unmap_page(ap->pdev, mapping,
 | 
				
			||||||
				       ACE_STD_BUFSIZE,
 | 
									       ACE_STD_BUFSIZE,
 | 
				
			||||||
				       PCI_DMA_FROMDEVICE);
 | 
									       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
| 
						 | 
					@ -681,7 +681,7 @@ static void __devexit acenic_remove_one(struct pci_dev *pdev)
 | 
				
			||||||
				dma_addr_t mapping;
 | 
									dma_addr_t mapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				ringp = &ap->skb->rx_mini_skbuff[i];
 | 
									ringp = &ap->skb->rx_mini_skbuff[i];
 | 
				
			||||||
				mapping = pci_unmap_addr(ringp,mapping);
 | 
									mapping = dma_unmap_addr(ringp,mapping);
 | 
				
			||||||
				pci_unmap_page(ap->pdev, mapping,
 | 
									pci_unmap_page(ap->pdev, mapping,
 | 
				
			||||||
					       ACE_MINI_BUFSIZE,
 | 
										       ACE_MINI_BUFSIZE,
 | 
				
			||||||
					       PCI_DMA_FROMDEVICE);
 | 
										       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
| 
						 | 
					@ -700,7 +700,7 @@ static void __devexit acenic_remove_one(struct pci_dev *pdev)
 | 
				
			||||||
			dma_addr_t mapping;
 | 
								dma_addr_t mapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ringp = &ap->skb->rx_jumbo_skbuff[i];
 | 
								ringp = &ap->skb->rx_jumbo_skbuff[i];
 | 
				
			||||||
			mapping = pci_unmap_addr(ringp, mapping);
 | 
								mapping = dma_unmap_addr(ringp, mapping);
 | 
				
			||||||
			pci_unmap_page(ap->pdev, mapping,
 | 
								pci_unmap_page(ap->pdev, mapping,
 | 
				
			||||||
				       ACE_JUMBO_BUFSIZE,
 | 
									       ACE_JUMBO_BUFSIZE,
 | 
				
			||||||
				       PCI_DMA_FROMDEVICE);
 | 
									       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
| 
						 | 
					@ -1683,7 +1683,7 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)
 | 
				
			||||||
				       ACE_STD_BUFSIZE,
 | 
									       ACE_STD_BUFSIZE,
 | 
				
			||||||
				       PCI_DMA_FROMDEVICE);
 | 
									       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
		ap->skb->rx_std_skbuff[idx].skb = skb;
 | 
							ap->skb->rx_std_skbuff[idx].skb = skb;
 | 
				
			||||||
		pci_unmap_addr_set(&ap->skb->rx_std_skbuff[idx],
 | 
							dma_unmap_addr_set(&ap->skb->rx_std_skbuff[idx],
 | 
				
			||||||
				   mapping, mapping);
 | 
									   mapping, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rd = &ap->rx_std_ring[idx];
 | 
							rd = &ap->rx_std_ring[idx];
 | 
				
			||||||
| 
						 | 
					@ -1744,7 +1744,7 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)
 | 
				
			||||||
				       ACE_MINI_BUFSIZE,
 | 
									       ACE_MINI_BUFSIZE,
 | 
				
			||||||
				       PCI_DMA_FROMDEVICE);
 | 
									       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
		ap->skb->rx_mini_skbuff[idx].skb = skb;
 | 
							ap->skb->rx_mini_skbuff[idx].skb = skb;
 | 
				
			||||||
		pci_unmap_addr_set(&ap->skb->rx_mini_skbuff[idx],
 | 
							dma_unmap_addr_set(&ap->skb->rx_mini_skbuff[idx],
 | 
				
			||||||
				   mapping, mapping);
 | 
									   mapping, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rd = &ap->rx_mini_ring[idx];
 | 
							rd = &ap->rx_mini_ring[idx];
 | 
				
			||||||
| 
						 | 
					@ -1800,7 +1800,7 @@ static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs)
 | 
				
			||||||
				       ACE_JUMBO_BUFSIZE,
 | 
									       ACE_JUMBO_BUFSIZE,
 | 
				
			||||||
				       PCI_DMA_FROMDEVICE);
 | 
									       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
		ap->skb->rx_jumbo_skbuff[idx].skb = skb;
 | 
							ap->skb->rx_jumbo_skbuff[idx].skb = skb;
 | 
				
			||||||
		pci_unmap_addr_set(&ap->skb->rx_jumbo_skbuff[idx],
 | 
							dma_unmap_addr_set(&ap->skb->rx_jumbo_skbuff[idx],
 | 
				
			||||||
				   mapping, mapping);
 | 
									   mapping, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rd = &ap->rx_jumbo_ring[idx];
 | 
							rd = &ap->rx_jumbo_ring[idx];
 | 
				
			||||||
| 
						 | 
					@ -2013,7 +2013,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
 | 
				
			||||||
		skb = rip->skb;
 | 
							skb = rip->skb;
 | 
				
			||||||
		rip->skb = NULL;
 | 
							rip->skb = NULL;
 | 
				
			||||||
		pci_unmap_page(ap->pdev,
 | 
							pci_unmap_page(ap->pdev,
 | 
				
			||||||
			       pci_unmap_addr(rip, mapping),
 | 
								       dma_unmap_addr(rip, mapping),
 | 
				
			||||||
			       mapsize,
 | 
								       mapsize,
 | 
				
			||||||
			       PCI_DMA_FROMDEVICE);
 | 
								       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
		skb_put(skb, retdesc->size);
 | 
							skb_put(skb, retdesc->size);
 | 
				
			||||||
| 
						 | 
					@ -2078,18 +2078,16 @@ static inline void ace_tx_int(struct net_device *dev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		struct sk_buff *skb;
 | 
							struct sk_buff *skb;
 | 
				
			||||||
		dma_addr_t mapping;
 | 
					 | 
				
			||||||
		struct tx_ring_info *info;
 | 
							struct tx_ring_info *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = ap->skb->tx_skbuff + idx;
 | 
							info = ap->skb->tx_skbuff + idx;
 | 
				
			||||||
		skb = info->skb;
 | 
							skb = info->skb;
 | 
				
			||||||
		mapping = pci_unmap_addr(info, mapping);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (mapping) {
 | 
							if (dma_unmap_len(info, maplen)) {
 | 
				
			||||||
			pci_unmap_page(ap->pdev, mapping,
 | 
								pci_unmap_page(ap->pdev, dma_unmap_addr(info, mapping),
 | 
				
			||||||
				       pci_unmap_len(info, maplen),
 | 
									       dma_unmap_len(info, maplen),
 | 
				
			||||||
				       PCI_DMA_TODEVICE);
 | 
									       PCI_DMA_TODEVICE);
 | 
				
			||||||
			pci_unmap_addr_set(info, mapping, 0);
 | 
								dma_unmap_len_set(info, maplen, 0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (skb) {
 | 
							if (skb) {
 | 
				
			||||||
| 
						 | 
					@ -2377,14 +2375,12 @@ static int ace_close(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) {
 | 
						for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) {
 | 
				
			||||||
		struct sk_buff *skb;
 | 
							struct sk_buff *skb;
 | 
				
			||||||
		dma_addr_t mapping;
 | 
					 | 
				
			||||||
		struct tx_ring_info *info;
 | 
							struct tx_ring_info *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = ap->skb->tx_skbuff + i;
 | 
							info = ap->skb->tx_skbuff + i;
 | 
				
			||||||
		skb = info->skb;
 | 
							skb = info->skb;
 | 
				
			||||||
		mapping = pci_unmap_addr(info, mapping);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (mapping) {
 | 
							if (dma_unmap_len(info, maplen)) {
 | 
				
			||||||
			if (ACE_IS_TIGON_I(ap)) {
 | 
								if (ACE_IS_TIGON_I(ap)) {
 | 
				
			||||||
				/* NB: TIGON_1 is special, tx_ring is in io space */
 | 
									/* NB: TIGON_1 is special, tx_ring is in io space */
 | 
				
			||||||
				struct tx_desc __iomem *tx;
 | 
									struct tx_desc __iomem *tx;
 | 
				
			||||||
| 
						 | 
					@ -2395,10 +2391,10 @@ static int ace_close(struct net_device *dev)
 | 
				
			||||||
			} else
 | 
								} else
 | 
				
			||||||
				memset(ap->tx_ring + i, 0,
 | 
									memset(ap->tx_ring + i, 0,
 | 
				
			||||||
				       sizeof(struct tx_desc));
 | 
									       sizeof(struct tx_desc));
 | 
				
			||||||
			pci_unmap_page(ap->pdev, mapping,
 | 
								pci_unmap_page(ap->pdev, dma_unmap_addr(info, mapping),
 | 
				
			||||||
				       pci_unmap_len(info, maplen),
 | 
									       dma_unmap_len(info, maplen),
 | 
				
			||||||
				       PCI_DMA_TODEVICE);
 | 
									       PCI_DMA_TODEVICE);
 | 
				
			||||||
			pci_unmap_addr_set(info, mapping, 0);
 | 
								dma_unmap_len_set(info, maplen, 0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (skb) {
 | 
							if (skb) {
 | 
				
			||||||
			dev_kfree_skb(skb);
 | 
								dev_kfree_skb(skb);
 | 
				
			||||||
| 
						 | 
					@ -2433,8 +2429,8 @@ ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	info = ap->skb->tx_skbuff + idx;
 | 
						info = ap->skb->tx_skbuff + idx;
 | 
				
			||||||
	info->skb = tail;
 | 
						info->skb = tail;
 | 
				
			||||||
	pci_unmap_addr_set(info, mapping, mapping);
 | 
						dma_unmap_addr_set(info, mapping, mapping);
 | 
				
			||||||
	pci_unmap_len_set(info, maplen, skb->len);
 | 
						dma_unmap_len_set(info, maplen, skb->len);
 | 
				
			||||||
	return mapping;
 | 
						return mapping;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2553,8 +2549,8 @@ static netdev_tx_t ace_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				info->skb = NULL;
 | 
									info->skb = NULL;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			pci_unmap_addr_set(info, mapping, mapping);
 | 
								dma_unmap_addr_set(info, mapping, mapping);
 | 
				
			||||||
			pci_unmap_len_set(info, maplen, frag->size);
 | 
								dma_unmap_len_set(info, maplen, frag->size);
 | 
				
			||||||
			ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
 | 
								ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2923,8 +2919,6 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz
 | 
				
			||||||
		dest += tsize;
 | 
							dest += tsize;
 | 
				
			||||||
		size -= tsize;
 | 
							size -= tsize;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -589,7 +589,7 @@ struct ace_info {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ring_info {
 | 
					struct ring_info {
 | 
				
			||||||
	struct sk_buff		*skb;
 | 
						struct sk_buff		*skb;
 | 
				
			||||||
	DECLARE_PCI_UNMAP_ADDR(mapping)
 | 
						DEFINE_DMA_UNMAP_ADDR(mapping);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -600,8 +600,8 @@ struct ring_info {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct tx_ring_info {
 | 
					struct tx_ring_info {
 | 
				
			||||||
	struct sk_buff		*skb;
 | 
						struct sk_buff		*skb;
 | 
				
			||||||
	DECLARE_PCI_UNMAP_ADDR(mapping)
 | 
						DEFINE_DMA_UNMAP_ADDR(mapping);
 | 
				
			||||||
	DECLARE_PCI_UNMAP_LEN(maplen)
 | 
						DEFINE_DMA_UNMAP_LEN(maplen);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1339,8 +1339,6 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
	writel( VAL1 | TDMD0, lp->mmio + CMD0);
 | 
						writel( VAL1 | TDMD0, lp->mmio + CMD0);
 | 
				
			||||||
	writel( VAL2 | RDMD0,lp->mmio + CMD0);
 | 
						writel( VAL2 | RDMD0,lp->mmio + CMD0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(amd8111e_tx_queue_avail(lp) < 0){
 | 
						if(amd8111e_tx_queue_avail(lp) < 0){
 | 
				
			||||||
		netif_stop_queue(dev);
 | 
							netif_stop_queue(dev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1376,7 +1374,7 @@ list to the device.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
static void amd8111e_set_multicast_list(struct net_device *dev)
 | 
					static void amd8111e_set_multicast_list(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dev_mc_list *mc_ptr;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	struct amd8111e_priv *lp = netdev_priv(dev);
 | 
						struct amd8111e_priv *lp = netdev_priv(dev);
 | 
				
			||||||
	u32 mc_filter[2] ;
 | 
						u32 mc_filter[2] ;
 | 
				
			||||||
	int bit_num;
 | 
						int bit_num;
 | 
				
			||||||
| 
						 | 
					@ -1407,8 +1405,8 @@ static void amd8111e_set_multicast_list(struct net_device *dev)
 | 
				
			||||||
	/* load all the multicast addresses in the logic filter */
 | 
						/* load all the multicast addresses in the logic filter */
 | 
				
			||||||
	lp->options |= OPTION_MULTICAST_ENABLE;
 | 
						lp->options |= OPTION_MULTICAST_ENABLE;
 | 
				
			||||||
	mc_filter[1] = mc_filter[0] = 0;
 | 
						mc_filter[1] = mc_filter[0] = 0;
 | 
				
			||||||
	netdev_for_each_mc_addr(mc_ptr, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		bit_num = (ether_crc_le(ETH_ALEN, mc_ptr->dmi_addr) >> 26) & 0x3f;
 | 
							bit_num = (ether_crc_le(ETH_ALEN, ha->addr) >> 26) & 0x3f;
 | 
				
			||||||
		mc_filter[bit_num >> 5] |= 1 << (bit_num & 31);
 | 
							mc_filter[bit_num >> 5] |= 1 << (bit_num & 31);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	amd8111e_writeq(*(u64*)mc_filter,lp->mmio+ LADRF);
 | 
						amd8111e_writeq(*(u64*)mc_filter,lp->mmio+ LADRF);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -521,7 +521,6 @@ apne_block_output(struct net_device *dev, int count,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
 | 
					    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
 | 
				
			||||||
    ei_status.dmaing &= ~0x01;
 | 
					    ei_status.dmaing &= ~0x01;
 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static irqreturn_t apne_interrupt(int irq, void *dev_id)
 | 
					static irqreturn_t apne_interrupt(int irq, void *dev_id)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -593,8 +593,6 @@ static void cops_load (struct net_device *dev)
 | 
				
			||||||
                tangent_wait_reset(ioaddr);
 | 
					                tangent_wait_reset(ioaddr);
 | 
				
			||||||
                inb(ioaddr);	/* Clear initial ready signal. */
 | 
					                inb(ioaddr);	/* Clear initial ready signal. */
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -701,8 +699,6 @@ static void cops_poll(unsigned long ltdev)
 | 
				
			||||||
	/* poll 20 times per second */
 | 
						/* poll 20 times per second */
 | 
				
			||||||
	cops_timer.expires = jiffies + HZ/20;
 | 
						cops_timer.expires = jiffies + HZ/20;
 | 
				
			||||||
	add_timer(&cops_timer);
 | 
						add_timer(&cops_timer);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -866,7 +862,7 @@ static void cops_timeout(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
 | 
						printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
 | 
				
			||||||
	cops_jumpstart(dev);	/* Restart the card. */
 | 
						cops_jumpstart(dev);	/* Restart the card. */
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue(dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -919,7 +915,6 @@ static netdev_tx_t cops_send_packet(struct sk_buff *skb,
 | 
				
			||||||
	/* Done sending packet, update counters and cleanup. */
 | 
						/* Done sending packet, update counters and cleanup. */
 | 
				
			||||||
	dev->stats.tx_packets++;
 | 
						dev->stats.tx_packets++;
 | 
				
			||||||
	dev->stats.tx_bytes += skb->len;
 | 
						dev->stats.tx_bytes += skb->len;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	dev_kfree_skb (skb);
 | 
						dev_kfree_skb (skb);
 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -641,7 +641,6 @@ static void idle(struct net_device *dev)
 | 
				
			||||||
		inb_p(base+7);
 | 
							inb_p(base+7);
 | 
				
			||||||
		inb_p(base+7);
 | 
							inb_p(base+7);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -654,7 +654,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		retval = NETDEV_TX_OK;
 | 
							retval = NETDEV_TX_OK;
 | 
				
			||||||
		dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
		lp->next_tx = txbuf;
 | 
							lp->next_tx = txbuf;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		retval = NETDEV_TX_BUSY;
 | 
							retval = NETDEV_TX_BUSY;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,8 +164,8 @@ static DEFINE_PCI_DEVICE_TABLE(com20020pci_id_table) = {
 | 
				
			||||||
	{ 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
						{ 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
				
			||||||
	{ 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
						{ 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
				
			||||||
	{ 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
						{ 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
				
			||||||
	{ 0x10B5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
						{ 0x10B5, 0x9030, 0x10B5,     0x2978,     0, 0, ARC_CAN_10MBIT },
 | 
				
			||||||
	{ 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
						{ 0x10B5, 0x9050, 0x10B5,     0x2273,     0, 0, ARC_CAN_10MBIT },
 | 
				
			||||||
	{ 0x14BA, 0x6000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
						{ 0x14BA, 0x6000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
				
			||||||
	{ 0x10B5, 0x2200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
						{ 0x10B5, 0x2200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 | 
				
			||||||
	{0,}
 | 
						{0,}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -677,8 +677,6 @@ static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
    lance->RAP = CSR0;		/* PCnet-ISA Controller Status */
 | 
					    lance->RAP = CSR0;		/* PCnet-ISA Controller Status */
 | 
				
			||||||
    lance->RDP = INEA|TDMD;
 | 
					    lance->RDP = INEA|TDMD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) != 0) {
 | 
					    if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) != 0) {
 | 
				
			||||||
	netif_stop_queue(dev);
 | 
						netif_stop_queue(dev);
 | 
				
			||||||
	priv->tx_full = 1;
 | 
						priv->tx_full = 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,12 +383,12 @@ static void am79c961_setmulticastlist (struct net_device *dev)
 | 
				
			||||||
	} else if (dev->flags & IFF_ALLMULTI) {
 | 
						} else if (dev->flags & IFF_ALLMULTI) {
 | 
				
			||||||
		memset(multi_hash, 0xff, sizeof(multi_hash));
 | 
							memset(multi_hash, 0xff, sizeof(multi_hash));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct dev_mc_list *dmi;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memset(multi_hash, 0x00, sizeof(multi_hash));
 | 
							memset(multi_hash, 0x00, sizeof(multi_hash));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		netdev_for_each_mc_addr(dmi, dev)
 | 
							netdev_for_each_mc_addr(ha, dev)
 | 
				
			||||||
			am79c961_mc_hash(dmi->dmi_addr, multi_hash);
 | 
								am79c961_mc_hash(ha->addr, multi_hash);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&priv->chip_lock, flags);
 | 
						spin_lock_irqsave(&priv->chip_lock, flags);
 | 
				
			||||||
| 
						 | 
					@ -469,7 +469,6 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&priv->chip_lock, flags);
 | 
						spin_lock_irqsave(&priv->chip_lock, flags);
 | 
				
			||||||
	write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
 | 
						write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	spin_unlock_irqrestore(&priv->chip_lock, flags);
 | 
						spin_unlock_irqrestore(&priv->chip_lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -557,14 +557,14 @@ static int hash_get_index(__u8 *addr)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void at91ether_sethashtable(struct net_device *dev)
 | 
					static void at91ether_sethashtable(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dev_mc_list *curr;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	unsigned long mc_filter[2];
 | 
						unsigned long mc_filter[2];
 | 
				
			||||||
	unsigned int bitnr;
 | 
						unsigned int bitnr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mc_filter[0] = mc_filter[1] = 0;
 | 
						mc_filter[0] = mc_filter[1] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netdev_for_each_mc_addr(curr, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		bitnr = hash_get_index(curr->dmi_addr);
 | 
							bitnr = hash_get_index(ha->addr);
 | 
				
			||||||
		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
 | 
							mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -824,7 +824,6 @@ static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		/* Set length of the packet in the Transmit Control register */
 | 
							/* Set length of the packet in the Transmit Control register */
 | 
				
			||||||
		at91_emac_write(AT91_EMAC_TCR, skb->len);
 | 
							at91_emac_write(AT91_EMAC_TCR, skb->len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
 | 
							printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
 | 
				
			||||||
		return NETDEV_TX_BUSY;	/* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
 | 
							return NETDEV_TX_BUSY;	/* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -374,8 +374,6 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
				skb->len, DMA_TO_DEVICE);
 | 
									skb->len, DMA_TO_DEVICE);
 | 
				
			||||||
	dev_kfree_skb(skb);
 | 
						dev_kfree_skb(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spin_lock_irq(&ep->tx_pending_lock);
 | 
						spin_lock_irq(&ep->tx_pending_lock);
 | 
				
			||||||
	ep->tx_pending++;
 | 
						ep->tx_pending++;
 | 
				
			||||||
	if (ep->tx_pending == TX_QUEUE_ENTRIES)
 | 
						if (ep->tx_pending == TX_QUEUE_ENTRIES)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -736,7 +736,6 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	local_irq_restore(flags);
 | 
						local_irq_restore(flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* handle transmit */
 | 
						/* handle transmit */
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* check to see if we have room for a full sized ether frame */
 | 
						/* check to see if we have room for a full sized ether frame */
 | 
				
			||||||
	tmp = priv(dev)->tx_head;
 | 
						tmp = priv(dev)->tx_head;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,7 +529,6 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		return NETDEV_TX_BUSY;	/* unable to queue */
 | 
							return NETDEV_TX_BUSY;	/* unable to queue */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	ptr		 = 0x600 * priv(dev)->tx_head;
 | 
						ptr		 = 0x600 * priv(dev)->tx_head;
 | 
				
			||||||
	priv(dev)->tx_head = next_ptr;
 | 
						priv(dev)->tx_head = next_ptr;
 | 
				
			||||||
	next_ptr	*= 0x600;
 | 
						next_ptr	*= 0x600;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -708,7 +708,6 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	/* NPE firmware pads short frames with zeros internally */
 | 
						/* NPE firmware pads short frames with zeros internally */
 | 
				
			||||||
	wmb();
 | 
						wmb();
 | 
				
			||||||
	queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc);
 | 
						queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */
 | 
						if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */
 | 
				
			||||||
#if DEBUG_TX
 | 
					#if DEBUG_TX
 | 
				
			||||||
| 
						 | 
					@ -736,7 +735,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
static void eth_set_mcast_list(struct net_device *dev)
 | 
					static void eth_set_mcast_list(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct port *port = netdev_priv(dev);
 | 
						struct port *port = netdev_priv(dev);
 | 
				
			||||||
	struct dev_mc_list *mclist;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	u8 diffs[ETH_ALEN], *addr;
 | 
						u8 diffs[ETH_ALEN], *addr;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -749,11 +748,11 @@ static void eth_set_mcast_list(struct net_device *dev)
 | 
				
			||||||
	memset(diffs, 0, ETH_ALEN);
 | 
						memset(diffs, 0, ETH_ALEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr = NULL;
 | 
						addr = NULL;
 | 
				
			||||||
	netdev_for_each_mc_addr(mclist, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		if (!addr)
 | 
							if (!addr)
 | 
				
			||||||
			addr = mclist->dmi_addr; /* first MAC address */
 | 
								addr = ha->addr; /* first MAC address */
 | 
				
			||||||
		for (i = 0; i < ETH_ALEN; i++)
 | 
							for (i = 0; i < ETH_ALEN; i++)
 | 
				
			||||||
			diffs[i] |= addr[i] ^ mclist->dmi_addr[i];
 | 
								diffs[i] |= addr[i] ^ ha->addr[i];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < ETH_ALEN; i++) {
 | 
						for (i = 0; i < ETH_ALEN; i++) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -332,16 +332,16 @@ ks8695_init_partial_multicast(struct ks8695_priv *ksp,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 low, high;
 | 
						u32 low, high;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i = 0;
 | 
						i = 0;
 | 
				
			||||||
	netdev_for_each_mc_addr(dmi, ndev) {
 | 
						netdev_for_each_mc_addr(ha, ndev) {
 | 
				
			||||||
		/* Ran out of space in chip? */
 | 
							/* Ran out of space in chip? */
 | 
				
			||||||
		BUG_ON(i == KS8695_NR_ADDRESSES);
 | 
							BUG_ON(i == KS8695_NR_ADDRESSES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		low = (dmi->dmi_addr[2] << 24) | (dmi->dmi_addr[3] << 16) |
 | 
							low = (ha->addr[2] << 24) | (ha->addr[3] << 16) |
 | 
				
			||||||
		      (dmi->dmi_addr[4] << 8) | (dmi->dmi_addr[5]);
 | 
							      (ha->addr[4] << 8) | (ha->addr[5]);
 | 
				
			||||||
		high = (dmi->dmi_addr[0] << 8) | (dmi->dmi_addr[1]);
 | 
							high = (ha->addr[0] << 8) | (ha->addr[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ks8695_writereg(ksp, KS8695_AAL_(i), low);
 | 
							ks8695_writereg(ksp, KS8695_AAL_(i), low);
 | 
				
			||||||
		ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high);
 | 
							ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high);
 | 
				
			||||||
| 
						 | 
					@ -1302,8 +1302,6 @@ ks8695_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 | 
				
			||||||
	if (++ksp->tx_ring_used == MAX_TX_DESC)
 | 
						if (++ksp->tx_ring_used == MAX_TX_DESC)
 | 
				
			||||||
		netif_stop_queue(ndev);
 | 
							netif_stop_queue(ndev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ndev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Kick the TX DMA in case it decided to go IDLE */
 | 
						/* Kick the TX DMA in case it decided to go IDLE */
 | 
				
			||||||
	ks8695_writereg(ksp, KS8695_DTSC, 0);
 | 
						ks8695_writereg(ksp, KS8695_DTSC, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1472,7 +1470,6 @@ ks8695_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Configure our private structure a little */
 | 
						/* Configure our private structure a little */
 | 
				
			||||||
	ksp = netdev_priv(ndev);
 | 
						ksp = netdev_priv(ndev);
 | 
				
			||||||
	memset(ksp, 0, sizeof(struct ks8695_priv));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ksp->dev = &pdev->dev;
 | 
						ksp->dev = &pdev->dev;
 | 
				
			||||||
	ksp->ndev = ndev;
 | 
						ksp->ndev = ndev;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -483,7 +483,7 @@ static void w90p910_reset_mac(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	w90p910_init_desc(dev);
 | 
						w90p910_init_desc(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	ether->cur_tx = 0x0;
 | 
						ether->cur_tx = 0x0;
 | 
				
			||||||
	ether->finish_tx = 0x0;
 | 
						ether->finish_tx = 0x0;
 | 
				
			||||||
	ether->cur_rx = 0x0;
 | 
						ether->cur_rx = 0x0;
 | 
				
			||||||
| 
						 | 
					@ -497,7 +497,7 @@ static void w90p910_reset_mac(struct net_device *dev)
 | 
				
			||||||
	w90p910_trigger_tx(dev);
 | 
						w90p910_trigger_tx(dev);
 | 
				
			||||||
	w90p910_trigger_rx(dev);
 | 
						w90p910_trigger_rx(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (netif_queue_stopped(dev))
 | 
						if (netif_queue_stopped(dev))
 | 
				
			||||||
		netif_wake_queue(dev);
 | 
							netif_wake_queue(dev);
 | 
				
			||||||
| 
						 | 
					@ -634,8 +634,6 @@ static int w90p910_send_frame(struct net_device *dev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	txbd = ðer->tdesc->desclist[ether->cur_tx];
 | 
						txbd = ðer->tdesc->desclist[ether->cur_tx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (txbd->mode & TX_OWEN_DMA)
 | 
						if (txbd->mode & TX_OWEN_DMA)
 | 
				
			||||||
		netif_stop_queue(dev);
 | 
							netif_stop_queue(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -744,7 +742,6 @@ static void netdev_rx(struct net_device *dev)
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			skb->dev = dev;
 | 
					 | 
				
			||||||
			skb_reserve(skb, 2);
 | 
								skb_reserve(skb, 2);
 | 
				
			||||||
			skb_put(skb, length);
 | 
								skb_put(skb, length);
 | 
				
			||||||
			skb_copy_to_linear_data(skb, data, length);
 | 
								skb_copy_to_linear_data(skb, data, length);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -583,7 +583,7 @@ static void net_tx_timeout (struct net_device *dev)
 | 
				
			||||||
	outb (0x00, ioaddr + TX_START);
 | 
						outb (0x00, ioaddr + TX_START);
 | 
				
			||||||
	outb (0x03, ioaddr + COL16CNTL);
 | 
						outb (0x03, ioaddr + COL16CNTL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lp->tx_started = 0;
 | 
						lp->tx_started = 0;
 | 
				
			||||||
	lp->tx_queue_ready = 1;
 | 
						lp->tx_queue_ready = 1;
 | 
				
			||||||
| 
						 | 
					@ -636,7 +636,6 @@ static netdev_tx_t net_send_packet (struct sk_buff *skb,
 | 
				
			||||||
		outb (0x80 | lp->tx_queue, ioaddr + TX_START);
 | 
							outb (0x80 | lp->tx_queue, ioaddr + TX_START);
 | 
				
			||||||
		lp->tx_queue = 0;
 | 
							lp->tx_queue = 0;
 | 
				
			||||||
		lp->tx_queue_len = 0;
 | 
							lp->tx_queue_len = 0;
 | 
				
			||||||
		dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
		lp->tx_started = 1;
 | 
							lp->tx_started = 1;
 | 
				
			||||||
		netif_start_queue (dev);
 | 
							netif_start_queue (dev);
 | 
				
			||||||
	} else if (lp->tx_queue_len < 4096 - 1502)
 | 
						} else if (lp->tx_queue_len < 4096 - 1502)
 | 
				
			||||||
| 
						 | 
					@ -796,7 +795,6 @@ net_rx(struct net_device *dev)
 | 
				
			||||||
			printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
 | 
								printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
 | 
				
			||||||
				   dev->name, inb(ioaddr + RX_MODE), i);
 | 
									   dev->name, inb(ioaddr + RX_MODE), i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The inverse routine to net_open(). */
 | 
					/* The inverse routine to net_open(). */
 | 
				
			||||||
| 
						 | 
					@ -847,12 +845,12 @@ set_rx_mode(struct net_device *dev)
 | 
				
			||||||
		memset(mc_filter, 0x00, sizeof(mc_filter));
 | 
							memset(mc_filter, 0x00, sizeof(mc_filter));
 | 
				
			||||||
		outb(1, ioaddr + RX_MODE);	/* Ignore almost all multicasts. */
 | 
							outb(1, ioaddr + RX_MODE);	/* Ignore almost all multicasts. */
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct dev_mc_list *mclist;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memset(mc_filter, 0, sizeof(mc_filter));
 | 
							memset(mc_filter, 0, sizeof(mc_filter));
 | 
				
			||||||
		netdev_for_each_mc_addr(mclist, dev) {
 | 
							netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
			unsigned int bit =
 | 
								unsigned int bit =
 | 
				
			||||||
				ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26;
 | 
									ether_crc_le(ETH_ALEN, ha->addr) >> 26;
 | 
				
			||||||
			mc_filter[bit >> 3] |= (1 << bit);
 | 
								mc_filter[bit >> 3] |= (1 << bit);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		outb(0x02, ioaddr + RX_MODE);	/* Use normal mode. */
 | 
							outb(0x02, ioaddr + RX_MODE);	/* Use normal mode. */
 | 
				
			||||||
| 
						 | 
					@ -870,7 +868,6 @@ set_rx_mode(struct net_device *dev)
 | 
				
			||||||
		outw(saved_bank, ioaddr + CONFIG_0);
 | 
							outw(saved_bank, ioaddr + CONFIG_0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	spin_unlock_irqrestore (&lp->lock, flags);
 | 
						spin_unlock_irqrestore (&lp->lock, flags);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef MODULE
 | 
					#ifdef MODULE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -767,8 +767,8 @@ static void lance_tx_timeout (struct net_device *dev)
 | 
				
			||||||
	/* lance_restart, essentially */
 | 
						/* lance_restart, essentially */
 | 
				
			||||||
	lance_init_ring(dev);
 | 
						lance_init_ring(dev);
 | 
				
			||||||
	REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
 | 
						REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue (dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 | 
					/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 | 
				
			||||||
| 
						 | 
					@ -836,7 +836,6 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Trigger an immediate send poll. */
 | 
						/* Trigger an immediate send poll. */
 | 
				
			||||||
	DREG = CSR0_INEA | CSR0_TDMD;
 | 
						DREG = CSR0_INEA | CSR0_TDMD;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
 | 
						if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
 | 
				
			||||||
		TMD1_OWN_HOST)
 | 
							TMD1_OWN_HOST)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -263,8 +263,6 @@ static void atl1c_get_wol(struct net_device *netdev,
 | 
				
			||||||
		wol->wolopts |= WAKE_MAGIC;
 | 
							wol->wolopts |= WAKE_MAGIC;
 | 
				
			||||||
	if (adapter->wol & AT_WUFC_LNKC)
 | 
						if (adapter->wol & AT_WUFC_LNKC)
 | 
				
			||||||
		wol->wolopts |= WAKE_PHY;
 | 
							wol->wolopts |= WAKE_PHY;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 | 
					static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -317,8 +317,6 @@ static void atl1c_common_task(struct work_struct *work)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE)
 | 
						if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE)
 | 
				
			||||||
		atl1c_check_link_status(adapter);
 | 
							atl1c_check_link_status(adapter);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,7 +352,7 @@ static void atl1c_set_multi(struct net_device *netdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atl1c_adapter *adapter = netdev_priv(netdev);
 | 
						struct atl1c_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
	struct atl1c_hw *hw = &adapter->hw;
 | 
						struct atl1c_hw *hw = &adapter->hw;
 | 
				
			||||||
	struct dev_mc_list *mc_ptr;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	u32 mac_ctrl_data;
 | 
						u32 mac_ctrl_data;
 | 
				
			||||||
	u32 hash_value;
 | 
						u32 hash_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -377,8 +375,8 @@ static void atl1c_set_multi(struct net_device *netdev)
 | 
				
			||||||
	AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 | 
						AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* comoute mc addresses' hash value ,and put it into hash table */
 | 
						/* comoute mc addresses' hash value ,and put it into hash table */
 | 
				
			||||||
	netdev_for_each_mc_addr(mc_ptr, netdev) {
 | 
						netdev_for_each_mc_addr(ha, netdev) {
 | 
				
			||||||
		hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr);
 | 
							hash_value = atl1c_hash_mc_addr(hw, ha->addr);
 | 
				
			||||||
		atl1c_hash_set(hw, hash_value);
 | 
							atl1c_hash_set(hw, hash_value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1817,7 +1815,6 @@ static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
 | 
				
			||||||
		atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
 | 
							atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
 | 
				
			||||||
		skb_put(skb, length - ETH_FCS_LEN);
 | 
							skb_put(skb, length - ETH_FCS_LEN);
 | 
				
			||||||
		skb->protocol = eth_type_trans(skb, netdev);
 | 
							skb->protocol = eth_type_trans(skb, netdev);
 | 
				
			||||||
		skb->dev = netdev;
 | 
					 | 
				
			||||||
		atl1c_rx_checksum(adapter, skb, rrs);
 | 
							atl1c_rx_checksum(adapter, skb, rrs);
 | 
				
			||||||
		if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) {
 | 
							if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) {
 | 
				
			||||||
			u16 vlan;
 | 
								u16 vlan;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -338,8 +338,6 @@ static void atl1e_get_wol(struct net_device *netdev,
 | 
				
			||||||
		wol->wolopts |= WAKE_MAGIC;
 | 
							wol->wolopts |= WAKE_MAGIC;
 | 
				
			||||||
	if (adapter->wol & AT_WUFC_LNKC)
 | 
						if (adapter->wol & AT_WUFC_LNKC)
 | 
				
			||||||
		wol->wolopts |= WAKE_PHY;
 | 
							wol->wolopts |= WAKE_PHY;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 | 
					static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -284,7 +284,7 @@ static void atl1e_set_multi(struct net_device *netdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atl1e_adapter *adapter = netdev_priv(netdev);
 | 
						struct atl1e_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
	struct atl1e_hw *hw = &adapter->hw;
 | 
						struct atl1e_hw *hw = &adapter->hw;
 | 
				
			||||||
	struct dev_mc_list *mc_ptr;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	u32 mac_ctrl_data = 0;
 | 
						u32 mac_ctrl_data = 0;
 | 
				
			||||||
	u32 hash_value;
 | 
						u32 hash_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -307,8 +307,8 @@ static void atl1e_set_multi(struct net_device *netdev)
 | 
				
			||||||
	AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 | 
						AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* comoute mc addresses' hash value ,and put it into hash table */
 | 
						/* comoute mc addresses' hash value ,and put it into hash table */
 | 
				
			||||||
	netdev_for_each_mc_addr(mc_ptr, netdev) {
 | 
						netdev_for_each_mc_addr(ha, netdev) {
 | 
				
			||||||
		hash_value = atl1e_hash_mc_addr(hw, mc_ptr->dmi_addr);
 | 
							hash_value = atl1e_hash_mc_addr(hw, ha->addr);
 | 
				
			||||||
		atl1e_hash_set(hw, hash_value);
 | 
							atl1e_hash_set(hw, hash_value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -707,8 +707,6 @@ static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
 | 
				
			||||||
	adapter->ring_vir_addr = NULL;
 | 
						adapter->ring_vir_addr = NULL;
 | 
				
			||||||
	adapter->rx_ring.desc = NULL;
 | 
						adapter->rx_ring.desc = NULL;
 | 
				
			||||||
	rwlock_init(&adapter->tx_ring.tx_lock);
 | 
						rwlock_init(&adapter->tx_ring.tx_lock);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -905,8 +903,6 @@ static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter)
 | 
				
			||||||
	AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size);
 | 
						AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size);
 | 
				
			||||||
	/* Load all of base address above */
 | 
						/* Load all of base address above */
 | 
				
			||||||
	AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
 | 
						AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
 | 
					static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
 | 
				
			||||||
| 
						 | 
					@ -950,7 +946,6 @@ static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
 | 
				
			||||||
			(((u16)hw->tpd_burst & TXQ_CTRL_NUM_TPD_BURST_MASK)
 | 
								(((u16)hw->tpd_burst & TXQ_CTRL_NUM_TPD_BURST_MASK)
 | 
				
			||||||
			 << TXQ_CTRL_NUM_TPD_BURST_SHIFT)
 | 
								 << TXQ_CTRL_NUM_TPD_BURST_SHIFT)
 | 
				
			||||||
			| TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN);
 | 
								| TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
 | 
					static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
 | 
				
			||||||
| 
						 | 
					@ -1004,7 +999,6 @@ static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
 | 
				
			||||||
			 RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
 | 
								 RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
 | 
						AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
 | 
					static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
 | 
				
			||||||
| 
						 | 
					@ -1024,7 +1018,6 @@ static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
 | 
				
			||||||
		<< DMA_CTRL_DMAW_DLY_CNT_SHIFT;
 | 
							<< DMA_CTRL_DMAW_DLY_CNT_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
 | 
						AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
 | 
					static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
 | 
				
			||||||
| 
						 | 
					@ -1428,7 +1421,6 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
 | 
				
			||||||
					    "Memory squeeze, deferring packet\n");
 | 
										    "Memory squeeze, deferring packet\n");
 | 
				
			||||||
				goto skip_pkt;
 | 
									goto skip_pkt;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			skb->dev = netdev;
 | 
					 | 
				
			||||||
			memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
 | 
								memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
 | 
				
			||||||
			skb_put(skb, packet_size);
 | 
								skb_put(skb, packet_size);
 | 
				
			||||||
			skb->protocol = eth_type_trans(skb, netdev);
 | 
								skb->protocol = eth_type_trans(skb, netdev);
 | 
				
			||||||
| 
						 | 
					@ -1680,7 +1672,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atl1e_tpd_desc *use_tpd = NULL;
 | 
						struct atl1e_tpd_desc *use_tpd = NULL;
 | 
				
			||||||
	struct atl1e_tx_buffer *tx_buffer = NULL;
 | 
						struct atl1e_tx_buffer *tx_buffer = NULL;
 | 
				
			||||||
	u16 buf_len = skb->len - skb->data_len;
 | 
						u16 buf_len = skb_headlen(skb);
 | 
				
			||||||
	u16 map_len = 0;
 | 
						u16 map_len = 0;
 | 
				
			||||||
	u16 mapped_len = 0;
 | 
						u16 mapped_len = 0;
 | 
				
			||||||
	u16 hdr_len = 0;
 | 
						u16 hdr_len = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1830,8 +1830,6 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
 | 
				
			||||||
		adapter->hw_csum_good++;
 | 
							adapter->hw_csum_good++;
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -2347,7 +2345,7 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atl1_adapter *adapter = netdev_priv(netdev);
 | 
						struct atl1_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
 | 
						struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
 | 
				
			||||||
	int len = skb->len;
 | 
						int len;
 | 
				
			||||||
	int tso;
 | 
						int tso;
 | 
				
			||||||
	int count = 1;
 | 
						int count = 1;
 | 
				
			||||||
	int ret_val;
 | 
						int ret_val;
 | 
				
			||||||
| 
						 | 
					@ -2359,7 +2357,7 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
 | 
				
			||||||
	unsigned int f;
 | 
						unsigned int f;
 | 
				
			||||||
	unsigned int proto_hdr_len;
 | 
						unsigned int proto_hdr_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len -= skb->data_len;
 | 
						len = skb_headlen(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(skb->len <= 0)) {
 | 
						if (unlikely(skb->len <= 0)) {
 | 
				
			||||||
		dev_kfree_skb_any(skb);
 | 
							dev_kfree_skb_any(skb);
 | 
				
			||||||
| 
						 | 
					@ -3390,7 +3388,6 @@ static void atl1_get_wol(struct net_device *netdev,
 | 
				
			||||||
	wol->wolopts = 0;
 | 
						wol->wolopts = 0;
 | 
				
			||||||
	if (adapter->wol & ATLX_WUFC_MAG)
 | 
						if (adapter->wol & ATLX_WUFC_MAG)
 | 
				
			||||||
		wol->wolopts |= WAKE_MAGIC;
 | 
							wol->wolopts |= WAKE_MAGIC;
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int atl1_set_wol(struct net_device *netdev,
 | 
					static int atl1_set_wol(struct net_device *netdev,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,7 +136,7 @@ static void atl2_set_multi(struct net_device *netdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atl2_adapter *adapter = netdev_priv(netdev);
 | 
						struct atl2_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
	struct atl2_hw *hw = &adapter->hw;
 | 
						struct atl2_hw *hw = &adapter->hw;
 | 
				
			||||||
	struct dev_mc_list *mc_ptr;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	u32 rctl;
 | 
						u32 rctl;
 | 
				
			||||||
	u32 hash_value;
 | 
						u32 hash_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -158,8 +158,8 @@ static void atl2_set_multi(struct net_device *netdev)
 | 
				
			||||||
	ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 | 
						ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* comoute mc addresses' hash value ,and put it into hash table */
 | 
						/* comoute mc addresses' hash value ,and put it into hash table */
 | 
				
			||||||
	netdev_for_each_mc_addr(mc_ptr, netdev) {
 | 
						netdev_for_each_mc_addr(ha, netdev) {
 | 
				
			||||||
		hash_value = atl2_hash_mc_addr(hw, mc_ptr->dmi_addr);
 | 
							hash_value = atl2_hash_mc_addr(hw, ha->addr);
 | 
				
			||||||
		atl2_hash_set(hw, hash_value);
 | 
							atl2_hash_set(hw, hash_value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -422,7 +422,6 @@ static void atl2_intr_rx(struct atl2_adapter *adapter)
 | 
				
			||||||
				netdev->stats.rx_dropped++;
 | 
									netdev->stats.rx_dropped++;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			skb->dev = netdev;
 | 
					 | 
				
			||||||
			memcpy(skb->data, rxd->packet, rx_size);
 | 
								memcpy(skb->data, rxd->packet, rx_size);
 | 
				
			||||||
			skb_put(skb, rx_size);
 | 
								skb_put(skb, rx_size);
 | 
				
			||||||
			skb->protocol = eth_type_trans(skb, netdev);
 | 
								skb->protocol = eth_type_trans(skb, netdev);
 | 
				
			||||||
| 
						 | 
					@ -893,7 +892,6 @@ static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
 | 
				
			||||||
		(adapter->txd_write_ptr >> 2));
 | 
							(adapter->txd_write_ptr >> 2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mmiowb();
 | 
						mmiowb();
 | 
				
			||||||
	netdev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	dev_kfree_skb_any(skb);
 | 
						dev_kfree_skb_any(skb);
 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,7 +123,7 @@ static void atlx_set_multi(struct net_device *netdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atlx_adapter *adapter = netdev_priv(netdev);
 | 
						struct atlx_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
	struct atlx_hw *hw = &adapter->hw;
 | 
						struct atlx_hw *hw = &adapter->hw;
 | 
				
			||||||
	struct dev_mc_list *mc_ptr;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	u32 rctl;
 | 
						u32 rctl;
 | 
				
			||||||
	u32 hash_value;
 | 
						u32 hash_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,8 +144,8 @@ static void atlx_set_multi(struct net_device *netdev)
 | 
				
			||||||
	iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
 | 
						iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* compute mc addresses' hash value ,and put it into hash table */
 | 
						/* compute mc addresses' hash value ,and put it into hash table */
 | 
				
			||||||
	netdev_for_each_mc_addr(mc_ptr, netdev) {
 | 
						netdev_for_each_mc_addr(ha, netdev) {
 | 
				
			||||||
		hash_value = atlx_hash_mc_addr(hw, mc_ptr->dmi_addr);
 | 
							hash_value = atlx_hash_mc_addr(hw, ha->addr);
 | 
				
			||||||
		atlx_hash_set(hw, hash_value);
 | 
							atlx_hash_set(hw, hash_value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,7 +547,7 @@ static void tx_timeout(struct net_device *dev)
 | 
				
			||||||
	dev->stats.tx_errors++;
 | 
						dev->stats.tx_errors++;
 | 
				
			||||||
	/* Try to restart the adapter. */
 | 
						/* Try to restart the adapter. */
 | 
				
			||||||
	hardware_init(dev);
 | 
						hardware_init(dev);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue(dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
	dev->stats.tx_errors++;
 | 
						dev->stats.tx_errors++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -586,7 +586,6 @@ static netdev_tx_t atp_send_packet(struct sk_buff *skb,
 | 
				
			||||||
	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
 | 
						write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
 | 
				
			||||||
	write_reg_high(ioaddr, IMR, ISRh_RxErr);
 | 
						write_reg_high(ioaddr, IMR, ISRh_RxErr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	dev_kfree_skb (skb);
 | 
						dev_kfree_skb (skb);
 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -803,7 +802,6 @@ static void net_rx(struct net_device *dev)
 | 
				
			||||||
 done:
 | 
					 done:
 | 
				
			||||||
	write_reg(ioaddr, CMR1, CMR1_NextPkt);
 | 
						write_reg(ioaddr, CMR1, CMR1_NextPkt);
 | 
				
			||||||
	lp->last_rx_time = jiffies;
 | 
						lp->last_rx_time = jiffies;
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void read_block(long ioaddr, int length, unsigned char *p, int data_mode)
 | 
					static void read_block(long ioaddr, int length, unsigned char *p, int data_mode)
 | 
				
			||||||
| 
						 | 
					@ -882,11 +880,11 @@ static void set_rx_mode_8012(struct net_device *dev)
 | 
				
			||||||
		memset(mc_filter, 0xff, sizeof(mc_filter));
 | 
							memset(mc_filter, 0xff, sizeof(mc_filter));
 | 
				
			||||||
		new_mode = CMR2h_Normal;
 | 
							new_mode = CMR2h_Normal;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct dev_mc_list *mclist;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memset(mc_filter, 0, sizeof(mc_filter));
 | 
							memset(mc_filter, 0, sizeof(mc_filter));
 | 
				
			||||||
		netdev_for_each_mc_addr(mclist, dev) {
 | 
							netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
			int filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
 | 
								int filterbit = ether_crc_le(ETH_ALEN, ha->addr) & 0x3f;
 | 
				
			||||||
			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 | 
								mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		new_mode = CMR2h_Normal;
 | 
							new_mode = CMR2h_Normal;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,14 +75,19 @@ static int au1000_debug = 5;
 | 
				
			||||||
static int au1000_debug = 3;
 | 
					static int au1000_debug = 3;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AU1000_DEF_MSG_ENABLE	(NETIF_MSG_DRV	| \
 | 
				
			||||||
 | 
									NETIF_MSG_PROBE	| \
 | 
				
			||||||
 | 
									NETIF_MSG_LINK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DRV_NAME	"au1000_eth"
 | 
					#define DRV_NAME	"au1000_eth"
 | 
				
			||||||
#define DRV_VERSION	"1.6"
 | 
					#define DRV_VERSION	"1.7"
 | 
				
			||||||
#define DRV_AUTHOR	"Pete Popov <ppopov@embeddedalley.com>"
 | 
					#define DRV_AUTHOR	"Pete Popov <ppopov@embeddedalley.com>"
 | 
				
			||||||
#define DRV_DESC	"Au1xxx on-chip Ethernet driver"
 | 
					#define DRV_DESC	"Au1xxx on-chip Ethernet driver"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULE_AUTHOR(DRV_AUTHOR);
 | 
					MODULE_AUTHOR(DRV_AUTHOR);
 | 
				
			||||||
MODULE_DESCRIPTION(DRV_DESC);
 | 
					MODULE_DESCRIPTION(DRV_DESC);
 | 
				
			||||||
MODULE_LICENSE("GPL");
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					MODULE_VERSION(DRV_VERSION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Theory of operation
 | 
					 * Theory of operation
 | 
				
			||||||
| 
						 | 
					@ -148,7 +153,7 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
 | 
				
			||||||
 * specific irq-map
 | 
					 * specific irq-map
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void enable_mac(struct net_device *dev, int force_reset)
 | 
					static void au1000_enable_mac(struct net_device *dev, int force_reset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
	struct au1000_private *aup = netdev_priv(dev);
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
| 
						 | 
					@ -182,8 +187,7 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 | 
				
			||||||
	while (*mii_control_reg & MAC_MII_BUSY) {
 | 
						while (*mii_control_reg & MAC_MII_BUSY) {
 | 
				
			||||||
		mdelay(1);
 | 
							mdelay(1);
 | 
				
			||||||
		if (--timedout == 0) {
 | 
							if (--timedout == 0) {
 | 
				
			||||||
			printk(KERN_ERR "%s: read_MII busy timeout!!\n",
 | 
								netdev_err(dev, "read_MII busy timeout!!\n");
 | 
				
			||||||
					dev->name);
 | 
					 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -197,8 +201,7 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 | 
				
			||||||
	while (*mii_control_reg & MAC_MII_BUSY) {
 | 
						while (*mii_control_reg & MAC_MII_BUSY) {
 | 
				
			||||||
		mdelay(1);
 | 
							mdelay(1);
 | 
				
			||||||
		if (--timedout == 0) {
 | 
							if (--timedout == 0) {
 | 
				
			||||||
			printk(KERN_ERR "%s: mdio_read busy timeout!!\n",
 | 
								netdev_err(dev, "mdio_read busy timeout!!\n");
 | 
				
			||||||
					dev->name);
 | 
					 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -217,8 +220,7 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr,
 | 
				
			||||||
	while (*mii_control_reg & MAC_MII_BUSY) {
 | 
						while (*mii_control_reg & MAC_MII_BUSY) {
 | 
				
			||||||
		mdelay(1);
 | 
							mdelay(1);
 | 
				
			||||||
		if (--timedout == 0) {
 | 
							if (--timedout == 0) {
 | 
				
			||||||
			printk(KERN_ERR "%s: mdio_write busy timeout!!\n",
 | 
								netdev_err(dev, "mdio_write busy timeout!!\n");
 | 
				
			||||||
					dev->name);
 | 
					 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -236,7 +238,7 @@ static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
 | 
				
			||||||
	 * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
 | 
						 * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
 | 
				
			||||||
	struct net_device *const dev = bus->priv;
 | 
						struct net_device *const dev = bus->priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enable_mac(dev, 0); /* make sure the MAC associated with this
 | 
						au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
 | 
				
			||||||
			     * mii_bus is enabled */
 | 
								     * mii_bus is enabled */
 | 
				
			||||||
	return au1000_mdio_read(dev, phy_addr, regnum);
 | 
						return au1000_mdio_read(dev, phy_addr, regnum);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -246,7 +248,7 @@ static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *const dev = bus->priv;
 | 
						struct net_device *const dev = bus->priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enable_mac(dev, 0); /* make sure the MAC associated with this
 | 
						au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
 | 
				
			||||||
			     * mii_bus is enabled */
 | 
								     * mii_bus is enabled */
 | 
				
			||||||
	au1000_mdio_write(dev, phy_addr, regnum, value);
 | 
						au1000_mdio_write(dev, phy_addr, regnum, value);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -256,28 +258,26 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *const dev = bus->priv;
 | 
						struct net_device *const dev = bus->priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enable_mac(dev, 0); /* make sure the MAC associated with this
 | 
						au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
 | 
				
			||||||
			     * mii_bus is enabled */
 | 
								     * mii_bus is enabled */
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hard_stop(struct net_device *dev)
 | 
					static void au1000_hard_stop(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *aup = netdev_priv(dev);
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, drv, dev, "hard stop\n");
 | 
				
			||||||
		printk(KERN_INFO "%s: hard stop\n", dev->name);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
 | 
						aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
 | 
				
			||||||
	au_sync_delay(10);
 | 
						au_sync_delay(10);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void enable_rx_tx(struct net_device *dev)
 | 
					static void au1000_enable_rx_tx(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *aup = netdev_priv(dev);
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, hw, dev, "enable_rx_tx\n");
 | 
				
			||||||
		printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
 | 
						aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
 | 
				
			||||||
	au_sync_delay(10);
 | 
						au_sync_delay(10);
 | 
				
			||||||
| 
						 | 
					@ -297,16 +297,15 @@ au1000_adjust_link(struct net_device *dev)
 | 
				
			||||||
	spin_lock_irqsave(&aup->lock, flags);
 | 
						spin_lock_irqsave(&aup->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (phydev->link && (aup->old_speed != phydev->speed)) {
 | 
						if (phydev->link && (aup->old_speed != phydev->speed)) {
 | 
				
			||||||
		// speed changed
 | 
							/* speed changed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch(phydev->speed) {
 | 
							switch (phydev->speed) {
 | 
				
			||||||
		case SPEED_10:
 | 
							case SPEED_10:
 | 
				
			||||||
		case SPEED_100:
 | 
							case SPEED_100:
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			printk(KERN_WARNING
 | 
								netdev_warn(dev, "Speed (%d) is not 10/100 ???\n",
 | 
				
			||||||
			       "%s: Speed (%d) is not 10/100 ???\n",
 | 
												phydev->speed);
 | 
				
			||||||
			       dev->name, phydev->speed);
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -316,10 +315,10 @@ au1000_adjust_link(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (phydev->link && (aup->old_duplex != phydev->duplex)) {
 | 
						if (phydev->link && (aup->old_duplex != phydev->duplex)) {
 | 
				
			||||||
		// duplex mode changed
 | 
							/* duplex mode changed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* switching duplex mode requires to disable rx and tx! */
 | 
							/* switching duplex mode requires to disable rx and tx! */
 | 
				
			||||||
		hard_stop(dev);
 | 
							au1000_hard_stop(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (DUPLEX_FULL == phydev->duplex)
 | 
							if (DUPLEX_FULL == phydev->duplex)
 | 
				
			||||||
			aup->mac->control = ((aup->mac->control
 | 
								aup->mac->control = ((aup->mac->control
 | 
				
			||||||
| 
						 | 
					@ -331,14 +330,14 @@ au1000_adjust_link(struct net_device *dev)
 | 
				
			||||||
					     | MAC_DISABLE_RX_OWN);
 | 
										     | MAC_DISABLE_RX_OWN);
 | 
				
			||||||
		au_sync_delay(1);
 | 
							au_sync_delay(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		enable_rx_tx(dev);
 | 
							au1000_enable_rx_tx(dev);
 | 
				
			||||||
		aup->old_duplex = phydev->duplex;
 | 
							aup->old_duplex = phydev->duplex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		status_change = 1;
 | 
							status_change = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(phydev->link != aup->old_link) {
 | 
						if (phydev->link != aup->old_link) {
 | 
				
			||||||
		// link state changed
 | 
							/* link state changed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!phydev->link) {
 | 
							if (!phydev->link) {
 | 
				
			||||||
			/* link went down */
 | 
								/* link went down */
 | 
				
			||||||
| 
						 | 
					@ -354,15 +353,15 @@ au1000_adjust_link(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status_change) {
 | 
						if (status_change) {
 | 
				
			||||||
		if (phydev->link)
 | 
							if (phydev->link)
 | 
				
			||||||
			printk(KERN_INFO "%s: link up (%d/%s)\n",
 | 
								netdev_info(dev, "link up (%d/%s)\n",
 | 
				
			||||||
			       dev->name, phydev->speed,
 | 
								       phydev->speed,
 | 
				
			||||||
			       DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
 | 
								       DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			printk(KERN_INFO "%s: link down\n", dev->name);
 | 
								netdev_info(dev, "link down\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mii_probe (struct net_device *dev)
 | 
					static int au1000_mii_probe (struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *const aup = netdev_priv(dev);
 | 
						struct au1000_private *const aup = netdev_priv(dev);
 | 
				
			||||||
	struct phy_device *phydev = NULL;
 | 
						struct phy_device *phydev = NULL;
 | 
				
			||||||
| 
						 | 
					@ -373,8 +372,7 @@ static int mii_probe (struct net_device *dev)
 | 
				
			||||||
		if (aup->phy_addr)
 | 
							if (aup->phy_addr)
 | 
				
			||||||
			phydev = aup->mii_bus->phy_map[aup->phy_addr];
 | 
								phydev = aup->mii_bus->phy_map[aup->phy_addr];
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
 | 
								netdev_info(dev, "using PHY-less setup\n");
 | 
				
			||||||
				dev->name);
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		int phy_addr;
 | 
							int phy_addr;
 | 
				
			||||||
| 
						 | 
					@ -391,7 +389,7 @@ static int mii_probe (struct net_device *dev)
 | 
				
			||||||
			/* try harder to find a PHY */
 | 
								/* try harder to find a PHY */
 | 
				
			||||||
			if (!phydev && (aup->mac_id == 1)) {
 | 
								if (!phydev && (aup->mac_id == 1)) {
 | 
				
			||||||
				/* no PHY found, maybe we have a dual PHY? */
 | 
									/* no PHY found, maybe we have a dual PHY? */
 | 
				
			||||||
				printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
 | 
									dev_info(&dev->dev, ": no PHY found on MAC1, "
 | 
				
			||||||
					"let's see if it's attached to MAC0...\n");
 | 
										"let's see if it's attached to MAC0...\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* find the first (lowest address) non-attached PHY on
 | 
									/* find the first (lowest address) non-attached PHY on
 | 
				
			||||||
| 
						 | 
					@ -417,7 +415,7 @@ static int mii_probe (struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!phydev) {
 | 
						if (!phydev) {
 | 
				
			||||||
		printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name);
 | 
							netdev_err(dev, "no PHY found\n");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -428,7 +426,7 @@ static int mii_probe (struct net_device *dev)
 | 
				
			||||||
			0, PHY_INTERFACE_MODE_MII);
 | 
								0, PHY_INTERFACE_MODE_MII);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (IS_ERR(phydev)) {
 | 
						if (IS_ERR(phydev)) {
 | 
				
			||||||
		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
 | 
							netdev_err(dev, "Could not attach to PHY\n");
 | 
				
			||||||
		return PTR_ERR(phydev);
 | 
							return PTR_ERR(phydev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -449,8 +447,8 @@ static int mii_probe (struct net_device *dev)
 | 
				
			||||||
	aup->old_duplex = -1;
 | 
						aup->old_duplex = -1;
 | 
				
			||||||
	aup->phy_dev = phydev;
 | 
						aup->phy_dev = phydev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk(KERN_INFO "%s: attached PHY driver [%s] "
 | 
						netdev_info(dev, "attached PHY driver [%s] "
 | 
				
			||||||
	       "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
 | 
						       "(mii_bus:phy_addr=%s, irq=%d)\n",
 | 
				
			||||||
	       phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
 | 
						       phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -462,7 +460,7 @@ static int mii_probe (struct net_device *dev)
 | 
				
			||||||
 * has the virtual and dma address of a buffer suitable for
 | 
					 * has the virtual and dma address of a buffer suitable for
 | 
				
			||||||
 * both, receive and transmit operations.
 | 
					 * both, receive and transmit operations.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static db_dest_t *GetFreeDB(struct au1000_private *aup)
 | 
					static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	db_dest_t *pDB;
 | 
						db_dest_t *pDB;
 | 
				
			||||||
	pDB = aup->pDBfree;
 | 
						pDB = aup->pDBfree;
 | 
				
			||||||
| 
						 | 
					@ -473,7 +471,7 @@ static db_dest_t *GetFreeDB(struct au1000_private *aup)
 | 
				
			||||||
	return pDB;
 | 
						return pDB;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
 | 
					void au1000_ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	db_dest_t *pDBfree = aup->pDBfree;
 | 
						db_dest_t *pDBfree = aup->pDBfree;
 | 
				
			||||||
	if (pDBfree)
 | 
						if (pDBfree)
 | 
				
			||||||
| 
						 | 
					@ -481,12 +479,12 @@ void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
 | 
				
			||||||
	aup->pDBfree = pDB;
 | 
						aup->pDBfree = pDB;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void reset_mac_unlocked(struct net_device *dev)
 | 
					static void au1000_reset_mac_unlocked(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *const aup = netdev_priv(dev);
 | 
						struct au1000_private *const aup = netdev_priv(dev);
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hard_stop(dev);
 | 
						au1000_hard_stop(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*aup->enable = MAC_EN_CLOCK_ENABLE;
 | 
						*aup->enable = MAC_EN_CLOCK_ENABLE;
 | 
				
			||||||
	au_sync_delay(2);
 | 
						au_sync_delay(2);
 | 
				
			||||||
| 
						 | 
					@ -507,18 +505,17 @@ static void reset_mac_unlocked(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void reset_mac(struct net_device *dev)
 | 
					static void au1000_reset_mac(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *const aup = netdev_priv(dev);
 | 
						struct au1000_private *const aup = netdev_priv(dev);
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, hw, dev, "reset mac, aup %x\n",
 | 
				
			||||||
		printk(KERN_INFO "%s: reset mac, aup %x\n",
 | 
										(unsigned)aup);
 | 
				
			||||||
		       dev->name, (unsigned)aup);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&aup->lock, flags);
 | 
						spin_lock_irqsave(&aup->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reset_mac_unlocked (dev);
 | 
						au1000_reset_mac_unlocked (dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irqrestore(&aup->lock, flags);
 | 
						spin_unlock_irqrestore(&aup->lock, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -529,7 +526,7 @@ static void reset_mac(struct net_device *dev)
 | 
				
			||||||
 * these are not descriptors sitting in memory.
 | 
					 * these are not descriptors sitting in memory.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
 | 
					au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -582,11 +579,25 @@ au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 | 
				
			||||||
	info->regdump_len = 0;
 | 
						info->regdump_len = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void au1000_set_msglevel(struct net_device *dev, u32 value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
 | 
						aup->msg_enable = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u32 au1000_get_msglevel(struct net_device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
 | 
						return aup->msg_enable;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ethtool_ops au1000_ethtool_ops = {
 | 
					static const struct ethtool_ops au1000_ethtool_ops = {
 | 
				
			||||||
	.get_settings = au1000_get_settings,
 | 
						.get_settings = au1000_get_settings,
 | 
				
			||||||
	.set_settings = au1000_set_settings,
 | 
						.set_settings = au1000_set_settings,
 | 
				
			||||||
	.get_drvinfo = au1000_get_drvinfo,
 | 
						.get_drvinfo = au1000_get_drvinfo,
 | 
				
			||||||
	.get_link = ethtool_op_get_link,
 | 
						.get_link = ethtool_op_get_link,
 | 
				
			||||||
 | 
						.get_msglevel = au1000_get_msglevel,
 | 
				
			||||||
 | 
						.set_msglevel = au1000_set_msglevel,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -606,11 +617,10 @@ static int au1000_init(struct net_device *dev)
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	u32 control;
 | 
						u32 control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, hw, dev, "au1000_init\n");
 | 
				
			||||||
		printk("%s: au1000_init\n", dev->name);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* bring the device out of reset */
 | 
						/* bring the device out of reset */
 | 
				
			||||||
	enable_mac(dev, 1);
 | 
						au1000_enable_mac(dev, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&aup->lock, flags);
 | 
						spin_lock_irqsave(&aup->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -649,7 +659,7 @@ static int au1000_init(struct net_device *dev)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void update_rx_stats(struct net_device *dev, u32 status)
 | 
					static inline void au1000_update_rx_stats(struct net_device *dev, u32 status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device_stats *ps = &dev->stats;
 | 
						struct net_device_stats *ps = &dev->stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -667,8 +677,7 @@ static inline void update_rx_stats(struct net_device *dev, u32 status)
 | 
				
			||||||
			ps->rx_crc_errors++;
 | 
								ps->rx_crc_errors++;
 | 
				
			||||||
		if (status & RX_COLL)
 | 
							if (status & RX_COLL)
 | 
				
			||||||
			ps->collisions++;
 | 
								ps->collisions++;
 | 
				
			||||||
	}
 | 
						} else
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		ps->rx_bytes += status & RX_FRAME_LEN_MASK;
 | 
							ps->rx_bytes += status & RX_FRAME_LEN_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -685,15 +694,14 @@ static int au1000_rx(struct net_device *dev)
 | 
				
			||||||
	db_dest_t *pDB;
 | 
						db_dest_t *pDB;
 | 
				
			||||||
	u32	frmlen;
 | 
						u32	frmlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 5)
 | 
						netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head);
 | 
				
			||||||
		printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	prxd = aup->rx_dma_ring[aup->rx_head];
 | 
						prxd = aup->rx_dma_ring[aup->rx_head];
 | 
				
			||||||
	buff_stat = prxd->buff_stat;
 | 
						buff_stat = prxd->buff_stat;
 | 
				
			||||||
	while (buff_stat & RX_T_DONE)  {
 | 
						while (buff_stat & RX_T_DONE)  {
 | 
				
			||||||
		status = prxd->status;
 | 
							status = prxd->status;
 | 
				
			||||||
		pDB = aup->rx_db_inuse[aup->rx_head];
 | 
							pDB = aup->rx_db_inuse[aup->rx_head];
 | 
				
			||||||
		update_rx_stats(dev, status);
 | 
							au1000_update_rx_stats(dev, status);
 | 
				
			||||||
		if (!(status & RX_ERROR))  {
 | 
							if (!(status & RX_ERROR))  {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* good frame */
 | 
								/* good frame */
 | 
				
			||||||
| 
						 | 
					@ -701,9 +709,7 @@ static int au1000_rx(struct net_device *dev)
 | 
				
			||||||
			frmlen -= 4; /* Remove FCS */
 | 
								frmlen -= 4; /* Remove FCS */
 | 
				
			||||||
			skb = dev_alloc_skb(frmlen + 2);
 | 
								skb = dev_alloc_skb(frmlen + 2);
 | 
				
			||||||
			if (skb == NULL) {
 | 
								if (skb == NULL) {
 | 
				
			||||||
				printk(KERN_ERR
 | 
									netdev_err(dev, "Memory squeeze, dropping packet.\n");
 | 
				
			||||||
				       "%s: Memory squeeze, dropping packet.\n",
 | 
					 | 
				
			||||||
				       dev->name);
 | 
					 | 
				
			||||||
				dev->stats.rx_dropped++;
 | 
									dev->stats.rx_dropped++;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -713,8 +719,7 @@ static int au1000_rx(struct net_device *dev)
 | 
				
			||||||
			skb_put(skb, frmlen);
 | 
								skb_put(skb, frmlen);
 | 
				
			||||||
			skb->protocol = eth_type_trans(skb, dev);
 | 
								skb->protocol = eth_type_trans(skb, dev);
 | 
				
			||||||
			netif_rx(skb);	/* pass the packet to upper layers */
 | 
								netif_rx(skb);	/* pass the packet to upper layers */
 | 
				
			||||||
		}
 | 
							} else {
 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			if (au1000_debug > 4) {
 | 
								if (au1000_debug > 4) {
 | 
				
			||||||
				if (status & RX_MISSED_FRAME)
 | 
									if (status & RX_MISSED_FRAME)
 | 
				
			||||||
					printk("rx miss\n");
 | 
										printk("rx miss\n");
 | 
				
			||||||
| 
						 | 
					@ -747,7 +752,7 @@ static int au1000_rx(struct net_device *dev)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void update_tx_stats(struct net_device *dev, u32 status)
 | 
					static void au1000_update_tx_stats(struct net_device *dev, u32 status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *aup = netdev_priv(dev);
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
	struct net_device_stats *ps = &dev->stats;
 | 
						struct net_device_stats *ps = &dev->stats;
 | 
				
			||||||
| 
						 | 
					@ -760,8 +765,7 @@ static void update_tx_stats(struct net_device *dev, u32 status)
 | 
				
			||||||
				ps->tx_errors++;
 | 
									ps->tx_errors++;
 | 
				
			||||||
				ps->tx_aborted_errors++;
 | 
									ps->tx_aborted_errors++;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							} else {
 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			ps->tx_errors++;
 | 
								ps->tx_errors++;
 | 
				
			||||||
			ps->tx_aborted_errors++;
 | 
								ps->tx_aborted_errors++;
 | 
				
			||||||
			if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
 | 
								if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
 | 
				
			||||||
| 
						 | 
					@ -783,7 +787,7 @@ static void au1000_tx_ack(struct net_device *dev)
 | 
				
			||||||
	ptxd = aup->tx_dma_ring[aup->tx_tail];
 | 
						ptxd = aup->tx_dma_ring[aup->tx_tail];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (ptxd->buff_stat & TX_T_DONE) {
 | 
						while (ptxd->buff_stat & TX_T_DONE) {
 | 
				
			||||||
		update_tx_stats(dev, ptxd->status);
 | 
							au1000_update_tx_stats(dev, ptxd->status);
 | 
				
			||||||
		ptxd->buff_stat &= ~TX_T_DONE;
 | 
							ptxd->buff_stat &= ~TX_T_DONE;
 | 
				
			||||||
		ptxd->len = 0;
 | 
							ptxd->len = 0;
 | 
				
			||||||
		au_sync();
 | 
							au_sync();
 | 
				
			||||||
| 
						 | 
					@ -817,18 +821,18 @@ static int au1000_open(struct net_device *dev)
 | 
				
			||||||
	int retval;
 | 
						int retval;
 | 
				
			||||||
	struct au1000_private *aup = netdev_priv(dev);
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, drv, dev, "open: dev=%p\n", dev);
 | 
				
			||||||
		printk("%s: open: dev=%p\n", dev->name, dev);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((retval = request_irq(dev->irq, au1000_interrupt, 0,
 | 
						retval = request_irq(dev->irq, au1000_interrupt, 0,
 | 
				
			||||||
					dev->name, dev))) {
 | 
										dev->name, dev);
 | 
				
			||||||
		printk(KERN_ERR "%s: unable to get IRQ %d\n",
 | 
						if (retval) {
 | 
				
			||||||
				dev->name, dev->irq);
 | 
							netdev_err(dev, "unable to get IRQ %d\n", dev->irq);
 | 
				
			||||||
		return retval;
 | 
							return retval;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((retval = au1000_init(dev))) {
 | 
						retval = au1000_init(dev);
 | 
				
			||||||
		printk(KERN_ERR "%s: error in au1000_init\n", dev->name);
 | 
						if (retval) {
 | 
				
			||||||
 | 
							netdev_err(dev, "error in au1000_init\n");
 | 
				
			||||||
		free_irq(dev->irq, dev);
 | 
							free_irq(dev->irq, dev);
 | 
				
			||||||
		return retval;
 | 
							return retval;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -841,8 +845,7 @@ static int au1000_open(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_start_queue(dev);
 | 
						netif_start_queue(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, drv, dev, "open: Initialization done.\n");
 | 
				
			||||||
		printk("%s: open: Initialization done.\n", dev->name);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -852,15 +855,14 @@ static int au1000_close(struct net_device *dev)
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
	struct au1000_private *const aup = netdev_priv(dev);
 | 
						struct au1000_private *const aup = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, drv, dev, "close: dev=%p\n", dev);
 | 
				
			||||||
		printk("%s: close: dev=%p\n", dev->name, dev);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (aup->phy_dev)
 | 
						if (aup->phy_dev)
 | 
				
			||||||
		phy_stop(aup->phy_dev);
 | 
							phy_stop(aup->phy_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&aup->lock, flags);
 | 
						spin_lock_irqsave(&aup->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reset_mac_unlocked (dev);
 | 
						au1000_reset_mac_unlocked (dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* stop the device */
 | 
						/* stop the device */
 | 
				
			||||||
	netif_stop_queue(dev);
 | 
						netif_stop_queue(dev);
 | 
				
			||||||
| 
						 | 
					@ -884,9 +886,8 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	db_dest_t *pDB;
 | 
						db_dest_t *pDB;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 5)
 | 
						netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n",
 | 
				
			||||||
		printk("%s: tx: aup %x len=%d, data=%p, head %d\n",
 | 
									(unsigned)aup, skb->len,
 | 
				
			||||||
				dev->name, (unsigned)aup, skb->len,
 | 
					 | 
				
			||||||
				skb->data, aup->tx_head);
 | 
									skb->data, aup->tx_head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ptxd = aup->tx_dma_ring[aup->tx_head];
 | 
						ptxd = aup->tx_dma_ring[aup->tx_head];
 | 
				
			||||||
| 
						 | 
					@ -896,9 +897,8 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		netif_stop_queue(dev);
 | 
							netif_stop_queue(dev);
 | 
				
			||||||
		aup->tx_full = 1;
 | 
							aup->tx_full = 1;
 | 
				
			||||||
		return NETDEV_TX_BUSY;
 | 
							return NETDEV_TX_BUSY;
 | 
				
			||||||
	}
 | 
						} else if (buff_stat & TX_T_DONE) {
 | 
				
			||||||
	else if (buff_stat & TX_T_DONE) {
 | 
							au1000_update_tx_stats(dev, ptxd->status);
 | 
				
			||||||
		update_tx_stats(dev, ptxd->status);
 | 
					 | 
				
			||||||
		ptxd->len = 0;
 | 
							ptxd->len = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -910,12 +910,11 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	pDB = aup->tx_db_inuse[aup->tx_head];
 | 
						pDB = aup->tx_db_inuse[aup->tx_head];
 | 
				
			||||||
	skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
 | 
						skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
 | 
				
			||||||
	if (skb->len < ETH_ZLEN) {
 | 
						if (skb->len < ETH_ZLEN) {
 | 
				
			||||||
		for (i=skb->len; i<ETH_ZLEN; i++) {
 | 
							for (i = skb->len; i < ETH_ZLEN; i++) {
 | 
				
			||||||
			((char *)pDB->vaddr)[i] = 0;
 | 
								((char *)pDB->vaddr)[i] = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ptxd->len = ETH_ZLEN;
 | 
							ptxd->len = ETH_ZLEN;
 | 
				
			||||||
	}
 | 
						} else
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		ptxd->len = skb->len;
 | 
							ptxd->len = skb->len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ps->tx_packets++;
 | 
						ps->tx_packets++;
 | 
				
			||||||
| 
						 | 
					@ -925,7 +924,6 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	au_sync();
 | 
						au_sync();
 | 
				
			||||||
	dev_kfree_skb(skb);
 | 
						dev_kfree_skb(skb);
 | 
				
			||||||
	aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
 | 
						aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -935,10 +933,10 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void au1000_tx_timeout(struct net_device *dev)
 | 
					static void au1000_tx_timeout(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev);
 | 
						netdev_err(dev, "au1000_tx_timeout: dev=%p\n", dev);
 | 
				
			||||||
	reset_mac(dev);
 | 
						au1000_reset_mac(dev);
 | 
				
			||||||
	au1000_init(dev);
 | 
						au1000_init(dev);
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue(dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -946,8 +944,7 @@ static void au1000_multicast_list(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *aup = netdev_priv(dev);
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (au1000_debug > 4)
 | 
						netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n", dev->flags);
 | 
				
			||||||
		printk("%s: au1000_multicast_list: flags=%x\n", dev->name, dev->flags);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 | 
						if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 | 
				
			||||||
		aup->mac->control |= MAC_PROMISCUOUS;
 | 
							aup->mac->control |= MAC_PROMISCUOUS;
 | 
				
			||||||
| 
						 | 
					@ -955,14 +952,14 @@ static void au1000_multicast_list(struct net_device *dev)
 | 
				
			||||||
			   netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
 | 
								   netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
 | 
				
			||||||
		aup->mac->control |= MAC_PASS_ALL_MULTI;
 | 
							aup->mac->control |= MAC_PASS_ALL_MULTI;
 | 
				
			||||||
		aup->mac->control &= ~MAC_PROMISCUOUS;
 | 
							aup->mac->control &= ~MAC_PROMISCUOUS;
 | 
				
			||||||
		printk(KERN_INFO "%s: Pass all multicast\n", dev->name);
 | 
							netdev_info(dev, "Pass all multicast\n");
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct dev_mc_list *mclist;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
		u32 mc_filter[2];	/* Multicast hash filter */
 | 
							u32 mc_filter[2];	/* Multicast hash filter */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		mc_filter[1] = mc_filter[0] = 0;
 | 
							mc_filter[1] = mc_filter[0] = 0;
 | 
				
			||||||
		netdev_for_each_mc_addr(mclist, dev)
 | 
							netdev_for_each_mc_addr(ha, dev)
 | 
				
			||||||
			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26,
 | 
								set_bit(ether_crc(ETH_ALEN, ha->addr)>>26,
 | 
				
			||||||
					(long *)mc_filter);
 | 
										(long *)mc_filter);
 | 
				
			||||||
		aup->mac->multi_hash_high = mc_filter[1];
 | 
							aup->mac->multi_hash_high = mc_filter[1];
 | 
				
			||||||
		aup->mac->multi_hash_low = mc_filter[0];
 | 
							aup->mac->multi_hash_low = mc_filter[0];
 | 
				
			||||||
| 
						 | 
					@ -975,9 +972,11 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct au1000_private *aup = netdev_priv(dev);
 | 
						struct au1000_private *aup = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!netif_running(dev)) return -EINVAL;
 | 
						if (!netif_running(dev))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!aup->phy_dev) return -EINVAL; // PHY not controllable
 | 
						if (!aup->phy_dev)
 | 
				
			||||||
 | 
							return -EINVAL; /* PHY not controllable */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
 | 
						return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -996,7 +995,7 @@ static const struct net_device_ops au1000_netdev_ops = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __devinit au1000_probe(struct platform_device *pdev)
 | 
					static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static unsigned version_printed = 0;
 | 
						static unsigned version_printed;
 | 
				
			||||||
	struct au1000_private *aup = NULL;
 | 
						struct au1000_private *aup = NULL;
 | 
				
			||||||
	struct au1000_eth_platform_data *pd;
 | 
						struct au1000_eth_platform_data *pd;
 | 
				
			||||||
	struct net_device *dev = NULL;
 | 
						struct net_device *dev = NULL;
 | 
				
			||||||
| 
						 | 
					@ -1007,40 +1006,40 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
						base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
				
			||||||
	if (!base) {
 | 
						if (!base) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to retrieve base register\n");
 | 
							dev_err(&pdev->dev, "failed to retrieve base register\n");
 | 
				
			||||||
		err = -ENODEV;
 | 
							err = -ENODEV;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 | 
						macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 | 
				
			||||||
	if (!macen) {
 | 
						if (!macen) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to retrieve MAC Enable register\n");
 | 
							dev_err(&pdev->dev, "failed to retrieve MAC Enable register\n");
 | 
				
			||||||
		err = -ENODEV;
 | 
							err = -ENODEV;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	irq = platform_get_irq(pdev, 0);
 | 
						irq = platform_get_irq(pdev, 0);
 | 
				
			||||||
	if (irq < 0) {
 | 
						if (irq < 0) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n");
 | 
							dev_err(&pdev->dev, "failed to retrieve IRQ\n");
 | 
				
			||||||
		err = -ENODEV;
 | 
							err = -ENODEV;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
 | 
						if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to request memory region for base registers\n");
 | 
							dev_err(&pdev->dev, "failed to request memory region for base registers\n");
 | 
				
			||||||
		err = -ENXIO;
 | 
							err = -ENXIO;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
 | 
						if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to request memory region for MAC enable register\n");
 | 
							dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n");
 | 
				
			||||||
		err = -ENXIO;
 | 
							err = -ENXIO;
 | 
				
			||||||
		goto err_request;
 | 
							goto err_request;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev = alloc_etherdev(sizeof(struct au1000_private));
 | 
						dev = alloc_etherdev(sizeof(struct au1000_private));
 | 
				
			||||||
	if (!dev) {
 | 
						if (!dev) {
 | 
				
			||||||
		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
 | 
							dev_err(&pdev->dev, "alloc_etherdev failed\n");
 | 
				
			||||||
		err = -ENOMEM;
 | 
							err = -ENOMEM;
 | 
				
			||||||
		goto err_alloc;
 | 
							goto err_alloc;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1050,6 +1049,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
	aup = netdev_priv(dev);
 | 
						aup = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_init(&aup->lock);
 | 
						spin_lock_init(&aup->lock);
 | 
				
			||||||
 | 
						aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Allocate the data buffers */
 | 
						/* Allocate the data buffers */
 | 
				
			||||||
	/* Snooping works fine with eth on all au1xxx */
 | 
						/* Snooping works fine with eth on all au1xxx */
 | 
				
			||||||
| 
						 | 
					@ -1057,7 +1057,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
						(NUM_TX_BUFFS + NUM_RX_BUFFS),
 | 
											(NUM_TX_BUFFS + NUM_RX_BUFFS),
 | 
				
			||||||
						&aup->dma_addr,	0);
 | 
											&aup->dma_addr,	0);
 | 
				
			||||||
	if (!aup->vaddr) {
 | 
						if (!aup->vaddr) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to allocate data buffers\n");
 | 
							dev_err(&pdev->dev, "failed to allocate data buffers\n");
 | 
				
			||||||
		err = -ENOMEM;
 | 
							err = -ENOMEM;
 | 
				
			||||||
		goto err_vaddr;
 | 
							goto err_vaddr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1065,7 +1065,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
	/* aup->mac is the base address of the MAC's registers */
 | 
						/* aup->mac is the base address of the MAC's registers */
 | 
				
			||||||
	aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
 | 
						aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
 | 
				
			||||||
	if (!aup->mac) {
 | 
						if (!aup->mac) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to ioremap MAC registers\n");
 | 
							dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
 | 
				
			||||||
		err = -ENXIO;
 | 
							err = -ENXIO;
 | 
				
			||||||
		goto err_remap1;
 | 
							goto err_remap1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1073,7 +1073,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
        /* Setup some variables for quick register address access */
 | 
					        /* Setup some variables for quick register address access */
 | 
				
			||||||
	aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
 | 
						aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
 | 
				
			||||||
	if (!aup->enable) {
 | 
						if (!aup->enable) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to ioremap MAC enable register\n");
 | 
							dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
 | 
				
			||||||
		err = -ENXIO;
 | 
							err = -ENXIO;
 | 
				
			||||||
		goto err_remap2;
 | 
							goto err_remap2;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1083,14 +1083,13 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
		if (prom_get_ethernet_addr(ethaddr) == 0)
 | 
							if (prom_get_ethernet_addr(ethaddr) == 0)
 | 
				
			||||||
			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
 | 
								memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			printk(KERN_INFO "%s: No MAC address found\n",
 | 
								netdev_info(dev, "No MAC address found\n");
 | 
				
			||||||
					 dev->name);
 | 
					 | 
				
			||||||
				/* Use the hard coded MAC addresses */
 | 
									/* Use the hard coded MAC addresses */
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
 | 
							au1000_setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
 | 
				
			||||||
	} else if (pdev->id == 1)
 | 
						} else if (pdev->id == 1)
 | 
				
			||||||
		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
 | 
							au1000_setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Assign to the Ethernet ports two consecutive MAC addresses
 | 
						 * Assign to the Ethernet ports two consecutive MAC addresses
 | 
				
			||||||
| 
						 | 
					@ -1104,7 +1103,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pd = pdev->dev.platform_data;
 | 
						pd = pdev->dev.platform_data;
 | 
				
			||||||
	if (!pd) {
 | 
						if (!pd) {
 | 
				
			||||||
		printk(KERN_INFO DRV_NAME ": no platform_data passed, PHY search on MAC0\n");
 | 
							dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n");
 | 
				
			||||||
		aup->phy1_search_mac0 = 1;
 | 
							aup->phy1_search_mac0 = 1;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		aup->phy_static_config = pd->phy_static_config;
 | 
							aup->phy_static_config = pd->phy_static_config;
 | 
				
			||||||
| 
						 | 
					@ -1116,7 +1115,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (aup->phy_busid && aup->phy_busid > 0) {
 | 
						if (aup->phy_busid && aup->phy_busid > 0) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": MAC0-associated PHY attached 2nd MACs MII"
 | 
							dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII"
 | 
				
			||||||
				"bus not supported yet\n");
 | 
									"bus not supported yet\n");
 | 
				
			||||||
		err = -ENODEV;
 | 
							err = -ENODEV;
 | 
				
			||||||
		goto err_mdiobus_alloc;
 | 
							goto err_mdiobus_alloc;
 | 
				
			||||||
| 
						 | 
					@ -1124,7 +1123,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	aup->mii_bus = mdiobus_alloc();
 | 
						aup->mii_bus = mdiobus_alloc();
 | 
				
			||||||
	if (aup->mii_bus == NULL) {
 | 
						if (aup->mii_bus == NULL) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME ": failed to allocate mdiobus structure\n");
 | 
							dev_err(&pdev->dev, "failed to allocate mdiobus structure\n");
 | 
				
			||||||
		err = -ENOMEM;
 | 
							err = -ENOMEM;
 | 
				
			||||||
		goto err_mdiobus_alloc;
 | 
							goto err_mdiobus_alloc;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1139,7 +1138,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
	if (aup->mii_bus->irq == NULL)
 | 
						if (aup->mii_bus->irq == NULL)
 | 
				
			||||||
		goto err_out;
 | 
							goto err_out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(i = 0; i < PHY_MAX_ADDR; ++i)
 | 
						for (i = 0; i < PHY_MAX_ADDR; ++i)
 | 
				
			||||||
		aup->mii_bus->irq[i] = PHY_POLL;
 | 
							aup->mii_bus->irq[i] = PHY_POLL;
 | 
				
			||||||
	/* if known, set corresponding PHY IRQs */
 | 
						/* if known, set corresponding PHY IRQs */
 | 
				
			||||||
	if (aup->phy_static_config)
 | 
						if (aup->phy_static_config)
 | 
				
			||||||
| 
						 | 
					@ -1148,11 +1147,11 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = mdiobus_register(aup->mii_bus);
 | 
						err = mdiobus_register(aup->mii_bus);
 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME " failed to register MDIO bus\n");
 | 
							dev_err(&pdev->dev, "failed to register MDIO bus\n");
 | 
				
			||||||
		goto err_mdiobus_reg;
 | 
							goto err_mdiobus_reg;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mii_probe(dev) != 0)
 | 
						if (au1000_mii_probe(dev) != 0)
 | 
				
			||||||
		goto err_out;
 | 
							goto err_out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pDBfree = NULL;
 | 
						pDBfree = NULL;
 | 
				
			||||||
| 
						 | 
					@ -1168,7 +1167,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
	aup->pDBfree = pDBfree;
 | 
						aup->pDBfree = pDBfree;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < NUM_RX_DMA; i++) {
 | 
						for (i = 0; i < NUM_RX_DMA; i++) {
 | 
				
			||||||
		pDB = GetFreeDB(aup);
 | 
							pDB = au1000_GetFreeDB(aup);
 | 
				
			||||||
		if (!pDB) {
 | 
							if (!pDB) {
 | 
				
			||||||
			goto err_out;
 | 
								goto err_out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1176,7 +1175,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
		aup->rx_db_inuse[i] = pDB;
 | 
							aup->rx_db_inuse[i] = pDB;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (i = 0; i < NUM_TX_DMA; i++) {
 | 
						for (i = 0; i < NUM_TX_DMA; i++) {
 | 
				
			||||||
		pDB = GetFreeDB(aup);
 | 
							pDB = au1000_GetFreeDB(aup);
 | 
				
			||||||
		if (!pDB) {
 | 
							if (!pDB) {
 | 
				
			||||||
			goto err_out;
 | 
								goto err_out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1195,17 +1194,16 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
	 * The boot code uses the ethernet controller, so reset it to start
 | 
						 * The boot code uses the ethernet controller, so reset it to start
 | 
				
			||||||
	 * fresh.  au1000_init() expects that the device is in reset state.
 | 
						 * fresh.  au1000_init() expects that the device is in reset state.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	reset_mac(dev);
 | 
						au1000_reset_mac(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = register_netdev(dev);
 | 
						err = register_netdev(dev);
 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
		printk(KERN_ERR DRV_NAME "%s: Cannot register net device, aborting.\n",
 | 
							netdev_err(dev, "Cannot register net device, aborting.\n");
 | 
				
			||||||
					dev->name);
 | 
					 | 
				
			||||||
		goto err_out;
 | 
							goto err_out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk("%s: Au1xx0 Ethernet found at 0x%lx, irq %d\n",
 | 
						netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n",
 | 
				
			||||||
			dev->name, (unsigned long)base->start, irq);
 | 
								(unsigned long)base->start, irq);
 | 
				
			||||||
	if (version_printed++ == 0)
 | 
						if (version_printed++ == 0)
 | 
				
			||||||
		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
 | 
							printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1217,15 +1215,15 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* here we should have a valid dev plus aup-> register addresses
 | 
						/* here we should have a valid dev plus aup-> register addresses
 | 
				
			||||||
	 * so we can reset the mac properly.*/
 | 
						 * so we can reset the mac properly.*/
 | 
				
			||||||
	reset_mac(dev);
 | 
						au1000_reset_mac(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < NUM_RX_DMA; i++) {
 | 
						for (i = 0; i < NUM_RX_DMA; i++) {
 | 
				
			||||||
		if (aup->rx_db_inuse[i])
 | 
							if (aup->rx_db_inuse[i])
 | 
				
			||||||
			ReleaseDB(aup, aup->rx_db_inuse[i]);
 | 
								au1000_ReleaseDB(aup, aup->rx_db_inuse[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (i = 0; i < NUM_TX_DMA; i++) {
 | 
						for (i = 0; i < NUM_TX_DMA; i++) {
 | 
				
			||||||
		if (aup->tx_db_inuse[i])
 | 
							if (aup->tx_db_inuse[i])
 | 
				
			||||||
			ReleaseDB(aup, aup->tx_db_inuse[i]);
 | 
								au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
err_mdiobus_reg:
 | 
					err_mdiobus_reg:
 | 
				
			||||||
	mdiobus_free(aup->mii_bus);
 | 
						mdiobus_free(aup->mii_bus);
 | 
				
			||||||
| 
						 | 
					@ -1261,11 +1259,11 @@ static int __devexit au1000_remove(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < NUM_RX_DMA; i++)
 | 
						for (i = 0; i < NUM_RX_DMA; i++)
 | 
				
			||||||
		if (aup->rx_db_inuse[i])
 | 
							if (aup->rx_db_inuse[i])
 | 
				
			||||||
			ReleaseDB(aup, aup->rx_db_inuse[i]);
 | 
								au1000_ReleaseDB(aup, aup->rx_db_inuse[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < NUM_TX_DMA; i++)
 | 
						for (i = 0; i < NUM_TX_DMA; i++)
 | 
				
			||||||
		if (aup->tx_db_inuse[i])
 | 
							if (aup->tx_db_inuse[i])
 | 
				
			||||||
			ReleaseDB(aup, aup->tx_db_inuse[i]);
 | 
								au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dma_free_noncoherent(NULL, MAX_BUF_SIZE *
 | 
						dma_free_noncoherent(NULL, MAX_BUF_SIZE *
 | 
				
			||||||
			(NUM_TX_BUFFS + NUM_RX_BUFFS),
 | 
								(NUM_TX_BUFFS + NUM_RX_BUFFS),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@
 | 
				
			||||||
#define NUM_TX_BUFFS 4
 | 
					#define NUM_TX_BUFFS 4
 | 
				
			||||||
#define MAX_BUF_SIZE 2048
 | 
					#define MAX_BUF_SIZE 2048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ETH_TX_TIMEOUT HZ/4
 | 
					#define ETH_TX_TIMEOUT (HZ/4)
 | 
				
			||||||
#define MAC_MIN_PKT_SIZE 64
 | 
					#define MAC_MIN_PKT_SIZE 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MULTICAST_FILTER_LIMIT 64
 | 
					#define MULTICAST_FILTER_LIMIT 64
 | 
				
			||||||
| 
						 | 
					@ -125,4 +125,6 @@ struct au1000_private {
 | 
				
			||||||
	dma_addr_t dma_addr;      /* dma address of rx/tx buffers       */
 | 
						dma_addr_t dma_addr;      /* dma address of rx/tx buffers       */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spinlock_t lock;       /* Serialise access to device */
 | 
						spinlock_t lock;       /* Serialise access to device */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 msg_enable;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,7 +303,6 @@ static void ax_block_output(struct net_device *dev, int count,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
 | 
						ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
 | 
				
			||||||
	ei_status.dmaing &= ~0x01;
 | 
						ei_status.dmaing &= ~0x01;
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* definitions for accessing MII/EEPROM interface */
 | 
					/* definitions for accessing MII/EEPROM interface */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1014,8 +1014,6 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	if (TX_BUFFS_AVAIL(bp) < 1)
 | 
						if (TX_BUFFS_AVAIL(bp) < 1)
 | 
				
			||||||
		netif_stop_queue(dev);
 | 
							netif_stop_queue(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
out_unlock:
 | 
					out_unlock:
 | 
				
			||||||
	spin_unlock_irqrestore(&bp->lock, flags);
 | 
						spin_unlock_irqrestore(&bp->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1681,15 +1679,15 @@ static struct net_device_stats *b44_get_stats(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __b44_load_mcast(struct b44 *bp, struct net_device *dev)
 | 
					static int __b44_load_mcast(struct b44 *bp, struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dev_mc_list *mclist;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	int i, num_ents;
 | 
						int i, num_ents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	num_ents = min_t(int, netdev_mc_count(dev), B44_MCAST_TABLE_SIZE);
 | 
						num_ents = min_t(int, netdev_mc_count(dev), B44_MCAST_TABLE_SIZE);
 | 
				
			||||||
	i = 0;
 | 
						i = 0;
 | 
				
			||||||
	netdev_for_each_mc_addr(mclist, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		if (i == num_ents)
 | 
							if (i == num_ents)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		__b44_cam_write(bp, mclist->dmi_addr, i++ + 1);
 | 
							__b44_cam_write(bp, ha->addr, i++ + 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return i+1;
 | 
						return i+1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -341,11 +341,9 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		skb_put(skb, len);
 | 
							skb_put(skb, len);
 | 
				
			||||||
		skb->dev = dev;
 | 
					 | 
				
			||||||
		skb->protocol = eth_type_trans(skb, dev);
 | 
							skb->protocol = eth_type_trans(skb, dev);
 | 
				
			||||||
		priv->stats.rx_packets++;
 | 
							priv->stats.rx_packets++;
 | 
				
			||||||
		priv->stats.rx_bytes += len;
 | 
							priv->stats.rx_bytes += len;
 | 
				
			||||||
		dev->last_rx = jiffies;
 | 
					 | 
				
			||||||
		netif_receive_skb(skb);
 | 
							netif_receive_skb(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	} while (--budget > 0);
 | 
						} while (--budget > 0);
 | 
				
			||||||
| 
						 | 
					@ -567,7 +565,6 @@ static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->stats.tx_bytes += skb->len;
 | 
						priv->stats.tx_bytes += skb->len;
 | 
				
			||||||
	priv->stats.tx_packets++;
 | 
						priv->stats.tx_packets++;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	ret = NETDEV_TX_OK;
 | 
						ret = NETDEV_TX_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_unlock:
 | 
					out_unlock:
 | 
				
			||||||
| 
						 | 
					@ -605,7 +602,7 @@ static int bcm_enet_set_mac_address(struct net_device *dev, void *p)
 | 
				
			||||||
static void bcm_enet_set_multicast_list(struct net_device *dev)
 | 
					static void bcm_enet_set_multicast_list(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bcm_enet_priv *priv;
 | 
						struct bcm_enet_priv *priv;
 | 
				
			||||||
	struct dev_mc_list *mc_list;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	u32 val;
 | 
						u32 val;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -633,14 +630,14 @@ static void bcm_enet_set_multicast_list(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i = 0;
 | 
						i = 0;
 | 
				
			||||||
	netdev_for_each_mc_addr(mc_list, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		u8 *dmi_addr;
 | 
							u8 *dmi_addr;
 | 
				
			||||||
		u32 tmp;
 | 
							u32 tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (i == 3)
 | 
							if (i == 3)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		/* update perfect match registers */
 | 
							/* update perfect match registers */
 | 
				
			||||||
		dmi_addr = mc_list->dmi_addr;
 | 
							dmi_addr = ha->addr;
 | 
				
			||||||
		tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) |
 | 
							tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) |
 | 
				
			||||||
			(dmi_addr[4] << 8) | dmi_addr[5];
 | 
								(dmi_addr[4] << 8) | dmi_addr[5];
 | 
				
			||||||
		enet_writel(priv, tmp, ENET_PML_REG(i + 1));
 | 
							enet_writel(priv, tmp, ENET_PML_REG(i + 1));
 | 
				
			||||||
| 
						 | 
					@ -960,7 +957,9 @@ static int bcm_enet_open(struct net_device *dev)
 | 
				
			||||||
	/* all set, enable mac and interrupts, start dma engine and
 | 
						/* all set, enable mac and interrupts, start dma engine and
 | 
				
			||||||
	 * kick rx dma channel */
 | 
						 * kick rx dma channel */
 | 
				
			||||||
	wmb();
 | 
						wmb();
 | 
				
			||||||
	enet_writel(priv, ENET_CTL_ENABLE_MASK, ENET_CTL_REG);
 | 
						val = enet_readl(priv, ENET_CTL_REG);
 | 
				
			||||||
 | 
						val |= ENET_CTL_ENABLE_MASK;
 | 
				
			||||||
 | 
						enet_writel(priv, val, ENET_CTL_REG);
 | 
				
			||||||
	enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
 | 
						enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
 | 
				
			||||||
	enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
 | 
						enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
 | 
				
			||||||
			ENETDMA_CHANCFG_REG(priv->rx_chan));
 | 
								ENETDMA_CHANCFG_REG(priv->rx_chan));
 | 
				
			||||||
| 
						 | 
					@ -1647,7 +1646,6 @@ static int __devinit bcm_enet_probe(struct platform_device *pdev)
 | 
				
			||||||
	if (!dev)
 | 
						if (!dev)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	priv = netdev_priv(dev);
 | 
						priv = netdev_priv(dev);
 | 
				
			||||||
	memset(priv, 0, sizeof(*priv));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = compute_hw_mtu(priv, dev->mtu);
 | 
						ret = compute_hw_mtu(priv, dev->mtu);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,8 @@ static inline char *nic_name(struct pci_dev *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FW_VER_LEN		32
 | 
					#define FW_VER_LEN		32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BE_MAX_VF		32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct be_dma_mem {
 | 
					struct be_dma_mem {
 | 
				
			||||||
	void *va;
 | 
						void *va;
 | 
				
			||||||
	dma_addr_t dma;
 | 
						dma_addr_t dma;
 | 
				
			||||||
| 
						 | 
					@ -207,7 +209,7 @@ struct be_tx_obj {
 | 
				
			||||||
/* Struct to remember the pages posted for rx frags */
 | 
					/* Struct to remember the pages posted for rx frags */
 | 
				
			||||||
struct be_rx_page_info {
 | 
					struct be_rx_page_info {
 | 
				
			||||||
	struct page *page;
 | 
						struct page *page;
 | 
				
			||||||
	dma_addr_t bus;
 | 
						DEFINE_DMA_UNMAP_ADDR(bus);
 | 
				
			||||||
	u16 page_offset;
 | 
						u16 page_offset;
 | 
				
			||||||
	bool last_page_user;
 | 
						bool last_page_user;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -281,8 +283,15 @@ struct be_adapter {
 | 
				
			||||||
	u8 port_type;
 | 
						u8 port_type;
 | 
				
			||||||
	u8 transceiver;
 | 
						u8 transceiver;
 | 
				
			||||||
	u8 generation;		/* BladeEngine ASIC generation */
 | 
						u8 generation;		/* BladeEngine ASIC generation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool sriov_enabled;
 | 
				
			||||||
 | 
						u32 vf_if_handle[BE_MAX_VF];
 | 
				
			||||||
 | 
						u32 vf_pmac_id[BE_MAX_VF];
 | 
				
			||||||
 | 
						u8 base_eq_id;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define be_physfn(adapter) (!adapter->pdev->is_virtfn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* BladeEngine Generation numbers */
 | 
					/* BladeEngine Generation numbers */
 | 
				
			||||||
#define BE_GEN2 2
 | 
					#define BE_GEN2 2
 | 
				
			||||||
#define BE_GEN3 3
 | 
					#define BE_GEN3 3
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -843,7 +843,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 | 
				
			||||||
 * Uses mbox
 | 
					 * Uses mbox
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
 | 
					int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
 | 
				
			||||||
		u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
 | 
							u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id,
 | 
				
			||||||
 | 
							u32 domain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct be_mcc_wrb *wrb;
 | 
						struct be_mcc_wrb *wrb;
 | 
				
			||||||
	struct be_cmd_req_if_create *req;
 | 
						struct be_cmd_req_if_create *req;
 | 
				
			||||||
| 
						 | 
					@ -860,6 +861,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
 | 
				
			||||||
	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 | 
						be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 | 
				
			||||||
		OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
 | 
							OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req->hdr.domain = domain;
 | 
				
			||||||
	req->capability_flags = cpu_to_le32(cap_flags);
 | 
						req->capability_flags = cpu_to_le32(cap_flags);
 | 
				
			||||||
	req->enable_flags = cpu_to_le32(en_flags);
 | 
						req->enable_flags = cpu_to_le32(en_flags);
 | 
				
			||||||
	req->pmac_invalid = pmac_invalid;
 | 
						req->pmac_invalid = pmac_invalid;
 | 
				
			||||||
| 
						 | 
					@ -1111,6 +1113,10 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
 | 
				
			||||||
	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
 | 
						be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
 | 
				
			||||||
		OPCODE_ETH_PROMISCUOUS, sizeof(*req));
 | 
							OPCODE_ETH_PROMISCUOUS, sizeof(*req));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* In FW versions X.102.149/X.101.487 and later,
 | 
				
			||||||
 | 
						 * the port setting associated only with the
 | 
				
			||||||
 | 
						 * issuing pci function will take effect
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	if (port_num)
 | 
						if (port_num)
 | 
				
			||||||
		req->port1_promiscuous = en;
 | 
							req->port1_promiscuous = en;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -1157,13 +1163,13 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 | 
				
			||||||
	req->interface_id = if_id;
 | 
						req->interface_id = if_id;
 | 
				
			||||||
	if (netdev) {
 | 
						if (netdev) {
 | 
				
			||||||
		int i;
 | 
							int i;
 | 
				
			||||||
		struct dev_mc_list *mc;
 | 
							struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		req->num_mac = cpu_to_le16(netdev_mc_count(netdev));
 | 
							req->num_mac = cpu_to_le16(netdev_mc_count(netdev));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		i = 0;
 | 
							i = 0;
 | 
				
			||||||
		netdev_for_each_mc_addr(mc, netdev)
 | 
							netdev_for_each_mc_addr(ha, netdev)
 | 
				
			||||||
			memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN);
 | 
								memcpy(req->mac[i].byte, ha->addr, ETH_ALEN);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		req->promiscuous = 1;
 | 
							req->promiscuous = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -878,7 +878,7 @@ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
 | 
				
			||||||
extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id);
 | 
					extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id);
 | 
				
			||||||
extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
 | 
					extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
 | 
				
			||||||
			u32 en_flags, u8 *mac, bool pmac_invalid,
 | 
								u32 en_flags, u8 *mac, bool pmac_invalid,
 | 
				
			||||||
			u32 *if_handle, u32 *pmac_id);
 | 
								u32 *if_handle, u32 *pmac_id, u32 domain);
 | 
				
			||||||
extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle);
 | 
					extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle);
 | 
				
			||||||
extern int be_cmd_eq_create(struct be_adapter *adapter,
 | 
					extern int be_cmd_eq_create(struct be_adapter *adapter,
 | 
				
			||||||
			struct be_queue_info *eq, int eq_delay);
 | 
								struct be_queue_info *eq, int eq_delay);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,8 +276,6 @@ be_get_ethtool_stats(struct net_device *netdev,
 | 
				
			||||||
		data[i] = (et_stats[i].size == sizeof(u64)) ?
 | 
							data[i] = (et_stats[i].size == sizeof(u64)) ?
 | 
				
			||||||
				*(u64 *)p: *(u32 *)p;
 | 
									*(u64 *)p: *(u32 *)p;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -466,7 +464,6 @@ be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		wol->wolopts = 0;
 | 
							wol->wolopts = 0;
 | 
				
			||||||
	memset(&wol->sopass, 0, sizeof(wol->sopass));
 | 
						memset(&wol->sopass, 0, sizeof(wol->sopass));
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					@ -496,7 +493,7 @@ be_test_ddr_dma(struct be_adapter *adapter)
 | 
				
			||||||
	ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size,
 | 
						ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size,
 | 
				
			||||||
					&ddrdma_cmd.dma);
 | 
										&ddrdma_cmd.dma);
 | 
				
			||||||
	if (!ddrdma_cmd.va) {
 | 
						if (!ddrdma_cmd.va) {
 | 
				
			||||||
		dev_err(&adapter->pdev->dev, "Memory allocation failure \n");
 | 
							dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,9 @@
 | 
				
			||||||
/* Number of entries posted */
 | 
					/* Number of entries posted */
 | 
				
			||||||
#define DB_MCCQ_NUM_POSTED_SHIFT	(16)	/* bits 16 - 29 */
 | 
					#define DB_MCCQ_NUM_POSTED_SHIFT	(16)	/* bits 16 - 29 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/********** SRIOV VF PCICFG OFFSET ********/
 | 
				
			||||||
 | 
					#define SRIOV_VF_PCICFG_OFFSET		(4096)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Flashrom related descriptors */
 | 
					/* Flashrom related descriptors */
 | 
				
			||||||
#define IMAGE_TYPE_FIRMWARE		160
 | 
					#define IMAGE_TYPE_FIRMWARE		160
 | 
				
			||||||
#define IMAGE_TYPE_BOOTCODE		224
 | 
					#define IMAGE_TYPE_BOOTCODE		224
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,8 +26,11 @@ MODULE_AUTHOR("ServerEngines Corporation");
 | 
				
			||||||
MODULE_LICENSE("GPL");
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int rx_frag_size = 2048;
 | 
					static unsigned int rx_frag_size = 2048;
 | 
				
			||||||
 | 
					static unsigned int num_vfs;
 | 
				
			||||||
module_param(rx_frag_size, uint, S_IRUGO);
 | 
					module_param(rx_frag_size, uint, S_IRUGO);
 | 
				
			||||||
 | 
					module_param(num_vfs, uint, S_IRUGO);
 | 
				
			||||||
MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
 | 
					MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
 | 
				
			||||||
 | 
					MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
 | 
					static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
 | 
				
			||||||
	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
 | 
						{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
 | 
				
			||||||
| 
						 | 
					@ -138,12 +141,19 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
 | 
				
			||||||
	if (!is_valid_ether_addr(addr->sa_data))
 | 
						if (!is_valid_ether_addr(addr->sa_data))
 | 
				
			||||||
		return -EADDRNOTAVAIL;
 | 
							return -EADDRNOTAVAIL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* MAC addr configuration will be done in hardware for VFs
 | 
				
			||||||
 | 
						 * by their corresponding PFs. Just copy to netdev addr here
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!be_physfn(adapter))
 | 
				
			||||||
 | 
							goto netdev_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id);
 | 
						status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id);
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		return status;
 | 
							return status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
 | 
						status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
 | 
				
			||||||
			adapter->if_handle, &adapter->pmac_id);
 | 
								adapter->if_handle, &adapter->pmac_id);
 | 
				
			||||||
 | 
					netdev_addr:
 | 
				
			||||||
	if (!status)
 | 
						if (!status)
 | 
				
			||||||
		memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 | 
							memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -386,26 +396,48 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
 | 
				
			||||||
	AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len);
 | 
						AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unmap_tx_frag(struct pci_dev *pdev, struct be_eth_wrb *wrb,
 | 
				
			||||||
 | 
							bool unmap_single)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dma_addr_t dma;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						be_dws_le_to_cpu(wrb, sizeof(*wrb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dma = (u64)wrb->frag_pa_hi << 32 | (u64)wrb->frag_pa_lo;
 | 
				
			||||||
 | 
						if (wrb->frag_len) {
 | 
				
			||||||
 | 
							if (unmap_single)
 | 
				
			||||||
 | 
								pci_unmap_single(pdev, dma, wrb->frag_len,
 | 
				
			||||||
 | 
									PCI_DMA_TODEVICE);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								pci_unmap_page(pdev, dma, wrb->frag_len,
 | 
				
			||||||
 | 
									PCI_DMA_TODEVICE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int make_tx_wrbs(struct be_adapter *adapter,
 | 
					static int make_tx_wrbs(struct be_adapter *adapter,
 | 
				
			||||||
		struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb)
 | 
							struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 busaddr;
 | 
						dma_addr_t busaddr;
 | 
				
			||||||
	u32 i, copied = 0;
 | 
						int i, copied = 0;
 | 
				
			||||||
	struct pci_dev *pdev = adapter->pdev;
 | 
						struct pci_dev *pdev = adapter->pdev;
 | 
				
			||||||
	struct sk_buff *first_skb = skb;
 | 
						struct sk_buff *first_skb = skb;
 | 
				
			||||||
	struct be_queue_info *txq = &adapter->tx_obj.q;
 | 
						struct be_queue_info *txq = &adapter->tx_obj.q;
 | 
				
			||||||
	struct be_eth_wrb *wrb;
 | 
						struct be_eth_wrb *wrb;
 | 
				
			||||||
	struct be_eth_hdr_wrb *hdr;
 | 
						struct be_eth_hdr_wrb *hdr;
 | 
				
			||||||
 | 
						bool map_single = false;
 | 
				
			||||||
 | 
						u16 map_head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hdr = queue_head_node(txq);
 | 
						hdr = queue_head_node(txq);
 | 
				
			||||||
	atomic_add(wrb_cnt, &txq->used);
 | 
					 | 
				
			||||||
	queue_head_inc(txq);
 | 
						queue_head_inc(txq);
 | 
				
			||||||
 | 
						map_head = txq->head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (skb->len > skb->data_len) {
 | 
						if (skb->len > skb->data_len) {
 | 
				
			||||||
		int len = skb->len - skb->data_len;
 | 
							int len = skb_headlen(skb);
 | 
				
			||||||
		busaddr = pci_map_single(pdev, skb->data, len,
 | 
							busaddr = pci_map_single(pdev, skb->data, len,
 | 
				
			||||||
					 PCI_DMA_TODEVICE);
 | 
										 PCI_DMA_TODEVICE);
 | 
				
			||||||
 | 
							if (pci_dma_mapping_error(pdev, busaddr))
 | 
				
			||||||
 | 
								goto dma_err;
 | 
				
			||||||
 | 
							map_single = true;
 | 
				
			||||||
		wrb = queue_head_node(txq);
 | 
							wrb = queue_head_node(txq);
 | 
				
			||||||
		wrb_fill(wrb, busaddr, len);
 | 
							wrb_fill(wrb, busaddr, len);
 | 
				
			||||||
		be_dws_cpu_to_le(wrb, sizeof(*wrb));
 | 
							be_dws_cpu_to_le(wrb, sizeof(*wrb));
 | 
				
			||||||
| 
						 | 
					@ -419,6 +451,8 @@ static int make_tx_wrbs(struct be_adapter *adapter,
 | 
				
			||||||
		busaddr = pci_map_page(pdev, frag->page,
 | 
							busaddr = pci_map_page(pdev, frag->page,
 | 
				
			||||||
				       frag->page_offset,
 | 
									       frag->page_offset,
 | 
				
			||||||
				       frag->size, PCI_DMA_TODEVICE);
 | 
									       frag->size, PCI_DMA_TODEVICE);
 | 
				
			||||||
 | 
							if (pci_dma_mapping_error(pdev, busaddr))
 | 
				
			||||||
 | 
								goto dma_err;
 | 
				
			||||||
		wrb = queue_head_node(txq);
 | 
							wrb = queue_head_node(txq);
 | 
				
			||||||
		wrb_fill(wrb, busaddr, frag->size);
 | 
							wrb_fill(wrb, busaddr, frag->size);
 | 
				
			||||||
		be_dws_cpu_to_le(wrb, sizeof(*wrb));
 | 
							be_dws_cpu_to_le(wrb, sizeof(*wrb));
 | 
				
			||||||
| 
						 | 
					@ -438,6 +472,16 @@ static int make_tx_wrbs(struct be_adapter *adapter,
 | 
				
			||||||
	be_dws_cpu_to_le(hdr, sizeof(*hdr));
 | 
						be_dws_cpu_to_le(hdr, sizeof(*hdr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return copied;
 | 
						return copied;
 | 
				
			||||||
 | 
					dma_err:
 | 
				
			||||||
 | 
						txq->head = map_head;
 | 
				
			||||||
 | 
						while (copied) {
 | 
				
			||||||
 | 
							wrb = queue_head_node(txq);
 | 
				
			||||||
 | 
							unmap_tx_frag(pdev, wrb, map_single);
 | 
				
			||||||
 | 
							map_single = false;
 | 
				
			||||||
 | 
							copied -= wrb->frag_len;
 | 
				
			||||||
 | 
							queue_head_inc(txq);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static netdev_tx_t be_xmit(struct sk_buff *skb,
 | 
					static netdev_tx_t be_xmit(struct sk_buff *skb,
 | 
				
			||||||
| 
						 | 
					@ -462,6 +506,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
 | 
				
			||||||
		 * *BEFORE* ringing the tx doorbell, so that we serialze the
 | 
							 * *BEFORE* ringing the tx doorbell, so that we serialze the
 | 
				
			||||||
		 * tx compls of the current transmit which'll wake up the queue
 | 
							 * tx compls of the current transmit which'll wake up the queue
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
							atomic_add(wrb_cnt, &txq->used);
 | 
				
			||||||
		if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >=
 | 
							if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >=
 | 
				
			||||||
								txq->len) {
 | 
													txq->len) {
 | 
				
			||||||
			netif_stop_queue(netdev);
 | 
								netif_stop_queue(netdev);
 | 
				
			||||||
| 
						 | 
					@ -541,6 +586,9 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct be_adapter *adapter = netdev_priv(netdev);
 | 
						struct be_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!be_physfn(adapter))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adapter->vlan_tag[vid] = 1;
 | 
						adapter->vlan_tag[vid] = 1;
 | 
				
			||||||
	adapter->vlans_added++;
 | 
						adapter->vlans_added++;
 | 
				
			||||||
	if (adapter->vlans_added <= (adapter->max_vlans + 1))
 | 
						if (adapter->vlans_added <= (adapter->max_vlans + 1))
 | 
				
			||||||
| 
						 | 
					@ -551,6 +599,9 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct be_adapter *adapter = netdev_priv(netdev);
 | 
						struct be_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!be_physfn(adapter))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adapter->vlan_tag[vid] = 0;
 | 
						adapter->vlan_tag[vid] = 0;
 | 
				
			||||||
	vlan_group_set_device(adapter->vlan_grp, vid, NULL);
 | 
						vlan_group_set_device(adapter->vlan_grp, vid, NULL);
 | 
				
			||||||
	adapter->vlans_added--;
 | 
						adapter->vlans_added--;
 | 
				
			||||||
| 
						 | 
					@ -588,6 +639,28 @@ static void be_set_multicast_list(struct net_device *netdev)
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct be_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
 | 
						int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!adapter->sriov_enabled)
 | 
				
			||||||
 | 
							return -EPERM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!is_valid_ether_addr(mac) || (vf >= num_vfs))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = be_cmd_pmac_del(adapter, adapter->vf_if_handle[vf],
 | 
				
			||||||
 | 
									adapter->vf_pmac_id[vf]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = be_cmd_pmac_add(adapter, mac, adapter->vf_if_handle[vf],
 | 
				
			||||||
 | 
									&adapter->vf_pmac_id[vf]);
 | 
				
			||||||
 | 
						if (!status)
 | 
				
			||||||
 | 
							dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
 | 
				
			||||||
 | 
									mac, vf);
 | 
				
			||||||
 | 
						return status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void be_rx_rate_update(struct be_adapter *adapter)
 | 
					static void be_rx_rate_update(struct be_adapter *adapter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct be_drvr_stats *stats = drvr_stats(adapter);
 | 
						struct be_drvr_stats *stats = drvr_stats(adapter);
 | 
				
			||||||
| 
						 | 
					@ -647,7 +720,7 @@ get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
 | 
				
			||||||
	BUG_ON(!rx_page_info->page);
 | 
						BUG_ON(!rx_page_info->page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rx_page_info->last_page_user) {
 | 
						if (rx_page_info->last_page_user) {
 | 
				
			||||||
		pci_unmap_page(adapter->pdev, pci_unmap_addr(rx_page_info, bus),
 | 
							pci_unmap_page(adapter->pdev, dma_unmap_addr(rx_page_info, bus),
 | 
				
			||||||
			adapter->big_page_size, PCI_DMA_FROMDEVICE);
 | 
								adapter->big_page_size, PCI_DMA_FROMDEVICE);
 | 
				
			||||||
		rx_page_info->last_page_user = false;
 | 
							rx_page_info->last_page_user = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -757,7 +830,6 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
	be_rx_stats_update(adapter, pktsize, num_rcvd);
 | 
						be_rx_stats_update(adapter, pktsize, num_rcvd);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Process the RX completion indicated by rxcp when GRO is disabled */
 | 
					/* Process the RX completion indicated by rxcp when GRO is disabled */
 | 
				
			||||||
| 
						 | 
					@ -791,7 +863,6 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb->truesize = skb->len + sizeof(struct sk_buff);
 | 
						skb->truesize = skb->len + sizeof(struct sk_buff);
 | 
				
			||||||
	skb->protocol = eth_type_trans(skb, adapter->netdev);
 | 
						skb->protocol = eth_type_trans(skb, adapter->netdev);
 | 
				
			||||||
	skb->dev = adapter->netdev;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
 | 
						vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
 | 
				
			||||||
	vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
 | 
						vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
 | 
				
			||||||
| 
						 | 
					@ -812,8 +883,6 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		netif_receive_skb(skb);
 | 
							netif_receive_skb(skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Process the RX completion indicated by rxcp when GRO is enabled */
 | 
					/* Process the RX completion indicated by rxcp when GRO is enabled */
 | 
				
			||||||
| 
						 | 
					@ -893,7 +962,6 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	be_rx_stats_update(adapter, pkt_size, num_rcvd);
 | 
						be_rx_stats_update(adapter, pkt_size, num_rcvd);
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
 | 
					static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
 | 
				
			||||||
| 
						 | 
					@ -959,7 +1027,7 @@ static void be_post_rx_frags(struct be_adapter *adapter)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		page_offset = page_info->page_offset;
 | 
							page_offset = page_info->page_offset;
 | 
				
			||||||
		page_info->page = pagep;
 | 
							page_info->page = pagep;
 | 
				
			||||||
		pci_unmap_addr_set(page_info, bus, page_dmaaddr);
 | 
							dma_unmap_addr_set(page_info, bus, page_dmaaddr);
 | 
				
			||||||
		frag_dmaaddr = page_dmaaddr + page_info->page_offset;
 | 
							frag_dmaaddr = page_dmaaddr + page_info->page_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rxd = queue_head_node(rxq);
 | 
							rxd = queue_head_node(rxq);
 | 
				
			||||||
| 
						 | 
					@ -987,8 +1055,6 @@ static void be_post_rx_frags(struct be_adapter *adapter)
 | 
				
			||||||
		/* Let be_worker replenish when memory is available */
 | 
							/* Let be_worker replenish when memory is available */
 | 
				
			||||||
		adapter->rx_post_starved = true;
 | 
							adapter->rx_post_starved = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
 | 
					static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
 | 
				
			||||||
| 
						 | 
					@ -1012,35 +1078,26 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
 | 
				
			||||||
	struct be_eth_wrb *wrb;
 | 
						struct be_eth_wrb *wrb;
 | 
				
			||||||
	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
 | 
						struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
 | 
				
			||||||
	struct sk_buff *sent_skb;
 | 
						struct sk_buff *sent_skb;
 | 
				
			||||||
	u64 busaddr;
 | 
						u16 cur_index, num_wrbs = 1; /* account for hdr wrb */
 | 
				
			||||||
	u16 cur_index, num_wrbs = 0;
 | 
						bool unmap_skb_hdr = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cur_index = txq->tail;
 | 
						sent_skb = sent_skbs[txq->tail];
 | 
				
			||||||
	sent_skb = sent_skbs[cur_index];
 | 
					 | 
				
			||||||
	BUG_ON(!sent_skb);
 | 
						BUG_ON(!sent_skb);
 | 
				
			||||||
	sent_skbs[cur_index] = NULL;
 | 
						sent_skbs[txq->tail] = NULL;
 | 
				
			||||||
	wrb = queue_tail_node(txq);
 | 
					
 | 
				
			||||||
	be_dws_le_to_cpu(wrb, sizeof(*wrb));
 | 
						/* skip header wrb */
 | 
				
			||||||
	busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
 | 
					 | 
				
			||||||
	if (busaddr != 0) {
 | 
					 | 
				
			||||||
		pci_unmap_single(adapter->pdev, busaddr,
 | 
					 | 
				
			||||||
				 wrb->frag_len, PCI_DMA_TODEVICE);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	num_wrbs++;
 | 
					 | 
				
			||||||
	queue_tail_inc(txq);
 | 
						queue_tail_inc(txq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (cur_index != last_index) {
 | 
						do {
 | 
				
			||||||
		cur_index = txq->tail;
 | 
							cur_index = txq->tail;
 | 
				
			||||||
		wrb = queue_tail_node(txq);
 | 
							wrb = queue_tail_node(txq);
 | 
				
			||||||
		be_dws_le_to_cpu(wrb, sizeof(*wrb));
 | 
							unmap_tx_frag(adapter->pdev, wrb, (unmap_skb_hdr &&
 | 
				
			||||||
		busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
 | 
										skb_headlen(sent_skb)));
 | 
				
			||||||
		if (busaddr != 0) {
 | 
							unmap_skb_hdr = false;
 | 
				
			||||||
			pci_unmap_page(adapter->pdev, busaddr,
 | 
					
 | 
				
			||||||
				       wrb->frag_len, PCI_DMA_TODEVICE);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		num_wrbs++;
 | 
							num_wrbs++;
 | 
				
			||||||
		queue_tail_inc(txq);
 | 
							queue_tail_inc(txq);
 | 
				
			||||||
	}
 | 
						} while (cur_index != last_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	atomic_sub(num_wrbs, &txq->used);
 | 
						atomic_sub(num_wrbs, &txq->used);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1255,6 +1312,8 @@ static int be_tx_queues_create(struct be_adapter *adapter)
 | 
				
			||||||
	/* Ask BE to create Tx Event queue */
 | 
						/* Ask BE to create Tx Event queue */
 | 
				
			||||||
	if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
 | 
						if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
 | 
				
			||||||
		goto tx_eq_free;
 | 
							goto tx_eq_free;
 | 
				
			||||||
 | 
						adapter->base_eq_id = adapter->tx_eq.q.id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Alloc TX eth compl queue */
 | 
						/* Alloc TX eth compl queue */
 | 
				
			||||||
	cq = &adapter->tx_obj.cq;
 | 
						cq = &adapter->tx_obj.cq;
 | 
				
			||||||
	if (be_queue_alloc(adapter, cq, TX_CQ_LEN,
 | 
						if (be_queue_alloc(adapter, cq, TX_CQ_LEN,
 | 
				
			||||||
| 
						 | 
					@ -1382,7 +1441,7 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 | 
				
			||||||
/* There are 8 evt ids per func. Retruns the evt id's bit number */
 | 
					/* There are 8 evt ids per func. Retruns the evt id's bit number */
 | 
				
			||||||
static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
 | 
					static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return eq_id % 8;
 | 
						return eq_id - adapter->base_eq_id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static irqreturn_t be_intx(int irq, void *dev)
 | 
					static irqreturn_t be_intx(int irq, void *dev)
 | 
				
			||||||
| 
						 | 
					@ -1557,7 +1616,27 @@ static void be_msix_enable(struct be_adapter *adapter)
 | 
				
			||||||
		BE_NUM_MSIX_VECTORS);
 | 
							BE_NUM_MSIX_VECTORS);
 | 
				
			||||||
	if (status == 0)
 | 
						if (status == 0)
 | 
				
			||||||
		adapter->msix_enabled = true;
 | 
							adapter->msix_enabled = true;
 | 
				
			||||||
	return;
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void be_sriov_enable(struct be_adapter *adapter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef CONFIG_PCI_IOV
 | 
				
			||||||
 | 
						int status;
 | 
				
			||||||
 | 
						if (be_physfn(adapter) && num_vfs) {
 | 
				
			||||||
 | 
							status = pci_enable_sriov(adapter->pdev, num_vfs);
 | 
				
			||||||
 | 
							adapter->sriov_enabled = status ? false : true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void be_sriov_disable(struct be_adapter *adapter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef CONFIG_PCI_IOV
 | 
				
			||||||
 | 
						if (adapter->sriov_enabled) {
 | 
				
			||||||
 | 
							pci_disable_sriov(adapter->pdev);
 | 
				
			||||||
 | 
							adapter->sriov_enabled = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
 | 
					static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
 | 
				
			||||||
| 
						 | 
					@ -1617,6 +1696,9 @@ static int be_irq_register(struct be_adapter *adapter)
 | 
				
			||||||
		status = be_msix_register(adapter);
 | 
							status = be_msix_register(adapter);
 | 
				
			||||||
		if (status == 0)
 | 
							if (status == 0)
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
 | 
							/* INTx is not supported for VF */
 | 
				
			||||||
 | 
							if (!be_physfn(adapter))
 | 
				
			||||||
 | 
								return status;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* INTx */
 | 
						/* INTx */
 | 
				
			||||||
| 
						 | 
					@ -1651,7 +1733,6 @@ static void be_irq_unregister(struct be_adapter *adapter)
 | 
				
			||||||
	be_free_irq(adapter, &adapter->rx_eq);
 | 
						be_free_irq(adapter, &adapter->rx_eq);
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
	adapter->isr_registered = false;
 | 
						adapter->isr_registered = false;
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int be_open(struct net_device *netdev)
 | 
					static int be_open(struct net_device *netdev)
 | 
				
			||||||
| 
						 | 
					@ -1690,14 +1771,17 @@ static int be_open(struct net_device *netdev)
 | 
				
			||||||
		goto ret_sts;
 | 
							goto ret_sts;
 | 
				
			||||||
	be_link_status_update(adapter, link_up);
 | 
						be_link_status_update(adapter, link_up);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (be_physfn(adapter))
 | 
				
			||||||
		status = be_vid_config(adapter);
 | 
							status = be_vid_config(adapter);
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto ret_sts;
 | 
							goto ret_sts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (be_physfn(adapter)) {
 | 
				
			||||||
		status = be_cmd_set_flow_control(adapter,
 | 
							status = be_cmd_set_flow_control(adapter,
 | 
				
			||||||
				adapter->tx_fc, adapter->rx_fc);
 | 
									adapter->tx_fc, adapter->rx_fc);
 | 
				
			||||||
		if (status)
 | 
							if (status)
 | 
				
			||||||
			goto ret_sts;
 | 
								goto ret_sts;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
 | 
						schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
 | 
				
			||||||
ret_sts:
 | 
					ret_sts:
 | 
				
			||||||
| 
						 | 
					@ -1723,7 +1807,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
 | 
				
			||||||
			PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK);
 | 
								PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK);
 | 
				
			||||||
		if (status) {
 | 
							if (status) {
 | 
				
			||||||
			dev_err(&adapter->pdev->dev,
 | 
								dev_err(&adapter->pdev->dev,
 | 
				
			||||||
				"Could not enable Wake-on-lan \n");
 | 
									"Could not enable Wake-on-lan\n");
 | 
				
			||||||
			pci_free_consistent(adapter->pdev, cmd.size, cmd.va,
 | 
								pci_free_consistent(adapter->pdev, cmd.size, cmd.va,
 | 
				
			||||||
					cmd.dma);
 | 
										cmd.dma);
 | 
				
			||||||
			return status;
 | 
								return status;
 | 
				
			||||||
| 
						 | 
					@ -1745,22 +1829,48 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
 | 
				
			||||||
static int be_setup(struct be_adapter *adapter)
 | 
					static int be_setup(struct be_adapter *adapter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *netdev = adapter->netdev;
 | 
						struct net_device *netdev = adapter->netdev;
 | 
				
			||||||
	u32 cap_flags, en_flags;
 | 
						u32 cap_flags, en_flags, vf = 0;
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
 | 
						u8 mac[ETH_ALEN];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
 | 
						cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST;
 | 
				
			||||||
			BE_IF_FLAGS_MCAST_PROMISCUOUS |
 | 
					
 | 
				
			||||||
 | 
						if (be_physfn(adapter)) {
 | 
				
			||||||
 | 
							cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS |
 | 
				
			||||||
				BE_IF_FLAGS_PROMISCUOUS |
 | 
									BE_IF_FLAGS_PROMISCUOUS |
 | 
				
			||||||
				BE_IF_FLAGS_PASS_L3L4_ERRORS;
 | 
									BE_IF_FLAGS_PASS_L3L4_ERRORS;
 | 
				
			||||||
	en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
 | 
							en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS;
 | 
				
			||||||
			BE_IF_FLAGS_PASS_L3L4_ERRORS;
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = be_cmd_if_create(adapter, cap_flags, en_flags,
 | 
						status = be_cmd_if_create(adapter, cap_flags, en_flags,
 | 
				
			||||||
			netdev->dev_addr, false/* pmac_invalid */,
 | 
								netdev->dev_addr, false/* pmac_invalid */,
 | 
				
			||||||
			&adapter->if_handle, &adapter->pmac_id);
 | 
								&adapter->if_handle, &adapter->pmac_id, 0);
 | 
				
			||||||
	if (status != 0)
 | 
						if (status != 0)
 | 
				
			||||||
		goto do_none;
 | 
							goto do_none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (be_physfn(adapter)) {
 | 
				
			||||||
 | 
							while (vf < num_vfs) {
 | 
				
			||||||
 | 
								cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED
 | 
				
			||||||
 | 
										| BE_IF_FLAGS_BROADCAST;
 | 
				
			||||||
 | 
								status = be_cmd_if_create(adapter, cap_flags, en_flags,
 | 
				
			||||||
 | 
										mac, true, &adapter->vf_if_handle[vf],
 | 
				
			||||||
 | 
										NULL, vf+1);
 | 
				
			||||||
 | 
								if (status) {
 | 
				
			||||||
 | 
									dev_err(&adapter->pdev->dev,
 | 
				
			||||||
 | 
									"Interface Create failed for VF %d\n", vf);
 | 
				
			||||||
 | 
									goto if_destroy;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								vf++;
 | 
				
			||||||
 | 
							} while (vf < num_vfs);
 | 
				
			||||||
 | 
						} else if (!be_physfn(adapter)) {
 | 
				
			||||||
 | 
							status = be_cmd_mac_addr_query(adapter, mac,
 | 
				
			||||||
 | 
								MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle);
 | 
				
			||||||
 | 
							if (!status) {
 | 
				
			||||||
 | 
								memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
 | 
				
			||||||
 | 
								memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = be_tx_queues_create(adapter);
 | 
						status = be_tx_queues_create(adapter);
 | 
				
			||||||
	if (status != 0)
 | 
						if (status != 0)
 | 
				
			||||||
		goto if_destroy;
 | 
							goto if_destroy;
 | 
				
			||||||
| 
						 | 
					@ -1782,6 +1892,9 @@ static int be_setup(struct be_adapter *adapter)
 | 
				
			||||||
tx_qs_destroy:
 | 
					tx_qs_destroy:
 | 
				
			||||||
	be_tx_queues_destroy(adapter);
 | 
						be_tx_queues_destroy(adapter);
 | 
				
			||||||
if_destroy:
 | 
					if_destroy:
 | 
				
			||||||
 | 
						for (vf = 0; vf < num_vfs; vf++)
 | 
				
			||||||
 | 
							if (adapter->vf_if_handle[vf])
 | 
				
			||||||
 | 
								be_cmd_if_destroy(adapter, adapter->vf_if_handle[vf]);
 | 
				
			||||||
	be_cmd_if_destroy(adapter, adapter->if_handle);
 | 
						be_cmd_if_destroy(adapter, adapter->if_handle);
 | 
				
			||||||
do_none:
 | 
					do_none:
 | 
				
			||||||
	return status;
 | 
						return status;
 | 
				
			||||||
| 
						 | 
					@ -2061,6 +2174,7 @@ static struct net_device_ops be_netdev_ops = {
 | 
				
			||||||
	.ndo_vlan_rx_register	= be_vlan_register,
 | 
						.ndo_vlan_rx_register	= be_vlan_register,
 | 
				
			||||||
	.ndo_vlan_rx_add_vid	= be_vlan_add_vid,
 | 
						.ndo_vlan_rx_add_vid	= be_vlan_add_vid,
 | 
				
			||||||
	.ndo_vlan_rx_kill_vid	= be_vlan_rem_vid,
 | 
						.ndo_vlan_rx_kill_vid	= be_vlan_rem_vid,
 | 
				
			||||||
 | 
						.ndo_set_vf_mac		= be_set_vf_mac
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void be_netdev_init(struct net_device *netdev)
 | 
					static void be_netdev_init(struct net_device *netdev)
 | 
				
			||||||
| 
						 | 
					@ -2102,37 +2216,48 @@ static void be_unmap_pci_bars(struct be_adapter *adapter)
 | 
				
			||||||
		iounmap(adapter->csr);
 | 
							iounmap(adapter->csr);
 | 
				
			||||||
	if (adapter->db)
 | 
						if (adapter->db)
 | 
				
			||||||
		iounmap(adapter->db);
 | 
							iounmap(adapter->db);
 | 
				
			||||||
	if (adapter->pcicfg)
 | 
						if (adapter->pcicfg && be_physfn(adapter))
 | 
				
			||||||
		iounmap(adapter->pcicfg);
 | 
							iounmap(adapter->pcicfg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int be_map_pci_bars(struct be_adapter *adapter)
 | 
					static int be_map_pci_bars(struct be_adapter *adapter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 __iomem *addr;
 | 
						u8 __iomem *addr;
 | 
				
			||||||
	int pcicfg_reg;
 | 
						int pcicfg_reg, db_reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (be_physfn(adapter)) {
 | 
				
			||||||
		addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
 | 
							addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
 | 
				
			||||||
				pci_resource_len(adapter->pdev, 2));
 | 
									pci_resource_len(adapter->pdev, 2));
 | 
				
			||||||
		if (addr == NULL)
 | 
							if (addr == NULL)
 | 
				
			||||||
			return -ENOMEM;
 | 
								return -ENOMEM;
 | 
				
			||||||
		adapter->csr = addr;
 | 
							adapter->csr = addr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4),
 | 
						if (adapter->generation == BE_GEN2) {
 | 
				
			||||||
			128 * 1024);
 | 
							pcicfg_reg = 1;
 | 
				
			||||||
 | 
							db_reg = 4;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							pcicfg_reg = 0;
 | 
				
			||||||
 | 
							if (be_physfn(adapter))
 | 
				
			||||||
 | 
								db_reg = 4;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								db_reg = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						addr = ioremap_nocache(pci_resource_start(adapter->pdev, db_reg),
 | 
				
			||||||
 | 
									pci_resource_len(adapter->pdev, db_reg));
 | 
				
			||||||
	if (addr == NULL)
 | 
						if (addr == NULL)
 | 
				
			||||||
		goto pci_map_err;
 | 
							goto pci_map_err;
 | 
				
			||||||
	adapter->db = addr;
 | 
						adapter->db = addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adapter->generation == BE_GEN2)
 | 
						if (be_physfn(adapter)) {
 | 
				
			||||||
		pcicfg_reg = 1;
 | 
							addr = ioremap_nocache(
 | 
				
			||||||
	else
 | 
									pci_resource_start(adapter->pdev, pcicfg_reg),
 | 
				
			||||||
		pcicfg_reg = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg),
 | 
					 | 
				
			||||||
				pci_resource_len(adapter->pdev, pcicfg_reg));
 | 
									pci_resource_len(adapter->pdev, pcicfg_reg));
 | 
				
			||||||
		if (addr == NULL)
 | 
							if (addr == NULL)
 | 
				
			||||||
			goto pci_map_err;
 | 
								goto pci_map_err;
 | 
				
			||||||
		adapter->pcicfg = addr;
 | 
							adapter->pcicfg = addr;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							adapter->pcicfg = adapter->db + SRIOV_VF_PCICFG_OFFSET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
pci_map_err:
 | 
					pci_map_err:
 | 
				
			||||||
| 
						 | 
					@ -2246,6 +2371,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	be_ctrl_cleanup(adapter);
 | 
						be_ctrl_cleanup(adapter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						be_sriov_disable(adapter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	be_msix_disable(adapter);
 | 
						be_msix_disable(adapter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_set_drvdata(pdev, NULL);
 | 
						pci_set_drvdata(pdev, NULL);
 | 
				
			||||||
| 
						 | 
					@ -2270,8 +2397,11 @@ static int be_get_config(struct be_adapter *adapter)
 | 
				
			||||||
		return status;
 | 
							return status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(mac, 0, ETH_ALEN);
 | 
						memset(mac, 0, ETH_ALEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (be_physfn(adapter)) {
 | 
				
			||||||
		status = be_cmd_mac_addr_query(adapter, mac,
 | 
							status = be_cmd_mac_addr_query(adapter, mac,
 | 
				
			||||||
			MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0);
 | 
								MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (status)
 | 
							if (status)
 | 
				
			||||||
			return status;
 | 
								return status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2280,6 +2410,7 @@ static int be_get_config(struct be_adapter *adapter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
 | 
							memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
 | 
				
			||||||
		memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
 | 
							memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adapter->cap & 0x400)
 | 
						if (adapter->cap & 0x400)
 | 
				
			||||||
		adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4;
 | 
							adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4;
 | 
				
			||||||
| 
						 | 
					@ -2296,6 +2427,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
 | 
				
			||||||
	struct be_adapter *adapter;
 | 
						struct be_adapter *adapter;
 | 
				
			||||||
	struct net_device *netdev;
 | 
						struct net_device *netdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = pci_enable_device(pdev);
 | 
						status = pci_enable_device(pdev);
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto do_none;
 | 
							goto do_none;
 | 
				
			||||||
| 
						 | 
					@ -2344,21 +2476,25 @@ static int __devinit be_probe(struct pci_dev *pdev,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						be_sriov_enable(adapter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = be_ctrl_init(adapter);
 | 
						status = be_ctrl_init(adapter);
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto free_netdev;
 | 
							goto free_netdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* sync up with fw's ready state */
 | 
						/* sync up with fw's ready state */
 | 
				
			||||||
 | 
						if (be_physfn(adapter)) {
 | 
				
			||||||
		status = be_cmd_POST(adapter);
 | 
							status = be_cmd_POST(adapter);
 | 
				
			||||||
		if (status)
 | 
							if (status)
 | 
				
			||||||
			goto ctrl_clean;
 | 
								goto ctrl_clean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* tell fw we're ready to fire cmds */
 | 
							status = be_cmd_reset_function(adapter);
 | 
				
			||||||
	status = be_cmd_fw_init(adapter);
 | 
					 | 
				
			||||||
		if (status)
 | 
							if (status)
 | 
				
			||||||
			goto ctrl_clean;
 | 
								goto ctrl_clean;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = be_cmd_reset_function(adapter);
 | 
						/* tell fw we're ready to fire cmds */
 | 
				
			||||||
 | 
						status = be_cmd_fw_init(adapter);
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto ctrl_clean;
 | 
							goto ctrl_clean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2391,6 +2527,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
 | 
				
			||||||
	be_ctrl_cleanup(adapter);
 | 
						be_ctrl_cleanup(adapter);
 | 
				
			||||||
free_netdev:
 | 
					free_netdev:
 | 
				
			||||||
	be_msix_disable(adapter);
 | 
						be_msix_disable(adapter);
 | 
				
			||||||
 | 
						be_sriov_disable(adapter);
 | 
				
			||||||
	free_netdev(adapter->netdev);
 | 
						free_netdev(adapter->netdev);
 | 
				
			||||||
	pci_set_drvdata(pdev, NULL);
 | 
						pci_set_drvdata(pdev, NULL);
 | 
				
			||||||
rel_reg:
 | 
					rel_reg:
 | 
				
			||||||
| 
						 | 
					@ -2474,8 +2611,6 @@ static void be_shutdown(struct pci_dev *pdev)
 | 
				
			||||||
		be_setup_wol(adapter, true);
 | 
							be_setup_wol(adapter, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_disable_device(pdev);
 | 
						pci_disable_device(pdev);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
 | 
					static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
 | 
				
			||||||
| 
						 | 
					@ -2557,7 +2692,6 @@ static void be_eeh_resume(struct pci_dev *pdev)
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
err:
 | 
					err:
 | 
				
			||||||
	dev_err(&adapter->pdev->dev, "EEH resume failed\n");
 | 
						dev_err(&adapter->pdev->dev, "EEH resume failed\n");
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct pci_error_handlers be_eeh_handlers = {
 | 
					static struct pci_error_handlers be_eeh_handlers = {
 | 
				
			||||||
| 
						 | 
					@ -2587,6 +2721,13 @@ static int __init be_init_module(void)
 | 
				
			||||||
		rx_frag_size = 2048;
 | 
							rx_frag_size = 2048;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (num_vfs > 32) {
 | 
				
			||||||
 | 
							printk(KERN_WARNING DRV_NAME
 | 
				
			||||||
 | 
								" : Module param num_vfs must not be greater than 32."
 | 
				
			||||||
 | 
								"Using 32\n");
 | 
				
			||||||
 | 
							num_vfs = 32;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pci_register_driver(&be_driver);
 | 
						return pci_register_driver(&be_driver);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
module_init(be_init_module);
 | 
					module_init(be_init_module);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@
 | 
				
			||||||
#include <asm/dma.h>
 | 
					#include <asm/dma.h>
 | 
				
			||||||
#include <linux/dma-mapping.h>
 | 
					#include <linux/dma-mapping.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <asm/div64.h>
 | 
				
			||||||
#include <asm/dpmc.h>
 | 
					#include <asm/dpmc.h>
 | 
				
			||||||
#include <asm/blackfin.h>
 | 
					#include <asm/blackfin.h>
 | 
				
			||||||
#include <asm/cacheflush.h>
 | 
					#include <asm/cacheflush.h>
 | 
				
			||||||
| 
						 | 
					@ -80,9 +81,6 @@ static u16 pin_req[] = P_RMII0;
 | 
				
			||||||
static u16 pin_req[] = P_MII0;
 | 
					static u16 pin_req[] = P_MII0;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bfin_mac_disable(void);
 | 
					 | 
				
			||||||
static void bfin_mac_enable(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void desc_list_free(void)
 | 
					static void desc_list_free(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_dma_desc_rx *r;
 | 
						struct net_dma_desc_rx *r;
 | 
				
			||||||
| 
						 | 
					@ -202,6 +200,11 @@ static int desc_list_init(void)
 | 
				
			||||||
			goto init_error;
 | 
								goto init_error;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		skb_reserve(new_skb, NET_IP_ALIGN);
 | 
							skb_reserve(new_skb, NET_IP_ALIGN);
 | 
				
			||||||
 | 
							/* Invidate the data cache of skb->data range when it is write back
 | 
				
			||||||
 | 
							 * cache. It will prevent overwritting the new data from DMA
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
 | 
				
			||||||
 | 
										 (unsigned long)new_skb->end);
 | 
				
			||||||
		r->skb = new_skb;
 | 
							r->skb = new_skb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -254,7 +257,7 @@ static int desc_list_init(void)
 | 
				
			||||||
 * MII operations
 | 
					 * MII operations
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
/* Wait until the previous MDC/MDIO transaction has completed */
 | 
					/* Wait until the previous MDC/MDIO transaction has completed */
 | 
				
			||||||
static void bfin_mdio_poll(void)
 | 
					static int bfin_mdio_poll(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int timeout_cnt = MAX_TIMEOUT_CNT;
 | 
						int timeout_cnt = MAX_TIMEOUT_CNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -264,22 +267,30 @@ static void bfin_mdio_poll(void)
 | 
				
			||||||
		if (timeout_cnt-- < 0) {
 | 
							if (timeout_cnt-- < 0) {
 | 
				
			||||||
			printk(KERN_ERR DRV_NAME
 | 
								printk(KERN_ERR DRV_NAME
 | 
				
			||||||
			": wait MDC/MDIO transaction to complete timeout\n");
 | 
								": wait MDC/MDIO transaction to complete timeout\n");
 | 
				
			||||||
			break;
 | 
								return -ETIMEDOUT;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Read an off-chip register in a PHY through the MDC/MDIO port */
 | 
					/* Read an off-chip register in a PHY through the MDC/MDIO port */
 | 
				
			||||||
static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
 | 
					static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bfin_mdio_poll();
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bfin_mdio_poll();
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* read mode */
 | 
						/* read mode */
 | 
				
			||||||
	bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
 | 
						bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
 | 
				
			||||||
				SET_REGAD((u16) regnum) |
 | 
									SET_REGAD((u16) regnum) |
 | 
				
			||||||
				STABUSY);
 | 
									STABUSY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bfin_mdio_poll();
 | 
						ret = bfin_mdio_poll();
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (int) bfin_read_EMAC_STADAT();
 | 
						return (int) bfin_read_EMAC_STADAT();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -288,7 +299,11 @@ static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
 | 
				
			||||||
static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
 | 
					static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
 | 
				
			||||||
			      u16 value)
 | 
								      u16 value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bfin_mdio_poll();
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bfin_mdio_poll();
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bfin_write_EMAC_STADAT((u32) value);
 | 
						bfin_write_EMAC_STADAT((u32) value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -298,9 +313,7 @@ static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
 | 
				
			||||||
				STAOP |
 | 
									STAOP |
 | 
				
			||||||
				STABUSY);
 | 
									STABUSY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bfin_mdio_poll();
 | 
						return bfin_mdio_poll();
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bfin_mdiobus_reset(struct mii_bus *bus)
 | 
					static int bfin_mdiobus_reset(struct mii_bus *bus)
 | 
				
			||||||
| 
						 | 
					@ -458,6 +471,14 @@ static int mii_probe(struct net_device *dev)
 | 
				
			||||||
 * Ethtool support
 | 
					 * Ethtool support
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * interrupt routine for magic packet wakeup
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static irqreturn_t bfin_mac_wake_interrupt(int irq, void *dev_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return IRQ_HANDLED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
bfin_mac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
 | 
					bfin_mac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -492,11 +513,57 @@ static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
 | 
				
			||||||
	strcpy(info->bus_info, dev_name(&dev->dev));
 | 
						strcpy(info->bus_info, dev_name(&dev->dev));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bfin_mac_ethtool_getwol(struct net_device *dev,
 | 
				
			||||||
 | 
						struct ethtool_wolinfo *wolinfo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wolinfo->supported = WAKE_MAGIC;
 | 
				
			||||||
 | 
						wolinfo->wolopts = lp->wol;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int bfin_mac_ethtool_setwol(struct net_device *dev,
 | 
				
			||||||
 | 
						struct ethtool_wolinfo *wolinfo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(dev);
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wolinfo->wolopts & (WAKE_MAGICSECURE |
 | 
				
			||||||
 | 
									WAKE_UCAST |
 | 
				
			||||||
 | 
									WAKE_MCAST |
 | 
				
			||||||
 | 
									WAKE_BCAST |
 | 
				
			||||||
 | 
									WAKE_ARP))
 | 
				
			||||||
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lp->wol = wolinfo->wolopts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lp->wol && !lp->irq_wake_requested) {
 | 
				
			||||||
 | 
							/* register wake irq handler */
 | 
				
			||||||
 | 
							rc = request_irq(IRQ_MAC_WAKEDET, bfin_mac_wake_interrupt,
 | 
				
			||||||
 | 
									 IRQF_DISABLED, "EMAC_WAKE", dev);
 | 
				
			||||||
 | 
							if (rc)
 | 
				
			||||||
 | 
								return rc;
 | 
				
			||||||
 | 
							lp->irq_wake_requested = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!lp->wol && lp->irq_wake_requested) {
 | 
				
			||||||
 | 
							free_irq(IRQ_MAC_WAKEDET, dev);
 | 
				
			||||||
 | 
							lp->irq_wake_requested = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure the PHY driver doesn't suspend */
 | 
				
			||||||
 | 
						device_init_wakeup(&dev->dev, lp->wol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ethtool_ops bfin_mac_ethtool_ops = {
 | 
					static const struct ethtool_ops bfin_mac_ethtool_ops = {
 | 
				
			||||||
	.get_settings = bfin_mac_ethtool_getsettings,
 | 
						.get_settings = bfin_mac_ethtool_getsettings,
 | 
				
			||||||
	.set_settings = bfin_mac_ethtool_setsettings,
 | 
						.set_settings = bfin_mac_ethtool_setsettings,
 | 
				
			||||||
	.get_link = ethtool_op_get_link,
 | 
						.get_link = ethtool_op_get_link,
 | 
				
			||||||
	.get_drvinfo = bfin_mac_ethtool_getdrvinfo,
 | 
						.get_drvinfo = bfin_mac_ethtool_getdrvinfo,
 | 
				
			||||||
 | 
						.get_wol = bfin_mac_ethtool_getwol,
 | 
				
			||||||
 | 
						.set_wol = bfin_mac_ethtool_setwol,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**************************************************************************/
 | 
					/**************************************************************************/
 | 
				
			||||||
| 
						 | 
					@ -509,10 +576,11 @@ void setup_system_regs(struct net_device *dev)
 | 
				
			||||||
	 * Configure checksum support and rcve frame word alignment
 | 
						 * Configure checksum support and rcve frame word alignment
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	sysctl = bfin_read_EMAC_SYSCTL();
 | 
						sysctl = bfin_read_EMAC_SYSCTL();
 | 
				
			||||||
#if defined(BFIN_MAC_CSUM_OFFLOAD)
 | 
					 | 
				
			||||||
	sysctl |= RXDWA | RXCKS;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	sysctl |= RXDWA;
 | 
						sysctl |= RXDWA;
 | 
				
			||||||
 | 
					#if defined(BFIN_MAC_CSUM_OFFLOAD)
 | 
				
			||||||
 | 
						sysctl |= RXCKS;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						sysctl &= ~RXCKS;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	bfin_write_EMAC_SYSCTL(sysctl);
 | 
						bfin_write_EMAC_SYSCTL(sysctl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -551,6 +619,309 @@ static int bfin_mac_set_mac_address(struct net_device *dev, void *p)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BFIN_MAC_USE_HWSTAMP
 | 
				
			||||||
 | 
					#define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
 | 
				
			||||||
 | 
							struct ifreq *ifr, int cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct hwtstamp_config config;
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(netdev);
 | 
				
			||||||
 | 
						u16 ptpctl;
 | 
				
			||||||
 | 
						u32 ptpfv1, ptpfv2, ptpfv3, ptpfoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_debug("%s config flag:0x%x, tx_type:0x%x, rx_filter:0x%x\n",
 | 
				
			||||||
 | 
								__func__, config.flags, config.tx_type, config.rx_filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* reserved for future extensions */
 | 
				
			||||||
 | 
						if (config.flags)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((config.tx_type != HWTSTAMP_TX_OFF) &&
 | 
				
			||||||
 | 
								(config.tx_type != HWTSTAMP_TX_ON))
 | 
				
			||||||
 | 
							return -ERANGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptpctl = bfin_read_EMAC_PTP_CTL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (config.rx_filter) {
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_NONE:
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Dont allow any timestamping
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfv3 = 0xFFFFFFFF;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV3(ptpfv3);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Clear the five comparison mask bits (bits[12:8]) in EMAC_PTP_CTL)
 | 
				
			||||||
 | 
							 * to enable all the field matches.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpctl &= ~0x1F00;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_CTL(ptpctl);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Keep the default values of the EMAC_PTP_FOFF register.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfoff = 0x4A24170C;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FOFF(ptpfoff);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Keep the default values of the EMAC_PTP_FV1 and EMAC_PTP_FV2
 | 
				
			||||||
 | 
							 * registers.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfv1 = 0x11040800;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV1(ptpfv1);
 | 
				
			||||||
 | 
							ptpfv2 = 0x0140013F;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV2(ptpfv2);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * The default value (0xFFFC) allows the timestamping of both
 | 
				
			||||||
 | 
							 * received Sync messages and Delay_Req messages.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfv3 = 0xFFFFFFFC;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV3(ptpfv3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
 | 
				
			||||||
 | 
							/* Clear all five comparison mask bits (bits[12:8]) in the
 | 
				
			||||||
 | 
							 * EMAC_PTP_CTL register to enable all the field matches.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpctl &= ~0x1F00;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_CTL(ptpctl);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Keep the default values of the EMAC_PTP_FOFF register, except set
 | 
				
			||||||
 | 
							 * the PTPCOF field to 0x2A.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfoff = 0x2A24170C;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FOFF(ptpfoff);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Keep the default values of the EMAC_PTP_FV1 and EMAC_PTP_FV2
 | 
				
			||||||
 | 
							 * registers.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfv1 = 0x11040800;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV1(ptpfv1);
 | 
				
			||||||
 | 
							ptpfv2 = 0x0140013F;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV2(ptpfv2);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * To allow the timestamping of Pdelay_Req and Pdelay_Resp, set
 | 
				
			||||||
 | 
							 * the value to 0xFFF0.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfv3 = 0xFFFFFFF0;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV3(ptpfv3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
 | 
				
			||||||
 | 
						case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Clear bits 8 and 12 of the EMAC_PTP_CTL register to enable only the
 | 
				
			||||||
 | 
							 * EFTM and PTPCM field comparison.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpctl &= ~0x1100;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_CTL(ptpctl);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Keep the default values of all the fields of the EMAC_PTP_FOFF
 | 
				
			||||||
 | 
							 * register, except set the PTPCOF field to 0x0E.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfoff = 0x0E24170C;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FOFF(ptpfoff);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Program bits [15:0] of the EMAC_PTP_FV1 register to 0x88F7, which
 | 
				
			||||||
 | 
							 * corresponds to PTP messages on the MAC layer.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfv1 = 0x110488F7;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV1(ptpfv1);
 | 
				
			||||||
 | 
							ptpfv2 = 0x0140013F;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV2(ptpfv2);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * To allow the timestamping of Pdelay_Req and Pdelay_Resp
 | 
				
			||||||
 | 
							 * messages, set the value to 0xFFF0.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ptpfv3 = 0xFFFFFFF0;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_FV3(ptpfv3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -ERANGE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (config.tx_type == HWTSTAMP_TX_OFF &&
 | 
				
			||||||
 | 
						    bfin_mac_hwtstamp_is_none(config.rx_filter)) {
 | 
				
			||||||
 | 
							ptpctl &= ~PTP_EN;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_CTL(ptpctl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SSYNC();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ptpctl |= PTP_EN;
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_CTL(ptpctl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * clear any existing timestamp
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							bfin_read_EMAC_PTP_RXSNAPLO();
 | 
				
			||||||
 | 
							bfin_read_EMAC_PTP_RXSNAPHI();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bfin_read_EMAC_PTP_TXSNAPLO();
 | 
				
			||||||
 | 
							bfin_read_EMAC_PTP_TXSNAPHI();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Set registers so that rollover occurs soon to test this.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_TIMELO(0x00000000);
 | 
				
			||||||
 | 
							bfin_write_EMAC_PTP_TIMEHI(0xFF800000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SSYNC();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							lp->compare.last_update = 0;
 | 
				
			||||||
 | 
							timecounter_init(&lp->clock,
 | 
				
			||||||
 | 
									&lp->cycles,
 | 
				
			||||||
 | 
									ktime_to_ns(ktime_get_real()));
 | 
				
			||||||
 | 
							timecompare_update(&lp->compare, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lp->stamp_cfg = config;
 | 
				
			||||||
 | 
						return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
 | 
				
			||||||
 | 
							-EFAULT : 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompare *cmp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ktime_t sys = ktime_get_real();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_debug("%s %s hardware:%d,%d transform system:%d,%d system:%d,%d, cmp:%lld, %lld\n",
 | 
				
			||||||
 | 
								__func__, s, hw->tv.sec, hw->tv.nsec, ts->tv.sec, ts->tv.nsec, sys.tv.sec,
 | 
				
			||||||
 | 
								sys.tv.nsec, cmp->offset, cmp->skew);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(netdev);
 | 
				
			||||||
 | 
						union skb_shared_tx *shtx = skb_tx(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (shtx->hardware) {
 | 
				
			||||||
 | 
							int timeout_cnt = MAX_TIMEOUT_CNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* When doing time stamping, keep the connection to the socket
 | 
				
			||||||
 | 
							 * a while longer
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							shtx->in_progress = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * The timestamping is done at the EMAC module's MII/RMII interface
 | 
				
			||||||
 | 
							 * when the module sees the Start of Frame of an event message packet. This
 | 
				
			||||||
 | 
							 * interface is the closest possible place to the physical Ethernet transmission
 | 
				
			||||||
 | 
							 * medium, providing the best timing accuracy.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							while ((!(bfin_read_EMAC_PTP_ISTAT() & TXTL)) && (--timeout_cnt))
 | 
				
			||||||
 | 
								udelay(1);
 | 
				
			||||||
 | 
							if (timeout_cnt == 0)
 | 
				
			||||||
 | 
								printk(KERN_ERR DRV_NAME
 | 
				
			||||||
 | 
										": fails to timestamp the TX packet\n");
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								struct skb_shared_hwtstamps shhwtstamps;
 | 
				
			||||||
 | 
								u64 ns;
 | 
				
			||||||
 | 
								u64 regval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								regval = bfin_read_EMAC_PTP_TXSNAPLO();
 | 
				
			||||||
 | 
								regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32;
 | 
				
			||||||
 | 
								memset(&shhwtstamps, 0, sizeof(shhwtstamps));
 | 
				
			||||||
 | 
								ns = timecounter_cyc2time(&lp->clock,
 | 
				
			||||||
 | 
										regval);
 | 
				
			||||||
 | 
								timecompare_update(&lp->compare, ns);
 | 
				
			||||||
 | 
								shhwtstamps.hwtstamp = ns_to_ktime(ns);
 | 
				
			||||||
 | 
								shhwtstamps.syststamp =
 | 
				
			||||||
 | 
									timecompare_transform(&lp->compare, ns);
 | 
				
			||||||
 | 
								skb_tstamp_tx(skb, &shhwtstamps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								bfin_dump_hwtamp("TX", &shhwtstamps.hwtstamp, &shhwtstamps.syststamp, &lp->compare);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(netdev);
 | 
				
			||||||
 | 
						u32 valid;
 | 
				
			||||||
 | 
						u64 regval, ns;
 | 
				
			||||||
 | 
						struct skb_shared_hwtstamps *shhwtstamps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bfin_mac_hwtstamp_is_none(lp->stamp_cfg.rx_filter))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						valid = bfin_read_EMAC_PTP_ISTAT() & RXEL;
 | 
				
			||||||
 | 
						if (!valid)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						shhwtstamps = skb_hwtstamps(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regval = bfin_read_EMAC_PTP_RXSNAPLO();
 | 
				
			||||||
 | 
						regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32;
 | 
				
			||||||
 | 
						ns = timecounter_cyc2time(&lp->clock, regval);
 | 
				
			||||||
 | 
						timecompare_update(&lp->compare, ns);
 | 
				
			||||||
 | 
						memset(shhwtstamps, 0, sizeof(*shhwtstamps));
 | 
				
			||||||
 | 
						shhwtstamps->hwtstamp = ns_to_ktime(ns);
 | 
				
			||||||
 | 
						shhwtstamps->syststamp = timecompare_transform(&lp->compare, ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bfin_dump_hwtamp("RX", &shhwtstamps->hwtstamp, &shhwtstamps->syststamp, &lp->compare);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * bfin_read_clock - read raw cycle counter (to be used by time counter)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static cycle_t bfin_read_clock(const struct cyclecounter *tc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u64 stamp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stamp =  bfin_read_EMAC_PTP_TIMELO();
 | 
				
			||||||
 | 
						stamp |= (u64)bfin_read_EMAC_PTP_TIMEHI() << 32ULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return stamp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PTP_CLK 25000000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bfin_mac_hwtstamp_init(struct net_device *netdev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(netdev);
 | 
				
			||||||
 | 
						u64 append;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize hardware timer */
 | 
				
			||||||
 | 
						append = PTP_CLK * (1ULL << 32);
 | 
				
			||||||
 | 
						do_div(append, get_sclk());
 | 
				
			||||||
 | 
						bfin_write_EMAC_PTP_ADDEND((u32)append);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&lp->cycles, 0, sizeof(lp->cycles));
 | 
				
			||||||
 | 
						lp->cycles.read = bfin_read_clock;
 | 
				
			||||||
 | 
						lp->cycles.mask = CLOCKSOURCE_MASK(64);
 | 
				
			||||||
 | 
						lp->cycles.mult = 1000000000 / PTP_CLK;
 | 
				
			||||||
 | 
						lp->cycles.shift = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Synchronize our NIC clock against system wall clock */
 | 
				
			||||||
 | 
						memset(&lp->compare, 0, sizeof(lp->compare));
 | 
				
			||||||
 | 
						lp->compare.source = &lp->clock;
 | 
				
			||||||
 | 
						lp->compare.target = ktime_get_real;
 | 
				
			||||||
 | 
						lp->compare.num_samples = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize hwstamp config */
 | 
				
			||||||
 | 
						lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
 | 
				
			||||||
 | 
						lp->stamp_cfg.tx_type = HWTSTAMP_TX_OFF;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define bfin_mac_hwtstamp_is_none(cfg) 0
 | 
				
			||||||
 | 
					# define bfin_mac_hwtstamp_init(dev)
 | 
				
			||||||
 | 
					# define bfin_mac_hwtstamp_ioctl(dev, ifr, cmd) (-EOPNOTSUPP)
 | 
				
			||||||
 | 
					# define bfin_rx_hwtstamp(dev, skb)
 | 
				
			||||||
 | 
					# define bfin_tx_hwtstamp(dev, skb)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void adjust_tx_list(void)
 | 
					static void adjust_tx_list(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int timeout_cnt = MAX_TIMEOUT_CNT;
 | 
						int timeout_cnt = MAX_TIMEOUT_CNT;
 | 
				
			||||||
| 
						 | 
					@ -608,18 +979,32 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 *data;
 | 
						u16 *data;
 | 
				
			||||||
	u32 data_align = (unsigned long)(skb->data) & 0x3;
 | 
						u32 data_align = (unsigned long)(skb->data) & 0x3;
 | 
				
			||||||
 | 
						union skb_shared_tx *shtx = skb_tx(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	current_tx_ptr->skb = skb;
 | 
						current_tx_ptr->skb = skb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (data_align == 0x2) {
 | 
						if (data_align == 0x2) {
 | 
				
			||||||
		/* move skb->data to current_tx_ptr payload */
 | 
							/* move skb->data to current_tx_ptr payload */
 | 
				
			||||||
		data = (u16 *)(skb->data) - 1;
 | 
							data = (u16 *)(skb->data) - 1;
 | 
				
			||||||
		*data = (u16)(skb->len);
 | 
							*data = (u16)(skb->len);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * When transmitting an Ethernet packet, the PTP_TSYNC module requires
 | 
				
			||||||
 | 
							 * a DMA_Length_Word field associated with the packet. The lower 12 bits
 | 
				
			||||||
 | 
							 * of this field are the length of the packet payload in bytes and the higher
 | 
				
			||||||
 | 
							 * 4 bits are the timestamping enable field.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (shtx->hardware)
 | 
				
			||||||
 | 
								*data |= 0x1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		current_tx_ptr->desc_a.start_addr = (u32)data;
 | 
							current_tx_ptr->desc_a.start_addr = (u32)data;
 | 
				
			||||||
		/* this is important! */
 | 
							/* this is important! */
 | 
				
			||||||
		blackfin_dcache_flush_range((u32)data,
 | 
							blackfin_dcache_flush_range((u32)data,
 | 
				
			||||||
				(u32)((u8 *)data + skb->len + 4));
 | 
									(u32)((u8 *)data + skb->len + 4));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
 | 
							*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
 | 
				
			||||||
 | 
							/* enable timestamping for the sent packet */
 | 
				
			||||||
 | 
							if (shtx->hardware)
 | 
				
			||||||
 | 
								*((u16 *)(current_tx_ptr->packet)) |= 0x1000;
 | 
				
			||||||
		memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
 | 
							memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
 | 
				
			||||||
			skb->len);
 | 
								skb->len);
 | 
				
			||||||
		current_tx_ptr->desc_a.start_addr =
 | 
							current_tx_ptr->desc_a.start_addr =
 | 
				
			||||||
| 
						 | 
					@ -653,20 +1038,42 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	adjust_tx_list();
 | 
						adjust_tx_list();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bfin_tx_hwtstamp(dev, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	current_tx_ptr = current_tx_ptr->next;
 | 
						current_tx_ptr = current_tx_ptr->next;
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
					 | 
				
			||||||
	dev->stats.tx_packets++;
 | 
						dev->stats.tx_packets++;
 | 
				
			||||||
	dev->stats.tx_bytes += (skb->len);
 | 
						dev->stats.tx_bytes += (skb->len);
 | 
				
			||||||
	return NETDEV_TX_OK;
 | 
						return NETDEV_TX_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IP_HEADER_OFF  0
 | 
				
			||||||
 | 
					#define RX_ERROR_MASK (RX_LONG | RX_ALIGN | RX_CRC | RX_LEN | \
 | 
				
			||||||
 | 
						RX_FRAG | RX_ADDR | RX_DMAO | RX_PHY | RX_LATE | RX_RANGE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bfin_mac_rx(struct net_device *dev)
 | 
					static void bfin_mac_rx(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff *skb, *new_skb;
 | 
						struct sk_buff *skb, *new_skb;
 | 
				
			||||||
	unsigned short len;
 | 
						unsigned short len;
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp __maybe_unused = netdev_priv(dev);
 | 
				
			||||||
 | 
					#if defined(BFIN_MAC_CSUM_OFFLOAD)
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
						unsigned char fcs[ETH_FCS_LEN + 1];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* check if frame status word reports an error condition
 | 
				
			||||||
 | 
						 * we which case we simply drop the packet
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (current_rx_ptr->status.status_word & RX_ERROR_MASK) {
 | 
				
			||||||
 | 
							printk(KERN_NOTICE DRV_NAME
 | 
				
			||||||
 | 
							       ": rx: receive error - packet dropped\n");
 | 
				
			||||||
 | 
							dev->stats.rx_dropped++;
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* allocate a new skb for next time receive */
 | 
						/* allocate a new skb for next time receive */
 | 
				
			||||||
	skb = current_rx_ptr->skb;
 | 
						skb = current_rx_ptr->skb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
 | 
						new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
 | 
				
			||||||
	if (!new_skb) {
 | 
						if (!new_skb) {
 | 
				
			||||||
		printk(KERN_NOTICE DRV_NAME
 | 
							printk(KERN_NOTICE DRV_NAME
 | 
				
			||||||
| 
						 | 
					@ -676,34 +1083,59 @@ static void bfin_mac_rx(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* reserve 2 bytes for RXDWA padding */
 | 
						/* reserve 2 bytes for RXDWA padding */
 | 
				
			||||||
	skb_reserve(new_skb, NET_IP_ALIGN);
 | 
						skb_reserve(new_skb, NET_IP_ALIGN);
 | 
				
			||||||
	current_rx_ptr->skb = new_skb;
 | 
					 | 
				
			||||||
	current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Invidate the data cache of skb->data range when it is write back
 | 
						/* Invidate the data cache of skb->data range when it is write back
 | 
				
			||||||
	 * cache. It will prevent overwritting the new data from DMA
 | 
						 * cache. It will prevent overwritting the new data from DMA
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
 | 
						blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
 | 
				
			||||||
					 (unsigned long)new_skb->end);
 | 
										 (unsigned long)new_skb->end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						current_rx_ptr->skb = new_skb;
 | 
				
			||||||
 | 
						current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
 | 
						len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
 | 
				
			||||||
 | 
						/* Deduce Ethernet FCS length from Ethernet payload length */
 | 
				
			||||||
 | 
						len -= ETH_FCS_LEN;
 | 
				
			||||||
	skb_put(skb, len);
 | 
						skb_put(skb, len);
 | 
				
			||||||
	blackfin_dcache_invalidate_range((unsigned long)skb->head,
 | 
					 | 
				
			||||||
					 (unsigned long)skb->tail);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb->protocol = eth_type_trans(skb, dev);
 | 
						skb->protocol = eth_type_trans(skb, dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bfin_rx_hwtstamp(dev, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(BFIN_MAC_CSUM_OFFLOAD)
 | 
					#if defined(BFIN_MAC_CSUM_OFFLOAD)
 | 
				
			||||||
 | 
						/* Checksum offloading only works for IPv4 packets with the standard IP header
 | 
				
			||||||
 | 
						 * length of 20 bytes, because the blackfin MAC checksum calculation is
 | 
				
			||||||
 | 
						 * based on that assumption. We must NOT use the calculated checksum if our
 | 
				
			||||||
 | 
						 * IP version or header break that assumption.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (skb->data[IP_HEADER_OFF] == 0x45) {
 | 
				
			||||||
		skb->csum = current_rx_ptr->status.ip_payload_csum;
 | 
							skb->csum = current_rx_ptr->status.ip_payload_csum;
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Deduce Ethernet FCS from hardware generated IP payload checksum.
 | 
				
			||||||
 | 
							 * IP checksum is based on 16-bit one's complement algorithm.
 | 
				
			||||||
 | 
							 * To deduce a value from checksum is equal to add its inversion.
 | 
				
			||||||
 | 
							 * If the IP payload len is odd, the inversed FCS should also
 | 
				
			||||||
 | 
							 * begin from odd address and leave first byte zero.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (skb->len % 2) {
 | 
				
			||||||
 | 
								fcs[0] = 0;
 | 
				
			||||||
 | 
								for (i = 0; i < ETH_FCS_LEN; i++)
 | 
				
			||||||
 | 
									fcs[i + 1] = ~skb->data[skb->len + i];
 | 
				
			||||||
 | 
								skb->csum = csum_partial(fcs, ETH_FCS_LEN + 1, skb->csum);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								for (i = 0; i < ETH_FCS_LEN; i++)
 | 
				
			||||||
 | 
									fcs[i] = ~skb->data[skb->len + i];
 | 
				
			||||||
 | 
								skb->csum = csum_partial(fcs, ETH_FCS_LEN, skb->csum);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		skb->ip_summed = CHECKSUM_COMPLETE;
 | 
							skb->ip_summed = CHECKSUM_COMPLETE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_rx(skb);
 | 
						netif_rx(skb);
 | 
				
			||||||
	dev->stats.rx_packets++;
 | 
						dev->stats.rx_packets++;
 | 
				
			||||||
	dev->stats.rx_bytes += len;
 | 
						dev->stats.rx_bytes += len;
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
	current_rx_ptr->status.status_word = 0x00000000;
 | 
						current_rx_ptr->status.status_word = 0x00000000;
 | 
				
			||||||
	current_rx_ptr = current_rx_ptr->next;
 | 
						current_rx_ptr = current_rx_ptr->next;
 | 
				
			||||||
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* interrupt routine to handle rx and error signal */
 | 
					/* interrupt routine to handle rx and error signal */
 | 
				
			||||||
| 
						 | 
					@ -755,8 +1187,9 @@ static void bfin_mac_disable(void)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Enable Interrupts, Receive, and Transmit
 | 
					 * Enable Interrupts, Receive, and Transmit
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void bfin_mac_enable(void)
 | 
					static int bfin_mac_enable(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
	u32 opmode;
 | 
						u32 opmode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr_debug("%s: %s\n", DRV_NAME, __func__);
 | 
						pr_debug("%s: %s\n", DRV_NAME, __func__);
 | 
				
			||||||
| 
						 | 
					@ -766,7 +1199,9 @@ static void bfin_mac_enable(void)
 | 
				
			||||||
	bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config);
 | 
						bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wait MII done */
 | 
						/* Wait MII done */
 | 
				
			||||||
	bfin_mdio_poll();
 | 
						ret = bfin_mdio_poll();
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We enable only RX here */
 | 
						/* We enable only RX here */
 | 
				
			||||||
	/* ASTP   : Enable Automatic Pad Stripping
 | 
						/* ASTP   : Enable Automatic Pad Stripping
 | 
				
			||||||
| 
						 | 
					@ -790,6 +1225,8 @@ static void bfin_mac_enable(void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	/* Turn on the EMAC rx */
 | 
						/* Turn on the EMAC rx */
 | 
				
			||||||
	bfin_write_EMAC_OPMODE(opmode);
 | 
						bfin_write_EMAC_OPMODE(opmode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Our watchdog timed out. Called by the networking layer */
 | 
					/* Our watchdog timed out. Called by the networking layer */
 | 
				
			||||||
| 
						 | 
					@ -805,21 +1242,21 @@ static void bfin_mac_timeout(struct net_device *dev)
 | 
				
			||||||
	bfin_mac_enable();
 | 
						bfin_mac_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We can accept TX packets again */
 | 
						/* We can accept TX packets again */
 | 
				
			||||||
	dev->trans_start = jiffies;
 | 
						dev->trans_start = jiffies; /* prevent tx timeout */
 | 
				
			||||||
	netif_wake_queue(dev);
 | 
						netif_wake_queue(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bfin_mac_multicast_hash(struct net_device *dev)
 | 
					static void bfin_mac_multicast_hash(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 emac_hashhi, emac_hashlo;
 | 
						u32 emac_hashhi, emac_hashlo;
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	char *addrs;
 | 
						char *addrs;
 | 
				
			||||||
	u32 crc;
 | 
						u32 crc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	emac_hashhi = emac_hashlo = 0;
 | 
						emac_hashhi = emac_hashlo = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netdev_for_each_mc_addr(dmi, dev) {
 | 
						netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
		addrs = dmi->dmi_addr;
 | 
							addrs = ha->addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* skip non-multicast addresses */
 | 
							/* skip non-multicast addresses */
 | 
				
			||||||
		if (!(*addrs & 1))
 | 
							if (!(*addrs & 1))
 | 
				
			||||||
| 
						 | 
					@ -836,8 +1273,6 @@ static void bfin_mac_multicast_hash(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bfin_write_EMAC_HASHHI(emac_hashhi);
 | 
						bfin_write_EMAC_HASHHI(emac_hashhi);
 | 
				
			||||||
	bfin_write_EMAC_HASHLO(emac_hashlo);
 | 
						bfin_write_EMAC_HASHLO(emac_hashlo);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -853,7 +1288,7 @@ static void bfin_mac_set_multicast_list(struct net_device *dev)
 | 
				
			||||||
	if (dev->flags & IFF_PROMISC) {
 | 
						if (dev->flags & IFF_PROMISC) {
 | 
				
			||||||
		printk(KERN_INFO "%s: set to promisc mode\n", dev->name);
 | 
							printk(KERN_INFO "%s: set to promisc mode\n", dev->name);
 | 
				
			||||||
		sysctl = bfin_read_EMAC_OPMODE();
 | 
							sysctl = bfin_read_EMAC_OPMODE();
 | 
				
			||||||
		sysctl |= RAF;
 | 
							sysctl |= PR;
 | 
				
			||||||
		bfin_write_EMAC_OPMODE(sysctl);
 | 
							bfin_write_EMAC_OPMODE(sysctl);
 | 
				
			||||||
	} else if (dev->flags & IFF_ALLMULTI) {
 | 
						} else if (dev->flags & IFF_ALLMULTI) {
 | 
				
			||||||
		/* accept all multicast */
 | 
							/* accept all multicast */
 | 
				
			||||||
| 
						 | 
					@ -874,6 +1309,16 @@ static void bfin_mac_set_multicast_list(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int bfin_mac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (cmd) {
 | 
				
			||||||
 | 
						case SIOCSHWTSTAMP:
 | 
				
			||||||
 | 
							return bfin_mac_hwtstamp_ioctl(netdev, ifr, cmd);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * this puts the device in an inactive state
 | 
					 * this puts the device in an inactive state
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -894,7 +1339,7 @@ static void bfin_mac_shutdown(struct net_device *dev)
 | 
				
			||||||
static int bfin_mac_open(struct net_device *dev)
 | 
					static int bfin_mac_open(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bfin_mac_local *lp = netdev_priv(dev);
 | 
						struct bfin_mac_local *lp = netdev_priv(dev);
 | 
				
			||||||
	int retval;
 | 
						int ret;
 | 
				
			||||||
	pr_debug("%s: %s\n", dev->name, __func__);
 | 
						pr_debug("%s: %s\n", dev->name, __func__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -908,18 +1353,21 @@ static int bfin_mac_open(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* initial rx and tx list */
 | 
						/* initial rx and tx list */
 | 
				
			||||||
	retval = desc_list_init();
 | 
						ret = desc_list_init();
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
	if (retval)
 | 
							return ret;
 | 
				
			||||||
		return retval;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	phy_start(lp->phydev);
 | 
						phy_start(lp->phydev);
 | 
				
			||||||
	phy_write(lp->phydev, MII_BMCR, BMCR_RESET);
 | 
						phy_write(lp->phydev, MII_BMCR, BMCR_RESET);
 | 
				
			||||||
	setup_system_regs(dev);
 | 
						setup_system_regs(dev);
 | 
				
			||||||
	setup_mac_addr(dev->dev_addr);
 | 
						setup_mac_addr(dev->dev_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bfin_mac_disable();
 | 
						bfin_mac_disable();
 | 
				
			||||||
	bfin_mac_enable();
 | 
						ret = bfin_mac_enable();
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
	pr_debug("hardware init finished\n");
 | 
						pr_debug("hardware init finished\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_start_queue(dev);
 | 
						netif_start_queue(dev);
 | 
				
			||||||
	netif_carrier_on(dev);
 | 
						netif_carrier_on(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -958,6 +1406,7 @@ static const struct net_device_ops bfin_mac_netdev_ops = {
 | 
				
			||||||
	.ndo_set_mac_address	= bfin_mac_set_mac_address,
 | 
						.ndo_set_mac_address	= bfin_mac_set_mac_address,
 | 
				
			||||||
	.ndo_tx_timeout		= bfin_mac_timeout,
 | 
						.ndo_tx_timeout		= bfin_mac_timeout,
 | 
				
			||||||
	.ndo_set_multicast_list	= bfin_mac_set_multicast_list,
 | 
						.ndo_set_multicast_list	= bfin_mac_set_multicast_list,
 | 
				
			||||||
 | 
						.ndo_do_ioctl           = bfin_mac_ioctl,
 | 
				
			||||||
	.ndo_validate_addr	= eth_validate_addr,
 | 
						.ndo_validate_addr	= eth_validate_addr,
 | 
				
			||||||
	.ndo_change_mtu		= eth_change_mtu,
 | 
						.ndo_change_mtu		= eth_change_mtu,
 | 
				
			||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
 | 
					#ifdef CONFIG_NET_POLL_CONTROLLER
 | 
				
			||||||
| 
						 | 
					@ -1017,6 +1466,11 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pd = pdev->dev.platform_data;
 | 
						pd = pdev->dev.platform_data;
 | 
				
			||||||
	lp->mii_bus = platform_get_drvdata(pd);
 | 
						lp->mii_bus = platform_get_drvdata(pd);
 | 
				
			||||||
 | 
						if (!lp->mii_bus) {
 | 
				
			||||||
 | 
							dev_err(&pdev->dev, "Cannot get mii_bus!\n");
 | 
				
			||||||
 | 
							rc = -ENODEV;
 | 
				
			||||||
 | 
							goto out_err_mii_bus_probe;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	lp->mii_bus->priv = ndev;
 | 
						lp->mii_bus->priv = ndev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = mii_probe(ndev);
 | 
						rc = mii_probe(ndev);
 | 
				
			||||||
| 
						 | 
					@ -1049,6 +1503,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 | 
				
			||||||
		goto out_err_reg_ndev;
 | 
							goto out_err_reg_ndev;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bfin_mac_hwtstamp_init(ndev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* now, print out the card info, in a short format.. */
 | 
						/* now, print out the card info, in a short format.. */
 | 
				
			||||||
	dev_info(&pdev->dev, "%s, Version %s\n", DRV_DESC, DRV_VERSION);
 | 
						dev_info(&pdev->dev, "%s, Version %s\n", DRV_DESC, DRV_VERSION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1060,6 +1516,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 | 
				
			||||||
out_err_mii_probe:
 | 
					out_err_mii_probe:
 | 
				
			||||||
	mdiobus_unregister(lp->mii_bus);
 | 
						mdiobus_unregister(lp->mii_bus);
 | 
				
			||||||
	mdiobus_free(lp->mii_bus);
 | 
						mdiobus_free(lp->mii_bus);
 | 
				
			||||||
 | 
					out_err_mii_bus_probe:
 | 
				
			||||||
	peripheral_free_list(pin_req);
 | 
						peripheral_free_list(pin_req);
 | 
				
			||||||
out_err_probe_mac:
 | 
					out_err_probe_mac:
 | 
				
			||||||
	platform_set_drvdata(pdev, NULL);
 | 
						platform_set_drvdata(pdev, NULL);
 | 
				
			||||||
| 
						 | 
					@ -1092,9 +1549,16 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev)
 | 
				
			||||||
static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t mesg)
 | 
					static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t mesg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *net_dev = platform_get_drvdata(pdev);
 | 
						struct net_device *net_dev = platform_get_drvdata(pdev);
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(net_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lp->wol) {
 | 
				
			||||||
 | 
							bfin_write_EMAC_OPMODE((bfin_read_EMAC_OPMODE() & ~TE) | RE);
 | 
				
			||||||
 | 
							bfin_write_EMAC_WKUP_CTL(MPKE);
 | 
				
			||||||
 | 
							enable_irq_wake(IRQ_MAC_WAKEDET);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		if (netif_running(net_dev))
 | 
							if (netif_running(net_dev))
 | 
				
			||||||
			bfin_mac_close(net_dev);
 | 
								bfin_mac_close(net_dev);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1102,9 +1566,16 @@ static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t mesg)
 | 
				
			||||||
static int bfin_mac_resume(struct platform_device *pdev)
 | 
					static int bfin_mac_resume(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *net_dev = platform_get_drvdata(pdev);
 | 
						struct net_device *net_dev = platform_get_drvdata(pdev);
 | 
				
			||||||
 | 
						struct bfin_mac_local *lp = netdev_priv(net_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lp->wol) {
 | 
				
			||||||
 | 
							bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
 | 
				
			||||||
 | 
							bfin_write_EMAC_WKUP_CTL(0);
 | 
				
			||||||
 | 
							disable_irq_wake(IRQ_MAC_WAKEDET);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		if (netif_running(net_dev))
 | 
							if (netif_running(net_dev))
 | 
				
			||||||
			bfin_mac_open(net_dev);
 | 
								bfin_mac_open(net_dev);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,12 @@
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Licensed under the GPL-2 or later.
 | 
					 * Licensed under the GPL-2 or later.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef _BFIN_MAC_H_
 | 
				
			||||||
 | 
					#define _BFIN_MAC_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/net_tstamp.h>
 | 
				
			||||||
 | 
					#include <linux/clocksource.h>
 | 
				
			||||||
 | 
					#include <linux/timecompare.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BFIN_MAC_CSUM_OFFLOAD
 | 
					#define BFIN_MAC_CSUM_OFFLOAD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +66,9 @@ struct bfin_mac_local {
 | 
				
			||||||
	unsigned char Mac[6];	/* MAC address of the board */
 | 
						unsigned char Mac[6];	/* MAC address of the board */
 | 
				
			||||||
	spinlock_t lock;
 | 
						spinlock_t lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int wol;		/* Wake On Lan */
 | 
				
			||||||
 | 
						int irq_wake_requested;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* MII and PHY stuffs */
 | 
						/* MII and PHY stuffs */
 | 
				
			||||||
	int old_link;          /* used by bf537_adjust_link */
 | 
						int old_link;          /* used by bf537_adjust_link */
 | 
				
			||||||
	int old_speed;
 | 
						int old_speed;
 | 
				
			||||||
| 
						 | 
					@ -67,6 +76,15 @@ struct bfin_mac_local {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct phy_device *phydev;
 | 
						struct phy_device *phydev;
 | 
				
			||||||
	struct mii_bus *mii_bus;
 | 
						struct mii_bus *mii_bus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BFIN_MAC_USE_HWSTAMP)
 | 
				
			||||||
 | 
						struct cyclecounter cycles;
 | 
				
			||||||
 | 
						struct timecounter clock;
 | 
				
			||||||
 | 
						struct timecompare compare;
 | 
				
			||||||
 | 
						struct hwtstamp_config stamp_cfg;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void bfin_get_ether_addr(char *addr);
 | 
					extern void bfin_get_ether_addr(char *addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,7 +167,6 @@ static inline void
 | 
				
			||||||
dbdma_st32(volatile __u32 __iomem *a, unsigned long x)
 | 
					dbdma_st32(volatile __u32 __iomem *a, unsigned long x)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	__asm__ volatile( "stwbrx %0,0,%1" : : "r" (x), "r" (a) : "memory");
 | 
						__asm__ volatile( "stwbrx %0,0,%1" : : "r" (x), "r" (a) : "memory");
 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline unsigned long
 | 
					static inline unsigned long
 | 
				
			||||||
| 
						 | 
					@ -382,8 +381,6 @@ bmac_init_registers(struct net_device *dev)
 | 
				
			||||||
	bmwrite(dev, RXCFG, RxCRCNoStrip | RxHashFilterEnable | RxRejectOwnPackets);
 | 
						bmwrite(dev, RXCFG, RxCRCNoStrip | RxHashFilterEnable | RxRejectOwnPackets);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bmwrite(dev, INTDISABLE, EnableNormal);
 | 
						bmwrite(dev, INTDISABLE, EnableNormal);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
| 
						 | 
					@ -972,7 +969,7 @@ bmac_remove_multi(struct net_device *dev,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void bmac_set_multicast(struct net_device *dev)
 | 
					static void bmac_set_multicast(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	struct bmac_data *bp = netdev_priv(dev);
 | 
						struct bmac_data *bp = netdev_priv(dev);
 | 
				
			||||||
	int num_addrs = netdev_mc_count(dev);
 | 
						int num_addrs = netdev_mc_count(dev);
 | 
				
			||||||
	unsigned short rx_cfg;
 | 
						unsigned short rx_cfg;
 | 
				
			||||||
| 
						 | 
					@ -1001,8 +998,8 @@ static void bmac_set_multicast(struct net_device *dev)
 | 
				
			||||||
			rx_cfg = bmac_rx_on(dev, 0, 0);
 | 
								rx_cfg = bmac_rx_on(dev, 0, 0);
 | 
				
			||||||
			XXDEBUG(("bmac: multi disabled, rx_cfg=%#08x\n", rx_cfg));
 | 
								XXDEBUG(("bmac: multi disabled, rx_cfg=%#08x\n", rx_cfg));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			netdev_for_each_mc_addr(dmi, dev)
 | 
								netdev_for_each_mc_addr(ha, dev)
 | 
				
			||||||
				bmac_addhash(bp, dmi->dmi_addr);
 | 
									bmac_addhash(bp, ha->addr);
 | 
				
			||||||
			bmac_update_hash_table_mask(dev, bp);
 | 
								bmac_update_hash_table_mask(dev, bp);
 | 
				
			||||||
			rx_cfg = bmac_rx_on(dev, 1, 0);
 | 
								rx_cfg = bmac_rx_on(dev, 1, 0);
 | 
				
			||||||
			XXDEBUG(("bmac: multi enabled, rx_cfg=%#08x\n", rx_cfg));
 | 
								XXDEBUG(("bmac: multi enabled, rx_cfg=%#08x\n", rx_cfg));
 | 
				
			||||||
| 
						 | 
					@ -1016,7 +1013,7 @@ static void bmac_set_multicast(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bmac_set_multicast(struct net_device *dev)
 | 
					static void bmac_set_multicast(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	char *addrs;
 | 
						char *addrs;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned short rx_cfg;
 | 
						unsigned short rx_cfg;
 | 
				
			||||||
| 
						 | 
					@ -1040,8 +1037,8 @@ static void bmac_set_multicast(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for(i = 0; i < 4; i++) hash_table[i] = 0;
 | 
							for(i = 0; i < 4; i++) hash_table[i] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		netdev_for_each_mc_addr(dmi, dev) {
 | 
							netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
			addrs = dmi->dmi_addr;
 | 
								addrs = ha->addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if(!(*addrs & 1))
 | 
								if(!(*addrs & 1))
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,11 +58,11 @@
 | 
				
			||||||
#include "bnx2_fw.h"
 | 
					#include "bnx2_fw.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DRV_MODULE_NAME		"bnx2"
 | 
					#define DRV_MODULE_NAME		"bnx2"
 | 
				
			||||||
#define DRV_MODULE_VERSION	"2.0.9"
 | 
					#define DRV_MODULE_VERSION	"2.0.15"
 | 
				
			||||||
#define DRV_MODULE_RELDATE	"April 27, 2010"
 | 
					#define DRV_MODULE_RELDATE	"May 4, 2010"
 | 
				
			||||||
#define FW_MIPS_FILE_06		"bnx2/bnx2-mips-06-5.0.0.j6.fw"
 | 
					#define FW_MIPS_FILE_06		"bnx2/bnx2-mips-06-5.0.0.j6.fw"
 | 
				
			||||||
#define FW_RV2P_FILE_06		"bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
 | 
					#define FW_RV2P_FILE_06		"bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
 | 
				
			||||||
#define FW_MIPS_FILE_09		"bnx2/bnx2-mips-09-5.0.0.j9.fw"
 | 
					#define FW_MIPS_FILE_09		"bnx2/bnx2-mips-09-5.0.0.j15.fw"
 | 
				
			||||||
#define FW_RV2P_FILE_09_Ax	"bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw"
 | 
					#define FW_RV2P_FILE_09_Ax	"bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw"
 | 
				
			||||||
#define FW_RV2P_FILE_09		"bnx2/bnx2-rv2p-09-5.0.0.j10.fw"
 | 
					#define FW_RV2P_FILE_09		"bnx2/bnx2-rv2p-09-5.0.0.j10.fw"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -656,19 +656,11 @@ bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
 | 
				
			||||||
	if (stop_cnic)
 | 
						if (stop_cnic)
 | 
				
			||||||
		bnx2_cnic_stop(bp);
 | 
							bnx2_cnic_stop(bp);
 | 
				
			||||||
	if (netif_running(bp->dev)) {
 | 
						if (netif_running(bp->dev)) {
 | 
				
			||||||
		int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		bnx2_napi_disable(bp);
 | 
							bnx2_napi_disable(bp);
 | 
				
			||||||
		netif_tx_disable(bp->dev);
 | 
							netif_tx_disable(bp->dev);
 | 
				
			||||||
		/* prevent tx timeout */
 | 
					 | 
				
			||||||
		for (i = 0; i <  bp->dev->num_tx_queues; i++) {
 | 
					 | 
				
			||||||
			struct netdev_queue *txq;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			txq = netdev_get_tx_queue(bp->dev, i);
 | 
					 | 
				
			||||||
			txq->trans_start = jiffies;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bnx2_disable_int_sync(bp);
 | 
						bnx2_disable_int_sync(bp);
 | 
				
			||||||
 | 
						netif_carrier_off(bp->dev);	/* prevent tx timeout */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -677,6 +669,10 @@ bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
 | 
				
			||||||
	if (atomic_dec_and_test(&bp->intr_sem)) {
 | 
						if (atomic_dec_and_test(&bp->intr_sem)) {
 | 
				
			||||||
		if (netif_running(bp->dev)) {
 | 
							if (netif_running(bp->dev)) {
 | 
				
			||||||
			netif_tx_wake_all_queues(bp->dev);
 | 
								netif_tx_wake_all_queues(bp->dev);
 | 
				
			||||||
 | 
								spin_lock_bh(&bp->phy_lock);
 | 
				
			||||||
 | 
								if (bp->link_up)
 | 
				
			||||||
 | 
									netif_carrier_on(bp->dev);
 | 
				
			||||||
 | 
								spin_unlock_bh(&bp->phy_lock);
 | 
				
			||||||
			bnx2_napi_enable(bp);
 | 
								bnx2_napi_enable(bp);
 | 
				
			||||||
			bnx2_enable_int(bp);
 | 
								bnx2_enable_int(bp);
 | 
				
			||||||
			if (start_cnic)
 | 
								if (start_cnic)
 | 
				
			||||||
| 
						 | 
					@ -2672,7 +2668,7 @@ bnx2_alloc_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rx_pg->page = page;
 | 
						rx_pg->page = page;
 | 
				
			||||||
	pci_unmap_addr_set(rx_pg, mapping, mapping);
 | 
						dma_unmap_addr_set(rx_pg, mapping, mapping);
 | 
				
			||||||
	rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
 | 
						rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
 | 
				
			||||||
	rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
 | 
						rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -2687,7 +2683,7 @@ bnx2_free_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
 | 
				
			||||||
	if (!page)
 | 
						if (!page)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping), PAGE_SIZE,
 | 
						pci_unmap_page(bp->pdev, dma_unmap_addr(rx_pg, mapping), PAGE_SIZE,
 | 
				
			||||||
		       PCI_DMA_FROMDEVICE);
 | 
							       PCI_DMA_FROMDEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__free_page(page);
 | 
						__free_page(page);
 | 
				
			||||||
| 
						 | 
					@ -2719,7 +2715,8 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rx_buf->skb = skb;
 | 
						rx_buf->skb = skb;
 | 
				
			||||||
	pci_unmap_addr_set(rx_buf, mapping, mapping);
 | 
						rx_buf->desc = (struct l2_fhdr *) skb->data;
 | 
				
			||||||
 | 
						dma_unmap_addr_set(rx_buf, mapping, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
 | 
						rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
 | 
				
			||||||
	rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
 | 
						rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
 | 
				
			||||||
| 
						 | 
					@ -2818,7 +2815,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
 | 
							pci_unmap_single(bp->pdev, dma_unmap_addr(tx_buf, mapping),
 | 
				
			||||||
			skb_headlen(skb), PCI_DMA_TODEVICE);
 | 
								skb_headlen(skb), PCI_DMA_TODEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		tx_buf->skb = NULL;
 | 
							tx_buf->skb = NULL;
 | 
				
			||||||
| 
						 | 
					@ -2828,7 +2825,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 | 
				
			||||||
			sw_cons = NEXT_TX_BD(sw_cons);
 | 
								sw_cons = NEXT_TX_BD(sw_cons);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pci_unmap_page(bp->pdev,
 | 
								pci_unmap_page(bp->pdev,
 | 
				
			||||||
				pci_unmap_addr(
 | 
									dma_unmap_addr(
 | 
				
			||||||
					&txr->tx_buf_ring[TX_RING_IDX(sw_cons)],
 | 
										&txr->tx_buf_ring[TX_RING_IDX(sw_cons)],
 | 
				
			||||||
					mapping),
 | 
										mapping),
 | 
				
			||||||
				skb_shinfo(skb)->frags[i].size,
 | 
									skb_shinfo(skb)->frags[i].size,
 | 
				
			||||||
| 
						 | 
					@ -2910,8 +2907,8 @@ bnx2_reuse_rx_skb_pages(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
 | 
				
			||||||
		if (prod != cons) {
 | 
							if (prod != cons) {
 | 
				
			||||||
			prod_rx_pg->page = cons_rx_pg->page;
 | 
								prod_rx_pg->page = cons_rx_pg->page;
 | 
				
			||||||
			cons_rx_pg->page = NULL;
 | 
								cons_rx_pg->page = NULL;
 | 
				
			||||||
			pci_unmap_addr_set(prod_rx_pg, mapping,
 | 
								dma_unmap_addr_set(prod_rx_pg, mapping,
 | 
				
			||||||
				pci_unmap_addr(cons_rx_pg, mapping));
 | 
									dma_unmap_addr(cons_rx_pg, mapping));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi;
 | 
								prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi;
 | 
				
			||||||
			prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
 | 
								prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
 | 
				
			||||||
| 
						 | 
					@ -2935,18 +2932,19 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
 | 
				
			||||||
	prod_rx_buf = &rxr->rx_buf_ring[prod];
 | 
						prod_rx_buf = &rxr->rx_buf_ring[prod];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_dma_sync_single_for_device(bp->pdev,
 | 
						pci_dma_sync_single_for_device(bp->pdev,
 | 
				
			||||||
		pci_unmap_addr(cons_rx_buf, mapping),
 | 
							dma_unmap_addr(cons_rx_buf, mapping),
 | 
				
			||||||
		BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
 | 
							BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rxr->rx_prod_bseq += bp->rx_buf_use_size;
 | 
						rxr->rx_prod_bseq += bp->rx_buf_use_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	prod_rx_buf->skb = skb;
 | 
						prod_rx_buf->skb = skb;
 | 
				
			||||||
 | 
						prod_rx_buf->desc = (struct l2_fhdr *) skb->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cons == prod)
 | 
						if (cons == prod)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_unmap_addr_set(prod_rx_buf, mapping,
 | 
						dma_unmap_addr_set(prod_rx_buf, mapping,
 | 
				
			||||||
			pci_unmap_addr(cons_rx_buf, mapping));
 | 
								dma_unmap_addr(cons_rx_buf, mapping));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cons_bd = &rxr->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)];
 | 
						cons_bd = &rxr->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)];
 | 
				
			||||||
	prod_bd = &rxr->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)];
 | 
						prod_bd = &rxr->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)];
 | 
				
			||||||
| 
						 | 
					@ -3019,7 +3017,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb,
 | 
				
			||||||
			/* Don't unmap yet.  If we're unable to allocate a new
 | 
								/* Don't unmap yet.  If we're unable to allocate a new
 | 
				
			||||||
			 * page, we need to recycle the page and the DMA addr.
 | 
								 * page, we need to recycle the page and the DMA addr.
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			mapping_old = pci_unmap_addr(rx_pg, mapping);
 | 
								mapping_old = dma_unmap_addr(rx_pg, mapping);
 | 
				
			||||||
			if (i == pages - 1)
 | 
								if (i == pages - 1)
 | 
				
			||||||
				frag_len -= 4;
 | 
									frag_len -= 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3074,6 +3072,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 | 
				
			||||||
	u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
 | 
						u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
 | 
				
			||||||
	struct l2_fhdr *rx_hdr;
 | 
						struct l2_fhdr *rx_hdr;
 | 
				
			||||||
	int rx_pkt = 0, pg_ring_used = 0;
 | 
						int rx_pkt = 0, pg_ring_used = 0;
 | 
				
			||||||
 | 
						struct pci_dev *pdev = bp->pdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hw_cons = bnx2_get_hw_rx_cons(bnapi);
 | 
						hw_cons = bnx2_get_hw_rx_cons(bnapi);
 | 
				
			||||||
	sw_cons = rxr->rx_cons;
 | 
						sw_cons = rxr->rx_cons;
 | 
				
			||||||
| 
						 | 
					@ -3086,7 +3085,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 | 
				
			||||||
	while (sw_cons != hw_cons) {
 | 
						while (sw_cons != hw_cons) {
 | 
				
			||||||
		unsigned int len, hdr_len;
 | 
							unsigned int len, hdr_len;
 | 
				
			||||||
		u32 status;
 | 
							u32 status;
 | 
				
			||||||
		struct sw_bd *rx_buf;
 | 
							struct sw_bd *rx_buf, *next_rx_buf;
 | 
				
			||||||
		struct sk_buff *skb;
 | 
							struct sk_buff *skb;
 | 
				
			||||||
		dma_addr_t dma_addr;
 | 
							dma_addr_t dma_addr;
 | 
				
			||||||
		u16 vtag = 0;
 | 
							u16 vtag = 0;
 | 
				
			||||||
| 
						 | 
					@ -3097,16 +3096,23 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rx_buf = &rxr->rx_buf_ring[sw_ring_cons];
 | 
							rx_buf = &rxr->rx_buf_ring[sw_ring_cons];
 | 
				
			||||||
		skb = rx_buf->skb;
 | 
							skb = rx_buf->skb;
 | 
				
			||||||
 | 
							prefetchw(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!get_dma_ops(&pdev->dev)->sync_single_for_cpu) {
 | 
				
			||||||
 | 
								next_rx_buf =
 | 
				
			||||||
 | 
									&rxr->rx_buf_ring[
 | 
				
			||||||
 | 
										RX_RING_IDX(NEXT_RX_BD(sw_cons))];
 | 
				
			||||||
 | 
								prefetch(next_rx_buf->desc);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		rx_buf->skb = NULL;
 | 
							rx_buf->skb = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dma_addr = pci_unmap_addr(rx_buf, mapping);
 | 
							dma_addr = dma_unmap_addr(rx_buf, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pci_dma_sync_single_for_cpu(bp->pdev, dma_addr,
 | 
							pci_dma_sync_single_for_cpu(bp->pdev, dma_addr,
 | 
				
			||||||
			BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH,
 | 
								BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH,
 | 
				
			||||||
			PCI_DMA_FROMDEVICE);
 | 
								PCI_DMA_FROMDEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rx_hdr = (struct l2_fhdr *) skb->data;
 | 
							rx_hdr = rx_buf->desc;
 | 
				
			||||||
		len = rx_hdr->l2_fhdr_pkt_len;
 | 
							len = rx_hdr->l2_fhdr_pkt_len;
 | 
				
			||||||
		status = rx_hdr->l2_fhdr_status;
 | 
							status = rx_hdr->l2_fhdr_status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3207,10 +3213,10 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef BCM_VLAN
 | 
					#ifdef BCM_VLAN
 | 
				
			||||||
		if (hw_vlan)
 | 
							if (hw_vlan)
 | 
				
			||||||
			vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
 | 
								vlan_gro_receive(&bnapi->napi, bp->vlgrp, vtag, skb);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			netif_receive_skb(skb);
 | 
								napi_gro_receive(&bnapi->napi, skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rx_pkt++;
 | 
							rx_pkt++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3548,7 +3554,6 @@ bnx2_set_rx_mode(struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		/* Accept one or more multicast(s). */
 | 
							/* Accept one or more multicast(s). */
 | 
				
			||||||
		struct dev_mc_list *mclist;
 | 
					 | 
				
			||||||
		u32 mc_filter[NUM_MC_HASH_REGISTERS];
 | 
							u32 mc_filter[NUM_MC_HASH_REGISTERS];
 | 
				
			||||||
		u32 regidx;
 | 
							u32 regidx;
 | 
				
			||||||
		u32 bit;
 | 
							u32 bit;
 | 
				
			||||||
| 
						 | 
					@ -3556,8 +3561,8 @@ bnx2_set_rx_mode(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memset(mc_filter, 0, 4 * NUM_MC_HASH_REGISTERS);
 | 
							memset(mc_filter, 0, 4 * NUM_MC_HASH_REGISTERS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		netdev_for_each_mc_addr(mclist, dev) {
 | 
							netdev_for_each_mc_addr(ha, dev) {
 | 
				
			||||||
			crc = ether_crc_le(ETH_ALEN, mclist->dmi_addr);
 | 
								crc = ether_crc_le(ETH_ALEN, ha->addr);
 | 
				
			||||||
			bit = crc & 0xff;
 | 
								bit = crc & 0xff;
 | 
				
			||||||
			regidx = (bit & 0xe0) >> 5;
 | 
								regidx = (bit & 0xe0) >> 5;
 | 
				
			||||||
			bit &= 0x1f;
 | 
								bit &= 0x1f;
 | 
				
			||||||
| 
						 | 
					@ -5318,7 +5323,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pci_unmap_single(bp->pdev,
 | 
								pci_unmap_single(bp->pdev,
 | 
				
			||||||
					 pci_unmap_addr(tx_buf, mapping),
 | 
										 dma_unmap_addr(tx_buf, mapping),
 | 
				
			||||||
					 skb_headlen(skb),
 | 
										 skb_headlen(skb),
 | 
				
			||||||
					 PCI_DMA_TODEVICE);
 | 
										 PCI_DMA_TODEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5329,7 +5334,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
 | 
				
			||||||
			for (k = 0; k < last; k++, j++) {
 | 
								for (k = 0; k < last; k++, j++) {
 | 
				
			||||||
				tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)];
 | 
									tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)];
 | 
				
			||||||
				pci_unmap_page(bp->pdev,
 | 
									pci_unmap_page(bp->pdev,
 | 
				
			||||||
					pci_unmap_addr(tx_buf, mapping),
 | 
										dma_unmap_addr(tx_buf, mapping),
 | 
				
			||||||
					skb_shinfo(skb)->frags[k].size,
 | 
										skb_shinfo(skb)->frags[k].size,
 | 
				
			||||||
					PCI_DMA_TODEVICE);
 | 
										PCI_DMA_TODEVICE);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -5359,7 +5364,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pci_unmap_single(bp->pdev,
 | 
								pci_unmap_single(bp->pdev,
 | 
				
			||||||
					 pci_unmap_addr(rx_buf, mapping),
 | 
										 dma_unmap_addr(rx_buf, mapping),
 | 
				
			||||||
					 bp->rx_buf_use_size,
 | 
										 bp->rx_buf_use_size,
 | 
				
			||||||
					 PCI_DMA_FROMDEVICE);
 | 
										 PCI_DMA_FROMDEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5765,11 +5770,11 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
 | 
				
			||||||
	rx_buf = &rxr->rx_buf_ring[rx_start_idx];
 | 
						rx_buf = &rxr->rx_buf_ring[rx_start_idx];
 | 
				
			||||||
	rx_skb = rx_buf->skb;
 | 
						rx_skb = rx_buf->skb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rx_hdr = (struct l2_fhdr *) rx_skb->data;
 | 
						rx_hdr = rx_buf->desc;
 | 
				
			||||||
	skb_reserve(rx_skb, BNX2_RX_OFFSET);
 | 
						skb_reserve(rx_skb, BNX2_RX_OFFSET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_dma_sync_single_for_cpu(bp->pdev,
 | 
						pci_dma_sync_single_for_cpu(bp->pdev,
 | 
				
			||||||
		pci_unmap_addr(rx_buf, mapping),
 | 
							dma_unmap_addr(rx_buf, mapping),
 | 
				
			||||||
		bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 | 
							bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rx_hdr->l2_fhdr_status &
 | 
						if (rx_hdr->l2_fhdr_status &
 | 
				
			||||||
| 
						 | 
					@ -6292,14 +6297,23 @@ static void
 | 
				
			||||||
bnx2_dump_state(struct bnx2 *bp)
 | 
					bnx2_dump_state(struct bnx2 *bp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *dev = bp->dev;
 | 
						struct net_device *dev = bp->dev;
 | 
				
			||||||
 | 
						u32 mcp_p0, mcp_p1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netdev_err(dev, "DEBUG: intr_sem[%x]\n", atomic_read(&bp->intr_sem));
 | 
						netdev_err(dev, "DEBUG: intr_sem[%x]\n", atomic_read(&bp->intr_sem));
 | 
				
			||||||
	netdev_err(dev, "DEBUG: EMAC_TX_STATUS[%08x] RPM_MGMT_PKT_CTRL[%08x]\n",
 | 
						netdev_err(dev, "DEBUG: EMAC_TX_STATUS[%08x] EMAC_RX_STATUS[%08x]\n",
 | 
				
			||||||
		   REG_RD(bp, BNX2_EMAC_TX_STATUS),
 | 
							   REG_RD(bp, BNX2_EMAC_TX_STATUS),
 | 
				
			||||||
 | 
							   REG_RD(bp, BNX2_EMAC_RX_STATUS));
 | 
				
			||||||
 | 
						netdev_err(dev, "DEBUG: RPM_MGMT_PKT_CTRL[%08x]\n",
 | 
				
			||||||
		   REG_RD(bp, BNX2_RPM_MGMT_PKT_CTRL));
 | 
							   REG_RD(bp, BNX2_RPM_MGMT_PKT_CTRL));
 | 
				
			||||||
 | 
						if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 | 
				
			||||||
 | 
							mcp_p0 = BNX2_MCP_STATE_P0;
 | 
				
			||||||
 | 
							mcp_p1 = BNX2_MCP_STATE_P1;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							mcp_p0 = BNX2_MCP_STATE_P0_5708;
 | 
				
			||||||
 | 
							mcp_p1 = BNX2_MCP_STATE_P1_5708;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n",
 | 
						netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n",
 | 
				
			||||||
		   bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P0),
 | 
							   bnx2_reg_rd_ind(bp, mcp_p0), bnx2_reg_rd_ind(bp, mcp_p1));
 | 
				
			||||||
		   bnx2_reg_rd_ind(bp, BNX2_MCP_STATE_P1));
 | 
					 | 
				
			||||||
	netdev_err(dev, "DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n",
 | 
						netdev_err(dev, "DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n",
 | 
				
			||||||
		   REG_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS));
 | 
							   REG_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS));
 | 
				
			||||||
	if (bp->flags & BNX2_FLAG_USING_MSIX)
 | 
						if (bp->flags & BNX2_FLAG_USING_MSIX)
 | 
				
			||||||
| 
						 | 
					@ -6429,7 +6443,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx_buf = &txr->tx_buf_ring[ring_prod];
 | 
						tx_buf = &txr->tx_buf_ring[ring_prod];
 | 
				
			||||||
	tx_buf->skb = skb;
 | 
						tx_buf->skb = skb;
 | 
				
			||||||
	pci_unmap_addr_set(tx_buf, mapping, mapping);
 | 
						dma_unmap_addr_set(tx_buf, mapping, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	txbd = &txr->tx_desc_ring[ring_prod];
 | 
						txbd = &txr->tx_desc_ring[ring_prod];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6454,7 +6468,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
			len, PCI_DMA_TODEVICE);
 | 
								len, PCI_DMA_TODEVICE);
 | 
				
			||||||
		if (pci_dma_mapping_error(bp->pdev, mapping))
 | 
							if (pci_dma_mapping_error(bp->pdev, mapping))
 | 
				
			||||||
			goto dma_error;
 | 
								goto dma_error;
 | 
				
			||||||
		pci_unmap_addr_set(&txr->tx_buf_ring[ring_prod], mapping,
 | 
							dma_unmap_addr_set(&txr->tx_buf_ring[ring_prod], mapping,
 | 
				
			||||||
				   mapping);
 | 
									   mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
 | 
							txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
 | 
				
			||||||
| 
						 | 
					@ -6491,7 +6505,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	ring_prod = TX_RING_IDX(prod);
 | 
						ring_prod = TX_RING_IDX(prod);
 | 
				
			||||||
	tx_buf = &txr->tx_buf_ring[ring_prod];
 | 
						tx_buf = &txr->tx_buf_ring[ring_prod];
 | 
				
			||||||
	tx_buf->skb = NULL;
 | 
						tx_buf->skb = NULL;
 | 
				
			||||||
	pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
 | 
						pci_unmap_single(bp->pdev, dma_unmap_addr(tx_buf, mapping),
 | 
				
			||||||
			 skb_headlen(skb), PCI_DMA_TODEVICE);
 | 
								 skb_headlen(skb), PCI_DMA_TODEVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* unmap remaining mapped pages */
 | 
						/* unmap remaining mapped pages */
 | 
				
			||||||
| 
						 | 
					@ -6499,7 +6513,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
		prod = NEXT_TX_BD(prod);
 | 
							prod = NEXT_TX_BD(prod);
 | 
				
			||||||
		ring_prod = TX_RING_IDX(prod);
 | 
							ring_prod = TX_RING_IDX(prod);
 | 
				
			||||||
		tx_buf = &txr->tx_buf_ring[ring_prod];
 | 
							tx_buf = &txr->tx_buf_ring[ring_prod];
 | 
				
			||||||
		pci_unmap_page(bp->pdev, pci_unmap_addr(tx_buf, mapping),
 | 
							pci_unmap_page(bp->pdev, dma_unmap_addr(tx_buf, mapping),
 | 
				
			||||||
			       skb_shinfo(skb)->frags[i].size,
 | 
								       skb_shinfo(skb)->frags[i].size,
 | 
				
			||||||
			       PCI_DMA_TODEVICE);
 | 
								       PCI_DMA_TODEVICE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -8297,7 +8311,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 | 
				
			||||||
	memcpy(dev->dev_addr, bp->mac_addr, 6);
 | 
						memcpy(dev->dev_addr, bp->mac_addr, 6);
 | 
				
			||||||
	memcpy(dev->perm_addr, bp->mac_addr, 6);
 | 
						memcpy(dev->perm_addr, bp->mac_addr, 6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 | 
						dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO;
 | 
				
			||||||
	vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG);
 | 
						vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG);
 | 
				
			||||||
	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 | 
						if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 | 
				
			||||||
		dev->features |= NETIF_F_IPV6_CSUM;
 | 
							dev->features |= NETIF_F_IPV6_CSUM;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6347,6 +6347,8 @@ struct l2_fhdr {
 | 
				
			||||||
#define BNX2_MCP_SCRATCH				0x00160000
 | 
					#define BNX2_MCP_SCRATCH				0x00160000
 | 
				
			||||||
#define BNX2_MCP_STATE_P1				 0x0016f9c8
 | 
					#define BNX2_MCP_STATE_P1				 0x0016f9c8
 | 
				
			||||||
#define BNX2_MCP_STATE_P0				 0x0016fdc8
 | 
					#define BNX2_MCP_STATE_P0				 0x0016fdc8
 | 
				
			||||||
 | 
					#define BNX2_MCP_STATE_P1_5708				 0x001699c8
 | 
				
			||||||
 | 
					#define BNX2_MCP_STATE_P0_5708				 0x00169dc8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BNX2_SHM_HDR_SIGNATURE				BNX2_MCP_SCRATCH
 | 
					#define BNX2_SHM_HDR_SIGNATURE				BNX2_MCP_SCRATCH
 | 
				
			||||||
#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK			 0xffff0000
 | 
					#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK			 0xffff0000
 | 
				
			||||||
| 
						 | 
					@ -6551,17 +6553,18 @@ struct l2_fhdr {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sw_bd {
 | 
					struct sw_bd {
 | 
				
			||||||
	struct sk_buff		*skb;
 | 
						struct sk_buff		*skb;
 | 
				
			||||||
	DECLARE_PCI_UNMAP_ADDR(mapping)
 | 
						struct l2_fhdr		*desc;
 | 
				
			||||||
 | 
						DEFINE_DMA_UNMAP_ADDR(mapping);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sw_pg {
 | 
					struct sw_pg {
 | 
				
			||||||
	struct page		*page;
 | 
						struct page		*page;
 | 
				
			||||||
	DECLARE_PCI_UNMAP_ADDR(mapping)
 | 
						DEFINE_DMA_UNMAP_ADDR(mapping);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sw_tx_bd {
 | 
					struct sw_tx_bd {
 | 
				
			||||||
	struct sk_buff		*skb;
 | 
						struct sk_buff		*skb;
 | 
				
			||||||
	DECLARE_PCI_UNMAP_ADDR(mapping)
 | 
						DEFINE_DMA_UNMAP_ADDR(mapping);
 | 
				
			||||||
	unsigned short		is_gso;
 | 
						unsigned short		is_gso;
 | 
				
			||||||
	unsigned short		nr_frags;
 | 
						unsigned short		nr_frags;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,17 +24,26 @@
 | 
				
			||||||
#define BCM_VLAN			1
 | 
					#define BCM_VLAN			1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
 | 
					 | 
				
			||||||
#define BCM_CNIC 1
 | 
					 | 
				
			||||||
#include "cnic_if.h"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BNX2X_MULTI_QUEUE
 | 
					#define BNX2X_MULTI_QUEUE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BNX2X_NEW_NAPI
 | 
					#define BNX2X_NEW_NAPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
 | 
				
			||||||
 | 
					#define BCM_CNIC 1
 | 
				
			||||||
 | 
					#include "cnic_if.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef BCM_CNIC
 | 
				
			||||||
 | 
					#define BNX2X_MIN_MSIX_VEC_CNT 3
 | 
				
			||||||
 | 
					#define BNX2X_MSIX_VEC_FP_START 2
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define BNX2X_MIN_MSIX_VEC_CNT 2
 | 
				
			||||||
 | 
					#define BNX2X_MSIX_VEC_FP_START 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/mdio.h>
 | 
					#include <linux/mdio.h>
 | 
				
			||||||
#include "bnx2x_reg.h"
 | 
					#include "bnx2x_reg.h"
 | 
				
			||||||
#include "bnx2x_fw_defs.h"
 | 
					#include "bnx2x_fw_defs.h"
 | 
				
			||||||
| 
						 | 
					@ -83,7 +92,12 @@ do {								\
 | 
				
			||||||
	       __func__, __LINE__,				\
 | 
						       __func__, __LINE__,				\
 | 
				
			||||||
	       bp->dev ? (bp->dev->name) : "?",			\
 | 
						       bp->dev ? (bp->dev->name) : "?",			\
 | 
				
			||||||
	       ##__args);					\
 | 
						       ##__args);					\
 | 
				
			||||||
} while (0)
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BNX2X_ERROR(__fmt, __args...) do { \
 | 
				
			||||||
 | 
						pr_err("[%s:%d]" __fmt, __func__, __LINE__, ##__args); \
 | 
				
			||||||
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* before we have a dev->name use dev_info() */
 | 
					/* before we have a dev->name use dev_info() */
 | 
				
			||||||
#define BNX2X_DEV_INFO(__fmt, __args...)			 \
 | 
					#define BNX2X_DEV_INFO(__fmt, __args...)			 \
 | 
				
			||||||
| 
						 | 
					@ -155,15 +169,21 @@ do {								 \
 | 
				
			||||||
#define SHMEM2_RD(bp, field)		REG_RD(bp, SHMEM2_ADDR(bp, field))
 | 
					#define SHMEM2_RD(bp, field)		REG_RD(bp, SHMEM2_ADDR(bp, field))
 | 
				
			||||||
#define SHMEM2_WR(bp, field, val)	REG_WR(bp, SHMEM2_ADDR(bp, field), val)
 | 
					#define SHMEM2_WR(bp, field, val)	REG_WR(bp, SHMEM2_ADDR(bp, field), val)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MF_CFG_RD(bp, field)		SHMEM_RD(bp, mf_cfg.field)
 | 
				
			||||||
 | 
					#define MF_CFG_WR(bp, field, val)	SHMEM_WR(bp, mf_cfg.field, val)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EMAC_RD(bp, reg)		REG_RD(bp, emac_base + reg)
 | 
					#define EMAC_RD(bp, reg)		REG_RD(bp, emac_base + reg)
 | 
				
			||||||
#define EMAC_WR(bp, reg, val)		REG_WR(bp, emac_base + reg, val)
 | 
					#define EMAC_WR(bp, reg, val)		REG_WR(bp, emac_base + reg, val)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \
 | 
				
			||||||
 | 
						AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* fast path */
 | 
					/* fast path */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sw_rx_bd {
 | 
					struct sw_rx_bd {
 | 
				
			||||||
	struct sk_buff	*skb;
 | 
						struct sk_buff	*skb;
 | 
				
			||||||
	DECLARE_PCI_UNMAP_ADDR(mapping)
 | 
						DEFINE_DMA_UNMAP_ADDR(mapping);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sw_tx_bd {
 | 
					struct sw_tx_bd {
 | 
				
			||||||
| 
						 | 
					@ -176,7 +196,7 @@ struct sw_tx_bd {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sw_rx_page {
 | 
					struct sw_rx_page {
 | 
				
			||||||
	struct page	*page;
 | 
						struct page	*page;
 | 
				
			||||||
	DECLARE_PCI_UNMAP_ADDR(mapping)
 | 
						DEFINE_DMA_UNMAP_ADDR(mapping);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
union db_prod {
 | 
					union db_prod {
 | 
				
			||||||
| 
						 | 
					@ -261,7 +281,7 @@ struct bnx2x_eth_q_stats {
 | 
				
			||||||
	u32 hw_csum_err;
 | 
						u32 hw_csum_err;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BNX2X_NUM_Q_STATS		11
 | 
					#define BNX2X_NUM_Q_STATS		13
 | 
				
			||||||
#define Q_STATS_OFFSET32(stat_name) \
 | 
					#define Q_STATS_OFFSET32(stat_name) \
 | 
				
			||||||
			(offsetof(struct bnx2x_eth_q_stats, stat_name) / 4)
 | 
								(offsetof(struct bnx2x_eth_q_stats, stat_name) / 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -767,7 +787,7 @@ struct bnx2x_eth_stats {
 | 
				
			||||||
	u32 nig_timer_max;
 | 
						u32 nig_timer_max;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BNX2X_NUM_STATS			41
 | 
					#define BNX2X_NUM_STATS			43
 | 
				
			||||||
#define STATS_OFFSET32(stat_name) \
 | 
					#define STATS_OFFSET32(stat_name) \
 | 
				
			||||||
			(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
 | 
								(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -818,6 +838,12 @@ struct attn_route {
 | 
				
			||||||
	u32	sig[4];
 | 
						u32	sig[4];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
						BNX2X_RECOVERY_DONE,
 | 
				
			||||||
 | 
						BNX2X_RECOVERY_INIT,
 | 
				
			||||||
 | 
						BNX2X_RECOVERY_WAIT,
 | 
				
			||||||
 | 
					} bnx2x_recovery_state_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct bnx2x {
 | 
					struct bnx2x {
 | 
				
			||||||
	/* Fields used in the tx and intr/napi performance paths
 | 
						/* Fields used in the tx and intr/napi performance paths
 | 
				
			||||||
	 * are grouped together in the beginning of the structure
 | 
						 * are grouped together in the beginning of the structure
 | 
				
			||||||
| 
						 | 
					@ -835,6 +861,9 @@ struct bnx2x {
 | 
				
			||||||
	struct pci_dev		*pdev;
 | 
						struct pci_dev		*pdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	atomic_t		intr_sem;
 | 
						atomic_t		intr_sem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bnx2x_recovery_state_t	recovery_state;
 | 
				
			||||||
 | 
						int			is_leader;
 | 
				
			||||||
#ifdef BCM_CNIC
 | 
					#ifdef BCM_CNIC
 | 
				
			||||||
	struct msix_entry	msix_table[MAX_CONTEXT+2];
 | 
						struct msix_entry	msix_table[MAX_CONTEXT+2];
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -842,7 +871,6 @@ struct bnx2x {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#define INT_MODE_INTx			1
 | 
					#define INT_MODE_INTx			1
 | 
				
			||||||
#define INT_MODE_MSI			2
 | 
					#define INT_MODE_MSI			2
 | 
				
			||||||
#define INT_MODE_MSIX			3
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int			tx_ring_size;
 | 
						int			tx_ring_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -924,8 +952,7 @@ struct bnx2x {
 | 
				
			||||||
	int			mrrs;
 | 
						int			mrrs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct delayed_work	sp_task;
 | 
						struct delayed_work	sp_task;
 | 
				
			||||||
	struct work_struct	reset_task;
 | 
						struct delayed_work	reset_task;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct timer_list	timer;
 | 
						struct timer_list	timer;
 | 
				
			||||||
	int			current_interval;
 | 
						int			current_interval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -961,6 +988,8 @@ struct bnx2x {
 | 
				
			||||||
	u16			rx_quick_cons_trip;
 | 
						u16			rx_quick_cons_trip;
 | 
				
			||||||
	u16			rx_ticks_int;
 | 
						u16			rx_ticks_int;
 | 
				
			||||||
	u16			rx_ticks;
 | 
						u16			rx_ticks;
 | 
				
			||||||
 | 
					/* Maximal coalescing timeout in us */
 | 
				
			||||||
 | 
					#define BNX2X_MAX_COALESCE_TOUT		(0xf0*12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u32			lin_cnt;
 | 
						u32			lin_cnt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1075,6 +1104,7 @@ struct bnx2x {
 | 
				
			||||||
#define INIT_CSEM_INT_TABLE_DATA(bp)	(bp->csem_int_table_data)
 | 
					#define INIT_CSEM_INT_TABLE_DATA(bp)	(bp->csem_int_table_data)
 | 
				
			||||||
#define INIT_CSEM_PRAM_DATA(bp)		(bp->csem_pram_data)
 | 
					#define INIT_CSEM_PRAM_DATA(bp)		(bp->csem_pram_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char			fw_ver[32];
 | 
				
			||||||
	const struct firmware	*firmware;
 | 
						const struct firmware	*firmware;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1125,6 +1155,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 | 
				
			||||||
#define LOAD_DIAG			2
 | 
					#define LOAD_DIAG			2
 | 
				
			||||||
#define UNLOAD_NORMAL			0
 | 
					#define UNLOAD_NORMAL			0
 | 
				
			||||||
#define UNLOAD_CLOSE			1
 | 
					#define UNLOAD_CLOSE			1
 | 
				
			||||||
 | 
					#define UNLOAD_RECOVERY                 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* DMAE command defines */
 | 
					/* DMAE command defines */
 | 
				
			||||||
| 
						 | 
					@ -1152,7 +1183,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 | 
				
			||||||
#define DMAE_CMD_E1HVN_SHIFT		DMAE_COMMAND_E1HVN_SHIFT
 | 
					#define DMAE_CMD_E1HVN_SHIFT		DMAE_COMMAND_E1HVN_SHIFT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DMAE_LEN32_RD_MAX		0x80
 | 
					#define DMAE_LEN32_RD_MAX		0x80
 | 
				
			||||||
#define DMAE_LEN32_WR_MAX		0x400
 | 
					#define DMAE_LEN32_WR_MAX(bp)		(CHIP_IS_E1(bp) ? 0x400 : 0x2000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DMAE_COMP_VAL			0xe0d0d0ae
 | 
					#define DMAE_COMP_VAL			0xe0d0d0ae
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1294,8 +1325,12 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 | 
				
			||||||
				 AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
 | 
									 AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
 | 
				
			||||||
				 AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
 | 
									 AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HW_PRTY_ASSERT_SET_3 (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
 | 
				
			||||||
 | 
							AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
 | 
				
			||||||
 | 
							AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
 | 
				
			||||||
 | 
							AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MULTI_FLAGS(bp) \
 | 
					#define RSS_FLAGS(bp) \
 | 
				
			||||||
		(TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
 | 
							(TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
 | 
				
			||||||
		 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
 | 
							 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
 | 
				
			||||||
		 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
 | 
							 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
 | 
				
			||||||
| 
						 | 
					@ -1333,6 +1368,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 | 
				
			||||||
#define PXP2_REG_PXP2_INT_STS		PXP2_REG_PXP2_INT_STS_0
 | 
					#define PXP2_REG_PXP2_INT_STS		PXP2_REG_PXP2_INT_STS_0
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BNX2X_VPD_LEN			128
 | 
				
			||||||
 | 
					#define VENDOR_ID_LEN			4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */
 | 
					/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* bnx2x.h */
 | 
					#endif /* bnx2x.h */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1594,7 +1594,7 @@ static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
 | 
				
			||||||
				MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
 | 
									MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
 | 
				
			||||||
		pause_result |= (lp_pause &
 | 
							pause_result |= (lp_pause &
 | 
				
			||||||
				 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
 | 
									 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
 | 
				
			||||||
		DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
 | 
							DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
 | 
				
			||||||
		   pause_result);
 | 
							   pause_result);
 | 
				
			||||||
		bnx2x_pause_resolve(vars, pause_result);
 | 
							bnx2x_pause_resolve(vars, pause_result);
 | 
				
			||||||
		if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
 | 
							if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
 | 
				
			||||||
| 
						 | 
					@ -1616,7 +1616,7 @@ static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
 | 
				
			||||||
				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
 | 
									MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bnx2x_pause_resolve(vars, pause_result);
 | 
								bnx2x_pause_resolve(vars, pause_result);
 | 
				
			||||||
			DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
 | 
								DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
 | 
				
			||||||
				 pause_result);
 | 
									 pause_result);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1974,7 +1974,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
 | 
						DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x\n",
 | 
				
			||||||
		 gp_status, vars->phy_link_up, vars->line_speed);
 | 
							 gp_status, vars->phy_link_up, vars->line_speed);
 | 
				
			||||||
	DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
 | 
						DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
 | 
				
			||||||
		 " autoneg 0x%x\n",
 | 
							 " autoneg 0x%x\n",
 | 
				
			||||||
| 
						 | 
					@ -3852,7 +3852,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 | 
				
			||||||
				    SPEED_AUTO_NEG) &&
 | 
									    SPEED_AUTO_NEG) &&
 | 
				
			||||||
				   ((params->speed_cap_mask &
 | 
									   ((params->speed_cap_mask &
 | 
				
			||||||
				     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
 | 
									     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
 | 
				
			||||||
				DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
 | 
									DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
 | 
				
			||||||
				bnx2x_cl45_write(bp, params->port, ext_phy_type,
 | 
									bnx2x_cl45_write(bp, params->port, ext_phy_type,
 | 
				
			||||||
					       ext_phy_addr, MDIO_AN_DEVAD,
 | 
										       ext_phy_addr, MDIO_AN_DEVAD,
 | 
				
			||||||
					       MDIO_AN_REG_ADV, 0x20);
 | 
										       MDIO_AN_REG_ADV, 0x20);
 | 
				
			||||||
| 
						 | 
					@ -4234,14 +4234,14 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 | 
				
			||||||
				      ext_phy_addr,
 | 
									      ext_phy_addr,
 | 
				
			||||||
				      MDIO_PMA_DEVAD,
 | 
									      MDIO_PMA_DEVAD,
 | 
				
			||||||
				      MDIO_PMA_REG_10G_CTRL2, &tmp1);
 | 
									      MDIO_PMA_REG_10G_CTRL2, &tmp1);
 | 
				
			||||||
				DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
 | 
									DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			} else if ((params->req_line_speed ==
 | 
								} else if ((params->req_line_speed ==
 | 
				
			||||||
				    SPEED_AUTO_NEG) &&
 | 
									    SPEED_AUTO_NEG) &&
 | 
				
			||||||
				   ((params->speed_cap_mask &
 | 
									   ((params->speed_cap_mask &
 | 
				
			||||||
				     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
 | 
									     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
 | 
									DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
 | 
				
			||||||
				bnx2x_cl45_write(bp, params->port, ext_phy_type,
 | 
									bnx2x_cl45_write(bp, params->port, ext_phy_type,
 | 
				
			||||||
					       ext_phy_addr, MDIO_AN_DEVAD,
 | 
										       ext_phy_addr, MDIO_AN_DEVAD,
 | 
				
			||||||
					       MDIO_PMA_REG_8727_MISC_CTRL, 0);
 | 
										       MDIO_PMA_REG_8727_MISC_CTRL, 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -766,6 +766,8 @@
 | 
				
			||||||
#define MCP_REG_MCPR_NVM_SW_ARB 				 0x86420
 | 
					#define MCP_REG_MCPR_NVM_SW_ARB 				 0x86420
 | 
				
			||||||
#define MCP_REG_MCPR_NVM_WRITE					 0x86408
 | 
					#define MCP_REG_MCPR_NVM_WRITE					 0x86408
 | 
				
			||||||
#define MCP_REG_MCPR_SCRATCH					 0xa0000
 | 
					#define MCP_REG_MCPR_SCRATCH					 0xa0000
 | 
				
			||||||
 | 
					#define MISC_AEU_GENERAL_MASK_REG_AEU_NIG_CLOSE_MASK		 (0x1<<1)
 | 
				
			||||||
 | 
					#define MISC_AEU_GENERAL_MASK_REG_AEU_PXP_CLOSE_MASK		 (0x1<<0)
 | 
				
			||||||
/* [R 32] read first 32 bit after inversion of function 0. mapped as
 | 
					/* [R 32] read first 32 bit after inversion of function 0. mapped as
 | 
				
			||||||
   follows: [0] NIG attention for function0; [1] NIG attention for
 | 
					   follows: [0] NIG attention for function0; [1] NIG attention for
 | 
				
			||||||
   function1; [2] GPIO1 mcp; [3] GPIO2 mcp; [4] GPIO3 mcp; [5] GPIO4 mcp;
 | 
					   function1; [2] GPIO1 mcp; [3] GPIO2 mcp; [4] GPIO3 mcp; [5] GPIO4 mcp;
 | 
				
			||||||
| 
						 | 
					@ -1249,6 +1251,8 @@
 | 
				
			||||||
#define MISC_REG_E1HMF_MODE					 0xa5f8
 | 
					#define MISC_REG_E1HMF_MODE					 0xa5f8
 | 
				
			||||||
/* [RW 32] Debug only: spare RW register reset by core reset */
 | 
					/* [RW 32] Debug only: spare RW register reset by core reset */
 | 
				
			||||||
#define MISC_REG_GENERIC_CR_0					 0xa460
 | 
					#define MISC_REG_GENERIC_CR_0					 0xa460
 | 
				
			||||||
 | 
					/* [RW 32] Debug only: spare RW register reset by por reset */
 | 
				
			||||||
 | 
					#define MISC_REG_GENERIC_POR_1					 0xa474
 | 
				
			||||||
/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of
 | 
					/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of
 | 
				
			||||||
   these bits is written as a '1'; the corresponding SPIO bit will turn off
 | 
					   these bits is written as a '1'; the corresponding SPIO bit will turn off
 | 
				
			||||||
   it's drivers and become an input. This is the reset state of all GPIO
 | 
					   it's drivers and become an input. This is the reset state of all GPIO
 | 
				
			||||||
| 
						 | 
					@ -1438,7 +1442,7 @@
 | 
				
			||||||
   (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */
 | 
					   (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */
 | 
				
			||||||
#define MISC_REG_SW_TIMER_RELOAD_VAL_4				 0xa2fc
 | 
					#define MISC_REG_SW_TIMER_RELOAD_VAL_4				 0xa2fc
 | 
				
			||||||
/* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses
 | 
					/* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses
 | 
				
			||||||
   in this register. addres 0 - timer 1; address - timer 2<EFBFBD>address 7 -
 | 
					   in this register. addres 0 - timer 1; address 1 - timer 2, ...  address 7 -
 | 
				
			||||||
   timer 8 */
 | 
					   timer 8 */
 | 
				
			||||||
#define MISC_REG_SW_TIMER_VAL					 0xa5c0
 | 
					#define MISC_REG_SW_TIMER_VAL					 0xa5c0
 | 
				
			||||||
/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
 | 
					/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
 | 
				
			||||||
| 
						 | 
					@ -2407,10 +2411,16 @@
 | 
				
			||||||
/* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means
 | 
					/* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means
 | 
				
			||||||
   this client is waiting for the arbiter. */
 | 
					   this client is waiting for the arbiter. */
 | 
				
			||||||
#define PXP_REG_HST_CLIENTS_WAITING_TO_ARB			 0x103008
 | 
					#define PXP_REG_HST_CLIENTS_WAITING_TO_ARB			 0x103008
 | 
				
			||||||
 | 
					/* [RW 1] When 1; doorbells are discarded and not passed to doorbell queue
 | 
				
			||||||
 | 
					   block. Should be used for close the gates. */
 | 
				
			||||||
 | 
					#define PXP_REG_HST_DISCARD_DOORBELLS				 0x1030a4
 | 
				
			||||||
/* [R 1] debug only: '1' means this PSWHST is discarding doorbells. This bit
 | 
					/* [R 1] debug only: '1' means this PSWHST is discarding doorbells. This bit
 | 
				
			||||||
   should update accoring to 'hst_discard_doorbells' register when the state
 | 
					   should update accoring to 'hst_discard_doorbells' register when the state
 | 
				
			||||||
   machine is idle */
 | 
					   machine is idle */
 | 
				
			||||||
#define PXP_REG_HST_DISCARD_DOORBELLS_STATUS			 0x1030a0
 | 
					#define PXP_REG_HST_DISCARD_DOORBELLS_STATUS			 0x1030a0
 | 
				
			||||||
 | 
					/* [RW 1] When 1; new internal writes arriving to the block are discarded.
 | 
				
			||||||
 | 
					   Should be used for close the gates. */
 | 
				
			||||||
 | 
					#define PXP_REG_HST_DISCARD_INTERNAL_WRITES			 0x1030a8
 | 
				
			||||||
/* [R 6] debug only: A bit mask for all PSWHST internal write clients. '1'
 | 
					/* [R 6] debug only: A bit mask for all PSWHST internal write clients. '1'
 | 
				
			||||||
   means this PSWHST is discarding inputs from this client. Each bit should
 | 
					   means this PSWHST is discarding inputs from this client. Each bit should
 | 
				
			||||||
   update accoring to 'hst_discard_internal_writes' register when the state
 | 
					   update accoring to 'hst_discard_internal_writes' register when the state
 | 
				
			||||||
| 
						 | 
					@ -4422,11 +4432,21 @@
 | 
				
			||||||
#define MISC_REGISTERS_GPIO_PORT_SHIFT				 4
 | 
					#define MISC_REGISTERS_GPIO_PORT_SHIFT				 4
 | 
				
			||||||
#define MISC_REGISTERS_GPIO_SET_POS				 8
 | 
					#define MISC_REGISTERS_GPIO_SET_POS				 8
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_1_CLEAR			 0x588
 | 
					#define MISC_REGISTERS_RESET_REG_1_CLEAR			 0x588
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_1_RST_HC			 (0x1<<29)
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_1_RST_NIG			 (0x1<<7)
 | 
					#define MISC_REGISTERS_RESET_REG_1_RST_NIG			 (0x1<<7)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_1_RST_PXP			 (0x1<<26)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_1_RST_PXPV			 (0x1<<27)
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_1_SET				 0x584
 | 
					#define MISC_REGISTERS_RESET_REG_1_SET				 0x584
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_2_CLEAR			 0x598
 | 
					#define MISC_REGISTERS_RESET_REG_2_CLEAR			 0x598
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_2_RST_BMAC0			 (0x1<<0)
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_BMAC0			 (0x1<<0)
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE		 (0x1<<14)
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE		 (0x1<<14)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE		 (0x1<<15)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_GRC			 (0x1<<4)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B	 (0x1<<6)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE (0x1<<5)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_MDIO			 (0x1<<13)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_MISC_CORE		 (0x1<<11)
 | 
				
			||||||
 | 
					#define MISC_REGISTERS_RESET_REG_2_RST_RBCN			 (0x1<<9)
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_2_SET				 0x594
 | 
					#define MISC_REGISTERS_RESET_REG_2_SET				 0x594
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_3_CLEAR			 0x5a8
 | 
					#define MISC_REGISTERS_RESET_REG_3_CLEAR			 0x5a8
 | 
				
			||||||
#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ	 (0x1<<1)
 | 
					#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ	 (0x1<<1)
 | 
				
			||||||
| 
						 | 
					@ -4454,6 +4474,7 @@
 | 
				
			||||||
#define HW_LOCK_RESOURCE_GPIO					 1
 | 
					#define HW_LOCK_RESOURCE_GPIO					 1
 | 
				
			||||||
#define HW_LOCK_RESOURCE_MDIO					 0
 | 
					#define HW_LOCK_RESOURCE_MDIO					 0
 | 
				
			||||||
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 			 3
 | 
					#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 			 3
 | 
				
			||||||
 | 
					#define HW_LOCK_RESOURCE_RESERVED_08				 8
 | 
				
			||||||
#define HW_LOCK_RESOURCE_SPIO					 2
 | 
					#define HW_LOCK_RESOURCE_SPIO					 2
 | 
				
			||||||
#define HW_LOCK_RESOURCE_UNDI					 5
 | 
					#define HW_LOCK_RESOURCE_UNDI					 5
 | 
				
			||||||
#define PRS_FLAG_OVERETH_IPV4					 1
 | 
					#define PRS_FLAG_OVERETH_IPV4					 1
 | 
				
			||||||
| 
						 | 
					@ -4474,6 +4495,10 @@
 | 
				
			||||||
#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0		      (1<<5)
 | 
					#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0		      (1<<5)
 | 
				
			||||||
#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1		      (1<<9)
 | 
					#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1		      (1<<9)
 | 
				
			||||||
#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR		      (1<<12)
 | 
					#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR		      (1<<12)
 | 
				
			||||||
 | 
					#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY	      (1<<28)
 | 
				
			||||||
 | 
					#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY	      (1<<31)
 | 
				
			||||||
 | 
					#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY	      (1<<29)
 | 
				
			||||||
 | 
					#define AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY	      (1<<30)
 | 
				
			||||||
#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT		      (1<<15)
 | 
					#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT		      (1<<15)
 | 
				
			||||||
#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR		      (1<<14)
 | 
					#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR		      (1<<14)
 | 
				
			||||||
#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR	      (1<<20)
 | 
					#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR	      (1<<20)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,6 @@
 | 
				
			||||||
static void bond_glean_dev_ipv6(struct net_device *dev, struct in6_addr *addr)
 | 
					static void bond_glean_dev_ipv6(struct net_device *dev, struct in6_addr *addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct inet6_dev *idev;
 | 
						struct inet6_dev *idev;
 | 
				
			||||||
	struct inet6_ifaddr *ifa;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!dev)
 | 
						if (!dev)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -47,10 +46,12 @@ static void bond_glean_dev_ipv6(struct net_device *dev, struct in6_addr *addr)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read_lock_bh(&idev->lock);
 | 
						read_lock_bh(&idev->lock);
 | 
				
			||||||
	ifa = idev->addr_list;
 | 
						if (!list_empty(&idev->addr_list)) {
 | 
				
			||||||
	if (ifa)
 | 
							struct inet6_ifaddr *ifa
 | 
				
			||||||
 | 
								= list_first_entry(&idev->addr_list,
 | 
				
			||||||
 | 
										   struct inet6_ifaddr, if_list);
 | 
				
			||||||
		ipv6_addr_copy(addr, &ifa->addr);
 | 
							ipv6_addr_copy(addr, &ifa->addr);
 | 
				
			||||||
	else
 | 
						} else
 | 
				
			||||||
		ipv6_addr_set(addr, 0, 0, 0, 0);
 | 
							ipv6_addr_set(addr, 0, 0, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read_unlock_bh(&idev->lock);
 | 
						read_unlock_bh(&idev->lock);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,6 +59,7 @@
 | 
				
			||||||
#include <linux/uaccess.h>
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
#include <linux/errno.h>
 | 
					#include <linux/errno.h>
 | 
				
			||||||
#include <linux/netdevice.h>
 | 
					#include <linux/netdevice.h>
 | 
				
			||||||
 | 
					#include <linux/netpoll.h>
 | 
				
			||||||
#include <linux/inetdevice.h>
 | 
					#include <linux/inetdevice.h>
 | 
				
			||||||
#include <linux/igmp.h>
 | 
					#include <linux/igmp.h>
 | 
				
			||||||
#include <linux/etherdevice.h>
 | 
					#include <linux/etherdevice.h>
 | 
				
			||||||
| 
						 | 
					@ -430,6 +431,17 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb->priority = 1;
 | 
						skb->priority = 1;
 | 
				
			||||||
 | 
					#ifdef CONFIG_NET_POLL_CONTROLLER
 | 
				
			||||||
 | 
						if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
 | 
				
			||||||
 | 
							struct netpoll *np = bond->dev->npinfo->netpoll;
 | 
				
			||||||
 | 
							slave_dev->npinfo = bond->dev->npinfo;
 | 
				
			||||||
 | 
							np->real_dev = np->dev = skb->dev;
 | 
				
			||||||
 | 
							slave_dev->priv_flags |= IFF_IN_NETPOLL;
 | 
				
			||||||
 | 
							netpoll_send_skb(np, skb);
 | 
				
			||||||
 | 
							slave_dev->priv_flags &= ~IFF_IN_NETPOLL;
 | 
				
			||||||
 | 
							np->dev = bond->dev;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		dev_queue_xmit(skb);
 | 
							dev_queue_xmit(skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -761,32 +773,6 @@ static int bond_check_dev_link(struct bonding *bond,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*----------------------------- Multicast list ------------------------------*/
 | 
					/*----------------------------- Multicast list ------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline int bond_is_dmi_same(const struct dev_mc_list *dmi1,
 | 
					 | 
				
			||||||
				   const struct dev_mc_list *dmi2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
 | 
					 | 
				
			||||||
			dmi1->dmi_addrlen == dmi2->dmi_addrlen;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * returns dmi entry if found, NULL otherwise
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi,
 | 
					 | 
				
			||||||
						 struct dev_mc_list *mc_list)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct dev_mc_list *idmi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (idmi = mc_list; idmi; idmi = idmi->next) {
 | 
					 | 
				
			||||||
		if (bond_is_dmi_same(dmi, idmi))
 | 
					 | 
				
			||||||
			return idmi;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Push the promiscuity flag down to appropriate slaves
 | 
					 * Push the promiscuity flag down to appropriate slaves
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -839,18 +825,18 @@ static int bond_set_allmulti(struct bonding *bond, int inc)
 | 
				
			||||||
 * Add a Multicast address to slaves
 | 
					 * Add a Multicast address to slaves
 | 
				
			||||||
 * according to mode
 | 
					 * according to mode
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void bond_mc_add(struct bonding *bond, void *addr, int alen)
 | 
					static void bond_mc_add(struct bonding *bond, void *addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (USES_PRIMARY(bond->params.mode)) {
 | 
						if (USES_PRIMARY(bond->params.mode)) {
 | 
				
			||||||
		/* write lock already acquired */
 | 
							/* write lock already acquired */
 | 
				
			||||||
		if (bond->curr_active_slave)
 | 
							if (bond->curr_active_slave)
 | 
				
			||||||
			dev_mc_add(bond->curr_active_slave->dev, addr, alen, 0);
 | 
								dev_mc_add(bond->curr_active_slave->dev, addr);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct slave *slave;
 | 
							struct slave *slave;
 | 
				
			||||||
		int i;
 | 
							int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bond_for_each_slave(bond, slave, i)
 | 
							bond_for_each_slave(bond, slave, i)
 | 
				
			||||||
			dev_mc_add(slave->dev, addr, alen, 0);
 | 
								dev_mc_add(slave->dev, addr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -858,18 +844,17 @@ static void bond_mc_add(struct bonding *bond, void *addr, int alen)
 | 
				
			||||||
 * Remove a multicast address from slave
 | 
					 * Remove a multicast address from slave
 | 
				
			||||||
 * according to mode
 | 
					 * according to mode
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
 | 
					static void bond_mc_del(struct bonding *bond, void *addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (USES_PRIMARY(bond->params.mode)) {
 | 
						if (USES_PRIMARY(bond->params.mode)) {
 | 
				
			||||||
		/* write lock already acquired */
 | 
							/* write lock already acquired */
 | 
				
			||||||
		if (bond->curr_active_slave)
 | 
							if (bond->curr_active_slave)
 | 
				
			||||||
			dev_mc_delete(bond->curr_active_slave->dev, addr,
 | 
								dev_mc_del(bond->curr_active_slave->dev, addr);
 | 
				
			||||||
				      alen, 0);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct slave *slave;
 | 
							struct slave *slave;
 | 
				
			||||||
		int i;
 | 
							int i;
 | 
				
			||||||
		bond_for_each_slave(bond, slave, i) {
 | 
							bond_for_each_slave(bond, slave, i) {
 | 
				
			||||||
			dev_mc_delete(slave->dev, addr, alen, 0);
 | 
								dev_mc_del(slave->dev, addr);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -895,50 +880,6 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
 | 
				
			||||||
	rcu_read_unlock();
 | 
						rcu_read_unlock();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Totally destroys the mc_list in bond
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void bond_mc_list_destroy(struct bonding *bond)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dmi = bond->mc_list;
 | 
					 | 
				
			||||||
	while (dmi) {
 | 
					 | 
				
			||||||
		bond->mc_list = dmi->next;
 | 
					 | 
				
			||||||
		kfree(dmi);
 | 
					 | 
				
			||||||
		dmi = bond->mc_list;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bond->mc_list = NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copy all the Multicast addresses from src to the bonding device dst
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond,
 | 
					 | 
				
			||||||
			     gfp_t gfp_flag)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct dev_mc_list *dmi, *new_dmi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (dmi = mc_list; dmi; dmi = dmi->next) {
 | 
					 | 
				
			||||||
		new_dmi = kmalloc(sizeof(struct dev_mc_list), gfp_flag);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!new_dmi) {
 | 
					 | 
				
			||||||
			/* FIXME: Potential memory leak !!! */
 | 
					 | 
				
			||||||
			return -ENOMEM;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		new_dmi->next = bond->mc_list;
 | 
					 | 
				
			||||||
		bond->mc_list = new_dmi;
 | 
					 | 
				
			||||||
		new_dmi->dmi_addrlen = dmi->dmi_addrlen;
 | 
					 | 
				
			||||||
		memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen);
 | 
					 | 
				
			||||||
		new_dmi->dmi_users = dmi->dmi_users;
 | 
					 | 
				
			||||||
		new_dmi->dmi_gusers = dmi->dmi_gusers;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * flush all members of flush->mc_list from device dev->mc_list
 | 
					 * flush all members of flush->mc_list from device dev->mc_list
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -946,16 +887,16 @@ static void bond_mc_list_flush(struct net_device *bond_dev,
 | 
				
			||||||
			       struct net_device *slave_dev)
 | 
								       struct net_device *slave_dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bonding *bond = netdev_priv(bond_dev);
 | 
						struct bonding *bond = netdev_priv(bond_dev);
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next)
 | 
						netdev_for_each_mc_addr(ha, bond_dev)
 | 
				
			||||||
		dev_mc_delete(slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
 | 
							dev_mc_del(slave_dev, ha->addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bond->params.mode == BOND_MODE_8023AD) {
 | 
						if (bond->params.mode == BOND_MODE_8023AD) {
 | 
				
			||||||
		/* del lacpdu mc addr from mc list */
 | 
							/* del lacpdu mc addr from mc list */
 | 
				
			||||||
		u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
 | 
							u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dev_mc_delete(slave_dev, lacpdu_multicast, ETH_ALEN, 0);
 | 
							dev_mc_del(slave_dev, lacpdu_multicast);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -969,7 +910,7 @@ static void bond_mc_list_flush(struct net_device *bond_dev,
 | 
				
			||||||
static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
 | 
					static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
 | 
				
			||||||
			 struct slave *old_active)
 | 
								 struct slave *old_active)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!USES_PRIMARY(bond->params.mode))
 | 
						if (!USES_PRIMARY(bond->params.mode))
 | 
				
			||||||
		/* nothing to do -  mc list is already up-to-date on
 | 
							/* nothing to do -  mc list is already up-to-date on
 | 
				
			||||||
| 
						 | 
					@ -984,9 +925,8 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
 | 
				
			||||||
		if (bond->dev->flags & IFF_ALLMULTI)
 | 
							if (bond->dev->flags & IFF_ALLMULTI)
 | 
				
			||||||
			dev_set_allmulti(old_active->dev, -1);
 | 
								dev_set_allmulti(old_active->dev, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next)
 | 
							netdev_for_each_mc_addr(ha, bond->dev)
 | 
				
			||||||
			dev_mc_delete(old_active->dev, dmi->dmi_addr,
 | 
								dev_mc_del(old_active->dev, ha->addr);
 | 
				
			||||||
				      dmi->dmi_addrlen, 0);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (new_active) {
 | 
						if (new_active) {
 | 
				
			||||||
| 
						 | 
					@ -997,9 +937,8 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
 | 
				
			||||||
		if (bond->dev->flags & IFF_ALLMULTI)
 | 
							if (bond->dev->flags & IFF_ALLMULTI)
 | 
				
			||||||
			dev_set_allmulti(new_active->dev, 1);
 | 
								dev_set_allmulti(new_active->dev, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next)
 | 
							netdev_for_each_mc_addr(ha, bond->dev)
 | 
				
			||||||
			dev_mc_add(new_active->dev, dmi->dmi_addr,
 | 
								dev_mc_add(new_active->dev, ha->addr);
 | 
				
			||||||
				   dmi->dmi_addrlen, 0);
 | 
					 | 
				
			||||||
		bond_resend_igmp_join_requests(bond);
 | 
							bond_resend_igmp_join_requests(bond);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1329,6 +1268,61 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
 | 
				
			||||||
	bond->slave_cnt--;
 | 
						bond->slave_cnt--;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_NET_POLL_CONTROLLER
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * You must hold read lock on bond->lock before calling this.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static bool slaves_support_netpoll(struct net_device *bond_dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bonding *bond = netdev_priv(bond_dev);
 | 
				
			||||||
 | 
						struct slave *slave;
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
						bool ret = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bond_for_each_slave(bond, slave, i) {
 | 
				
			||||||
 | 
							if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL) ||
 | 
				
			||||||
 | 
							    !slave->dev->netdev_ops->ndo_poll_controller)
 | 
				
			||||||
 | 
								ret = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return i != 0 && ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bond_poll_controller(struct net_device *bond_dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct net_device *dev = bond_dev->npinfo->netpoll->real_dev;
 | 
				
			||||||
 | 
						if (dev != bond_dev)
 | 
				
			||||||
 | 
							netpoll_poll_dev(dev);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bond_netpoll_cleanup(struct net_device *bond_dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bonding *bond = netdev_priv(bond_dev);
 | 
				
			||||||
 | 
						struct slave *slave;
 | 
				
			||||||
 | 
						const struct net_device_ops *ops;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						read_lock(&bond->lock);
 | 
				
			||||||
 | 
						bond_dev->npinfo = NULL;
 | 
				
			||||||
 | 
						bond_for_each_slave(bond, slave, i) {
 | 
				
			||||||
 | 
							if (slave->dev) {
 | 
				
			||||||
 | 
								ops = slave->dev->netdev_ops;
 | 
				
			||||||
 | 
								if (ops->ndo_netpoll_cleanup)
 | 
				
			||||||
 | 
									ops->ndo_netpoll_cleanup(slave->dev);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									slave->dev->npinfo = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						read_unlock(&bond->lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bond_netpoll_cleanup(struct net_device *bond_dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*---------------------------------- IOCTL ----------------------------------*/
 | 
					/*---------------------------------- IOCTL ----------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bond_sethwaddr(struct net_device *bond_dev,
 | 
					static int bond_sethwaddr(struct net_device *bond_dev,
 | 
				
			||||||
| 
						 | 
					@ -1411,7 +1405,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 | 
				
			||||||
	struct bonding *bond = netdev_priv(bond_dev);
 | 
						struct bonding *bond = netdev_priv(bond_dev);
 | 
				
			||||||
	const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
 | 
						const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
 | 
				
			||||||
	struct slave *new_slave = NULL;
 | 
						struct slave *new_slave = NULL;
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
	struct sockaddr addr;
 | 
						struct sockaddr addr;
 | 
				
			||||||
	int link_reporting;
 | 
						int link_reporting;
 | 
				
			||||||
	int old_features = bond_dev->features;
 | 
						int old_features = bond_dev->features;
 | 
				
			||||||
| 
						 | 
					@ -1485,14 +1479,27 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 | 
				
			||||||
				 bond_dev->name,
 | 
									 bond_dev->name,
 | 
				
			||||||
				 bond_dev->type, slave_dev->type);
 | 
									 bond_dev->type, slave_dev->type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			netdev_bonding_change(bond_dev, NETDEV_BONDING_OLDTYPE);
 | 
								res = netdev_bonding_change(bond_dev,
 | 
				
			||||||
 | 
											    NETDEV_PRE_TYPE_CHANGE);
 | 
				
			||||||
 | 
								res = notifier_to_errno(res);
 | 
				
			||||||
 | 
								if (res) {
 | 
				
			||||||
 | 
									pr_err("%s: refused to change device type\n",
 | 
				
			||||||
 | 
									       bond_dev->name);
 | 
				
			||||||
 | 
									res = -EBUSY;
 | 
				
			||||||
 | 
									goto err_undo_flags;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Flush unicast and multicast addresses */
 | 
				
			||||||
 | 
								dev_uc_flush(bond_dev);
 | 
				
			||||||
 | 
								dev_mc_flush(bond_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (slave_dev->type != ARPHRD_ETHER)
 | 
								if (slave_dev->type != ARPHRD_ETHER)
 | 
				
			||||||
				bond_setup_by_slave(bond_dev, slave_dev);
 | 
									bond_setup_by_slave(bond_dev, slave_dev);
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				ether_setup(bond_dev);
 | 
									ether_setup(bond_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			netdev_bonding_change(bond_dev, NETDEV_BONDING_NEWTYPE);
 | 
								netdev_bonding_change(bond_dev,
 | 
				
			||||||
 | 
										      NETDEV_POST_TYPE_CHANGE);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (bond_dev->type != slave_dev->type) {
 | 
						} else if (bond_dev->type != slave_dev->type) {
 | 
				
			||||||
		pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it.\n",
 | 
							pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it.\n",
 | 
				
			||||||
| 
						 | 
					@ -1593,9 +1600,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		netif_addr_lock_bh(bond_dev);
 | 
							netif_addr_lock_bh(bond_dev);
 | 
				
			||||||
		/* upload master's mc_list to new slave */
 | 
							/* upload master's mc_list to new slave */
 | 
				
			||||||
		for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next)
 | 
							netdev_for_each_mc_addr(ha, bond_dev)
 | 
				
			||||||
			dev_mc_add(slave_dev, dmi->dmi_addr,
 | 
								dev_mc_add(slave_dev, ha->addr);
 | 
				
			||||||
				   dmi->dmi_addrlen, 0);
 | 
					 | 
				
			||||||
		netif_addr_unlock_bh(bond_dev);
 | 
							netif_addr_unlock_bh(bond_dev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1603,7 +1609,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 | 
				
			||||||
		/* add lacpdu mc addr to mc list */
 | 
							/* add lacpdu mc addr to mc list */
 | 
				
			||||||
		u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
 | 
							u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dev_mc_add(slave_dev, lacpdu_multicast, ETH_ALEN, 0);
 | 
							dev_mc_add(slave_dev, lacpdu_multicast);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bond_add_vlans_on_slave(bond, slave_dev);
 | 
						bond_add_vlans_on_slave(bond, slave_dev);
 | 
				
			||||||
| 
						 | 
					@ -1735,6 +1741,18 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bond_set_carrier(bond);
 | 
						bond_set_carrier(bond);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_NET_POLL_CONTROLLER
 | 
				
			||||||
 | 
						if (slaves_support_netpoll(bond_dev)) {
 | 
				
			||||||
 | 
							bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
 | 
				
			||||||
 | 
							if (bond_dev->npinfo)
 | 
				
			||||||
 | 
								slave_dev->npinfo = bond_dev->npinfo;
 | 
				
			||||||
 | 
						} else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) {
 | 
				
			||||||
 | 
							bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
 | 
				
			||||||
 | 
							pr_info("New slave device %s does not support netpoll\n",
 | 
				
			||||||
 | 
								slave_dev->name);
 | 
				
			||||||
 | 
							pr_info("Disabling netpoll support for %s\n", bond_dev->name);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	read_unlock(&bond->lock);
 | 
						read_unlock(&bond->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res = bond_create_slave_symlinks(bond_dev, slave_dev);
 | 
						res = bond_create_slave_symlinks(bond_dev, slave_dev);
 | 
				
			||||||
| 
						 | 
					@ -1801,6 +1819,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE);
 | 
				
			||||||
	write_lock_bh(&bond->lock);
 | 
						write_lock_bh(&bond->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	slave = bond_get_slave_by_dev(bond, slave_dev);
 | 
						slave = bond_get_slave_by_dev(bond, slave_dev);
 | 
				
			||||||
| 
						 | 
					@ -1929,6 +1948,17 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netdev_set_master(slave_dev, NULL);
 | 
						netdev_set_master(slave_dev, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_NET_POLL_CONTROLLER
 | 
				
			||||||
 | 
						read_lock_bh(&bond->lock);
 | 
				
			||||||
 | 
						if (slaves_support_netpoll(bond_dev))
 | 
				
			||||||
 | 
							bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
 | 
				
			||||||
 | 
						read_unlock_bh(&bond->lock);
 | 
				
			||||||
 | 
						if (slave_dev->netdev_ops->ndo_netpoll_cleanup)
 | 
				
			||||||
 | 
							slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							slave_dev->npinfo = NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* close slave before restoring its mac address */
 | 
						/* close slave before restoring its mac address */
 | 
				
			||||||
	dev_close(slave_dev);
 | 
						dev_close(slave_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3905,10 +3935,24 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool bond_addr_in_mc_list(unsigned char *addr,
 | 
				
			||||||
 | 
									 struct netdev_hw_addr_list *list,
 | 
				
			||||||
 | 
									 int addrlen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						netdev_hw_addr_list_for_each(ha, list)
 | 
				
			||||||
 | 
							if (!memcmp(ha->addr, addr, addrlen))
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bond_set_multicast_list(struct net_device *bond_dev)
 | 
					static void bond_set_multicast_list(struct net_device *bond_dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bonding *bond = netdev_priv(bond_dev);
 | 
						struct bonding *bond = netdev_priv(bond_dev);
 | 
				
			||||||
	struct dev_mc_list *dmi;
 | 
						struct netdev_hw_addr *ha;
 | 
				
			||||||
 | 
						bool found;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Do promisc before checking multicast_mode
 | 
						 * Do promisc before checking multicast_mode
 | 
				
			||||||
| 
						 | 
					@ -3943,20 +3987,25 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
 | 
				
			||||||
	bond->flags = bond_dev->flags;
 | 
						bond->flags = bond_dev->flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* looking for addresses to add to slaves' mc list */
 | 
						/* looking for addresses to add to slaves' mc list */
 | 
				
			||||||
	for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
 | 
						netdev_for_each_mc_addr(ha, bond_dev) {
 | 
				
			||||||
		if (!bond_mc_list_find_dmi(dmi, bond->mc_list))
 | 
							found = bond_addr_in_mc_list(ha->addr, &bond->mc_list,
 | 
				
			||||||
			bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen);
 | 
										     bond_dev->addr_len);
 | 
				
			||||||
 | 
							if (!found)
 | 
				
			||||||
 | 
								bond_mc_add(bond, ha->addr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* looking for addresses to delete from slaves' list */
 | 
						/* looking for addresses to delete from slaves' list */
 | 
				
			||||||
	for (dmi = bond->mc_list; dmi; dmi = dmi->next) {
 | 
						netdev_hw_addr_list_for_each(ha, &bond->mc_list) {
 | 
				
			||||||
		if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list))
 | 
							found = bond_addr_in_mc_list(ha->addr, &bond_dev->mc,
 | 
				
			||||||
			bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen);
 | 
										     bond_dev->addr_len);
 | 
				
			||||||
 | 
							if (!found)
 | 
				
			||||||
 | 
								bond_mc_del(bond, ha->addr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* save master's multicast list */
 | 
						/* save master's multicast list */
 | 
				
			||||||
	bond_mc_list_destroy(bond);
 | 
						__hw_addr_flush(&bond->mc_list);
 | 
				
			||||||
	bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC);
 | 
						__hw_addr_add_multiple(&bond->mc_list, &bond_dev->mc,
 | 
				
			||||||
 | 
								       bond_dev->addr_len, NETDEV_HW_ADDR_T_MULTICAST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read_unlock(&bond->lock);
 | 
						read_unlock(&bond->lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4448,6 +4497,10 @@ static const struct net_device_ops bond_netdev_ops = {
 | 
				
			||||||
	.ndo_vlan_rx_register	= bond_vlan_rx_register,
 | 
						.ndo_vlan_rx_register	= bond_vlan_rx_register,
 | 
				
			||||||
	.ndo_vlan_rx_add_vid 	= bond_vlan_rx_add_vid,
 | 
						.ndo_vlan_rx_add_vid 	= bond_vlan_rx_add_vid,
 | 
				
			||||||
	.ndo_vlan_rx_kill_vid	= bond_vlan_rx_kill_vid,
 | 
						.ndo_vlan_rx_kill_vid	= bond_vlan_rx_kill_vid,
 | 
				
			||||||
 | 
					#ifdef CONFIG_NET_POLL_CONTROLLER
 | 
				
			||||||
 | 
						.ndo_netpoll_cleanup	= bond_netpoll_cleanup,
 | 
				
			||||||
 | 
						.ndo_poll_controller	= bond_poll_controller,
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bond_destructor(struct net_device *bond_dev)
 | 
					static void bond_destructor(struct net_device *bond_dev)
 | 
				
			||||||
| 
						 | 
					@ -4541,6 +4594,8 @@ static void bond_uninit(struct net_device *bond_dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bonding *bond = netdev_priv(bond_dev);
 | 
						struct bonding *bond = netdev_priv(bond_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bond_netpoll_cleanup(bond_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Release the bonded slaves */
 | 
						/* Release the bonded slaves */
 | 
				
			||||||
	bond_release_all(bond_dev);
 | 
						bond_release_all(bond_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4550,9 +4605,7 @@ static void bond_uninit(struct net_device *bond_dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bond_remove_proc_entry(bond);
 | 
						bond_remove_proc_entry(bond);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_addr_lock_bh(bond_dev);
 | 
						__hw_addr_flush(&bond->mc_list);
 | 
				
			||||||
	bond_mc_list_destroy(bond);
 | 
					 | 
				
			||||||
	netif_addr_unlock_bh(bond_dev);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*------------------------- Module initialization ---------------------------*/
 | 
					/*------------------------- Module initialization ---------------------------*/
 | 
				
			||||||
| 
						 | 
					@ -4683,13 +4736,13 @@ static int bond_check_params(struct bond_params *params)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (num_grat_arp < 0 || num_grat_arp > 255) {
 | 
						if (num_grat_arp < 0 || num_grat_arp > 255) {
 | 
				
			||||||
		pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1 \n",
 | 
							pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1\n",
 | 
				
			||||||
			   num_grat_arp);
 | 
								   num_grat_arp);
 | 
				
			||||||
		num_grat_arp = 1;
 | 
							num_grat_arp = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (num_unsol_na < 0 || num_unsol_na > 255) {
 | 
						if (num_unsol_na < 0 || num_unsol_na > 255) {
 | 
				
			||||||
		pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1 \n",
 | 
							pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
 | 
				
			||||||
			   num_unsol_na);
 | 
								   num_unsol_na);
 | 
				
			||||||
		num_unsol_na = 1;
 | 
							num_unsol_na = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -4924,6 +4977,8 @@ static int bond_init(struct net_device *bond_dev)
 | 
				
			||||||
	list_add_tail(&bond->bond_list, &bn->dev_list);
 | 
						list_add_tail(&bond->bond_list, &bn->dev_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bond_prepare_sysfs_group(bond);
 | 
						bond_prepare_sysfs_group(bond);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__hw_addr_init(&bond->mc_list);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,7 +202,7 @@ struct bonding {
 | 
				
			||||||
	char     proc_file_name[IFNAMSIZ];
 | 
						char     proc_file_name[IFNAMSIZ];
 | 
				
			||||||
#endif /* CONFIG_PROC_FS */
 | 
					#endif /* CONFIG_PROC_FS */
 | 
				
			||||||
	struct   list_head bond_list;
 | 
						struct   list_head bond_list;
 | 
				
			||||||
	struct   dev_mc_list *mc_list;
 | 
						struct   netdev_hw_addr_list mc_list;
 | 
				
			||||||
	int      (*xmit_hash_policy)(struct sk_buff *, int);
 | 
						int      (*xmit_hash_policy)(struct sk_buff *, int);
 | 
				
			||||||
	__be32   master_ip;
 | 
						__be32   master_ip;
 | 
				
			||||||
	u16      flags;
 | 
						u16      flags;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								drivers/net/caif/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								drivers/net/caif/Kconfig
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# CAIF physical drivers
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if CAIF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					comment "CAIF transport drivers"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config CAIF_TTY
 | 
				
			||||||
 | 
						tristate "CAIF TTY transport driver"
 | 
				
			||||||
 | 
						default n
 | 
				
			||||||
 | 
						---help---
 | 
				
			||||||
 | 
						The CAIF TTY transport driver is a Line Discipline (ldisc)
 | 
				
			||||||
 | 
						identified as N_CAIF. When this ldisc is opened from user space
 | 
				
			||||||
 | 
						it will redirect the TTY's traffic into the CAIF stack.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endif # CAIF
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue