lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080217100300.4de13078@osprey.hogchain.net>
Date:	Sun, 17 Feb 2008 10:03:00 -0600
From:	Jay Cliburn <jacliburn@...lsouth.net>
To:	"Subbu Seetharaman" <subbus@...verengines.com>
Cc:	netdev@...r.kernel.org
Subject: Re: [PATHCH 1/16]  ServerEngines 10Gb NIC driver



On Sat, 16 Feb 2008 18:30:31 -0800
"Subbu Seetharaman" <subbus@...verengines.com> wrote:

At least one patch is corrupt and won't apply.


jcliburn@...rey:~/kernel-work/linux-2.6.git$ git-am ~/Desktop/bes/*

Applying ServerEngines 10Gb NIC driver

Wrote tree b1ecce4b33eb3dbb3d0785f3ab853f0b1102f2ad
Committed: 8a4bff06c085e2d131c4d95487d5363a8a2db438

Applying ServerEngines 10Gb NIC driver

Wrote tree 2b24436f71bda6986d752ac239ecdf3e5a73c488
Committed: 552235405edc310e25441eb1d301511b3e1bc35f

Applying ServerEngines 10Gb NIC driver

Wrote tree 9c6298ac1d1bd7356f0c2afb9404fd8937df2b79
Committed: e586bba1963d80c1b4e798117bbf4cef281864b1

Applying ServerEngines 10Gb NIC driver

Wrote tree da1742e47795eeb99a19d8f5d5b86dc3e45f40d1
Committed: 6ec3655d569cdc240557f52de80fee12c4a9a4b5

Applying ServerEngines 10Gb NIC driver

Wrote tree 2fe60b30217ae99ce06082cbc0ac1a80177b337a
Committed: a0e6eeed7f262ab757a3b3cb304c8afb4e4f4f6a

Applying ServerEngines 10Gb NIC driver

Adds trailing whitespace.
.dotest/patch:36: * Autogenerated by srcgen version: 0127  */ #ifndef 
Adds trailing whitespace.
.dotest/patch:52:   /* iSCSI Completion Queue Entry definition for cmd/cxn level 
Adds trailing whitespace.
.dotest/patch:77:   /* iSCSI Completion Queue Entry definition for cmd/cxn level 
Adds trailing whitespace.
.dotest/patch:99:SG_C_ASSERT(__sizeof__ISCSI_CQ_ENTRY, sizeof(ISCSI_CQ_ENTRY) == 16); 
Adds trailing whitespace.
.dotest/patch:305:   /* iSCSI Completion Queue Entry definition for driver msg 
fatal: corrupt patch at line 633
Patch failed at 0006.
When you have resolved this problem run "git-am --resolved".
If you would prefer to skip this patch, instead run "git-am --skip".


> NIC driver header files, h/w initialization function and
> driver entry points.

Need Signed-off-by.

General comments:

1.  See Documentation/Submit* for patch submittal guidelines.

2,  Run scripts/checkpatch.pl and try to eliminate the errors it
reports.  You might not reach zero errors, but you shouldn't have
hundreds like you do now.

3.  I highly recommend you use git.  It will greatly simplify your
patch submittals to lkml.

4.  Avoid typedefs (you have hundreds).

5.  Avoid bitfields.

6.  Reorder code to minimize forward declarations.

A few other comments inline below.

> 
> ------------------------------
> diff -uprN orig/linux-2.6.24.2/drivers/net/benet/be.h
> benet/linux-2.6.24.2/drivers/net/benet/be.h ---
> orig/linux-2.6.24.2/drivers/net/benet/be.h	1970-01-01
> 05:30:00.000000000 +0530 +++
> benet/linux-2.6.24.2/drivers/net/benet/be.h	2008-02-14
> 15:23:07.787208928 +0530 @@ -0,0 +1,373 @@ +/*
> + * Copyright (C) 2005 - 2008 ServerEngines
> + * All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or at your option any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> + * See the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, 5th Floor
> + * Boston, MA 02110-1301 USA
> + *
> + *
> + * The full GNU General Public License is included in this
> distribution
> + * in the file called GPL.
> + *
> + * Contact Information:
> + * linux-drivers@...verengines.com
> + *
> + * ServerEngines
> + * 209 N. Fair Oaks Ave
> + * Sunnyvale, CA 94085
> + *
> + */
> +#ifndef _BE_H
> +#define _BE_H
> +
> +#include <linux/netdevice.h>
> +#include "bni.h"
> +
> +typedef union _PHYSICAL_ADDRESS {
> +	struct {
> +		u32 pa_lo;
> +		u32 pa_hi;
> +	};
> +	u64 pa;
> +} PHYSICAL_ADDRESS;
> +
> +#define BE_ETHERNET_FCS_SIZE    		4

include/linux/if_ether.h already provides some of these.

> +#define BE_ENET_HEADER_SIZE     		14
> +#define BE_VLAN_HEADER_SIZE     		4
> +#define BE_SNAP_HEADER_SIZE     		5
> +#define BE_HEADER_ETHERNET_II_802_3_SIZE 	14
> +#define BE_HEADER_802_2_SIZE    		3
> +#define BE_MIN_ETHER_FRAME_SIZE 		64
> +#define BE_MIN_SUPPORT_FRAME_SIZE 		256
> +#define BE_MAX_JUMBO_FRAME_SIZE 		9000
> +#define BE_MAXIMUM_ETHERNET_FRAME_SIZE  	1518	/*With
> FCS */ +
> +extern unsigned int dbg_mask;
> +extern unsigned int pm_resume;
> +
> +extern char be_drvr_ver[];
> +extern char be_fw_ver[];
> +extern char be_driver_name[];
> +
> +typedef enum {
> +	BE_DEVICE_1,
> +	BE_DEVICE_2,
> +	MAX_BE_DEVICES
> +} BE_DEVICE_NUM;
> +
> +typedef enum {
> +	BE_DEV_STATE_NONE,
> +	BE_DEV_STATE_INIT,
> +	BE_DEV_STATE_OPEN
> +} BE_DEV_STATE;
> +
> +#define BE_DEV_STATE_OPEN(adapter) (adapter->dev_state ==
> BE_DEV_STATE_OPEN) +
> +/*
> + * BE driver statistics.
> + */
> +struct _be_stat {
> +	u32 bes_tx_reqs;	/* number of TX requests initiated */
> +	u32 bes_tx_fails;	/* number of TX requests that
> failed */
> +	u32 bes_fwd_reqs;	/* number of send reqs through
> forwarding i/f */
> +	u32 bes_tx_wrbs;	/* number of tx WRBs used */
> +
> +	u32 bes_ints;		/* number of interrupts */
> +	u32 bes_polls;		/* number of times NAPI called
> poll function */
> +	u32 bes_events;		/* total evet entries
> processed */
> +	u32 bes_tx_events;	/* number of tx completion events
> */
> +	u32 bes_ucrx_events;	/* number of ucast rx completion
> events  */
> +	u32 bes_bcrx_events;	/* number of bcast rx completion
> events  */
> +	u32 bes_tx_compl;	/* number of tx completion entries
> processed */
> +	u32 bes_ucrx_compl;	/* number of ucrx completion
> entries
> +				   processed */
> +	u32 bes_bcrx_compl;	/* number of bcrx completion
> entries
> +				   processed */
> +	u32 bes_ethrx_post_fail;	/* number of ethrx buffer
> alloc
> +					   failures */
> +	/*
> +	 *
> +	 * number of non ether type II frames dropped where
> +	 * frame len > length field of Mac Hdr
> +	 */
> +	u32 bes_802_3_dropped_frames;
> +	/*
> +	 * number of non ether type II frames malformed where
> +	 * in frame len < length field of Mac Hdr
> +	 */
> +	u32 bes_802_3_malformed_frames;
> +	u32 bes_ips;		/*  interrupts / sec */
> +	u32 bes_prev_ints;	/* bes_ints at last IPS
> calculation  */
> +	u16 bes_eth_tx_rate;	/*  ETH TX rate - Mb/sec */
> +	u16 bes_eth_rx_rate;	/*  ETH RX rate - Mb/sec */
> +#ifdef RX_PKT_COALESCE
> +	u32 bes_rx_coal;	/* Num pkts coalasced */
> +	u32 bes_rx_flush;	/* Num times coalasced */
> +#endif
> +	u32 bes_link_change_physical;	/*Num of times physical
> link changed */
> +	u32 bes_link_change_virtual;	/*Num of times virtual
> link changed */ +};
> +
> +/* Macro to update RX/TX rates */
> +#define UPDATE_RATE(AP, JIF, BYTES, RATE)
> 				\
> +		if ((jiffies - AP->JIF) > 2*(HZ))
> { 			\
> +			u32
> r;						\
> +			r = AP->BYTES /
> ((jiffies-AP->JIF)/(HZ));	\
> +			r = (r / 1000000); /* MB/Sec
> */			\
> +			AP->be_stat.RATE = (r * 8); /* Mega Bits/Sec
> */	\
> +			AP->JIF =
> jiffies;				\
> +			AP->BYTES =
> 0;					\
> +		}
> +
> +/*
> + * Every second we look at the ints/sec and adjust eq_delay
> + * between AP->min_eqd and AP->max_eqd to keep the ints/sec between
> + * IPS_HI_WM and IPS_LO_WM.
> + */
> +#define IPS_HI_WM	18000
> +#define IPS_LO_WM	8000
> +#define UPDATE_IPS(AP, NP)
> 						\
> +		if ((jiffies - AP->ips_jiffies) > 1*(HZ))
> {		\
> +			/* One second elapsed since last
> update	 */	\
> +			u32 r, new_eqd =
> -1;				\
> +			if (AP->be_stat.bes_prev_ints >
> 		\
> +					AP->be_stat.bes_ints)
> {		\
> +				/* interrupt counter wrapped aroud
> */	\
> +				r = (0xFFFFFFFF -
> 			\
> +					AP->be_stat.bes_prev_ints)
> +	\
> +
> AP->be_stat.bes_ints;		\
> +			}
> \
> +
> else						\
> +				r = AP->be_stat.bes_ints -
> 		\
> +
> AP->be_stat.bes_prev_ints;	\
> +			r =  r / ((jiffies -
> AP->ips_jiffies)/(HZ));	\
> +			AP->be_stat.bes_ips =
> r;			\
> +			AP->ips_jiffies =
> jiffies;			\
> +			AP->be_stat.bes_prev_ints =
> 			\
> +
> AP->be_stat.bes_ints;	\
> +			if (r > IPS_HI_WM &&
> 				\
> +					AP->cur_eqd < AP->max_eqd)
> {	\
> +				/* increase eqdelay by a notch
> */	\
> +				new_eqd = (AP->cur_eqd +
> 8);		\
> +			}
> \
> +			if (r < IPS_LO_WM &&
> 				\
> +					AP->cur_eqd > AP->min_eqd)
> {	\
> +				/* decrease eqdelay by a notch
> */	\
> +				new_eqd = (AP->cur_eqd -
> 8);		\
> +			}
> \
> +			if (AP->enable_aic && new_eqd != -1)
> {		\
> +				/* program new delay
> */			\
> +				if (bni_change_eqd(NP, new_eqd) ==
> 	\
> +						BE_SUCCESS)
> 		\
> +					AP->cur_eqd =
> new_eqd;		\
> +			}
> \
> +		}
> +
> +#define FAIL	1
> +#define	SUCCESS	0
> +
> +#define MAX_EQD				120
> +
> +/*
> + * timer to prevent system shutdown hang for ever if h/w stops
> responding
> + */
> +typedef struct {
> +	atomic_t get_stat_flag;
> +	struct timer_list get_stats_timer;
> +	unsigned long get_stat_sem;	/* semaphore to wait  */
> +} be_timer_ctxt_t;
> +
> +#ifdef RX_PKT_COALESCE
> +#define MAX_COALESCE_SIZE	48*1024
> +#define MAX_COALESCE_FRAGS	(MAX_SKB_FRAGS - 1)
> +#define MAX_COALESCE_OBJECTS	8
> +/* struture to keep track of adjacent packets in a connection that
> + * can be colesced to a larger packet during RX completion
> processing.
> + */
> +struct be_coalesce_object {
> +	PBNI_NET_OBJECT pnob;
> +	struct sk_buff *skb;
> +	unsigned int frag_cnt;
> +	unsigned int next_pkt_seq;
> +	unsigned int next_ack_seq;
> +	unsigned int tcp_timestamp;
> +	unsigned int tcp_tsecr;
> +	unsigned int tcp_tsval;
> +	unsigned short sport;
> +	unsigned short dport;
> +	unsigned int saddr;
> +	unsigned int daddr;
> +	unsigned short last_seen_window;
> +	unsigned short mss;
> +	unsigned short vlant;
> +	unsigned short rsvd;
> +
> +};
> +#endif /* RX_PKT_COALESCE */
> +
> +/* This structure is the main BladeEngine driver context.  */
> +typedef struct _BE_ADAPTER {
> +	struct net_device *netdevp;
> +	struct _be_stat be_stat;
> +	struct net_device_stats benet_stats;
> +	u32 num_bars;
> +	SA_DEV_BAR_LOCATIONS pci_bars[3];	/* PCI BAR details
> */ +#ifdef CONFIG_PM
> +	u32 pci_state[16];
> +#endif
> +	SA_DEV sa_device;	/* device object owned by beclib */
> +	BE_CHIP_OBJECT chip_object;	/* BEClib chip object  */
> +
> +	struct tasklet_struct sts_handler;
> +	struct timer_list cq_timer;
> +	spinlock_t int_lock;
> +
> +	PIOCTL_ETH_GET_STATISTICS eth_statsp;
> +	/*
> +	 * This will enable the use of ethtool to enable or disable
> +	 * Checksum on Rx pkts to be obeyed or disobeyed.
> +	 * If this is TRUE = 1, then whatever is the checksum on the
> +	 * Received pkt as per BE, it will be given to the stack.
> +	 * Else the stack will re calculate it.
> +	 */
> +	BOOLEAN rx_csum;

Use bool, already provided in include/linux/types.h

> +#ifdef RX_PKT_COALESCE
> +	/*
> +	 * This will enable the use of ethtool to enable or disable
> +	 * Coalese on Rx pkts to be obeyed or disobeyed.
> +	 * If this is grater than 0 and less than 16 then coalascing
> +	 * is enabled else it is disabled
> +	 */
> +	u32 max_rx_coal;
> +#endif
> +	struct pci_dev *pdev;	/* Pointer to OS's PCI dvice */
> +
> +	spinlock_t txq_lock;
> +
> +	u32 isr;		/* copy of Intr status reg. */
> +
> +	u32 port0_link_sts;	/* Port 0 link status */
> +	u32 port1_link_sts;	/* port 1 list status */
> +	PBE_LINK_STATUS be_link_sts;
> +	PBNI_NET_OBJECT net_obj;
> +
> +	/*  Flags to indicate what to clean up */
> +	BOOLEAN tasklet_started;
> +	BOOLEAN isr_registered;
> +	/*
> +	 * adaptive interrupt coalescing (AIC) related
> +	 */
> +	u16 enable_aic;		/* 1 if AIC is enabled */
> +	u16 min_eqd;		/* minimum EQ delay in usec */
> +	u16 max_eqd;		/* minimum EQ delay in usec */
> +	u16 cur_eqd;		/* current EQ delay in usec */
> +	/*
> +	 * book keeping for interrupt / sec and TX/RX rate
> calculation
> +	 */
> +	ulong ips_jiffies;	/* jiffies at last IPS calc */
> +	u32 eth_tx_bytes;
> +	ulong eth_tx_jiffies;
> +	u32 eth_rx_bytes;
> +	ulong eth_rx_jiffies;
> +
> +	struct semaphore get_eth_stat_sem;
> +	be_timer_ctxt_t *ctxt;	/* context for get stats timer
> */ +
> +#define BE_MAX_MSIX_VECTORS             32
> +#define BE_MAX_REQ_MSIX_VECTORS         1
> +	struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
> +	BOOLEAN msix_enabled;	/*MSI has been enabled */
> +	BOOLEAN dma_64bit_cap;	/* is the Device DAC capable */
> +	int be_fw_ver;		/* BE F/W version */
> +	BOOLEAN dev_state;	/* The current state of the device

bool

> */ +
> +} BE_ADAPTER, *PBE_ADAPTER;
> +
> +extern PBE_ADAPTER be_adapter[MAX_BE_DEVICES];
> +
> +typedef struct be_rx_page_info {
> +	struct page *page;
> +	dma_addr_t bus;
> +	u16 page_offset;
> +} BE_RX_PAGE_INFO;
> +
> +/*
> + * linux_net_object is an extension to BNI's NetObject structure.
> + * NetObject has a pointer to this structure
> + */
> +typedef struct {
> +	PVOID os_handle;	/* Context info for VMM */
> +	BNI_RECV_BUFFER eth_rx_bufs[256];	/* to pass Rx buffer
> +						   addresses */
> +	PBE_ADAPTER adapter;	/* Pointer to OSM adapter */
> +	u32 devno;		/* OSM, network dev no. */
> +	u32 use_port;		/* Current active port */
> +	BE_RX_PAGE_INFO *rx_page_info;	/* Array of Rx buf
> pages */
> +	u32 rx_pg_info_hd;	/* Head of queue */
> +	int rxbuf_post_fail;	/* RxBuff posting fail count */
> +	BOOLEAN rx_pg_shared;	/* Is an allocsted page shared
> as two frags ? */
> +	struct vlan_group *vlan_grp;
> +	u32 num_vlans;		/* Number of vlans in BE's
> filter */
> +	u16 vlan_tag[BE_NUM_VLAN_SUPPORTED]; /* vlans currently
> configured */ +#ifdef CONFIG_BENET_NAPI
> +	struct napi_struct napi;
> +	u32 work_quota;		/* Max RX packets to process
> */
> +	BOOLEAN rx_sched;

bool

> +	spinlock_t rx_lock;
> +#endif
> +#ifdef RX_PKT_COALESCE
> +	struct be_coalesce_object rxc_obj[MAX_COALESCE_OBJECTS];
> +	u32 num_coalesce_objects;
> +#endif
> +} linux_net_object_t;
> +
> +/* convenience macro to access members in Linux extension of
> NetObject */ +#define OSM_NOB(x)	((linux_net_object_t *)
> (x)->osm_netobj) +
> +/* proto declarations */

Please reorder your code to minimize the need for forward declarations.

> +
> +int benet_probe(struct net_device *netdev);
> +void be_set_ethtool_ops(struct net_device *netdev);
> +int be_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr);
> +struct net_device_stats *benet_get_stats(struct net_device *);
> +
> +int be_prepare_interface(PBE_ADAPTER adapter);
> +void cleanup_netobject(PBNI_NET_OBJECT);
> +void osm_process_sts(unsigned long context);
> +irqreturn_t be_int(int irq, PVOID dev, struct pt_regs *regs);
> +
> +int betx_ether_frame(PBE_ADAPTER pBeAdapter, PBNI_NET_OBJECT
> NetObject,
> +		     struct sk_buff *skb, u8 proto, u8 forward,
> +		     u16 lso_mss);
> +
> +void post_eth_rx_buffs(PBNI_NET_OBJECT NetObject);
> +void get_stat_cb(PVOID context, BESTATUS status, MCC_WRB
> *optional_wrb); +
> +void get_stats_timer_handler(unsigned long context);
> +
> +void enable_eq_intr(PBNI_NET_OBJECT pnob);
> +void disable_eq_intr(PBNI_NET_OBJECT pnob);
> +
> +void wait_nic_tx_cmpl(PBNI_NET_OBJECT pnob);
> +void be_print_link_info(PBE_LINK_STATUS lnk_status);
> +void be_update_link_status(PBE_ADAPTER adapter);
> +
> +void be_init_procfs(PBE_ADAPTER adapter);
> +void be_cleanup_procfs(PBE_ADAPTER adapter);
> +
> +#ifdef CONFIG_BENET_NAPI
> +int be_poll(struct napi_struct *napi, int budget);
> +#endif
> +#endif /* _BE_H */
> diff -uprN orig/linux-2.6.24.2/drivers/net/benet/bni.h
> benet/linux-2.6.24.2/drivers/net/benet/bni.h ---
> orig/linux-2.6.24.2/drivers/net/benet/bni.h	1970-01-01
> 05:30:00.000000000 +0530 +++
> benet/linux-2.6.24.2/drivers/net/benet/bni.h	2008-02-14
> 15:23:07.788208776 +0530 @@ -0,0 +1,374 @@ +/*
> + * Copyright (C) 2005 - 2008 ServerEngines
> + * All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or at your option any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> + * See the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, 5th Floor
> + * Boston, MA 02110-1301 USA
> + *
> + *
> + * The full GNU General Public License is included in this
> distribution
> + * in the file called GPL.
> + *
> + * Contact Information:
> + * linux-drivers@...verengines.com
> + *
> + * ServerEngines
> + * 209 N. Fair Oaks Ave
> + * Sunnyvale, CA 94085
> + *
> + */
> +/*
> +
> +@...e
> +    bni.h
> +
> +@...ef
> +    Definitions and macros that are required for all .c files
> +    that use the BNI API and implement the BNI API functions
> +*/
> +#ifndef _BNI_H
> +#define _BNI_H
> +
> +#define _SA_MODULE_NAME "net-driver"
> +#include "beclib_ll.h"
> +
> +#define VLAN_VALID_BIT		0x8000
> +#define BE_NUM_VLAN_SUPPORTED	32
> +#define BE_PORT_LINK_DOWN       0000
> +#define BE_PORT_LINK_UP         0001
> +
> +typedef unsigned char BOOLEAN;

typedef, bool.

> +
> +#define TOU32(_struct_) *((u32 *)(&(_struct_)))
> +
> +/*
> + * DLs used by the Network driver. 0x00000000 to 0x00000800 are used
> + * by SA/BECLIB
> + */
> +typedef enum _NETD_DEBUG_LEVELS {
> +	DL_ERROR = DL_ERR,
> +	DL_EVENT = 0x00001000,
> +	DL_CQ = 0x00002000,
> +	DL_SEND = 0x00004000,
> +	DL_RECV = 0x00008000,
> +	DL_WINDOW = 0x00010000,
> +	DL_OFFLOAD = 0x00020000,
> +	DL_UPLOAD = 0x00040000,
> +	DL_VLAN = 0x00080000,
> +	DL_IPSEC = 0x00100000,
> +	DL_INT = 0x00200000,
> +	DL_PNP = 0x00400000,
> +	DL_ETH_INFO = 0x00800000,
> +	DL_TIMER = 0x01000000,
> +	DL_INIT = 0x02000000,
> +	DL_SHUTDOWN = 0x04000000,
> +} NET_DEBUG_LEVELS;
> +
> +/*
> + * Structure to return Ethernet statistics counters maintained by BE.
> + * Defined in srcgen.
> + */
> +typedef BE_RXF_STATS BLADE_ETH_STATS, *PBLADE_ETH_STATS;
> +
> +/*
> +@...ef
> +    This structure is used by the OSM driver to give BNI
> +    physical fragments to use for DMAing data from NIC.
> +*/
> +typedef struct _BNI_RECV_BUFFER {
> +	SA_LIST_ENTRY rxb_list;	/* for maintaining a linked
> list */
> +	PVOID rxb_va;		/* buffer virtual address */
> +	u32 rxb_pa_lo;		/* low part of physical
> address */
> +	u32 rxb_pa_hi;		/* high part of physical
> address */
> +	u32 rxb_len;		/* length of recv buffer */
> +	PVOID rxb_ctxt;		/* context for OSM driver to
> use */ +} BNI_RECV_BUFFER, *PBNI_RECV_BUFFER;
> +
> +/*
> + * fragment list to describe scattered data.
> + */
> +typedef struct _BNI_TX_FRAG_LIST {
> +	u32 txb_len;		/* Size of this fragment */
> +	u32 txb_pa_lo;		/* Lower 32 bits of 64 bit
> physical addr */
> +	u32 txb_pa_hi;		/* Higher 32 bits of 64 bit
> physical addr */ +} BNI_TX_FRAG_LIST, *PBNI_TX_FRAG_LIST;
> +/*
> + * maximum fragements in a TX request
> + */
> +#define	BE_MAX_TX_FRAG_COUNT		(30)
> +
> +/*
> + * Flag bits for send operation
> + */
> +#define IPCS            (1 << 0)	/* Enable IP checksum
> offload */ +#define UDPCS           (1 << 1)	/* Enable UDP
> checksum offload */ +#define TCPCS           (1 << 2)	/*
> Enable TCP checksum offload */ +#define LSO             (1 <<
> 3)	/* Enable Large Segment  offload */ +#define
> ETHVLAN         (1 << 4)	/* Enable VLAN insert */ +#define
> ETHEVENT        (1 << 5)	/* Generate  event on completion */
> +#define ETHCOMPLETE     (1 << 6)	/* Generate completion when
> done */ +#define IPSEC           (1 << 7)	/* Enable IPSEC */
> +#define FORWARD         (1 << 8)	/* Send the packet in
> forwarding path */ +#define FIN             (1 << 9)	/* Issue
> FIN segment */ + +/* @brief
> + *  This structure is the main tracking structure for a NIC
> interface.
> + *  This data structure contains OS agnostic data members for
> processing
> + *  intialization, sends, receives, and asynchronous events from the
> + *  BladeEngine network function. The OSM driver makes
> + *  calls into functions defined at this layer for initialization,
> + *  eumeration and population of physical fragments with per-packet
> + *  control flags for send and receive operations, population of
> + *  receive buffers for NIC , and handling asynchronous
> + *  events (such as link status change, packet pattern recognition
> etc.).
> + */
> +typedef struct _BNI_NET_OBJECT {
> +
> +	/*
> +	 * MCC Ring - used to send ioctl cmds to embedded ARM
> processor
> +	 */
> +	PMCC_WRB mcc_q;			/* VA of the start of
> the ring */
> +	u32 mcc_q_len;			/* # of WRB entries in
> this ring */
> +	u32 mcc_q_hd;			/* MCC ring head */
> +	u8 mcc_q_created;		/* flag to help cleanup */
> +	u8 mcc_q_pages;			/* Num of pages
> allocacted by OSM */
> +	BE_MCC_OBJECT mcc_q_obj;	/* BECLIB's MCC ring Object
> */
> +	SA_PHYSICAL_ADDRESS mcc_q_pa;	/* Physical address in
> LE order */
> +	/*
> +	 * MCC Completion Ring - ARM's responses to ioctls sent from
> MCC ring
> +	 */
> +	PMCC_CQ_ENTRY mcc_cq;		/* VA of the start of
> the ring */
> +	u32 mcc_cq_len;			/* # of compl.
> entries in this ring */
> +	u32 mcc_cq_tl;			/* compl. ring tail */
> +	u8 mcc_cq_created;		/* flag to help cleanup */
> +	u8 mcc_cq_pages;		/* Num of pages allocacted
> by OSM */
> +	BE_CQ_OBJECT mcc_cq_obj;	/* BECLIB's MCC compl. ring
> object */
> +	u32 mcc_cq_id;			/* MCC ring ID */
> +	SA_PHYSICAL_ADDRESS mcc_cq_pa;	/* Physical address in
> LE order */
> +	/*
> +	 * BEClib uses an array of context objects to track
> outstanding
> +	 * requests to the MCC.  We need allocate the same number of
> +	 * conext entries as the number of entries in the MCC WRB
> ring
> +	 */
> +	u8 mcc_wrb_ctxt_pages;		/* Num of pages
> allocacted by OSM */
> +	PVOID mcc_wrb_ctxt;		/* pointer to the context
> area */
> +	u32 mcc_wrb_ctxtLen;		/* Number of entries in
> the context */
> +	/*
> +	 * NIC send request ring - used for xmitting raw ether
> frames.
> +	 */
> +	PETH_WRB tx_q;			/* VA of the start of
> the ring */
> +	u32 tx_q_len;			/* # if entries in the
> send ring */
> +	u32 tx_q_hd;			/* Head index. Next req.
> goes here */
> +	u32 tx_q_tl;			/* Tail indx. oldest
> outstanding req. */
> +	u8 tx_q_created;		/* flag to help cleanup */
> +	u8 tx_q_pages;			/* Num of pages
> allocacted by OSM */
> +	BE_ETHSQ_OBJECT tx_q_obj;	/* BECLIB's send Q handle */
> +	SA_PHYSICAL_ADDRESS tx_q_pa;	/* Physical address in
> LE order */
> +	u32 tx_q_id;			/* send queue ring ID */
> +	u32 tx_q_port;			/* 0 no binding, 1
> port A,  2 port B */ +
> +	u32 tx_q_used;			/* # of WRBs used */
> +	/* ptr to an array in which we store context info for each
> send req. */
> +	PVOID *tx_ctxt;
> +	/*
> +	 * NIC Send compl. ring - completion status for all NIC
> frames xmitted.
> +	 */
> +	PETH_TX_COMPL tx_cq;		/* VA of start of the
> ring */
> +	u32 txcq_len;			/* # of entries in the
> ring */
> +	/*
> +	 * index into compl ring where the host expects next
> completion entry
> +	 */
> +	u32 tx_cq_tl;
> +	u32 tx_cq_id;			/* completion queue id
> */
> +	u8 tx_cq_created;		/* flag to help cleanup */
> +	u8 tx_cq_pages;			/* Num of pages
> allocacted by OSM */
> +	BE_CQ_OBJECT tx_cq_obj;
> +	SA_PHYSICAL_ADDRESS tx_cq_pa;	/* Physical address in
> LE order */
> +	/*
> +	 * Event Queue - all completion entries post events here.
> +	 */
> +	PEQ_ENTRY event_q;		/* VA of start of event
> queue */
> +	u32 event_q_len;		/* # of entries */
> +	u32 event_q_tl;			/* Tail of the event
> queue */
> +	u32 event_q_id;			/* Event queue ID */
> +	u8 event_q_created;		/* flag to help cleanup */
> +	u8 event_q_pages;		/* Num of pages allocacted
> by OSM */
> +	BE_EQ_OBJECT event_q_obj;	/* Queue handle */
> +	SA_PHYSICAL_ADDRESS event_q_pa;	/* Physical address
> in LE order */
> +	/*
> +	 * NIC receive queue - Data buffers to be used for receiving
> unicast,
> +	 * broadcast and multi-cast frames  are posted here.
> +	 */
> +	PETH_RX_D rx_q;			/* VA of start of the
> queue */
> +	u32 rx_q_len;			/* # of entries */
> +	u32 rx_q_hd;			/* Head of the queue */
> +	u32 rx_q_posted;		/* number of posted buffers
> */
> +	u32 rx_q_id;			/* queue ID */
> +	u8 rx_q_created;		/* flag to help cleanup */
> +	u8 rx_q_pages;			/* Num of pages
> allocacted by OSM */
> +	BE_ETHRQ_OBJECT rx_q_obj;	/* NIC RX queue handle */
> +	SA_PHYSICAL_ADDRESS rx_q_pa;	/* Physical address */
> +	/*
> +	 * Pointer to an array of opaque context object for use by
> OSM driver
> +	 */
> +	PVOID *rx_ctxt;
> +	/*
> +	 * NIC unicast RX completion queue - all unicast ether frame
> completion
> +	 * statuses from BE come here.
> +	 */
> +	PETH_RX_COMPL ucrx_cq;		/* VA of start of the
> queue */
> +	u32 ucrx_cq_len;		/* # of entries */
> +	u32 ucrx_cq_tl;			/* Tail of the queue
> */
> +	u32 ucrx_cq_id;			/* queue ID */
> +	u8 ucrx_cq_created;		/* flag to help cleanup */
> +	u8 ucrx_cq_pages;		/* Num of pages allocacted
> by OSM */
> +	BE_CQ_OBJECT ucrx_cq_obj;	/* queue handle */
> +	SA_PHYSICAL_ADDRESS ucrx_cq_pa;	/* Physical address
> in LE order */
> +	/*
> +	 * Broadcast RX completion queue - all broadcast and
> multicast ether
> +	 * completion statues from BE come here.
> +	 */
> +	PETH_RX_COMPL bcrx_cq;		/* VA of start of
> queue */
> +	u32 bcrx_cq_len;		/* # of entries */
> +	u32 bcrx_cq_tl;			/* Tail of the queue
> */
> +	u32 bcrx_cq_id;			/* Queue ID */
> +	u8 bcrx_cq_created;		/* flag to help cleanup */
> +	u8 bcrx_cq_pages;		/* Num of pages allocacted
> by OSM */
> +	BE_CQ_OBJECT bcrx_cq_obj;	/* queue handle */
> +	SA_PHYSICAL_ADDRESS bcrx_cq_pa;	/* Physical address
> in LE order */ +
> +	BE_FUNCTION_OBJECT fn_obj;	/* function object   */
> +	u32 rx_buf_size;		/* Size of the RX buffers */
> +	u8 mac_address[6];		/* MAC address */
> +	/*
> +	 * OSM handle. OSM drivers can use this pointer to extend
> NetObject.
> +	 */
> +	PVOID osm_netobj;
> +	SA_SGL mb_sgl;			/* SGL for
> MCC_MAIL_BOX */
> +	PVOID mb_ptr;			/* mailbox ptr to be
> freed  */ +} BNI_NET_OBJECT, *PBNI_NET_OBJECT;
> +
> +/*
> + * convenience macros to access some NetObject members
> + */
> +#define NET_FH(np)       (&(np)->fn_obj)
> +
> +/*
> + * Functions to advance the head and tail in various rings.
> + */
> +static INLINE void bni_adv_eq_tl(PBNI_NET_OBJECT pnob)
> +{
> +	pnob->event_q_tl = (pnob->event_q_tl + 1) %
> pnob->event_q_len; +}
> +
> +static INLINE void bni_adv_txq_hd(PBNI_NET_OBJECT pnob)
> +{
> +	pnob->tx_q_hd = (pnob->tx_q_hd + 1) % pnob->tx_q_len;
> +}
> +
> +static INLINE void bni_adv_txq_tl(PBNI_NET_OBJECT pnob)
> +{
> +	pnob->tx_q_tl = (pnob->tx_q_tl + 1) % pnob->tx_q_len;
> +}
> +
> +static INLINE void bni_adv_txcq_tl(PBNI_NET_OBJECT pnob)
> +{
> +	pnob->tx_cq_tl = (pnob->tx_cq_tl + 1) % pnob->txcq_len;
> +}
> +
> +static INLINE void bni_adv_rxq_hd(PBNI_NET_OBJECT pnob)
> +{
> +	pnob->rx_q_hd = (pnob->rx_q_hd + 1) % pnob->rx_q_len;
> +}
> +
> +static INLINE void bni_adv_ucrxcq_tl(PBNI_NET_OBJECT pnob)
> +{
> +	pnob->ucrx_cq_tl = (pnob->ucrx_cq_tl + 1) %
> pnob->ucrx_cq_len; +}
> +
> +static INLINE void bni_adv_bcrxcq_tl(PBNI_NET_OBJECT pnob)
> +{
> +	pnob->bcrx_cq_tl = (pnob->bcrx_cq_tl + 1) %
> pnob->bcrx_cq_len; +}
> +
> +static INLINE BESTATUS bni_process_mcc_cmpl(BE_MCC_OBJECT *pMccObj)
> +{
> +	return (be_mcc_process_cq(pMccObj, 1));
> +}
> +
> +/* forward declarations of function prototypes */
> +BESTATUS bni_init(PBE_CHIP_OBJECT);
> +BESTATUS bni_create_mcc_rings(PBNI_NET_OBJECT pnob);
> +extern void bni_destroy_netobj(PBNI_NET_OBJECT, SA_DEV *);
> +void bni_cleanup(PBE_CHIP_OBJECT chipobj);
> +
> +BESTATUS bni_create_netobj(PBNI_NET_OBJECT, SA_DEV_BAR_LOCATIONS *,
> u32,
> +			   SA_DEV *, PBE_CHIP_OBJECT);
> +
> +BESTATUS bni_tx_pkt(PBNI_NET_OBJECT, PBNI_TX_FRAG_LIST, u32,
> +		    u32, u32, void *, u32);
> +void bni_start_tx(PBNI_NET_OBJECT, u32);
> +
> +u32 bni_post_rx_buffs(PBNI_NET_OBJECT, PSA_LIST_ENTRY);
> +BESTATUS bni_change_eqd(PBNI_NET_OBJECT, u32);
> +
> +PETH_TX_COMPL bni_get_tx_cmpl(PBNI_NET_OBJECT);
> +PETH_RX_COMPL bni_get_ucrx_cmpl(PBNI_NET_OBJECT);
> +PETH_RX_COMPL bni_get_bcrx_cmpl(PBNI_NET_OBJECT);
> +void bni_notify_cmpl(PBNI_NET_OBJECT, int, int, int);
> +
> +void bni_enable_intr(PBNI_NET_OBJECT);
> +void bni_enable_eq_intr(PBNI_NET_OBJECT);
> +void bni_disable_intr(PBNI_NET_OBJECT);
> +void bni_disable_eq_intr(PBNI_NET_OBJECT);
> +
> +u32 bni_get_isr(PBNI_NET_OBJECT);
> +
> +PEQ_ENTRY bni_get_event(PBNI_NET_OBJECT);
> +void bni_notify_event(PBNI_NET_OBJECT, int, int);
> +
> +BESTATUS bni_get_uc_mac_adrr(PBNI_NET_OBJECT, u8, u8, u8 Pd,
> +			     PSA_MAC_ADDRESS macAddr,
> +			     MCC_WRB_CQE_CALLBACK cbf, PVOID cbc);
> +
> +BESTATUS bni_set_uc_mac_adr(PBNI_NET_OBJECT, u8, u8, u8 Pd,
> +			    PSA_MAC_ADDRESS macAddr,
> +			    MCC_WRB_CQE_CALLBACK cbf, PVOID cbc);
> +
> +BESTATUS bni_set_mc_filter(PBNI_NET_OBJECT pnob, u32 NumMac,
> +			   BOOLEAN Promiscuous,
> +			   PSA_MAC_ADDRESS macAddr,
> +			   MCC_WRB_CQE_CALLBACK cbf, PVOID cbc);
> +
> +void bni_set_promisc(PBNI_NET_OBJECT pnob);
> +void bni_reset_promisc(PBNI_NET_OBJECT pnob);
> +BESTATUS bni_config_vlan(PBNI_NET_OBJECT pnob, u16 *VlanId,
> +			 u32 numVlans, MCC_WRB_CQE_CALLBACK cbf,
> +			 PVOID cbc, BOOLEAN Promiscuous);
> +
> +BESTATUS bni_get_stats(PBNI_NET_OBJECT pnob,
> +		       IOCTL_ETH_GET_STATISTICS *ioctl_va,
> +		       u64 ioctl_pa, MCC_WRB_CQE_CALLBACK cbf, PVOID
> cbc); +
> +BESTATUS bni_get_link_sts(PBNI_NET_OBJECT pnob,
> +			  PBE_LINK_STATUS be_link_sts,
> +			  MCC_WRB_CQE_CALLBACK cbf, PVOID cbc);
> +BESTATUS bni_set_flow_ctll(PBE_FUNCTION_OBJECT pFnObj, boolean
> txfc_enable,
> +			   boolean rxfc_enable);
> +BESTATUS bni_get_flow_ctl(PBE_FUNCTION_OBJECT pFnObj,
> +			  boolean *txfc_enable, boolean
> *rxfc_enable); +u32 bni_process_rx_flush_cmpl(PBNI_NET_OBJECT pnob);
> +
> +#endif /* #ifndef _BNI_H_ */
> diff -uprN orig/linux-2.6.24.2/drivers/net/benet/be_init.c
> benet/linux-2.6.24.2/drivers/net/benet/be_init.c ---
> orig/linux-2.6.24.2/drivers/net/benet/be_init.c	1970-01-01
> 05:30:00.000000000 +0530 +++
> benet/linux-2.6.24.2/drivers/net/benet/be_init.c	2008-02-14
> 15:29:34.088482208 +0530 @@ -0,0 +1,1426 @@ +/*
> + * Copyright (C) 2005 - 2008 ServerEngines
> + * All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or at your option any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> + * See the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, 5th Floor
> + * Boston, MA 02110-1301 USA
> + *
> + *
> + * The full GNU General Public License is included in this
> distribution
> + * in the file called GPL.
> + *
> + * Contact Information:
> + * linux-drivers@...verengines.com
> + *
> + * ServerEngines
> + * 209 N. Fair Oaks Ave
> + * Sunnyvale, CA 94085
> + *
> + */
> +
> +#include <linux/pci.h>
> +#include <linux/etherdevice.h>
> +
> +#include "be.h"
> +
> +#define  DRVR_VERSION  "1.0.688"
> +
> +static struct pci_device_id be_device_id_table[] = {
> +	{0x19a2, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> +	{0, 0, 0, 0, 0, 0, 0}
> +};
> +
> +MODULE_DEVICE_TABLE(pci, be_device_id_table);
> +
> +MODULE_VERSION(DRVR_VERSION);
> +
> +#define DRV_DESCRIPTION "ServerEngines BladeEngine Network Driver
> Version " \
> +			DRVR_VERSION
> +
> +MODULE_DESCRIPTION(DRV_DESCRIPTION);
> +MODULE_AUTHOR("ServerEngines");
> +MODULE_LICENSE("GPL");
> +
> +unsigned int dbg_mask = (DL_ALWAYS | DL_ERR);	/* always show
> error messages */ +unsigned int msix;		/*By default  */
> +unsigned int ls_mss = (60 * 1024);
> +
> +unsigned int rxbuf_size = 2048;	/*Size of Receive buffers
> posted  */ +
> +module_param(msix, uint, (0 | 1));
> +module_param(dbg_mask, uint, (DL_ALWAYS | DL_ERR));
> +module_param(rxbuf_size, uint, 0);
> +
> +MODULE_PARM_DESC(msix, "Use MSI-x interrupts");
> +MODULE_PARM_DESC(dbg_mask, "Debug mask");
> +MODULE_PARM_DESC(rxbuf_size, "Size of buffers to hold Rx data");
> +
> +static int be_probe(struct pci_dev *, const struct pci_device_id *);
> +static void be_remove(struct pci_dev *);
> +
> +#ifdef CONFIG_PM
> +static void be_pm_cleanup(PBE_ADAPTER, PBNI_NET_OBJECT,
> +			  struct net_device *);
> +static void be_up(PBE_ADAPTER);
> +static int be_resume(struct pci_dev *);
> +
> +static int be_suspend(struct pci_dev *, pm_message_t);
> +#endif
> +
> +int be_mcc_init(PBE_ADAPTER adapter);
> +void be_update_link_status(PBE_ADAPTER adapter);
> +void be_link_status_async_callback(PVOID context, u32 event_code,
> +				   PVOID event);
> +
> +char be_drvr_ver[] = DRVR_VERSION;
> +char be_fw_ver[32];		/* F/W version filled in by
> be_probe */ +
> +char be_driver_name[] = "benet";
> +
> +static struct pci_driver be_driver = {
> +      name:be_driver_name,
> +      id_table:be_device_id_table,
> +      probe:be_probe,
> +#ifdef CONFIG_PM
> +      suspend:be_suspend,
> +      resume:be_resume,
> +#endif
> +      remove:be_remove
> +};
> +
> +/*
> + * Number of entries in each queue.
> + */
> +#define EVENT_Q_LEN		1024
> +#define ETH_TXQ_LEN		2048
> +#define ETH_TXCQ_LEN		1024
> +#define ETH_RXQ_LEN		1024	/* Does not support
> any other value */ +#define ETH_UC_RXCQ_LEN		1024
> +#define ETH_BC_RXCQ_LEN		256
> +#define MCC_Q_LEN               64	/* total size not to
> exceed 8 pages */ +#define MCC_CQ_LEN              256
> +
> +PBE_ADAPTER be_adapter[MAX_BE_DEVICES];
> +
> +/*
> + * Intialize and register a network device for the NetObject.
> + */
> +static int init_be_netdev(PBE_ADAPTER adapter, PBNI_NET_OBJECT pnob)
> +{
> +	struct net_device *netdev;
> +	int ret = 0;
> +	unsigned char *p;
> +
> +#ifdef CONFIG_PM
> +	if (pm_resume) {
> +		bni_set_uc_mac_adr(pnob, 0, 0, 0,
> +				   (PSA_MAC_ADDRESS)
> pnob->mac_address,
> +				   NULL, NULL);
> +		return 0;
> +	}
> +#endif
> +
> +	/*
> +	 * Allocate netdev. No private data structure is
> +	 * allocated with netdev
> +	 */
> +	netdev = alloc_etherdev(0);
> +	if (netdev == NULL)
> +		return -ENOMEM;
> +
> +	p = (u8 *) (pnob->mac_address);
> +	/*
> +	 * Get MAC address from receive table
> +	 */
> +	bni_get_uc_mac_adrr(pnob, 0, 0, OSM_NOB(pnob)->devno,
> +		(PSA_MAC_ADDRESS) pnob->mac_address, NULL, NULL);
> +
> +	memcpy(netdev->dev_addr, pnob->mac_address, 6);
> +	netdev->priv = pnob;	/* We use the Net Object as
> private data */
> +	netdev->init = &benet_probe;
> +	/*
> +	 * Initialize to No Link.  Link will be enabled during
> +	 * benet_open() or when physical Link is up
> +	 */
> +	netif_carrier_off(netdev);
> +	netif_stop_queue(netdev);
> +
> +	strcpy(netdev->name, "eth%d");
> +
> +	SET_NETDEV_DEV(netdev, &(adapter->pdev->dev));
> +	ret = register_netdev(netdev);
> +	if (ret != 0) {
> +		TRACE(DL_INIT,
> +		      "Netdevice registration failed - Errno %d\n",
> ret);
> +		free_netdev(netdev);
> +		return (ret);
> +	}
> +	OSM_NOB(pnob)->os_handle = netdev;
> +	return ret;
> +}
> +
> +/* Initialize the pci_info structure for this function */
> +static int init_pci_be_function(PBE_ADAPTER adapter, struct pci_dev
> *pdev) +{
> +	adapter->num_bars = 3;
> +	/* CSR */
> +	adapter->pci_bars[0].base_pa = pci_resource_start(pdev, 2);
> +	adapter->pci_bars[0].base_va =
> +	    ioremap_nocache(adapter->pci_bars[0].base_pa,
> +			    pci_resource_len(pdev, 2));
> +	if (adapter->pci_bars[0].base_va == NULL)
> +		return -ENOMEM;
> +	adapter->pci_bars[0].length = sizeof(BLADE_ENGINE_CSRMAP);
> +	adapter->pci_bars[0].mem_or_io_mapped = SA_MEM_MAPPED;
> +	adapter->pci_bars[0].type = SA_BAR_TYPE_CSR;
> +
> +	/* Door Bell */
> +	adapter->pci_bars[1].base_pa = pci_resource_start(pdev, 4);
> +	adapter->pci_bars[1].base_va =
> +	    ioremap_nocache(adapter->pci_bars[1].base_pa, (128 *
> 1024));
> +	if (adapter->pci_bars[1].base_va == NULL) {
> +		iounmap(adapter->pci_bars[0].base_va);
> +		return -ENOMEM;
> +	}
> +	adapter->pci_bars[1].length =
> sizeof(PROTECTION_DOMAIN_DBMAP);
> +	adapter->pci_bars[1].mem_or_io_mapped = SA_MEM_MAPPED;
> +	adapter->pci_bars[1].type = SA_BAR_TYPE_PD;
> +
> +	/* PCI */
> +	adapter->pci_bars[2].base_pa = pci_resource_start(pdev, 1);
> +	adapter->pci_bars[2].length = pci_resource_len(pdev, 1);
> +	adapter->pci_bars[2].base_va =
> +	    ioremap_nocache(adapter->pci_bars[2].base_pa,
> +			    adapter->pci_bars[2].length);
> +	if (adapter->pci_bars[2].base_va == NULL) {
> +		iounmap(adapter->pci_bars[0].base_va);
> +		iounmap(adapter->pci_bars[1].base_va);
> +		return -ENOMEM;
> +	}
> +	adapter->pci_bars[2].mem_or_io_mapped = SA_MEM_MAPPED;
> +	adapter->pci_bars[2].type = SA_BAR_TYPE_PCI;
> +
> +	adapter->pdev = pdev;
> +
> +	return 0;
> +}
> +
> +/*
> + * Enable MSIx and return 1 if successful. Else return 0
> + */
> +int be_enable_msix(PBE_ADAPTER adapter)
> +{
> +	unsigned int i, ret;
> +
> +	if (!msix)
> +		return 0;
> +
> +	adapter->msix_enabled = 1;
> +
> +	for (i = 0; i < BE_MAX_REQ_MSIX_VECTORS; i++) {
> +		adapter->msix_entries[i].entry = i;
> +	}
> +
> +	ret = pci_enable_msix(adapter->pdev,
> +			      adapter->msix_entries,
> +			      BE_MAX_REQ_MSIX_VECTORS);
> +
> +	if (ret) {
> +		adapter->msix_enabled = 0;
> +		return 0;
> +	}
> +
> +	return 1;
> +}
> +
> +/*
> + * Module init entry point. Registers our our device and return.
> + * Our probe will be called if the device is found.
> + */
> +
> +static int __init be_init_module(void)
> +{
> +	int ret;
> +
> +	if ((rxbuf_size != 8192) && (rxbuf_size != 4096)
> +	    && (rxbuf_size != 2048)) {
> +		printk(KERN_WARNING
> +		       "Unsupported receive buffer size (%d)
> requested\n",
> +		       rxbuf_size);
> +		printk(KERN_WARNING
> +		       "Must be 2048 or 4096. Defaulting to 2048\n");

You also allow 8192.  Intentional?

> +		rxbuf_size = 2048;
> +	}
> +
> +	ret = pci_register_driver(&be_driver);
> +	TRACE(DL_INIT, "pci_module_init returned %d", ret);
> +
> +	return ret;
> +}
> +
> +module_init(be_init_module);
> +
> +/*
> + * be_exit_module - Driver Exit Cleanup Routine
> + */
> +static void __exit be_exit_module(void)
> +{
> +	TRACE(DL_SHUTDOWN, "%s Entry\n", __FUNCTION__);
> +
> +	pci_unregister_driver(&be_driver);
> +}
> +
> +module_exit(be_exit_module);
> +
> +/*
> + * Registers ISR for BE. Uses MSIx interrupt if configured and
> requested.
> + * If not, uses INTx interrupt. Returns 0 for success and -1 for
> filure.
> + */
> +int register_isr(PBE_ADAPTER adapter, PBNI_NET_OBJECT pnob)
> +{
> +	int msix_intr, r;
> +	struct net_device *netdev = OSM_NOB(pnob)->os_handle;
> +	u32 msix_ret = 0;
> +
> +	netdev->irq = adapter->pdev->irq;
> +
> +	msix_intr = 0;
> +	msix_ret = be_enable_msix(adapter);
> +	if (msix_ret) {
> +		/* Register MSIx Interrupt handler */
> +		r = request_irq(adapter->msix_entries[0].vector,
> +				(void *)be_int, IRQF_SHARED,
> +				netdev->name, netdev);
> +		if (r) {
> +			printk(KERN_WARNING
> +			       "MSIX Request IRQ failed - Errno
> %d\n", r);
> +		} else {
> +			msix_intr = 1;
> +			TRACE(DL_INIT, "MSIx IRQ %d for %s\n",
> +			      adapter->msix_entries[0].vector,
> +			      netdev->name);
> +		}
> +	}
> +	if (msix_intr == 0) {
> +		/* request legacy INTx interrupt */
> +		r = request_irq(netdev->irq, (void *)be_int,
> +				IRQF_SHARED, netdev->name, netdev);
> +		if (r) {
> +			printk(KERN_ERR
> +			       "INTx Request IRQ failed - Errno
> %d\n", r);
> +			return (-1);
> +		}
> +		TRACE(DL_INIT, "BE: INTx IRQ %d for %s\n",
> +		      netdev->irq, netdev->name);
> +	}
> +	return (0);
> +}
> +
> +/*
> + * This function is called by the PCI sub-system when it finds a PCI
> + * device with dev/vendor IDs that match with one of our devices.
> + * All of the driver initialization is done in this function.
> + */
> +static int be_probe(struct pci_dev *pdev,
> +		    const struct pci_device_id *pdev_id)
> +{
> +	int status = 0;
> +	PBE_ADAPTER adapter = NULL;
> +	u32 r;
> +	u32 adapt_num = 0;
> +	IOCTL_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD ioctl_pload;
> +	PBNI_NET_OBJECT pnob = NULL;
> +
> +	TRACE(DL_INFO, "Entering probe");
> +	while (adapt_num < MAX_BE_DEVICES) {
> +		if (!be_adapter[adapt_num])
> +			break;
> +		adapt_num++;
> +	}
> +
> +	if (adapt_num == MAX_BE_DEVICES) {
> +		printk(KERN_WARNING "Cannot support more than %d BE
> Adapters",
> +		       MAX_BE_DEVICES);
> +		return -1;
> +	}
> +
> +	status = pci_enable_device(pdev);
> +	if (status) {
> +		printk(KERN_ERR "pci_enable_device() for BE adapter
> %d failed",
> +		       adapt_num);
> +		return status;
> +	}
> +
> +	status = pci_request_regions(pdev, be_driver_name);
> +	if (status)
> +		return status;
> +
> +	pci_set_master(pdev);
> +
> +	adapter = (PBE_ADAPTER) kmalloc(sizeof(BE_ADAPTER),
> GFP_KERNEL);
> +	if (adapter == NULL) {
> +		TRACE(DL_INIT,
> +		      "Failed to alloc memory for adapter
> structure\n");
> +		pci_release_regions(pdev);
> +		goto err_ret;
> +	}
> +
> +	memset(adapter, 0, sizeof(BE_ADAPTER));

If you use kzalloc, you won't need the memset.

> +
> +	be_adapter[adapt_num] = adapter;
> +	/*
> +	 * Adapative interrupt coalescing limits in usecs.
> +	 * should be a multiple of 8.
> +	 */
> +	adapter->enable_aic = 1;
> +	adapter->max_eqd = MAX_EQD;
> +	adapter->min_eqd = 0;
> +	adapter->cur_eqd = 0;	/* start with no EQ delay */
> +	r = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
> +	if (!r) {
> +		/* Device is DAC Capable.  */
> +		adapter->dma_64bit_cap = TRUE;
> +	} else {
> +		adapter->dma_64bit_cap = FALSE;
> +		r = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
> +		if (r) {
> +			printk(KERN_ERR "Could not set PCI DMA
> Mask\n");
> +			return r;
> +		}
> +	}
> +
> +	status = init_pci_be_function(adapter, pdev);
> +	if (status < 0) {
> +		printk(KERN_ERR "Failed to map PCI BARS\n");
> +		status = -ENOMEM;
> +		goto cleanup1;
> +	}
> +
> +	(void)sa_trace_set_level(dbg_mask);
> +
> +	r = bni_init(&adapter->chip_object);
> +	if (r != 0) {
> +		printk("bni_init() failed - Error %d\n", r);
> +		goto cleanup1;
> +	}
> +
> +	/* Allocate Memory for getting the Link status */
> +	adapter->be_link_sts = (PBE_LINK_STATUS)
> +	    kmalloc(sizeof(BE_LINK_STATUS), GFP_KERNEL);
> +	if (adapter->be_link_sts == NULL) {
> +		printk("Memory allocation for link status buffer
> failed\n");

Add log level.

> +		goto cleanup1;
> +	}
> +	spin_lock_init(&adapter->txq_lock);
> +
> +	status = be_prepare_interface(adapter);
> +	if (status < 0) {
> +		goto cleanup1;
> +	}
> +	pnob = adapter->net_obj;
> +
> +	/* if the rx_frag size if 2K, one page is shared as two RX
> frags */
> +	OSM_NOB(pnob)->rx_pg_shared =
> +			(pnob->rx_buf_size <= PAGE_SIZE / 2) ?
> TRUE : FALSE;
> +	if (pnob->rx_buf_size != rxbuf_size) {
> +		printk(KERN_WARNING
> +		       "Could not set Rx buffer size to %d. Using
> %d\n",
> +		       rxbuf_size, pnob->rx_buf_size);
> +		rxbuf_size = pnob->rx_buf_size;
> +	}
> +
> +	tasklet_init(&(adapter->sts_handler), osm_process_sts,
> +		     (unsigned long)adapter);
> +	adapter->tasklet_started = 1;	/* indication to
> cleanup */
> +	spin_lock_init(&(adapter->int_lock));
> +
> +	if (register_isr(adapter, pnob) != 0)
> +		goto cleanup;
> +
> +	adapter->isr_registered = 1;
> +	adapter->rx_csum = 1;	/* enable RX checksum check */
> +#ifdef RX_PKT_COALESCE
> +	adapter->max_rx_coal = MAX_COALESCE_FRAGS;
> +#endif
> +
> +	/* print the version numbers */
> +	memset(&ioctl_pload, 0,
> +	       sizeof(IOCTL_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD));
> +	printk(KERN_INFO "BladeEngine Driver version:%s. "
> +	       "Copyright ServerEngines, Corporation 2005 - 2008\n",
> +		be_drvr_ver);
> +	if (be_function_get_fw_version(&pnob->fn_obj, &ioctl_pload,
> NULL,
> +				       NULL) == BE_SUCCESS) {
> +		adapter->be_fw_ver =
> +
> simple_strtoul(ioctl_pload.firmware_version_string + 4,
> +				   NULL, 10);
> +		strncpy(be_fw_ver,
> ioctl_pload.firmware_version_string, 32);
> +		printk(KERN_INFO "BladeEngine Firmware Version:%s\n",
> +		       ioctl_pload.firmware_version_string);
> +	} else {
> +		printk(KERN_WARNING "Unable to get BE Firmware
> Version\n");
> +	}
> +
> +	sema_init(&adapter->get_eth_stat_sem, 0);
> +
> +	adapter->ctxt = (be_timer_ctxt_t *)
> +	    kmalloc(sizeof(be_timer_ctxt_t), GFP_KERNEL);
> +
> +	init_timer(&adapter->ctxt->get_stats_timer);
> +	atomic_set(&adapter->ctxt->get_stat_flag, 0);
> +	adapter->ctxt->get_stats_timer.function =
> &get_stats_timer_handler; +
> +	status = be_mcc_init(adapter);
> +	if (status < 0) {
> +		goto cleanup;
> +	}
> +
> +	be_update_link_status(adapter);
> +
> +	/* Register async call back function to handle link status
> updates */
> +	if
> (be_mcc_add_async_event_callback(&adapter->net_obj->mcc_q_obj,
> +			    be_link_status_async_callback,
> +					    (PVOID) adapter) !=
> BE_SUCCESS) {

Coding style:
val = be_mcc_add...();
if (val) {

> +		printk(KERN_WARNING "add_async_event_callback
> failed");
> +		printk(KERN_WARNING
> +		       "Link status changes may not be reflected\n");
> +	}
> +
> +	/* Enable ChipInterrupt and EQ Interrupt */
> +	bni_enable_intr(adapter->net_obj);
> +	enable_eq_intr(adapter->net_obj);
> +	adapter->dev_state = BE_DEV_STATE_INIT;
> +	return 0;		/* successful return */
> +
> +cleanup1:
> +	pci_release_regions(pdev);
> +	pci_disable_device(pdev);
> +	be_adapter[adapt_num] = NULL;
> +	kfree(adapter);
> +	goto err_ret;
> +
> +cleanup:
> +	be_remove(pdev);
> +
> +err_ret:
> +	printk(KERN_ERR "BladeEngine init failed\n");
> +	return -ENOMEM;
> +}
> +
> +/*
> + * Get the current link status and print the status on console
> + */
> +void be_update_link_status(PBE_ADAPTER adapter)
> +{
> +	int status;
> +	PBNI_NET_OBJECT pnob = adapter->net_obj;
> +
> +	status = bni_get_link_sts(pnob, adapter->be_link_sts, NULL,
> NULL); +
> +	if (status == BE_SUCCESS) {
> +		if (adapter->be_link_sts->mac0_speed &&
> +		    adapter->be_link_sts->mac0_duplex)
> +			adapter->port0_link_sts = BE_PORT_LINK_UP;
> +		else
> +			adapter->port0_link_sts = BE_PORT_LINK_DOWN;
> +
> +		if (adapter->be_link_sts->mac1_speed &&
> +		    adapter->be_link_sts->mac1_duplex)
> +			adapter->port1_link_sts = BE_PORT_LINK_UP;
> +		else
> +			adapter->port1_link_sts = BE_PORT_LINK_DOWN;
> +
> +		printk(KERN_INFO "Link Properties for %s:\n",
> +		       ((struct net_device
> *)(OSM_NOB(pnob)->os_handle))->name);
> +		be_print_link_info(adapter->be_link_sts);
> +		return;
> +	}
> +	printk(KERN_WARNING "Could not get link status for %s\n",
> +	       ((struct net_device
> *)(OSM_NOB(pnob)->os_handle))->name);
> +	return;
> +}
> +
> +/* This function handles async callback for link status */
> +void be_link_status_async_callback(PVOID context, u32 event_code,
> +				   PVOID event)
> +{
> +	ASYNC_EVENT_LINK_STATE *link_status =
> (ASYNC_EVENT_LINK_STATE *) event;
> +	PBE_ADAPTER adapter = (PBE_ADAPTER) context;
> +	BOOLEAN link_enable = FALSE;
> +	PBNI_NET_OBJECT pnob;
> +	ASYNC_EVENT_TRAILER *async_trailer;
> +	struct net_device *netdev;
> +
> +	if (event_code != ASYNC_EVENT_CODE_LINK_STATE) {
> +		/* Not our event to handle */
> +		return;
> +	}
> +	async_trailer = (ASYNC_EVENT_TRAILER *) ((u8 *) event +
> +			 sizeof(MCC_CQ_ENTRY) - sizeof
> (ASYNC_EVENT_TRAILER)); +
> +	SA_ASSERT(async_trailer->event_code ==
> ASYNC_EVENT_CODE_LINK_STATE); +
> +	pnob = adapter->net_obj;
> +	SA_ASSERT(pnob);
> +	netdev = (struct net_device *)OSM_NOB(pnob)->os_handle;
> +	SA_ASSERT(netdev);
> +
> +	/* Determine if this event is a switch VLD or a physical
> link event */
> +	if (async_trailer->event_type == NTWK_LINK_TYPE_VIRTUAL) {
> +		adapter->be_stat.bes_link_change_virtual++;
> +		if (adapter->be_link_sts->active_port !=
> +		    link_status->active_port) {
> +			printk("Active port changed due to VLD on
> switch\n");
> +		} else {
> +			/* Link of atleast one of the ports changed
> */
> +			printk("Link status update\n");
> +		}
> +
> +	} else {
> +		adapter->be_stat.bes_link_change_physical++;
> +		if (adapter->be_link_sts->active_port !=
> +				link_status->active_port) {
> +			printk("Active port changed due to port link
> status"
> +				" change\n");
> +		} else {
> +			/* Link of atleast one of the ports changed
> */
> +			printk("Link status update\n");
> +		}
> +	}
> +
> +	/* Clear memory of adapter->be_link_sts */
> +	memset(adapter->be_link_sts, 0,
> sizeof(adapter->be_link_sts)); +
> +	if ((link_status->port0_link_status == ASYNC_EVENT_LINK_UP)
> ||
> +	    (link_status->port1_link_status == ASYNC_EVENT_LINK_UP))
> {
> +		if ((adapter->port0_link_sts == BE_PORT_LINK_DOWN) &&
> +		    (adapter->port1_link_sts == BE_PORT_LINK_DOWN)) {
> +			/*
> +			 * Earlier both the ports are down
> +			 * So link is up
> +			 */
> +			link_enable = TRUE;
> +		}
> +
> +		if (link_status->port0_link_status ==
> ASYNC_EVENT_LINK_UP) {
> +			adapter->port0_link_sts = BE_PORT_LINK_UP;
> +			adapter->be_link_sts->mac0_duplex =
> +			    link_status->port0_duplex;
> +			adapter->be_link_sts->mac0_speed =
> +			    link_status->port0_speed;
> +			if (link_status->active_port == NTWK_PORT_A)
> +				adapter->be_link_sts->active_port =
> 0;
> +		} else
> +			adapter->port0_link_sts = BE_PORT_LINK_DOWN;
> +
> +		if (link_status->port1_link_status ==
> ASYNC_EVENT_LINK_UP) {
> +			adapter->port1_link_sts = BE_PORT_LINK_UP;
> +			adapter->be_link_sts->mac1_duplex =
> +			    link_status->port1_duplex;
> +			adapter->be_link_sts->mac1_speed =
> +			    link_status->port1_speed;
> +			if (link_status->active_port == NTWK_PORT_B)
> +				adapter->be_link_sts->active_port =
> 1;
> +		} else
> +			adapter->port1_link_sts = BE_PORT_LINK_DOWN;
> +
> +		printk(KERN_INFO "Link Properties for %s:\n",
> netdev->name);
> +		be_print_link_info(adapter->be_link_sts);
> +
> +		if (!link_enable)
> +			return;
> +		/*
> +		 * Both ports were down previously, but atleast one
> of
> +		 * them has come up if this netdevice's carrier is
> not up,
> +		 * then indicate to stack
> +		 */
> +		if (!netif_carrier_ok(netdev)) {
> +			netif_start_queue(netdev);
> +			netif_carrier_on(netdev);
> +		}
> +		return;
> +	}
> +
> +	/* Now both the ports are down. Tell the stack about it */
> +	printk(KERN_INFO "Both ports are down\n");
> +
> +	adapter->port0_link_sts = BE_PORT_LINK_DOWN;
> +	adapter->port1_link_sts = BE_PORT_LINK_DOWN;
> +
> +	/* if this netdevice's carrier is not down, then indicate to
> stack */
> +	if (netif_carrier_ok(netdev)) {
> +		netif_carrier_off(netdev);
> +		netif_stop_queue(netdev);
> +	}
> +	return;
> +}
> +
> +/* Function to initialize MCC rings */
> +int be_mcc_init(PBE_ADAPTER adapter)
> +{
> +	u32 n, r, m;
> +	PBNI_NET_OBJECT pnob;
> +
> +	pnob = adapter->net_obj;
> +	if (!pm_resume) {
> +		be_init_procfs(adapter);
> +		/*
> +		 * Create the MCC ring so that all further
> communication with
> +		 * MCC can go thru the ring. we do this at the end
> since
> +		 * we do not want to be dealing with interrupts
> until the
> +		 * initialization is complete.
> +		 */
> +		pnob->mcc_q_len = MCC_Q_LEN;
> +		n = pnob->mcc_q_len * sizeof(MCC_WRB);
> +		n = MAX(n, PAGE_SIZE);
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->mcc_q =
> +		    (PMCC_WRB) __get_free_pages(GFP_KERNEL,
> sa_log2(m));
> +		if (pnob->mcc_q == NULL)
> +			goto cleanup;
> +		pnob->mcc_q_pages = m;
> +		pnob->mcc_q_pa = virt_to_phys(pnob->mcc_q);
> +		pnob->mcc_q_pa = cpu_to_le64(pnob->mcc_q_pa);
> +		/*
> +		 * space for MCC WRB context
> +		 */
> +		pnob->mcc_wrb_ctxtLen = MCC_Q_LEN;
> +		n = pnob->mcc_wrb_ctxtLen *
> sizeof(BE_MCC_WRB_CONTEXT);
> +		n = MAX(n, PAGE_SIZE);	/* Need to allocate
> alteast one page */
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->mcc_wrb_ctxt =
> +		    (PVOID) __get_free_pages(GFP_KERNEL, sa_log2(m));
> +		if (pnob->mcc_wrb_ctxt == NULL)
> +			goto cleanup;
> +		pnob->mcc_wrb_ctxt_pages = m;
> +		/*
> +		 * Space for MCC compl. ring
> +		 */
> +		pnob->mcc_cq_len = MCC_CQ_LEN;
> +		n = pnob->mcc_cq_len * sizeof(MCC_CQ_ENTRY);
> +		n = MAX(n, PAGE_SIZE);	/* Need to allocate
> alteast one page */
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->mcc_cq =
> +		    (PMCC_CQ_ENTRY) __get_free_pages(GFP_KERNEL,
> +						     sa_log2(m));
> +		if (pnob->mcc_cq == NULL)
> +			goto cleanup;
> +		pnob->mcc_cq_pa = virt_to_phys(pnob->mcc_cq);
> +		pnob->mcc_cq_pa = cpu_to_le64(pnob->mcc_cq_pa);
> +		pnob->mcc_cq_pages = m;
> +
> +	}
> +	memset(pnob->mcc_q, 0, pnob->mcc_q_pages * PAGE_SIZE);
> +	pnob->mcc_q_hd = 0;
> +
> +	memset(pnob->mcc_wrb_ctxt, 0,
> +	       pnob->mcc_wrb_ctxt_pages * PAGE_SIZE);
> +
> +	memset(pnob->mcc_cq, 0, pnob->mcc_cq_pages * PAGE_SIZE);
> +	pnob->mcc_cq_tl = 0;
> +
> +	r = bni_create_mcc_rings(adapter->net_obj);
> +	if (r != BE_SUCCESS)
> +		goto cleanup;
> +
> +	return 0;
> +cleanup:
> +	TRACE(DL_INIT, "Failed to create MCC rings\n");
> +	return -ENOMEM;
> +
> +}
> +
> +static void be_remove(struct pci_dev *pdev)
> +{
> +	PBNI_NET_OBJECT pnob = NULL;
> +	PBE_ADAPTER adapter = NULL;
> +	int adapt_num = 0;
> +	int i;
> +
> +	while (adapt_num < MAX_BE_DEVICES) {
> +		if ((be_adapter[adapt_num]) &&
> +		    (be_adapter[adapt_num]->pdev == pdev)) {
> +			adapter = be_adapter[adapt_num];
> +			pnob = (BNI_NET_OBJECT *) adapter->net_obj;
> +			break;
> +		}
> +		adapt_num++;
> +	}
> +
> +	SA_ASSERT(adapter);
> +
> +	flush_scheduled_work();
> +
> +	/* Unregister async call back function for link status
> updates */
> +	if (be_mcc_add_async_event_callback(&pnob->mcc_q_obj,
> +					    NULL, NULL) !=
> BE_SUCCESS)
> +		printk(KERN_WARNING "Unregister async callback for
> link "
> +		       "status updates failed.\n");
> +
> +	cleanup_netobject(adapter->net_obj);
> +
> +	be_cleanup_procfs(adapter);
> +
> +	bni_cleanup(&adapter->chip_object);
> +
> +	for (i = 0; i < adapter->num_bars; i++) {
> +		if (adapter->pci_bars[i].base_va) {
> +			iounmap(adapter->pci_bars[i].base_va);
> +		}
> +	}
> +
> +	pci_release_regions(adapter->pdev);
> +	pci_disable_device(adapter->pdev);
> +
> +	/* Free Link status structure */
> +	if (adapter->be_link_sts) {
> +		kfree(adapter->be_link_sts);
> +	}
> +
> +	if (adapter->eth_statsp) {
> +		kfree(adapter->eth_statsp);
> +	}
> +
> +	del_timer_sync(&adapter->ctxt->get_stats_timer);
> +
> +	if (adapter->ctxt) {
> +		kfree(adapter->ctxt);
> +	}
> +
> +	be_adapter[adapt_num] = NULL;
> +	kfree(adapter);
> +}
> +
> +static int be_suspend(struct pci_dev *pdev, pm_message_t state)
> +{
> +#ifdef CONFIG_PM
> +	struct net_device *netdev = NULL;
> +	PBNI_NET_OBJECT pnob = NULL;
> +	PBE_ADAPTER adapter = NULL;
> +
> +	int adapt_num = 0;
> +	while (adapt_num < MAX_BE_DEVICES) {
> +		if (be_adapter[adapt_num] &&
> +		    (be_adapter[adapt_num]->pdev == pdev)) {
> +			adapter = be_adapter[adapt_num];
> +			pnob = (BNI_NET_OBJECT *)
> adapter->netdevp->priv;
> +			netdev = adapter->netdevp;
> +			netif_device_detach(netdev);
> +			break;
> +		}
> +		adapt_num++;
> +	}
> +	SA_ASSERT(adapter);
> +
> +	netif_device_detach(netdev);
> +	if (netif_running(netdev))
> +		be_pm_cleanup(adapter, pnob, netdev);
> +
> +	pci_enable_wake(pdev, 3, 1);
> +	pci_enable_wake(pdev, 4, 1);	/* D3 Cold = 4 */
> +	pci_save_state(pdev);
> +	pci_disable_device(pdev);
> +	pci_set_power_state(pdev, pci_choose_state(pdev, state));
> +#endif
> +	return 0;
> +}
> +
> +static int be_resume(struct pci_dev *pdev)
> +{
> +#ifdef CONFIG_PM
> +	int status = 0;
> +	struct net_device *netdev = NULL;
> +	PBNI_NET_OBJECT pnob = NULL;
> +	PBE_ADAPTER adapter = NULL;
> +	u32 adapt_num = 0;
> +
> +	pm_resume = 1;
> +	while (adapt_num < MAX_BE_DEVICES) {
> +		if (be_adapter[adapt_num] &&
> +			    (be_adapter[adapt_num]->pdev == pdev)) {
> +			adapter = be_adapter[adapt_num];
> +			pnob = (BNI_NET_OBJECT *)
> adapter->netdevp->priv;
> +			netdev = adapter->netdevp;
> +			netif_device_detach(netdev);
> +			break;
> +		}
> +		adapt_num++;
> +	}
> +	SA_ASSERT(adapter);
> +
> +	status = pci_enable_device(pdev);
> +	if (status)
> +		return status;
> +
> +	pci_set_power_state(pdev, 0);
> +	pci_restore_state(pdev);
> +	pci_enable_wake(pdev, 3, 0);
> +	pci_enable_wake(pdev, 4, 0);	/* 4 is D3 cold */
> +
> +	netif_carrier_on(netdev);
> +	netif_start_queue(netdev);
> +
> +	if (netif_running(netdev)) {
> +		status = be_prepare_interface(adapter);
> +
> +		if (status < 0) {
> +			return (status);
> +		}
> +		status = be_mcc_init(adapter);
> +		if (status < 0) {
> +			printk(KERN_ERR "be_mcc_init failed\n");
> +			return (status);
> +		}
> +		be_update_link_status(adapter);
> +		/*
> +		 * Register async call back function to handle link
> +		 * status updates
> +		 */
> +		if (be_mcc_add_async_event_callback(
> +			&adapter->net_obj->mcc_q_obj,
> +			be_link_status_async_callback,
> +					    (PVOID) adapter) !=
> BE_SUCCESS) {
> +			printk(KERN_WARNING
> "add_async_event_callback failed");
> +			printk(KERN_WARNING
> +			       "Link status changes may not be
> reflected\n");
> +		}

val = be_mcc...()
if (val) {

> +		bni_enable_intr(pnob);
> +		enable_eq_intr(pnob);
> +		be_up(adapter);
> +	}
> +	netif_device_attach(netdev);
> +	pm_resume = 0;
> +#endif
> +	return 0;
> +
> +}
> +
> +#ifdef CONFIG_PM
> +static void be_pm_cleanup(PBE_ADAPTER adapter,
> +			  PBNI_NET_OBJECT pnob, struct net_device
> *netdev) +{
> +	u32 i;
> +
> +	netif_carrier_off(netdev);
> +	netif_stop_queue(netdev);
> +
> +	wait_nic_tx_cmpl(pnob);
> +	disable_eq_intr(pnob);
> +	if (adapter->tasklet_started) {
> +		tasklet_kill(&(adapter->sts_handler));
> +		adapter->isr_registered = 0;
> +	}
> +	if (adapter->isr_registered) {
> +		free_irq(netdev->irq, netdev);
> +		adapter->tasklet_started = 0;
> +	}
> +	/* Disable chip interrupt */
> +	bni_disable_intr(pnob);
> +	bni_destroy_netobj(pnob, &adapter->sa_device);
> +
> +	if (pnob->rx_ctxt) {
> +		BE_RX_PAGE_INFO *rx_page_info;
> +
> +		/*
> +		 * go through RX context array and free
> +		 * data buffs
> +		 */
> +		for (i = 0; i < pnob->rx_q_len; i++) {
> +			rx_page_info =
> &(OSM_NOB(pnob)->rx_page_info[i]);
> +			if ((OSM_NOB(pnob)->rx_pg_shared == FALSE) ||
> +
> (rx_page_info->page_offset))
> +				pci_unmap_page(adapter->pdev,
> +
> pci_unmap_addr(rx_page_info,
> +							      bus),
> +					       pnob->rx_buf_size,
> +					       PCI_DMA_FROMDEVICE);
> +			if (rx_page_info->page)
> +				put_page(rx_page_info->page);
> +			memset(rx_page_info, 0,
> sizeof(BE_RX_PAGE_INFO));
> +		}
> +		OSM_NOB(pnob)->rx_pg_info_hd = 0;
> +	}
> +
> +}
> +
> +static void be_up(PBE_ADAPTER adapter)
> +{
> +	PBNI_NET_OBJECT pnob = adapter->net_obj;
> +
> +	if (OSM_NOB(pnob)->num_vlans != 0)
> +		bni_config_vlan(pnob, OSM_NOB(pnob)->vlan_tag,
> +				OSM_NOB(pnob)->num_vlans, NULL,
> NULL, 0); +
> +}
> +#endif
> +
> +static int be_setup_tx_res(PBNI_NET_OBJECT NetObject)
> +{
> +	int n;
> +
> +	n = NetObject->tx_q_len * sizeof(PVOID *);
> +	if (!pm_resume) {
> +		NetObject->tx_ctxt = (PVOID *) kmalloc(n,
> GFP_KERNEL); +
> +		if (NetObject->tx_ctxt == NULL) {
> +			TRACE(DL_INIT,
> +			      "Failed to alloc memory for
> tx_ctxt\n");
> +			return -1;
> +		}
> +	}
> +	memset(NetObject->tx_ctxt, 0, n);
> +	return 0;
> +}
> +
> +static int be_setup_rx_res(PBNI_NET_OBJECT NetObject)
> +{
> +	int n;
> +
> +	if (!pm_resume) {
> +		n = (NetObject->rx_q_len * sizeof(PVOID));
> +		NetObject->rx_ctxt = kmalloc(n, GFP_KERNEL);
> +		if (NetObject->rx_ctxt == NULL) {
> +			TRACE(DL_INIT, "Failed to alloc memory for
> rx_ctxt\n");
> +			return -1;
> +		}
> +
> +		n = (NetObject->rx_q_len * sizeof(BE_RX_PAGE_INFO));
> +		OSM_NOB(NetObject)->rx_page_info = kmalloc(n,
> GFP_KERNEL);
> +		if (OSM_NOB(NetObject)->rx_page_info == NULL) {
> +			TRACE(DL_INIT,
> +			      "Failed to alloc memory for receive
> page info\n");
> +			kfree(NetObject->rx_ctxt);
> +			return -1;
> +		}
> +	}
> +
> +	memset(NetObject->rx_ctxt, 0, NetObject->rx_q_len *
> sizeof(PVOID));
> +	memset(OSM_NOB(NetObject)->rx_page_info, 0,
> +	       NetObject->rx_q_len * sizeof(BE_RX_PAGE_INFO));
> +	OSM_NOB(NetObject)->rx_pg_info_hd = 0;
> +	NetObject->rx_q_hd = 0;
> +	NetObject->rx_q_posted = 0;
> +	/* post  ETH RX buffers */
> +	post_eth_rx_buffs(NetObject);
> +
> +	return 0;
> +}
> +
> +/*
> + * free all resources associated with a NetObject
> + * Called at the time of module cleanup as well a any error during
> + * module init.  Some resources may be partially allocated in a
> NetObj.
> + */
> +void cleanup_netobject(PBNI_NET_OBJECT pnob)
> +{
> +	struct net_device *netdev;
> +	PBE_ADAPTER adapter;
> +	struct sk_buff *skb;
> +	int i;
> +
> +	SA_ASSERT(pnob);
> +	netdev = (struct net_device *)OSM_NOB(pnob)->os_handle;
> +	SA_ASSERT(netdev);
> +	adapter = (PBE_ADAPTER) OSM_NOB(pnob)->adapter;
> +	SA_ASSERT(adapter);
> +
> +	/* Only if this netdev is up */
> +	if (netif_running(netdev)) {
> +		/*
> +		 * Let us stop the dev queue for the
> +		 * interface associated with this netobj.
> +		 */
> +		netif_stop_queue(netdev);
> +
> +		/* Wait until no more pending transmits  */
> +		wait_nic_tx_cmpl(pnob);
> +
> +		/* Disable this EQ's interrupt  */
> +		disable_eq_intr(pnob);
> +	}
> +
> +	if ((adapter->isr_registered) & (adapter->msix_enabled))
> +		free_irq(adapter->msix_entries[0].vector, netdev);
> +	else if ((adapter->isr_registered)
> & !(adapter->msix_enabled))
> +		free_irq(netdev->irq, netdev);
> +
> +	adapter->isr_registered = 0;
> +	if (adapter->msix_enabled) {
> +		pci_disable_msix(adapter->pdev);
> +		adapter->msix_enabled = 0;
> +	}
> +	if (adapter->tasklet_started) {
> +		tasklet_kill(&(adapter->sts_handler));
> +		adapter->tasklet_started = 0;
> +	}
> +	/* Disable chip interrupt */
> +	bni_disable_intr(pnob);
> +
> +	unregister_netdev(netdev);
> +	/* memory associted with netdev is freed by OS  */
> +
> +	/* Destroy Net Object */
> +	bni_destroy_netobj(pnob, &adapter->sa_device);
> +
> +	adapter->net_obj = NULL;
> +	adapter->netdevp = NULL;
> +
> +	/* free all the memory allocated for the queues */
> +
> +	if (pnob->mcc_q) {
> +		free_pages((unsigned long)pnob->mcc_q,
> +			   sa_log2(pnob->mcc_q_pages));
> +	}
> +
> +	if (pnob->mcc_wrb_ctxt) {
> +		free_pages((unsigned long)pnob->mcc_wrb_ctxt,
> +			   sa_log2(pnob->mcc_wrb_ctxt_pages));
> +	}
> +
> +	if (pnob->mcc_cq) {
> +		free_pages((unsigned long)pnob->mcc_cq,
> +			   sa_log2(pnob->mcc_cq_pages));
> +	}
> +
> +	if (pnob->event_q) {
> +		free_pages((unsigned long)pnob->event_q,
> +			   sa_log2(pnob->event_q_pages));
> +	}
> +
> +	if (pnob->tx_cq) {
> +		free_pages((unsigned long)pnob->tx_cq,
> +			   sa_log2(pnob->tx_cq_pages));
> +	}
> +
> +	if (pnob->tx_q) {
> +		free_pages((unsigned long)pnob->tx_q,
> +			   sa_log2(pnob->tx_q_pages));
> +	}
> +
> +	if (pnob->bcrx_cq) {
> +		free_pages((unsigned long)pnob->bcrx_cq,
> +			   sa_log2(pnob->bcrx_cq_pages));
> +	}
> +
> +	if (pnob->rx_q) {
> +		free_pages((unsigned long)pnob->rx_q,
> +			   sa_log2(pnob->rx_q_pages));
> +	}
> +
> +	if (pnob->ucrx_cq) {
> +		free_pages((unsigned long)pnob->ucrx_cq,
> +			   sa_log2(pnob->ucrx_cq_pages));
> +	}
> +
> +	/* free all allocated memory stored in the net object */
> +	if (pnob->rx_ctxt) {
> +		BE_RX_PAGE_INFO *rx_page_info;
> +		/*
> +		 * go through RX context array and free data buffs
> +		 */
> +		for (i = 0; i < pnob->rx_q_len; i++) {
> +			rx_page_info =
> &(OSM_NOB(pnob)->rx_page_info[i]);
> +			if ((OSM_NOB(pnob)->rx_pg_shared == FALSE) ||
> +
> (rx_page_info->page_offset)) {
> +				pci_unmap_page(adapter->pdev,
> +					pci_unmap_addr(rx_page_info,
> bus),
> +					pnob->rx_buf_size,
> PCI_DMA_FROMDEVICE);
> +			}
> +			if (rx_page_info->page) {
> +				put_page(rx_page_info->page);
> +			}
> +			memset(rx_page_info, 0,
> sizeof(BE_RX_PAGE_INFO));
> +		}
> +		OSM_NOB(pnob)->rx_pg_info_hd = 0;
> +		kfree(OSM_NOB(pnob)->rx_page_info);
> +		kfree(pnob->rx_ctxt);
> +	}
> +
> +	if (pnob->tx_ctxt) {
> +		for (i = 0; i < pnob->tx_q_len; i++) {
> +			skb = (struct sk_buff *)pnob->tx_ctxt[i];
> +			if (skb) {
> +				kfree_skb(skb);
> +			}
> +		}
> +		kfree(pnob->tx_ctxt);
> +	}
> +
> +	if (pnob->mb_ptr) {
> +		kfree(pnob->mb_ptr);
> +	}
> +
> +	if (OSM_NOB(pnob)) {
> +		kfree(OSM_NOB(pnob));
> +	}
> +
> +	/* finally,  free the net object itself */
> +	kfree(pnob);
> +
> +}
> +
> +/*
> + * this function creates a NetObject with a set of Eth rings.
> + */
> +int be_prepare_interface(PBE_ADAPTER adapter)
> +{
> +	struct net_device *netdev = NULL;
> +	PBNI_NET_OBJECT pnob = NULL;
> +	SA_DEV_BAR_LOCATIONS pci_bars[3];
> +	int status;
> +	u32 n, m;
> +	PVOID p;
> +
> +	if (!pm_resume) {
> +		/*Normal Mode */
> +		memcpy(pci_bars, adapter->pci_bars,
> +		       sizeof(adapter->pci_bars));
> +
> +		pnob = (PBNI_NET_OBJECT)
> +		    kmalloc(sizeof(BNI_NET_OBJECT), GFP_KERNEL);
> +
> +		if (pnob == NULL) {
> +			TRACE(DL_INIT,
> +			      "Failed to alloc memory for
> NetObject\n");
> +			goto err_ret1;
> +		}
> +		memset(pnob, 0, sizeof(BNI_NET_OBJECT));
> +		TRACE(DL_INIT, "Done with net obj alloc\n");
> +
> +		pnob->osm_netobj = (linux_net_object_t *)
> +		    kmalloc(sizeof(linux_net_object_t), GFP_KERNEL);
> +		if (pnob->osm_netobj == NULL) {
> +			TRACE(DL_INIT,
> +			      "Failed to alloc memory OSM
> NetObject\n");
> +			kfree(pnob);
> +			goto err_ret1;
> +		}
> +		memset(pnob->osm_netobj, 0,
> sizeof(linux_net_object_t)); +
> +		OSM_NOB(pnob)->devno = 0;
> +		OSM_NOB(pnob)->adapter = adapter;
> +
> +		/* Mail box sgl */
> +		pnob->mb_sgl.length = sizeof(MCC_MAILBOX);
> +		p = kmalloc(pnob->mb_sgl.length + 16, GFP_KERNEL);
> +		if (p == NULL) {
> +			TRACE(DL_INIT,
> +			      "Failed to alloc mem for
> MCC_MAILBOX\n");
> +			goto err_ret1;
> +		}
> +		/* Mailbox pointer needs to be 16 byte aligned */
> +		pnob->mb_ptr = p;
> +		p = (PVOID) ((unsigned long)(p + 15) & ~0xf);
> +		pnob->mb_sgl.va = (void *)p;
> +		pnob->mb_sgl.pa = virt_to_phys(p);
> +		pnob->mb_sgl.pa = cpu_to_le64(pnob->mb_sgl.pa);
> +		/*
> +		 * Event queue
> +		 */
> +		pnob->event_q_len = EVENT_Q_LEN;
> +		n = pnob->event_q_len * sizeof(EQ_ENTRY);
> +		n = MAX(n, (2 * PAGE_SIZE));
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->event_q = (PEQ_ENTRY)
> +		    __get_free_pages(GFP_KERNEL, sa_log2(m));
> +		if (pnob->event_q == NULL)
> +			goto err_ret1;
> +		pnob->event_q_pa = virt_to_phys(pnob->event_q);
> +		pnob->event_q_pa = cpu_to_le64(pnob->event_q_pa);
> +		pnob->event_q_pages = m;
> +		/*
> +		 * Eth TX queue
> +		 */
> +		pnob->tx_q_len = ETH_TXQ_LEN;
> +		pnob->tx_q_port = 0;	/* No port binding */
> +		n = pnob->tx_q_len * sizeof(ETH_WRB);
> +		n = MAX(n, PAGE_SIZE);	/* Need to allocate
> alteast one page */
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->tx_q = (PETH_WRB)
> +		    __get_free_pages(GFP_KERNEL, sa_log2(m));
> +		if (pnob->tx_q == NULL)
> +			goto err_ret1;
> +		pnob->tx_q_pa = virt_to_phys(pnob->tx_q);
> +		pnob->tx_q_pa = cpu_to_le64(pnob->tx_q_pa);
> +		pnob->tx_q_pages = m;
> +		/*
> +		 * Eth TX Compl queue
> +		 */
> +		pnob->txcq_len = ETH_TXCQ_LEN;
> +		n = pnob->txcq_len * sizeof(ETH_TX_COMPL);
> +		n = MAX(n, PAGE_SIZE);	/* Need to allocate
> alteast one page */
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->tx_cq = (PETH_TX_COMPL)
> +		    __get_free_pages(GFP_KERNEL, sa_log2(m));
> +		if (pnob->tx_cq == NULL)
> +			goto err_ret1;
> +		pnob->tx_cq_pa = virt_to_phys(pnob->tx_cq);
> +		pnob->tx_cq_pa = cpu_to_le64(pnob->tx_cq_pa);
> +		pnob->tx_cq_pages = m;
> +		/*
> +		 * Eth RX queue
> +		 */
> +		pnob->rx_q_len = ETH_RXQ_LEN;
> +		n = pnob->rx_q_len * sizeof(ETH_RX_D);
> +		n = MAX(n, PAGE_SIZE);	/* Need to allocate
> alteast one page */
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->rx_q = (PETH_RX_D)
> +		    __get_free_pages(GFP_KERNEL, sa_log2(m));
> +		if (pnob->rx_q == NULL)
> +			goto err_ret1;
> +		pnob->rx_q_pa = virt_to_phys(pnob->rx_q);
> +		pnob->rx_q_pa = cpu_to_le64(pnob->rx_q_pa);
> +		pnob->rx_q_pages = m;
> +		/*
> +		 * Eth Unicast RX Compl queue
> +		 */
> +		pnob->ucrx_cq_len = ETH_UC_RXCQ_LEN;
> +		n = pnob->ucrx_cq_len * sizeof(ETH_RX_COMPL);
> +		n = MAX(n, PAGE_SIZE);	/* Need to allocate
> alteast one page */
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->ucrx_cq = (PETH_RX_COMPL)
> +		    __get_free_pages(GFP_KERNEL, sa_log2(m));
> +		if (pnob->ucrx_cq == NULL)
> +			goto err_ret1;
> +		pnob->ucrx_cq_pa = virt_to_phys(pnob->ucrx_cq);
> +		pnob->ucrx_cq_pa = cpu_to_le64(pnob->ucrx_cq_pa);
> +		pnob->ucrx_cq_pages = m;
> +		/*
> +		 * Eth Broadcast RX Compl queue
> +		 */
> +		pnob->bcrx_cq_len = ETH_BC_RXCQ_LEN;
> +		n = pnob->bcrx_cq_len * sizeof(ETH_RX_COMPL);
> +		n = MAX(n, PAGE_SIZE);
> +		/* Get number of pages */
> +		m = (n + (PAGE_SIZE - 1)) / (PAGE_SIZE);
> +		pnob->bcrx_cq = (PETH_RX_COMPL)
> +		    __get_free_pages(GFP_KERNEL, sa_log2(m));
> +		if (pnob->bcrx_cq == NULL)
> +			goto err_ret1;
> +		pnob->bcrx_cq_pa = virt_to_phys(pnob->bcrx_cq);
> +		pnob->bcrx_cq_pa = cpu_to_le64(pnob->bcrx_cq_pa);
> +		pnob->bcrx_cq_pages = m;
> +
> +		/* Allocate DMA'ble Memory for
> IOCTL_ETH_GET_STATISTICS */
> +		adapter->eth_statsp = (IOCTL_ETH_GET_STATISTICS *)
> +		    kmalloc(sizeof(IOCTL_ETH_GET_STATISTICS),
> GFP_KERNEL);
> +		if (adapter->eth_statsp == NULL) {
> +			TRACE(DL_INIT,
> +			      "Failed to alloc memory for Eth
> stats\n");
> +			goto err_ret1;
> +		}
> +		pnob->rx_buf_size = rxbuf_size;
> +		/*
> +		 * Set dev close to be TRUE. This will be enabled on
> dev open
> +		 */
> +		adapter->dev_state = BE_DEV_STATE_NONE;
> +	} else {
> +		pnob = adapter->net_obj;
> +		memcpy(pci_bars, adapter->pci_bars,
> +		       sizeof(adapter->pci_bars));
> +	}
> +
> +	memset(pnob->event_q, 0, pnob->event_q_pages * PAGE_SIZE);
> +	pnob->event_q_tl = 0;
> +
> +	memset(pnob->tx_q, 0, pnob->tx_q_pages * PAGE_SIZE);
> +	pnob->tx_q_hd = 0;
> +	pnob->tx_q_tl = 0;
> +
> +	memset(pnob->tx_cq, 0, pnob->tx_cq_pages * PAGE_SIZE);
> +	pnob->tx_cq_tl = 0;
> +
> +	memset(pnob->rx_q, 0, pnob->rx_q_pages * PAGE_SIZE);
> +
> +	memset(pnob->ucrx_cq, 0, pnob->ucrx_cq_pages * PAGE_SIZE);
> +	pnob->ucrx_cq_tl = 0;
> +
> +	memset(pnob->bcrx_cq, 0, pnob->bcrx_cq_pages * PAGE_SIZE);
> +	pnob->bcrx_cq_tl = 0;
> +	n = bni_create_netobj(pnob, pci_bars, adapter->num_bars,
> +				   &adapter->sa_device,
> +				   &adapter->chip_object);
> +	if (n != BE_SUCCESS) {
> +		TRACE(DL_ERROR, "bni_create_netobj failed - returned
> %x", n);
> +		goto err_ret1;
> +	}
> +	TRACE(DL_INIT, "Creation of NetObject Done");
> +
> +	status = init_be_netdev(adapter, pnob);
> +	if (status < 0)
> +		goto err_ret;
> +	netdev = OSM_NOB(pnob)->os_handle;
> +
> +#ifdef CONFIG_BENET_NAPI
> +	netif_napi_add(netdev, &OSM_NOB(pnob)->napi, be_poll, 64);
> +	OSM_NOB(pnob)->rx_sched = FALSE;
> +	spin_lock_init(&OSM_NOB(pnob)->rx_lock);
> +#endif
> +
> +	if (be_setup_tx_res(pnob))
> +		goto err_ret;
> +	if (be_setup_rx_res(pnob))
> +		goto err_ret;
> +
> +	if (!pm_resume) {
> +		adapter->netdevp = OSM_NOB(pnob)->os_handle;
> +		adapter->net_obj = pnob;
> +	}
> +	return 0;
> +
> +err_ret:
> +	cleanup_netobject(pnob);
> +
> +err_ret1:
> +	printk(KERN_ERR "Interface initialization failed\n");
> +	return -1;
> +}
> +
> +void enable_eq_intr(PBNI_NET_OBJECT pnob)
> +{
> +	bni_enable_eq_intr(pnob);
> +}
> +
> +void disable_eq_intr(PBNI_NET_OBJECT pnob)
> +{
> +	bni_disable_eq_intr(pnob);
> +}
> +
> +/* Wait until no more pending transmits  */
> +void wait_nic_tx_cmpl(PBNI_NET_OBJECT pnob)
> +{
> +	int i;
> +
> +	/* Wait for 20us * 50000 (= 1s) and no more */
> +	i = 0;
> +	while ((pnob->tx_q_tl != pnob->tx_q_hd) && (i < 50000)) {
> +		++i;
> +		udelay(20);
> +	}
> +
> +	/* Check for no more pending transmits */
> +	if (i >= 50000) {
> +		printk(KERN_WARNING
> +		       "Did not receive completions for all TX
> requests\n");
> +	}
> +}
> diff -uprN orig/linux-2.6.24.2/drivers/net/benet/be_netif.c
> benet/linux-2.6.24.2/drivers/net/benet/be_netif.c ---
> orig/linux-2.6.24.2/drivers/net/benet/be_netif.c	1970-01-01
> 05:30:00.000000000 +0530 +++
> benet/linux-2.6.24.2/drivers/net/benet/be_netif.c	2008-02-14
> 15:31:33.420341008 +0530 @@ -0,0 +1,600 @@ +/*
> + * Copyright (C) 2005 - 2008 ServerEngines
> + * All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or at your option any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> + * See the GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, 5th Floor
> + * Boston, MA 02110-1301 USA
> + *
> + *
> + * The full GNU General Public License is included in this
> distribution
> + * in the file called GPL.
> + *
> + * Contact Information:
> + * linux-drivers@...verengines.com
> + *
> + * ServerEngines
> + * 209 N. Fair Oaks Ave
> + * Sunnyvale, CA 94085
> + *
> + */
> +/*
> + * be_netif.c
> + *
> + * This file contains various entry points of drivers seen by tcp/ip
> stack.
> + */
> +
> +#include <linux/pci.h>
> +#include "be.h"
> +#include <linux/ip.h>
> +
> +extern unsigned int ls_mss;
> +
> +unsigned int pm_resume;
> +
> +/* Strings to print Link properties */
> +char *link_speed[] = {
> +	"Invalid link Speed Value",
> +	"10 Mbps",
> +	"100 Mbps",
> +	"1 Gbps",
> +	"10 Gbps"
> +};
> +
> +char *link_duplex[] = {
> +	"Invalid Duplex Value",
> +	"Half Duplex",
> +	"Full Duplex"
> +};
> +
> +#ifdef BE_POLL_MODE
> +struct net_device *irq_netdev;
> +#endif
> +
> +int benet_xmit(struct sk_buff *skb, struct net_device *netdev);
> +int benet_set_mac_addr(struct net_device *netdev, void *p);
> +
> +void be_print_link_info(PBE_LINK_STATUS lnk_status)
> +{
> +	printk("PortNo 0:");
> +	if (lnk_status->mac0_speed && lnk_status->mac0_duplex) {
> +		/* Port is up and running */
> +		if (lnk_status->mac0_speed < 5)
> +			printk(" Link Speed: %s,",
> +			       link_speed[lnk_status->mac0_speed]);
> +		else
> +			printk(" %s,", link_speed[0]);
> +
> +		if (lnk_status->mac0_duplex < 3)
> +			printk(" %s",
> +			       link_duplex[lnk_status->mac0_duplex]);
> +		else
> +			printk(" %s", link_duplex[0]);
> +
> +		if (lnk_status->active_port == 0)
> +			printk("(active)\n");
> +		else
> +			printk("\n");
> +	} else
> +		printk(" Down \n");
> +
> +	printk("PortNo 1:");
> +	if (lnk_status->mac1_speed && lnk_status->mac1_duplex) {
> +		/* Port is up and running */
> +		if (lnk_status->mac1_speed < 5)
> +			printk(" Link Speed: %s,",
> +			       link_speed[lnk_status->mac1_speed]);
> +		else
> +			printk(" %s,", link_speed[0]);
> +
> +		if (lnk_status->mac1_duplex < 3)
> +			printk(" %s",
> +			       link_duplex[lnk_status->mac1_duplex]);
> +		else
> +			printk(" %s", link_duplex[0]);
> +
> +		if (lnk_status->active_port == 1)
> +			printk("(active)\n");
> +		else
> +			printk("\n");
> +	} else
> +		printk(" Down \n");
> +
> +	return;
> +}
> +
> +int benet_open(struct net_device *netdev)
> +{
> +	PBNI_NET_OBJECT pnob = (BNI_NET_OBJECT *) netdev->priv;
> +	PBE_ADAPTER adapter = OSM_NOB(pnob)->adapter;
> +
> +	TRACE(DL_INIT, "entered-benet_open()");
> +
> +	if (adapter->dev_state < BE_DEV_STATE_INIT)
> +		return -EAGAIN;
> +
> +	be_update_link_status(adapter);
> +
> +	/*
> +	 * Set carrier on only if Physical Link up
> +	 * Either of the port link status up signifies this
> +	 */
> +	if ((adapter->port0_link_sts == BE_PORT_LINK_UP) ||
> +	    (adapter->port1_link_sts == BE_PORT_LINK_UP)) {
> +		netif_start_queue(netdev);
> +		netif_carrier_on(netdev);
> +	}
> +
> +	enable_eq_intr(pnob);
> +	adapter->dev_state = BE_DEV_STATE_OPEN;
> +
> +#ifdef CONFIG_BENET_NAPI
> +	napi_enable(&OSM_NOB(pnob)->napi);
> +#endif
> +	return 0;
> +}
> +
> +int benet_close(struct net_device *netdev)
> +{
> +	PBNI_NET_OBJECT pnob = (BNI_NET_OBJECT *) netdev->priv;
> +	PBE_ADAPTER adapter = OSM_NOB(pnob)->adapter;
> +
> +	/* Stop Transmitting */
> +	netif_stop_queue(netdev);
> +
> +	synchronize_irq(netdev->irq);
> +
> +	/* Wait until no more pending transmits  */
> +	wait_nic_tx_cmpl(pnob);
> +
> +	adapter->dev_state = BE_DEV_STATE_INIT;
> +
> +	netif_carrier_off(netdev);
> +
> +	adapter->port0_link_sts = BE_PORT_LINK_DOWN;
> +	adapter->port1_link_sts = BE_PORT_LINK_DOWN;
> +
> +#ifdef CONFIG_BENET_NAPI
> +	napi_disable(&OSM_NOB(pnob)->napi);
> +#endif
> +	return 0;
> +}
> +
> +int benet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
> +{
> +	TRACE(DL_INIT, "entered benet_ioctl()");
> +
> +	switch (cmd) {
> +	case SIOCETHTOOL:
> +		return be_ethtool_ioctl(dev, ifr);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
> +/*
> + * Setting a Mac Address for BE
> + * Takes netdev and a void pointer as arguments.
> + * The pointer holds the new addres to be used.
> + */
> +int benet_set_mac_addr(struct net_device *netdev, void *p)
> +{
> +	struct sockaddr *addr = p;
> +	PBNI_NET_OBJECT pnob;
> +	SA_MAC_ADDRESS mac_addr;
> +
> +	SA_ASSERT(netdev);
> +	pnob = (PBNI_NET_OBJECT) netdev->priv;
> +	SA_ASSERT(pnob);
> +
> +	memcpy(pnob->mac_address, addr->sa_data, netdev->addr_len);
> +	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
> +	memcpy(mac_addr.bytes, pnob->mac_address,
> SA_MAC_ADDRESS_SIZE);
> +	bni_set_uc_mac_adr(pnob, 0, 0, OSM_NOB(pnob)->devno,
> +			   &mac_addr, NULL, NULL);
> +	/*
> +	 * Since we are doing Active-Passive failover, both
> +	 * ports should have matching MAC addresses everytime.
> +	 */
> +	bni_set_uc_mac_adr(pnob, 1, 0, OSM_NOB(pnob)->devno,
> +			   &mac_addr, NULL, NULL);
> +
> +	return 0;
> +}
> +
> +void get_stats_timer_handler(unsigned long context)
> +{
> +	be_timer_ctxt_t *ctxt = (be_timer_ctxt_t *) context;
> +	if (atomic_read(&ctxt->get_stat_flag)) {
> +		atomic_dec(&ctxt->get_stat_flag);
> +		up((PVOID) ctxt->get_stat_sem);
> +	}
> +	del_timer(&ctxt->get_stats_timer);
> +	return;
> +}
> +
> +void get_stat_cb(PVOID context, BESTATUS status, MCC_WRB
> *optional_wrb) +{
> +	be_timer_ctxt_t *ctxt = (be_timer_ctxt_t *) context;
> +	/*
> +	 * just up the semaphore if the get_stat_flag
> +	 * reads 1. so that the waiter can continue.
> +	 * If it is 0, then it was handled by the timer handler.
> +	 */
> +	if (atomic_read(&ctxt->get_stat_flag)) {
> +		atomic_dec(&ctxt->get_stat_flag);
> +		up((PVOID) ctxt->get_stat_sem);
> +	}
> +}
> +
> +struct net_device_stats *benet_get_stats(struct net_device *dev)
> +{
> +	PBNI_NET_OBJECT pnob = dev->priv;
> +	PBE_ADAPTER adapter = OSM_NOB(pnob)->adapter;
> +	u64 pa;
> +	be_timer_ctxt_t *ctxt = adapter->ctxt;
> +
> +	if (!BE_DEV_STATE_OPEN(adapter) || (pm_resume)) {
> +		/* Return previously read stats */
> +		return &(adapter->benet_stats);
> +	}
> +	/* Get Physical Addr */
> +	pa = pci_map_single(adapter->pdev, adapter->eth_statsp,
> +			    sizeof(IOCTL_ETH_GET_STATISTICS),
> +			    PCI_DMA_FROMDEVICE);
> +	pa = cpu_to_le64(pa);
> +	ctxt->get_stat_sem = (unsigned
> long)&adapter->get_eth_stat_sem;
> +	bni_get_stats(adapter->net_obj, adapter->eth_statsp,
> +		      pa, get_stat_cb, (PVOID) ctxt);
> +	atomic_inc(&ctxt->get_stat_flag);
> +	ctxt->get_stats_timer.data = (unsigned long)ctxt;
> +	mod_timer(&ctxt->get_stats_timer, (jiffies + (HZ * 2)));
> +	down((PVOID) ctxt->get_stat_sem); /* block till callback is
> called */ +
> +	/*Adding port0 and port1 stats. */
> +	adapter->benet_stats.rx_packets =
> +	    adapter->eth_statsp->params.response.p0recvdtotalframes +
> +	    adapter->eth_statsp->params.response.p1recvdtotalframes;
> +	adapter->benet_stats.tx_packets =
> +	    adapter->eth_statsp->params.response.p0xmitunicastframes
> +
> +	    adapter->eth_statsp->params.response.p1xmitunicastframes;
> +	adapter->benet_stats.tx_bytes =
> +	    adapter->eth_statsp->params.response.p0xmitbyteslsd +
> +	    adapter->eth_statsp->params.response.p1xmitbyteslsd;
> +	adapter->benet_stats.rx_errors =
> +	    adapter->eth_statsp->params.response.p0crcerrors +
> +	    adapter->eth_statsp->params.response.p1crcerrors;
> +	adapter->benet_stats.rx_errors +=
> +	    adapter->eth_statsp->params.response.p0alignmentsymerrs +
> +	    adapter->eth_statsp->params.response.p1alignmentsymerrs;
> +	adapter->benet_stats.rx_errors +=
> +	    adapter->eth_statsp->params.response.p0inrangelenerrors +
> +	    adapter->eth_statsp->params.response.p1inrangelenerrors;
> +	adapter->benet_stats.rx_bytes =
> +
> adapter->eth_statsp->params.response.p0recvdtotalbytesLSD +
> +
> adapter->eth_statsp->params.response.p1recvdtotalbytesLSD;
> +	adapter->benet_stats.rx_crc_errors =
> +	    adapter->eth_statsp->params.response.p0crcerrors +
> +	    adapter->eth_statsp->params.response.p1crcerrors;
> +
> +	adapter->benet_stats.tx_packets +=
> +
> adapter->eth_statsp->params.response.p0xmitmulticastframes +
> +
> adapter->eth_statsp->params.response.p1xmitmulticastframes;
> +	adapter->benet_stats.tx_packets +=
> +
> adapter->eth_statsp->params.response.p0xmitbroadcastframes +
> +
> adapter->eth_statsp->params.response.p1xmitbroadcastframes;
> +	adapter->benet_stats.tx_errors = 0;
> +
> +	adapter->benet_stats.multicast =
> +
> adapter->eth_statsp->params.response.p0xmitmulticastframes +
> +
> adapter->eth_statsp->params.response.p1xmitmulticastframes; +
> +	adapter->benet_stats.rx_fifo_errors =
> +
> adapter->eth_statsp->params.response.p0rxfifooverflowdropped +
> +
> adapter->eth_statsp->params.response.p1rxfifooverflowdropped;
> +	adapter->benet_stats.rx_frame_errors =
> +	    adapter->eth_statsp->params.response.p0alignmentsymerrs +
> +	    adapter->eth_statsp->params.response.p1alignmentsymerrs;
> +	adapter->benet_stats.rx_length_errors =
> +	    adapter->eth_statsp->params.response.p0inrangelenerrors +
> +	    adapter->eth_statsp->params.response.p1inrangelenerrors;
> +	adapter->benet_stats.rx_length_errors +=
> +	    adapter->eth_statsp->params.response.p0outrangeerrors +
> +	    adapter->eth_statsp->params.response.p1outrangeerrors;
> +	adapter->benet_stats.rx_length_errors +=
> +
> adapter->eth_statsp->params.response.p0frametoolongerrors +
> +
> adapter->eth_statsp->params.response.p1frametoolongerrors; +
> +	pci_unmap_single(adapter->pdev, (ulong) adapter->eth_statsp,
> +			 sizeof(IOCTL_ETH_GET_STATISTICS),
> +			 PCI_DMA_FROMDEVICE);
> +	return &(adapter->benet_stats);
> +
> +}
> +
> +/*
> + * function called by the stack for transmitting an ether frame
> + */
> +int benet_xmit(struct sk_buff *skb, struct net_device *netdev)
> +{
> +	PBNI_NET_OBJECT pnob = netdev->priv;
> +	PBE_ADAPTER adapter = OSM_NOB(pnob)->adapter;
> +	u8 proto;
> +	struct iphdr *ip;
> +	u16 lso_mss;
> +#ifdef NETIF_F_TSO
> +	u32 segs;
> +
> +	lso_mss = skb_shinfo(skb)->gso_size;
> +	segs = skb_shinfo(skb)->gso_segs;
> +	/*
> +	 * bug# 3356.
> +	 * If a LSO request translates into a single segment,
> +	 * it should be posted as a ethernet WRB with no LSO.
> +	 */
> +	if (segs == 1)
> +		lso_mss = 0;
> +#else
> +	lso_mss = 0;
> +#endif /*TSO */
> +
> +	TRACE(DL_SEND, "benet_xmit: Entry... len = %d", skb->len);
> +
> +	if (skb->ip_summed == CHECKSUM_PARTIAL) {
> +		ip = (struct iphdr *)ip_hdr(skb);
> +		proto = ip->protocol;
> +	} else {
> +		proto = 0;
> +	}
> +
> +	if (betx_ether_frame(adapter, pnob, skb, proto, 0,
> lso_mss) !=
> +						BE_SUCCESS) {
> +		return 1;	/* NETDEV_TX_BUSY */
> +	}
> +
> +	netdev->trans_start = jiffies;
> +	TRACE(DL_SEND, "benet_xmit() : Exit");
> +	return 0;		/*NETDEV_TX_OK */
> +
> +}
> +
> +/*
> + * This is the driver entry point to change the mtu of the device
> + * Returns 0 for success and errno for failure.
> + */
> +int benet_change_mtu(struct net_device *netdev, int new_mtu)
> +{
> +	u32 mtu, max_mtu, max_hdr;
> +	max_hdr = BE_ENET_HEADER_SIZE + BE_ETHERNET_FCS_SIZE +
> +	    BE_SNAP_HEADER_SIZE + BE_HEADER_802_2_SIZE;
> +
> +	if (netdev->priv_flags & IFF_802_1Q_VLAN)
> +		max_hdr += BE_VLAN_HEADER_SIZE;
> +
> +	mtu = new_mtu + max_hdr;
> +
> +	/*
> +	 * BE supports jumbo frame size upto 9000 bytes including
> the link layer
> +	 * header. Considering the different variants of frame
> formats possible
> +	 * like VLAN, SNAP/LLC, the maximum possible value for MTU
> is 8974 bytes
> +	 */
> +	max_mtu = BE_MAX_JUMBO_FRAME_SIZE;
> +
> +	if ((mtu < BE_MIN_ETHER_FRAME_SIZE) || (mtu > max_mtu)) {
> +		printk(KERN_WARNING "Invalid MTU requested. "
> +		       "Must be between %d and %d bytes\n",
> +		       BE_MIN_SUPPORT_FRAME_SIZE, (max_mtu -
> max_hdr));
> +		return -EINVAL;
> +	}
> +	printk(KERN_INFO "MTU changed from %d to %d\n", netdev->mtu,
> +	       new_mtu);
> +	netdev->mtu = new_mtu;
> +	return 0;
> +}
> +
> +/*
> + * This is the driver entry point to register a vlan with the device
> + */
> +void benet_vlan_register(struct net_device *netdev, struct
> vlan_group *grp) +{
> +	PBNI_NET_OBJECT pnob = netdev->priv;
> +
> +	TRACE(DL_VLAN, "vlan register called");
> +
> +	disable_eq_intr(pnob);
> +	OSM_NOB(pnob)->vlan_grp = grp;
> +	OSM_NOB(pnob)->num_vlans = 0;
> +	enable_eq_intr(pnob);
> +}
> +
> +/*
> + * This is the driver entry point to add a vlan vlan_id
> + * with the device netdev
> + */
> +void benet_vlan_add_vid(struct net_device *netdev, u16 vlan_id)
> +{
> +	PBNI_NET_OBJECT pnob = netdev->priv;
> +
> +	TRACE(DL_VLAN, "Add vlan ID");
> +	if (OSM_NOB(pnob)->num_vlans == (BE_NUM_VLAN_SUPPORTED-1)) {
> +		/* no  way to return an error */
> +		printk(KERN_ERR
> +			"BladeEngine: Cannot configure more than %d
> Vlans\n",
> +				BE_NUM_VLAN_SUPPORTED);
> +		return;
> +	}
> +	/*The new vlan tag will be in the slot indicated by
> num_vlans. */
> +	OSM_NOB(pnob)->vlan_tag[OSM_NOB(pnob)->num_vlans++] =
> vlan_id;
> +	bni_config_vlan(pnob, OSM_NOB(pnob)->vlan_tag,
> +			OSM_NOB(pnob)->num_vlans, NULL, NULL, 0);
> +}
> +
> +/*
> + * This is the driver entry point to remove a vlan vlan_id
> + * with the device netdev
> + */
> +void benet_vlan_rem_vid(struct net_device *netdev, u16 vlan_id)
> +{
> +	PBNI_NET_OBJECT pnob = netdev->priv;
> +
> +	u32 i, value;
> +
> +	TRACE(DL_VLAN, "Remove vlan ID");
> +	/*
> +	 * In Blade Engine, we support 32 vlan tag filters across
> both ports.
> +	 * To program a vlan tag, the RXF_RTPR_CSR register is used.
> +	 * Each 32-bit value of RXF_RTDR_CSR can address 2 vlan tag
> entries.
> +	 * The Vlan table is of depth 16. thus we support 32 tags.
> +	 */
> +
> +	value = vlan_id | VLAN_VALID_BIT;
> +	TRACE(DL_VLAN, "Value is %x", value);
> +	TRACE(DL_VLAN, "Number of vlan tags is %d",
> OSM_NOB(pnob)->num_vlans);
> +	for (i = 0; i < BE_NUM_VLAN_SUPPORTED; i++) {
> +		TRACE(DL_VLAN, "Value at index %d is %x", i,
> +		      OSM_NOB(pnob)->vlan_tag[i]);
> +		if (OSM_NOB(pnob)->vlan_tag[i] == vlan_id) {
> +			TRACE(DL_VLAN, "Vlan ID found at index %d",
> i);
> +			break;
> +		}
> +	}
> +
> +	if (i == BE_NUM_VLAN_SUPPORTED) {
> +		TRACE(DL_VLAN, "Vlan ID %d not dound - remove
> failed", value);
> +		return;
> +	}
> +	/* Now compact the vlan tag array by removing hole created.
> */
> +	while ((i + 1) < BE_NUM_VLAN_SUPPORTED) {
> +		OSM_NOB(pnob)->vlan_tag[i] =
> OSM_NOB(pnob)->vlan_tag[i + 1];
> +		i++;
> +	}
> +	if ((i + 1) == BE_NUM_VLAN_SUPPORTED) {
> +		OSM_NOB(pnob)->vlan_tag[i] = (u16) 0x0;
> +	}
> +	OSM_NOB(pnob)->num_vlans--;
> +	bni_config_vlan(pnob, OSM_NOB(pnob)->vlan_tag,
> +			OSM_NOB(pnob)->num_vlans, NULL, NULL, 0);
> +	TRACE(DL_VLAN, "Removed the vlan ID of %d", vlan_id);
> +}
> +
> +/*
> + * This function is called to program multicast
> + * address in the multicast filter of the ASIC.
> + */
> +void be_set_multicast_filter(struct net_device *netdev)
> +{
> +	PBNI_NET_OBJECT pnob = netdev->priv;
> +	struct dev_mc_list *mc_ptr;
> +	SA_MAC_ADDRESS mac_addr[32];
> +	int i;
> +
> +	if (netdev->flags & IFF_ALLMULTI) {
> +		/* set BE in Multicast promiscuous */
> +		bni_set_mc_filter(pnob, 0, TRUE, NULL, NULL, NULL);
> +		return;
> +	}
> +
> +	for (mc_ptr = netdev->mc_list, i = 0; mc_ptr;
> +	     mc_ptr = mc_ptr->next, i++) {
> +		memcpy(mac_addr[i].bytes, mc_ptr->dmi_addr,
> +		       SA_MAC_ADDRESS_SIZE);
> +	}
> +	/* reset the promiscuous mode also. */
> +	bni_set_mc_filter(pnob, i, FALSE, mac_addr, NULL, NULL);
> +
> +}
> +
> +/*
> + * This is the driver entry point to set multicast list
> + * with the device netdev. This function will be used to
> + * set promiscuous mode or multicast promiscuous mode
> + * or multicast mode....
> + */
> +void benet_set_multicast_list(struct net_device *netdev)
> +{
> +	PBNI_NET_OBJECT pnob = netdev->priv;
> +	PBE_ADAPTER adapter = OSM_NOB(pnob)->adapter;
> +
> +	if (netdev->flags & IFF_PROMISC) {
> +		bni_set_promisc(adapter->net_obj);
> +
> +	} else if (netdev->flags & IFF_ALLMULTI) {
> +		bni_reset_promisc(adapter->net_obj);
> +		be_set_multicast_filter(netdev);
> +	} else {
> +		bni_reset_promisc(adapter->net_obj);
> +		be_set_multicast_filter(netdev);
> +	}
> +}
> +
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +static void be_netpoll(struct net_device *netdev)
> +{
> +	disable_irq(netdev->irq);
> +	be_int(netdev->irq, netdev, NULL);
> +	enable_irq(netdev->irq);
> +}
> +#endif
> +
> +/*
> + * standard entry point functions for all Linux network interface
> drivers
> + */
> +int benet_probe(struct net_device *netdev)
> +{
> +	PBNI_NET_OBJECT pnob = netdev->priv;
> +	PBE_ADAPTER adapter = OSM_NOB(pnob)->adapter;
> +
> +	TRACE(DL_INIT, "entered-benet_probe().");
> +
> +	ether_setup(netdev);
> +
> +	netdev->open = &benet_open;
> +	netdev->stop = &benet_close;
> +	netdev->do_ioctl = &benet_ioctl;
> +
> +	netdev->hard_start_xmit = &benet_xmit;
> +
> +	netdev->get_stats = &benet_get_stats;
> +
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +	netdev->poll_controller = &be_netpoll;
> +#endif
> +
> +	netdev->set_multicast_list = &benet_set_multicast_list;
> +
> +	netdev->change_mtu = &benet_change_mtu;
> +	netdev->set_mac_address = &benet_set_mac_addr;
> +
> +	netdev->vlan_rx_register = benet_vlan_register;
> +	netdev->vlan_rx_add_vid = benet_vlan_add_vid;
> +	netdev->vlan_rx_kill_vid = benet_vlan_rem_vid;
> +
> +	netdev->features =
> +	    NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_RX |
> +	    NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
> NETIF_F_IP_CSUM; +
> +	netdev->flags |= IFF_MULTICAST;
> +
> +	/* If device is DAC Capable, set the HIGHDMA flag for
> netdevice. */
> +	if (adapter->dma_64bit_cap)
> +		netdev->features |= NETIF_F_HIGHDMA;
> +
> +#ifdef NETIF_F_TSO

NETIF_F_TSO is always defined.

> +	netdev->features |= NETIF_F_TSO;
> +#endif
> +
> +	be_set_ethtool_ops(netdev);
> +
> +	return 0;
> +}
> 
> ___________________________________________________________________________________
> This message, together with any attachment(s), contains confidential
> and proprietary information of ServerEngines Corporation and is
> intended only for the designated recipient(s) named above. Any
> unauthorized review, printing, retention, copying, disclosure or
> distribution is strictly prohibited.  If you are not the intended
> recipient of this message, please immediately advise the sender by
> reply email message and delete all copies of this message and any
> attachment(s). Thank you.
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ