summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-06-27 11:28:02 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-06-27 11:28:02 -0700
commit31cafd958932a90174118ad062fdc37ffb6bf31c (patch)
tree21f04c11d9e759c1f65cfaa1e4fbd79ee1e60753 /drivers
parente7865c234fff2db474f21a62b2f906a70317c972 (diff)
parente2f5b04563786d4b7d7648868de7e941a0649372 (diff)
downloadlinux-31cafd958932a90174118ad062fdc37ffb6bf31c.tar.gz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (52 commits)
  phylib: Add autoload support for the LXT973 phy.
  ISDN: hysdn, fix potential NULL dereference
  vxge: fix memory leak in vxge_alloc_msix() error path
  isdn/gigaset: correct CAPI connection state storage
  isdn/gigaset: encode HLC and BC together
  isdn/gigaset: correct CAPI DATA_B3 Delivery Confirmation
  isdn/gigaset: correct CAPI voice connection encoding
  isdn/gigaset: honor CAPI application's buffer size request
  cpmac: do not leak struct net_device on phy_connect errors
  smc91c92_cs: fix the problem that lan & modem does not work simultaneously
  ipv6: fix NULL reference in proxy neighbor discovery
  Bluetooth: Bring back var 'i' increment
  xfrm: check bundle policy existance before dereferencing it
  sky2: enable rx/tx in sky2_phy_reinit()
  cnic: Disable statistics initialization for eth clients that do not support statistics
  net: add dependency on fw class module to qlcnic and netxen_nic
  snmp: fix SNMP_ADD_STATS()
  hso: remove setting of low_latency flag
  udp: Fix bogus UFO packet generation
  lasi82596: fix netdev_mc_count conversion
  ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/isdn/gigaset/asyncdata.c44
-rw-r--r--drivers/isdn/gigaset/capi.c405
-rw-r--r--drivers/isdn/gigaset/common.c36
-rw-r--r--drivers/isdn/gigaset/ev-layer.c4
-rw-r--r--drivers/isdn/gigaset/gigaset.h38
-rw-r--r--drivers/isdn/gigaset/i4l.c21
-rw-r--r--drivers/isdn/gigaset/isocdata.c72
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c3
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/bnx2.c11
-rw-r--r--drivers/net/cnic.c55
-rw-r--r--drivers/net/cpmac.c3
-rw-r--r--drivers/net/e1000/e1000_main.c17
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c9
-rw-r--r--drivers/net/enic/vnic_dev.c2
-rw-r--r--drivers/net/gianfar.c25
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c37
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c4
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c2
-rw-r--r--drivers/net/lib82596.c2
-rw-r--r--drivers/net/mipsnet.c2
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c3
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c4
-rw-r--r--drivers/net/netxen/netxen_nic_init.c13
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c1
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c18
-rw-r--r--drivers/net/phy/lxt.c1
-rw-r--r--drivers/net/sky2.c19
-rw-r--r--drivers/net/ucc_geth.c2
-rw-r--r--drivers/net/usb/hso.c1
-rw-r--r--drivers/net/vxge/vxge-main.c29
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c15
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c13
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c9
-rw-r--r--drivers/net/wireless/libertas_tf/main.c2
-rw-r--r--drivers/net/wireless/p54/p54pci.c2
-rw-r--r--drivers/serial/serial_cs.c1
44 files changed, 592 insertions, 358 deletions
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index c5016bd2d94f..c3b1dc3a13a0 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -126,26 +126,6 @@ static unsigned lock_loop(unsigned numbytes, struct inbuf_t *inbuf)
 	return numbytes;
 }
 
-/* set up next receive skb for data mode
- */
-static void new_rcv_skb(struct bc_state *bcs)
-{
-	struct cardstate *cs = bcs->cs;
-	unsigned short hw_hdr_len = cs->hw_hdr_len;
-
-	if (bcs->ignore) {
-		bcs->skb = NULL;
-		return;
-	}
-
-	bcs->skb = dev_alloc_skb(SBUFSIZE + hw_hdr_len);
-	if (bcs->skb == NULL) {
-		dev_warn(cs->dev, "could not allocate new skb\n");
-		return;
-	}
-	skb_reserve(bcs->skb, hw_hdr_len);
-}
-
 /* process a block of received bytes in HDLC data mode
  * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 == L2_HDLC)
  * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes.
@@ -159,8 +139,8 @@ static unsigned hdlc_loop(unsigned numbytes, struct inbuf_t *inbuf)
 	struct cardstate *cs = inbuf->cs;
 	struct bc_state *bcs = cs->bcs;
 	int inputstate = bcs->inputstate;
-	__u16 fcs = bcs->fcs;
-	struct sk_buff *skb = bcs->skb;
+	__u16 fcs = bcs->rx_fcs;
+	struct sk_buff *skb = bcs->rx_skb;
 	unsigned char *src = inbuf->data + inbuf->head;
 	unsigned procbytes = 0;
 	unsigned char c;
@@ -245,8 +225,7 @@ byte_stuff:
 
 				/* prepare reception of next frame */
 				inputstate &= ~INS_have_data;
-				new_rcv_skb(bcs);
-				skb = bcs->skb;
+				skb = gigaset_new_rx_skb(bcs);
 			} else {
 				/* empty frame (7E 7E) */
 #ifdef CONFIG_GIGASET_DEBUG
@@ -255,8 +234,7 @@ byte_stuff:
 				if (!skb) {
 					/* skipped (?) */
 					gigaset_isdn_rcv_err(bcs);
-					new_rcv_skb(bcs);
-					skb = bcs->skb;
+					skb = gigaset_new_rx_skb(bcs);
 				}
 			}
 
@@ -279,11 +257,11 @@ byte_stuff:
 #endif
 		inputstate |= INS_have_data;
 		if (skb) {
-			if (skb->len == SBUFSIZE) {
+			if (skb->len >= bcs->rx_bufsize) {
 				dev_warn(cs->dev, "received packet too long\n");
 				dev_kfree_skb_any(skb);
 				/* skip remainder of packet */
-				bcs->skb = skb = NULL;
+				bcs->rx_skb = skb = NULL;
 			} else {
 				*__skb_put(skb, 1) = c;
 				fcs = crc_ccitt_byte(fcs, c);
@@ -292,7 +270,7 @@ byte_stuff:
 	}
 
 	bcs->inputstate = inputstate;
-	bcs->fcs = fcs;
+	bcs->rx_fcs = fcs;
 	return procbytes;
 }
 
@@ -308,18 +286,18 @@ static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf)
 	struct cardstate *cs = inbuf->cs;
 	struct bc_state *bcs = cs->bcs;
 	int inputstate = bcs->inputstate;
-	struct sk_buff *skb = bcs->skb;
+	struct sk_buff *skb = bcs->rx_skb;
 	unsigned char *src = inbuf->data + inbuf->head;
 	unsigned procbytes = 0;
 	unsigned char c;
 
 	if (!skb) {
 		/* skip this block */
-		new_rcv_skb(bcs);
+		gigaset_new_rx_skb(bcs);
 		return numbytes;
 	}
 
-	while (procbytes < numbytes && skb->len < SBUFSIZE) {
+	while (procbytes < numbytes && skb->len < bcs->rx_bufsize) {
 		c = *src++;
 		procbytes++;
 
@@ -343,7 +321,7 @@ static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf)
 	if (inputstate & INS_have_data) {
 		gigaset_skb_rcvd(bcs, skb);
 		inputstate &= ~INS_have_data;
-		new_rcv_skb(bcs);
+		gigaset_new_rx_skb(bcs);
 	}
 
 	bcs->inputstate = inputstate;
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 8f78f15c8ef7..6fbe8999c419 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -70,7 +70,7 @@
 #define MAX_NUMBER_DIGITS 20
 #define MAX_FMT_IE_LEN 20
 
-/* values for gigaset_capi_appl.connected */
+/* values for bcs->apconnstate */
 #define APCONN_NONE	0	/* inactive/listening */
 #define APCONN_SETUP	1	/* connecting */
 #define APCONN_ACTIVE	2	/* B channel up */
@@ -80,10 +80,10 @@ struct gigaset_capi_appl {
 	struct list_head ctrlist;
 	struct gigaset_capi_appl *bcnext;
 	u16 id;
+	struct capi_register_params rp;
 	u16 nextMessageNumber;
 	u32 listenInfoMask;
 	u32 listenCIPmask;
-	int connected;
 };
 
 /* CAPI specific controller data structure */
@@ -319,6 +319,39 @@ static const char *format_ie(const char *ie)
 	return result;
 }
 
+/*
+ * emit DATA_B3_CONF message
+ */
+static void send_data_b3_conf(struct cardstate *cs, struct capi_ctr *ctr,
+			      u16 appl, u16 msgid, int channel,
+			      u16 handle, u16 info)
+{
+	struct sk_buff *cskb;
+	u8 *msg;
+
+	cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
+	if (!cskb) {
+		dev_err(cs->dev, "%s: out of memory\n", __func__);
+		return;
+	}
+	/* frequent message, avoid _cmsg overhead */
+	msg = __skb_put(cskb, CAPI_DATA_B3_CONF_LEN);
+	CAPIMSG_SETLEN(msg, CAPI_DATA_B3_CONF_LEN);
+	CAPIMSG_SETAPPID(msg, appl);
+	CAPIMSG_SETCOMMAND(msg, CAPI_DATA_B3);
+	CAPIMSG_SETSUBCOMMAND(msg,  CAPI_CONF);
+	CAPIMSG_SETMSGID(msg, msgid);
+	CAPIMSG_SETCONTROLLER(msg, ctr->cnr);
+	CAPIMSG_SETPLCI_PART(msg, channel);
+	CAPIMSG_SETNCCI_PART(msg, 1);
+	CAPIMSG_SETHANDLE_CONF(msg, handle);
+	CAPIMSG_SETINFO_CONF(msg, info);
+
+	/* emit message */
+	dump_rawmsg(DEBUG_MCMD, __func__, msg);
+	capi_ctr_handle_message(ctr, appl, cskb);
+}
+
 
 /*
  * driver interface functions
@@ -339,7 +372,6 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
 	struct gigaset_capi_ctr *iif = cs->iif;
 	struct gigaset_capi_appl *ap = bcs->ap;
 	unsigned char *req = skb_mac_header(dskb);
-	struct sk_buff *cskb;
 	u16 flags;
 
 	/* update statistics */
@@ -351,39 +383,22 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
 	}
 
 	/* don't send further B3 messages if disconnected */
-	if (ap->connected < APCONN_ACTIVE) {
+	if (bcs->apconnstate < APCONN_ACTIVE) {
 		gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
 		return;
 	}
 
-	/* ToDo: honor unset "delivery confirmation" bit */
+	/*
+	 * send DATA_B3_CONF if "delivery confirmation" bit was set in request;
+	 * otherwise it has already been sent by do_data_b3_req()
+	 */
 	flags = CAPIMSG_FLAGS(req);
-
-	/* build DATA_B3_CONF message */
-	cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
-	if (!cskb) {
-		dev_err(cs->dev, "%s: out of memory\n", __func__);
-		return;
-	}
-	/* frequent message, avoid _cmsg overhead */
-	CAPIMSG_SETLEN(cskb->data, CAPI_DATA_B3_CONF_LEN);
-	CAPIMSG_SETAPPID(cskb->data, ap->id);
-	CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3);
-	CAPIMSG_SETSUBCOMMAND(cskb->data,  CAPI_CONF);
-	CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(req));
-	CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr);
-	CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1);
-	CAPIMSG_SETNCCI_PART(cskb->data, 1);
-	CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(req));
-	if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION)
-		CAPIMSG_SETINFO_CONF(cskb->data,
-				     CapiFlagsNotSupportedByProtocol);
-	else
-		CAPIMSG_SETINFO_CONF(cskb->data, CAPI_NOERROR);
-
-	/* emit message */
-	dump_rawmsg(DEBUG_LLDATA, "DATA_B3_CONF", cskb->data);
-	capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
+	if (flags & CAPI_FLAGS_DELIVERY_CONFIRMATION)
+		send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req),
+				  bcs->channel + 1, CAPIMSG_HANDLE_REQ(req),
+				  (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ?
+					CapiFlagsNotSupportedByProtocol :
+					CAPI_NOERROR);
 }
 EXPORT_SYMBOL_GPL(gigaset_skb_sent);
 
@@ -412,7 +427,7 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
 	}
 
 	/* don't send further B3 messages if disconnected */
-	if (ap->connected < APCONN_ACTIVE) {
+	if (bcs->apconnstate < APCONN_ACTIVE) {
 		gig_dbg(DEBUG_LLDATA, "disconnected, discarding data");
 		dev_kfree_skb_any(skb);
 		return;
@@ -484,6 +499,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
 	u32 actCIPmask;
 	struct sk_buff *skb;
 	unsigned int msgsize;
+	unsigned long flags;
 	int i;
 
 	/*
@@ -608,7 +624,14 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
 		format_ie(iif->hcmsg.CalledPartyNumber));
 
 	/* scan application list for matching listeners */
-	bcs->ap = NULL;
+	spin_lock_irqsave(&bcs->aplock, flags);
+	if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE) {
+		dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n",
+			 __func__, bcs->ap, bcs->apconnstate);
+		bcs->ap = NULL;
+		bcs->apconnstate = APCONN_NONE;
+	}
+	spin_unlock_irqrestore(&bcs->aplock, flags);
 	actCIPmask = 1 | (1 << iif->hcmsg.CIPValue);
 	list_for_each_entry(ap, &iif->appls, ctrlist)
 		if (actCIPmask & ap->listenCIPmask) {
@@ -626,10 +649,12 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
 			dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
 
 			/* add to listeners on this B channel, update state */
+			spin_lock_irqsave(&bcs->aplock, flags);
 			ap->bcnext = bcs->ap;
 			bcs->ap = ap;
 			bcs->chstate |= CHS_NOTIFY_LL;
-			ap->connected = APCONN_SETUP;
+			bcs->apconnstate = APCONN_SETUP;
+			spin_unlock_irqrestore(&bcs->aplock, flags);
 
 			/* emit message */
 			capi_ctr_handle_message(&iif->ctr, ap->id, skb);
@@ -654,7 +679,7 @@ static void send_disconnect_ind(struct bc_state *bcs,
 	struct gigaset_capi_ctr *iif = cs->iif;
 	struct sk_buff *skb;
 
-	if (ap->connected == APCONN_NONE)
+	if (bcs->apconnstate == APCONN_NONE)
 		return;
 
 	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT, CAPI_IND,
@@ -668,7 +693,6 @@ static void send_disconnect_ind(struct bc_state *bcs,
 	}
 	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN));
 	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
-	ap->connected = APCONN_NONE;
 	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
 }
 
@@ -685,9 +709,9 @@ static void send_disconnect_b3_ind(struct bc_state *bcs,
 	struct sk_buff *skb;
 
 	/* nothing to do if no logical connection active */
-	if (ap->connected < APCONN_ACTIVE)
+	if (bcs->apconnstate < APCONN_ACTIVE)
 		return;
-	ap->connected = APCONN_SETUP;
+	bcs->apconnstate = APCONN_SETUP;
 
 	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
 			 ap->nextMessageNumber++,
@@ -714,14 +738,25 @@ void gigaset_isdn_connD(struct bc_state *bcs)
 {
 	struct cardstate *cs = bcs->cs;
 	struct gigaset_capi_ctr *iif = cs->iif;
-	struct gigaset_capi_appl *ap = bcs->ap;
+	struct gigaset_capi_appl *ap;
 	struct sk_buff *skb;
 	unsigned int msgsize;
+	unsigned long flags;
 
+	spin_lock_irqsave(&bcs->aplock, flags);
+	ap = bcs->ap;
 	if (!ap) {
+		spin_unlock_irqrestore(&bcs->aplock, flags);
 		dev_err(cs->dev, "%s: no application\n", __func__);
 		return;
 	}
+	if (bcs->apconnstate == APCONN_NONE) {
+		spin_unlock_irqrestore(&bcs->aplock, flags);
+		dev_warn(cs->dev, "%s: application %u not connected\n",
+			 __func__, ap->id);
+		return;
+	}
+	spin_unlock_irqrestore(&bcs->aplock, flags);
 	while (ap->bcnext) {
 		/* this should never happen */
 		dev_warn(cs->dev, "%s: dropping extra application %u\n",
@@ -730,11 +765,6 @@ void gigaset_isdn_connD(struct bc_state *bcs)
 				    CapiCallGivenToOtherApplication);
 		ap->bcnext = ap->bcnext->bcnext;
 	}
-	if (ap->connected == APCONN_NONE) {
-		dev_warn(cs->dev, "%s: application %u not connected\n",
-			 __func__, ap->id);
-		return;
-	}
 
 	/* prepare CONNECT_ACTIVE_IND message
 	 * Note: LLC not supported by device
@@ -772,17 +802,24 @@ void gigaset_isdn_connD(struct bc_state *bcs)
 void gigaset_isdn_hupD(struct bc_state *bcs)
 {
 	struct gigaset_capi_appl *ap;
+	unsigned long flags;
 
 	/*
 	 * ToDo: pass on reason code reported by device
 	 * (requires ev-layer state machine extension to collect
 	 * ZCAU device reply)
 	 */
-	for (ap = bcs->ap; ap != NULL; ap = ap->bcnext) {
+	spin_lock_irqsave(&bcs->aplock, flags);
+	while (bcs->ap != NULL) {
+		ap = bcs->ap;
+		bcs->ap = ap->bcnext;
+		spin_unlock_irqrestore(&bcs->aplock, flags);
 		send_disconnect_b3_ind(bcs, ap);
 		send_disconnect_ind(bcs, ap, 0);
+		spin_lock_irqsave(&bcs->aplock, flags);
 	}
-	bcs->ap = NULL;
+	bcs->apconnstate = APCONN_NONE;
+	spin_unlock_irqrestore(&bcs->aplock, flags);
 }
 
 /**
@@ -796,24 +833,21 @@ void gigaset_isdn_connB(struct bc_state *bcs)
 {
 	struct cardstate *cs = bcs->cs;
 	struct gigaset_capi_ctr *iif = cs->iif;
-	struct gigaset_capi_appl *ap = bcs->ap;
+	struct gigaset_capi_appl *ap;
 	struct sk_buff *skb;
+	unsigned long flags;
 	unsigned int msgsize;
 	u8 command;
 
+	spin_lock_irqsave(&bcs->aplock, flags);
+	ap = bcs->ap;
 	if (!ap) {
+		spin_unlock_irqrestore(&bcs->aplock, flags);
 		dev_err(cs->dev, "%s: no application\n", __func__);
 		return;
 	}
-	while (ap->bcnext) {
-		/* this should never happen */
-		dev_warn(cs->dev, "%s: dropping extra application %u\n",
-			 __func__, ap->bcnext->id);
-		send_disconnect_ind(bcs, ap->bcnext,
-				    CapiCallGivenToOtherApplication);
-		ap->bcnext = ap->bcnext->bcnext;
-	}
-	if (!ap->connected) {
+	if (!bcs->apconnstate) {
+		spin_unlock_irqrestore(&bcs->aplock, flags);
 		dev_warn(cs->dev, "%s: application %u not connected\n",
 			 __func__, ap->id);
 		return;
@@ -825,13 +859,26 @@ void gigaset_isdn_connB(struct bc_state *bcs)
 	 * CONNECT_B3_ACTIVE_IND in reply to CONNECT_B3_RESP
 	 * Parameters in both cases always: NCCI = 1, NCPI empty
 	 */
-	if (ap->connected >= APCONN_ACTIVE) {
+	if (bcs->apconnstate >= APCONN_ACTIVE) {
 		command = CAPI_CONNECT_B3_ACTIVE;
 		msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
 	} else {
 		command = CAPI_CONNECT_B3;
 		msgsize = CAPI_CONNECT_B3_IND_BASELEN;
 	}
+	bcs->apconnstate = APCONN_ACTIVE;
+
+	spin_unlock_irqrestore(&bcs->aplock, flags);
+
+	while (ap->bcnext) {
+		/* this should never happen */
+		dev_warn(cs->dev, "%s: dropping extra application %u\n",
+			 __func__, ap->bcnext->id);
+		send_disconnect_ind(bcs, ap->bcnext,
+				    CapiCallGivenToOtherApplication);
+		ap->bcnext = ap->bcnext->bcnext;
+	}
+
 	capi_cmsg_header(&iif->hcmsg, ap->id, command, CAPI_IND,
 			 ap->nextMessageNumber++,
 			 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
@@ -842,7 +889,6 @@ void gigaset_isdn_connB(struct bc_state *bcs)
 	}
 	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
 	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
-	ap->connected = APCONN_ACTIVE;
 	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
 }
 
@@ -945,8 +991,64 @@ static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
 		return;
 	}
 	ap->id = appl;
+	ap->rp = *rp;
 
 	list_add(&ap->ctrlist, &iif->appls);
+	dev_info(cs->dev, "application %u registered\n", ap->id);
+}
+
+/*
+ * remove CAPI application from channel
+ * helper function to keep indentation levels down and stay in 80 columns
+ */
+
+static inline void remove_appl_from_channel(struct bc_state *bcs,
+					    struct gigaset_capi_appl *ap)
+{
+	struct cardstate *cs = bcs->cs;
+	struct gigaset_capi_appl *bcap;
+	unsigned long flags;
+	int prevconnstate;
+
+	spin_lock_irqsave(&bcs->aplock, flags);
+	bcap = bcs->ap;
+	if (bcap == NULL) {
+		spin_unlock_irqrestore(&bcs->aplock, flags);
+		return;
+	}
+
+	/* check first application on channel */
+	if (bcap == ap) {
+		bcs->ap = ap->bcnext;
+		if (bcs->ap != NULL) {
+			spin_unlock_irqrestore(&bcs->aplock, flags);
+			return;
+		}
+
+		/* none left, clear channel state */
+		prevconnstate = bcs->apconnstate;
+		bcs->apconnstate = APCONN_NONE;
+		spin_unlock_irqrestore(&bcs->aplock, flags);
+
+		if (prevconnstate == APCONN_ACTIVE) {
+			dev_notice(cs->dev, "%s: hanging up channel %u\n",
+				   __func__, bcs->channel);
+			gigaset_add_event(cs, &bcs->at_state,
+					  EV_HUP, NULL, 0, NULL);
+			gigaset_schedule_event(cs);
+		}
+		return;
+	}
+
+	/* check remaining list */
+	do {
+		if (bcap->bcnext == ap) {
+			bcap->bcnext = bcap->bcnext->bcnext;
+			return;
+		}
+		bcap = bcap->bcnext;
+	} while (bcap != NULL);
+	spin_unlock_irqrestore(&bcs->aplock, flags);
 }
 
 /*
@@ -958,19 +1060,19 @@ static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
 		= container_of(ctr, struct gigaset_capi_ctr, ctr);
 	struct cardstate *cs = iif->ctr.driverdata;
 	struct gigaset_capi_appl *ap, *tmp;
+	unsigned ch;
 
 	list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
 		if (ap->id == appl) {
-			if (ap->connected != APCONN_NONE) {
-				dev_err(cs->dev,
-					"%s: application %u still connected\n",
-					__func__, ap->id);
-				/* ToDo: clear active connection */
-			}
+			/* remove from any channels */
+			for (ch = 0; ch < cs->channels; ch++)
+				remove_appl_from_channel(&cs->bcs[ch], ap);
+
+			/* remove from registration list */
 			list_del(&ap->ctrlist);
 			kfree(ap);
+			dev_info(cs->dev, "application %u released\n", appl);
 		}
-
 }
 
 /*
@@ -1149,7 +1251,8 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 	char **commands;
 	char *s;
 	u8 *pp;
-	int i, l;
+	unsigned long flags;
+	int i, l, lbc, lhlc;
 	u16 info;
 
 	/* decode message */
@@ -1164,8 +1267,18 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 		send_conf(iif, ap, skb, CapiNoPlciAvailable);
 		return;
 	}
+	spin_lock_irqsave(&bcs->aplock, flags);
+	if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE)
+		dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n",
+			 __func__, bcs->ap, bcs->apconnstate);
 	ap->bcnext = NULL;
 	bcs->ap = ap;
+	bcs->apconnstate = APCONN_SETUP;
+	spin_unlock_irqrestore(&bcs->aplock, flags);
+
+	bcs->rx_bufsize = ap->rp.datablklen;
+	dev_kfree_skb(bcs->rx_skb);
+	gigaset_new_rx_skb(bcs);
 	cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;
 
 	/* build command table */
@@ -1273,42 +1386,59 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 		goto error;
 	}
 
-	/* check/encode parameter: BC */
-	if (cmsg->BC && cmsg->BC[0]) {
-		/* explicit BC overrides CIP */
-		l = 2*cmsg->BC[0] + 7;
+	/*
+	 * check/encode parameters: BC & HLC
+	 * must be encoded together as device doesn't accept HLC separately
+	 * explicit parameters override values derived from CIP
+	 */
+
+	/* determine lengths */
+	if (cmsg->BC && cmsg->BC[0])		/* BC specified explicitly */
+		lbc = 2*cmsg->BC[0];
+	else if (cip2bchlc[cmsg->CIPValue].bc)	/* BC derived from CIP */
+		lbc = strlen(cip2bchlc[cmsg->CIPValue].bc);
+	else					/* no BC */
+		lbc = 0;
+	if (cmsg->HLC && cmsg->HLC[0])		/* HLC specified explicitly */
+		lhlc = 2*cmsg->HLC[0];
+	else if (cip2bchlc[cmsg->CIPValue].hlc)	/* HLC derived from CIP */
+		lhlc = strlen(cip2bchlc[cmsg->CIPValue].hlc);
+	else					/* no HLC */
+		lhlc = 0;
+
+	if (lbc) {
+		/* have BC: allocate and assemble command string */
+		l = lbc + 7;		/* "^SBC=" + value + "\r" + null byte */
+		if (lhlc)
+			l += lhlc + 7;	/* ";^SHLC=" + value */
 		commands[AT_BC] = kmalloc(l, GFP_KERNEL);
 		if (!commands[AT_BC])
 			goto oom;
 		strcpy(commands[AT_BC], "^SBC=");
-		decode_ie(cmsg->BC, commands[AT_BC]+5);
+		if (cmsg->BC && cmsg->BC[0])	/* BC specified explicitly */
+			decode_ie(cmsg->BC, commands[AT_BC] + 5);
+		else				/* BC derived from CIP */
+			strcpy(commands[AT_BC] + 5,
+			       cip2bchlc[cmsg->CIPValue].bc);
+		if (lhlc) {
+			strcpy(commands[AT_BC] + lbc + 5, ";^SHLC=");
+			if (cmsg->HLC && cmsg->HLC[0])
+				/* HLC specified explicitly */
+				decode_ie(cmsg->HLC,
+					  commands[AT_BC] + lbc + 12);
+			else	/* HLC derived from CIP */
+				strcpy(commands[AT_BC] + lbc + 12,
+				       cip2bchlc[cmsg->CIPValue].hlc);
+		}
 		strcpy(commands[AT_BC] + l - 2, "\r");
-	} else if (cip2bchlc[cmsg->CIPValue].bc) {
-		l = strlen(cip2bchlc[cmsg->CIPValue].bc) + 7;
-		commands[AT_BC] = kmalloc(l, GFP_KERNEL);
-		if (!commands[AT_BC])
-			goto oom;
-		snprintf(commands[AT_BC], l, "^SBC=%s\r",
-			 cip2bchlc[cmsg->CIPValue].bc);
-	}
-
-	/* check/encode parameter: HLC */
-	if (cmsg->HLC && cmsg->HLC[0]) {
-		/* explicit HLC overrides CIP */
-		l = 2*cmsg->HLC[0] + 7;
-		commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
-		if (!commands[AT_HLC])
-			goto oom;
-		strcpy(commands[AT_HLC], "^SHLC=");
-		decode_ie(cmsg->HLC, commands[AT_HLC]+5);
-		strcpy(commands[AT_HLC] + l - 2, "\r");
-	} else if (cip2bchlc[cmsg->CIPValue].hlc) {
-		l = strlen(cip2bchlc[cmsg->CIPValue].hlc) + 7;
-		commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
-		if (!commands[AT_HLC])
-			goto oom;
-		snprintf(commands[AT_HLC], l, "^SHLC=%s\r",
-			 cip2bchlc[cmsg->CIPValue].hlc);
+	} else {
+		/* no BC */
+		if (lhlc) {
+			dev_notice(cs->dev, "%s: cannot set HLC without BC\n",
+				   "CONNECT_REQ");
+			info = CapiIllMessageParmCoding; /* ? */
+			goto error;
+		}
 	}
 
 	/* check/encode parameter: B Protocol */
@@ -1322,13 +1452,13 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 			bcs->proto2 = L2_HDLC;
 			break;
 		case 1:
-			bcs->proto2 = L2_BITSYNC;
+			bcs->proto2 = L2_VOICE;
 			break;
 		default:
 			dev_warn(cs->dev,
 			    "B1 Protocol %u unsupported, using Transparent\n",
 				 cmsg->B1protocol);
-			bcs->proto2 = L2_BITSYNC;
+			bcs->proto2 = L2_VOICE;
 		}
 		if (cmsg->B2protocol != 1)
 			dev_warn(cs->dev,
@@ -1382,7 +1512,6 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 		goto error;
 	}
 	gigaset_schedule_event(cs);
-	ap->connected = APCONN_SETUP;
 	send_conf(iif, ap, skb, CapiSuccess);
 	return;
 
@@ -1410,6 +1539,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 	_cmsg *cmsg = &iif->acmsg;
 	struct bc_state *bcs;
 	struct gigaset_capi_appl *oap;
+	unsigned long flags;
 	int channel;
 
 	/* decode message */
@@ -1429,12 +1559,24 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 	switch (cmsg->Reject) {
 	case 0:		/* Accept */
 		/* drop all competing applications, keep only this one */
-		for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
-			if (oap != ap)
+		spin_lock_irqsave(&bcs->aplock, flags);
+		while (bcs->ap != NULL) {
+			oap = bcs->ap;
+			bcs->ap = oap->bcnext;
+			if (oap != ap) {
+				spin_unlock_irqrestore(&bcs->aplock, flags);
 				send_disconnect_ind(bcs, oap,
 					CapiCallGivenToOtherApplication);
+				spin_lock_irqsave(&bcs->aplock, flags);
+			}
+		}
 		ap->bcnext = NULL;
 		bcs->ap = ap;
+		spin_unlock_irqrestore(&bcs->aplock, flags);
+
+		bcs->rx_bufsize = ap->rp.datablklen;
+		dev_kfree_skb(bcs->rx_skb);
+		gigaset_new_rx_skb(bcs);
 		bcs->chstate |= CHS_NOTIFY_LL;
 
 		/* check/encode B channel protocol */
@@ -1448,13 +1590,13 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 				bcs->proto2 = L2_HDLC;
 				break;
 			case 1:
-				bcs->proto2 = L2_BITSYNC;
+				bcs->proto2 = L2_VOICE;
 				break;
 			default:
 				dev_warn(cs->dev,
 			"B1 Protocol %u unsupported, using Transparent\n",
 					 cmsg->B1protocol);
-				bcs->proto2 = L2_BITSYNC;
+				bcs->proto2 = L2_VOICE;
 			}
 			if (cmsg->B2protocol != 1)
 				dev_warn(cs->dev,
@@ -1502,31 +1644,45 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 		send_disconnect_ind(bcs, ap, 0);
 
 		/* remove it from the list of listening apps */
+		spin_lock_irqsave(&bcs->aplock, flags);
 		if (bcs->ap == ap) {
 			bcs->ap = ap->bcnext;
-			if (bcs->ap == NULL)
+			if (bcs->ap == NULL) {
 				/* last one: stop ev-layer hupD notifications */
+				bcs->apconnstate = APCONN_NONE;
 				bcs->chstate &= ~CHS_NOTIFY_LL;
+			}
+			spin_unlock_irqrestore(&bcs->aplock, flags);
 			return;
 		}
 		for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) {
 			if (oap->bcnext == ap) {
 				oap->bcnext = oap->bcnext->bcnext;
+				spin_unlock_irqrestore(&bcs->aplock, flags);
 				return;
 			}
 		}
+		spin_unlock_irqrestore(&bcs->aplock, flags);
 		dev_err(cs->dev, "%s: application %u not found\n",
 			__func__, ap->id);
 		return;
 
 	default:		/* Reject */
 		/* drop all competing applications, keep only this one */
-		for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
-			if (oap != ap)
+		spin_lock_irqsave(&bcs->aplock, flags);
+		while (bcs->ap != NULL) {
+			oap = bcs->ap;
+			bcs->ap = oap->bcnext;
+			if (oap != ap) {
+				spin_unlock_irqrestore(&bcs->aplock, flags);
 				send_disconnect_ind(bcs, oap,
 					CapiCallGivenToOtherApplication);
+				spin_lock_irqsave(&bcs->aplock, flags);
+			}
+		}
 		ap->bcnext = NULL;
 		bcs->ap = ap;
+		spin_unlock_irqrestore(&bcs->aplock, flags);
 
 		/* reject call - will trigger DISCONNECT_IND for this app */
 		dev_info(cs->dev, "%s: Reject=%x\n",
@@ -1549,6 +1705,7 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
 {
 	struct cardstate *cs = iif->ctr.driverdata;
 	_cmsg *cmsg = &iif->acmsg;
+	struct bc_state *bcs;
 	int channel;
 
 	/* decode message */
@@ -1563,9 +1720,10 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
 		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
 		return;
 	}
+	bcs = &cs->bcs[channel-1];
 
 	/* mark logical connection active */
-	ap->connected = APCONN_ACTIVE;
+	bcs->apconnstate = APCONN_ACTIVE;
 
 	/* build NCCI: always 1 (one B3 connection only) */
 	cmsg->adr.adrNCCI |= 1 << 16;
@@ -1611,7 +1769,7 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
 
 	if (cmsg->Reject) {
 		/* Reject: clear B3 connect received flag */
-		ap->connected = APCONN_SETUP;
+		bcs->apconnstate = APCONN_SETUP;
 
 		/* trigger hangup, causing eventual DISCONNECT_IND */
 		if (!gigaset_add_event(cs, &bcs->at_state,
@@ -1683,11 +1841,11 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
 	}
 
 	/* skip if DISCONNECT_IND already sent */
-	if (!ap->connected)
+	if (!bcs->apconnstate)
 		return;
 
 	/* check for active logical connection */
-	if (ap->connected >= APCONN_ACTIVE) {
+	if (bcs->apconnstate >= APCONN_ACTIVE) {
 		/*
 		 * emit DISCONNECT_B3_IND with cause 0x3301
 		 * use separate cmsg structure, as the content of iif->acmsg
@@ -1736,6 +1894,7 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
 {
 	struct cardstate *cs = iif->ctr.driverdata;
 	_cmsg *cmsg = &iif->acmsg;
+	struct bc_state *bcs;
 	int channel;
 
 	/* decode message */
@@ -1751,17 +1910,17 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
 		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
 		return;
 	}
+	bcs = &cs->bcs[channel-1];
 
 	/* reject if logical connection not active */
-	if (ap->connected < APCONN_ACTIVE) {
+	if (bcs->apconnstate < APCONN_ACTIVE) {
 		send_conf(iif, ap, skb,
 			  CapiMessageNotSupportedInCurrentState);
 		return;
 	}
 
 	/* trigger hangup, causing eventual DISCONNECT_B3_IND */
-	if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
-			       EV_HUP, NULL, 0, NULL)) {
+	if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
 		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
 		return;
 	}
@@ -1782,11 +1941,14 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
 			   struct sk_buff *skb)
 {
 	struct cardstate *cs = iif->ctr.driverdata;
+	struct bc_state *bcs;
 	int channel = CAPIMSG_PLCI_PART(skb->data);
 	u16 ncci = CAPIMSG_NCCI_PART(skb->data);
 	u16 msglen = CAPIMSG_LEN(skb->data);
 	u16 datalen = CAPIMSG_DATALEN(skb->data);
 	u16 flags = CAPIMSG_FLAGS(skb->data);
+	u16 msgid = CAPIMSG_MSGID(skb->data);
+	u16 handle = CAPIMSG_HANDLE_REQ(skb->data);
 
 	/* frequent message, avoid _cmsg overhead */
 	dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);
@@ -1802,6 +1964,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
 		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
 		return;
 	}
+	bcs = &cs->bcs[channel-1];
 	if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
 		dev_notice(cs->dev, "%s: unexpected length %d\n",
 			   "DATA_B3_REQ", msglen);
@@ -1821,7 +1984,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
 	}
 
 	/* reject if logical connection not active */
-	if (ap->connected < APCONN_ACTIVE) {
+	if (bcs->apconnstate < APCONN_ACTIVE) {
 		send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
 		return;
 	}
@@ -1832,17 +1995,19 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
 	skb_pull(skb, msglen);
 
 	/* pass to device-specific module */
-	if (cs->ops->send_skb(&cs->bcs[channel-1], skb) < 0) {
+	if (cs->ops->send_skb(bcs, skb) < 0) {
 		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
 		return;
 	}
 
-	/* DATA_B3_CONF reply will be sent by gigaset_skb_sent() */
-
 	/*
-	 * ToDo: honor unset "delivery confirmation" bit
-	 * (send DATA_B3_CONF immediately?)
+	 * DATA_B3_CONF will be sent by gigaset_skb_sent() only if "delivery
+	 * confirmation" bit is set; otherwise we have to send it now
 	 */
+	if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION))
+		send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle,
+				  flags ? CapiFlagsNotSupportedByProtocol
+					: CAPI_NOERROR);
 }
 
 /*
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index f6f45f221920..5d4befb81057 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -399,8 +399,8 @@ static void gigaset_freebcs(struct bc_state *bcs)
 	gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel);
 	clear_at_state(&bcs->at_state);
 	gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel);
-	dev_kfree_skb(bcs->skb);
-	bcs->skb = NULL;
+	dev_kfree_skb(bcs->rx_skb);
+	bcs->rx_skb = NULL;
 
 	for (i = 0; i < AT_NUM; ++i) {
 		kfree(bcs->commands[i]);
@@ -634,19 +634,10 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
 	bcs->emptycount = 0;
 #endif
 
-	gig_dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel);
-	bcs->fcs = PPP_INITFCS;
+	bcs->rx_bufsize = 0;
+	bcs->rx_skb = NULL;
+	bcs->rx_fcs = PPP_INITFCS;
 	bcs->inputstate = 0;
-	if (cs->ignoreframes) {
-		bcs->skb = NULL;
-	} else {
-		bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
-		if (bcs->skb != NULL)
-			skb_reserve(bcs->skb, cs->hw_hdr_len);
-		else
-			pr_err("out of memory\n");
-	}
-
 	bcs->channel = channel;
 	bcs->cs = cs;
 
@@ -658,16 +649,15 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
 	for (i = 0; i < AT_NUM; ++i)
 		bcs->commands[i] = NULL;
 
+	spin_lock_init(&bcs->aplock);
+	bcs->ap = NULL;
+	bcs->apconnstate = 0;
+
 	gig_dbg(DEBUG_INIT, "  setting up bcs[%d]->hw", channel);
 	if (cs->ops->initbcshw(bcs))
 		return bcs;
 
 	gig_dbg(DEBUG_INIT, "  failed");
-
-	gig_dbg(DEBUG_INIT, "  freeing bcs[%d]->skb", channel);
-	dev_kfree_skb(bcs->skb);
-	bcs->skb = NULL;
-
 	return NULL;
 }
 
@@ -839,14 +829,12 @@ void gigaset_bcs_reinit(struct bc_state *bcs)
 	bcs->emptycount = 0;
 #endif
 
-	bcs->fcs = PPP_INITFCS;
+	bcs->rx_fcs = PPP_INITFCS;
 	bcs->chstate = 0;
 
 	bcs->ignore = cs->ignoreframes;
-	if (bcs->ignore) {
-		dev_kfree_skb(bcs->skb);
-		bcs->skb = NULL;
-	}
+	dev_kfree_skb(bcs->rx_skb);
+	bcs->rx_skb = NULL;
 
 	cs->ops->reinitbcshw(bcs);
 }
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 206c380c5235..ceaef9a04a42 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -282,9 +282,7 @@ struct reply_t gigaset_tab_cid[] =
 /* dial */
 {EV_DIAL,	 -1,  -1, -1,			 -1, -1, {ACT_DIAL} },
 {RSP_INIT,	  0,   0, SEQ_DIAL,		601,  5, {ACT_CMD+AT_BC} },
-{RSP_OK,	601, 601, -1,			602,  5, {ACT_CMD+AT_HLC} },
-{RSP_NULL,	602, 602, -1,			603,  5, {ACT_CMD+AT_PROTO} },
-{RSP_OK,	602, 602, -1,			603,  5, {ACT_CMD+AT_PROTO} },
+{RSP_OK,	601, 601, -1,			603,  5, {ACT_CMD+AT_PROTO} },
 {RSP_OK,	603, 603, -1,			604,  5, {ACT_CMD+AT_TYPE} },
 {RSP_OK,	604, 604, -1,			605,  5, {ACT_CMD+AT_MSN} },
 {RSP_NULL,	605, 605, -1,			606,  5, {ACT_CMD+AT_CLIP} },
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 05947f9c1849..8738b0821fc9 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -45,10 +45,6 @@
 #define MAX_EVENTS 64		/* size of event queue */
 
 #define RBUFSIZE 8192
-#define SBUFSIZE 4096		/* sk_buff payload size */
-
-#define TRANSBUFSIZE 768	/* bytes per skb for transparent receive */
-#define MAX_BUF_SIZE (SBUFSIZE - 2)	/* Max. size of a data packet from LL */
 
 /* compile time options */
 #define GIG_MAJOR 0
@@ -190,10 +186,9 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
 #define AT_BC		3
 #define AT_PROTO	4
 #define AT_TYPE		5
-#define AT_HLC		6
-#define AT_CLIP		7
+#define AT_CLIP		6
 /* total number */
-#define AT_NUM		8
+#define AT_NUM		7
 
 /* variables in struct at_state_t */
 #define VAR_ZSAU	0
@@ -380,8 +375,10 @@ struct bc_state {
 
 	struct at_state_t at_state;
 
-	__u16 fcs;
-	struct sk_buff *skb;
+	/* receive buffer */
+	unsigned rx_bufsize;		/* max size accepted by application */
+	struct sk_buff *rx_skb;
+	__u16 rx_fcs;
 	int inputstate;			/* see INS_XXXX */
 
 	int channel;
@@ -406,7 +403,9 @@ struct bc_state {
 		struct bas_bc_state *bas;	/* usb hardware driver (base) */
 	} hw;
 
-	void *ap;			/* LL application structure */
+	void *ap;			/* associated LL application */
+	int apconnstate;		/* LL application connection state */
+	spinlock_t aplock;
 };
 
 struct cardstate {
@@ -801,8 +800,23 @@ static inline void gigaset_bchannel_up(struct bc_state *bcs)
 	gigaset_schedule_event(bcs->cs);
 }
 
-/* handling routines for sk_buff */
-/* ============================= */
+/* set up next receive skb for data mode */
+static inline struct sk_buff *gigaset_new_rx_skb(struct bc_state *bcs)
+{
+	struct cardstate *cs = bcs->cs;
+	unsigned short hw_hdr_len = cs->hw_hdr_len;
+
+	if (bcs->ignore) {
+		bcs->rx_skb = NULL;
+	} else {
+		bcs->rx_skb = dev_alloc_skb(bcs->rx_bufsize + hw_hdr_len);
+		if (bcs->rx_skb == NULL)
+			dev_warn(cs->dev, "could not allocate skb\n");
+		else
+			skb_reserve(bcs->rx_skb, hw_hdr_len);
+	}
+	return bcs->rx_skb;
+}
 
 /* append received bytes to inbuf */
 int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index c22e5ace8276..f01c3c2e2e46 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -16,7 +16,10 @@
 #include "gigaset.h"
 #include <linux/isdnif.h>
 
+#define SBUFSIZE	4096	/* sk_buff payload size */
+#define TRANSBUFSIZE	768	/* bytes per skb for transparent receive */
 #define HW_HDR_LEN	2	/* Header size used to store ack info */
+#define MAX_BUF_SIZE	(SBUFSIZE - HW_HDR_LEN)	/* max data packet from LL */
 
 /* == Handling of I4L IO =====================================================*/
 
@@ -231,6 +234,15 @@ static int command_from_LL(isdn_ctrl *cntrl)
 			dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n");
 			return -EBUSY;
 		}
+		switch (bcs->proto2) {
+		case L2_HDLC:
+			bcs->rx_bufsize = SBUFSIZE;
+			break;
+		default:			/* assume transparent */
+			bcs->rx_bufsize = TRANSBUFSIZE;
+		}
+		dev_kfree_skb(bcs->rx_skb);
+		gigaset_new_rx_skb(bcs);
 
 		commands = kzalloc(AT_NUM*(sizeof *commands), GFP_ATOMIC);
 		if (!commands) {
@@ -314,6 +326,15 @@ static int command_from_LL(isdn_ctrl *cntrl)
 			return -EINVAL;
 		}
 		bcs = cs->bcs + ch;
+		switch (bcs->proto2) {
+		case L2_HDLC:
+			bcs->rx_bufsize = SBUFSIZE;
+			break;
+		default:			/* assume transparent */
+			bcs->rx_bufsize = TRANSBUFSIZE;
+		}
+		dev_kfree_skb(bcs->rx_skb);
+		gigaset_new_rx_skb(bcs);
 		if (!gigaset_add_event(cs, &bcs->at_state,
 				       EV_ACCEPT, NULL, 0, NULL))
 			return -ENOMEM;
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 16fd3bd48883..2dfd346fc889 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -500,19 +500,18 @@ int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len)
  */
 static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs)
 {
-	bcs->fcs = crc_ccitt_byte(bcs->fcs, c);
-	if (unlikely(bcs->skb == NULL)) {
+	bcs->rx_fcs = crc_ccitt_byte(bcs->rx_fcs, c);
+	if (bcs->rx_skb == NULL)
 		/* skipping */
 		return;
-	}
-	if (unlikely(bcs->skb->len == SBUFSIZE)) {
+	if (bcs->rx_skb->len >= bcs->rx_bufsize) {
 		dev_warn(bcs->cs->dev, "received oversized packet discarded\n");
 		bcs->hw.bas->giants++;
-		dev_kfree_skb_any(bcs->skb);
-		bcs->skb = NULL;
+		dev_kfree_skb_any(bcs->rx_skb);
+		bcs->rx_skb = NULL;
 		return;
 	}
-	*__skb_put(bcs->skb, 1) = c;
+	*__skb_put(bcs->rx_skb, 1) = c;
 }
 
 /* hdlc_flush
@@ -521,18 +520,13 @@ static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs)
 static inline void hdlc_flush(struct bc_state *bcs)
 {
 	/* clear skb or allocate new if not skipping */
-	if (likely(bcs->skb != NULL))
-		skb_trim(bcs->skb, 0);
-	else if (!bcs->ignore) {
-		bcs->skb = dev_alloc_skb(SBUFSIZE + bcs->cs->hw_hdr_len);
-		if (bcs->skb)
-			skb_reserve(bcs->skb, bcs->cs->hw_hdr_len);
-		else
-			dev_err(bcs->cs->dev, "could not allocate skb\n");
-	}
+	if (bcs->rx_skb != NULL)
+		skb_trim(bcs->rx_skb, 0);
+	else
+		gigaset_new_rx_skb(bcs);
 
 	/* reset packet state */
-	bcs->fcs = PPP_INITFCS;
+	bcs->rx_fcs = PPP_INITFCS;
 }
 
 /* hdlc_done
@@ -549,7 +543,7 @@ static inline void hdlc_done(struct bc_state *bcs)
 		hdlc_flush(bcs);
 		return;
 	}
-	procskb = bcs->skb;
+	procskb = bcs->rx_skb;
 	if (procskb == NULL) {
 		/* previous error */
 		gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);
@@ -560,8 +554,8 @@ static inline void hdlc_done(struct bc_state *bcs)
 		bcs->hw.bas->runts++;
 		dev_kfree_skb_any(procskb);
 		gigaset_isdn_rcv_err(bcs);
-	} else if (bcs->fcs != PPP_GOODFCS) {
-		dev_notice(cs->dev, "frame check error (0x%04x)\n", bcs->fcs);
+	} else if (bcs->rx_fcs != PPP_GOODFCS) {
+		dev_notice(cs->dev, "frame check error\n");
 		bcs->hw.bas->fcserrs++;
 		dev_kfree_skb_any(procskb);
 		gigaset_isdn_rcv_err(bcs);
@@ -574,13 +568,8 @@ static inline void hdlc_done(struct bc_state *bcs)
 		bcs->hw.bas->goodbytes += len;
 		gigaset_skb_rcvd(bcs, procskb);
 	}
-
-	bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
-	if (bcs->skb)
-		skb_reserve(bcs->skb, cs->hw_hdr_len);
-	else
-		dev_err(cs->dev, "could not allocate skb\n");
-	bcs->fcs = PPP_INITFCS;
+	gigaset_new_rx_skb(bcs);
+	bcs->rx_fcs = PPP_INITFCS;
 }
 
 /* hdlc_frag
@@ -597,8 +586,8 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits)
 	dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);
 	bcs->hw.bas->alignerrs++;
 	gigaset_isdn_rcv_err(bcs);
-	__skb_trim(bcs->skb, 0);
-	bcs->fcs = PPP_INITFCS;
+	__skb_trim(bcs->rx_skb, 0);
+	bcs->rx_fcs = PPP_INITFCS;
 }
 
 /* bit counts lookup table for HDLC bit unstuffing
@@ -847,7 +836,6 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
 static inline void trans_receive(unsigned char *src, unsigned count,
 				 struct bc_state *bcs)
 {
-	struct cardstate *cs = bcs->cs;
 	struct sk_buff *skb;
 	int dobytes;
 	unsigned char *dst;
@@ -857,17 +845,11 @@ static inline void trans_receive(unsigned char *src, unsigned count,
 		hdlc_flush(bcs);
 		return;
 	}
-	skb = bcs->skb;
-	if (unlikely(skb == NULL)) {
-		bcs->skb = skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
-		if (!skb) {
-			dev_err(cs->dev, "could not allocate skb\n");
-			return;
-		}
-		skb_reserve(skb, cs->hw_hdr_len);
-	}
+	skb = bcs->rx_skb;
+	if (skb == NULL)
+		skb = gigaset_new_rx_skb(bcs);
 	bcs->hw.bas->goodbytes += skb->len;
-	dobytes = TRANSBUFSIZE - skb->len;
+	dobytes = bcs->rx_bufsize - skb->len;
 	while (count > 0) {
 		dst = skb_put(skb, count < dobytes ? count : dobytes);
 		while (count > 0 && dobytes > 0) {
@@ -879,14 +861,10 @@ static inline void trans_receive(unsigned char *src, unsigned count,
 			dump_bytes(DEBUG_STREAM_DUMP,
 				   "rcv data", skb->data, skb->len);
 			gigaset_skb_rcvd(bcs, skb);
-			bcs->skb = skb =
-				dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
-			if (!skb) {
-				dev_err(cs->dev, "could not allocate skb\n");
+			skb = gigaset_new_rx_skb(bcs);
+			if (skb == NULL)
 				return;
-			}
-			skb_reserve(skb, cs->hw_hdr_len);
-			dobytes = TRANSBUFSIZE;
+			dobytes = bcs->rx_bufsize;
 		}
 	}
 }
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index 72eb92647c1b..feec8d89d719 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -187,12 +187,13 @@ void
 hysdn_rx_netpkt(hysdn_card * card, unsigned char *buf, unsigned short len)
 {
 	struct net_local *lp = card->netif;
-	struct net_device *dev = lp->dev;
+	struct net_device *dev;
 	struct sk_buff *skb;
 
 	if (!lp)
 		return;		/* non existing device */
 
+	dev = lp->dev;
 	dev->stats.rx_bytes += len;
 
 	skb = dev_alloc_skb(len);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2decc597bda7..ce2fcdd4ab90 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2754,6 +2754,7 @@ config MYRI10GE_DCA
 config NETXEN_NIC
 	tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
 	depends on PCI
+	select FW_LOADER
 	help
 	  This enables the support for NetXen's Gigabit Ethernet card.
 
@@ -2819,6 +2820,7 @@ config BNX2X
 config QLCNIC
 	tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
 	depends on PCI
+	select FW_LOADER
 	help
 	  This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
 	  devices.
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 949d7a9dcf92..117432222a09 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -3073,7 +3073,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 	u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
 	struct l2_fhdr *rx_hdr;
 	int rx_pkt = 0, pg_ring_used = 0;
-	struct pci_dev *pdev = bp->pdev;
 
 	hw_cons = bnx2_get_hw_rx_cons(bnapi);
 	sw_cons = rxr->rx_cons;
@@ -3099,12 +3098,10 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 		skb = rx_buf->skb;
 		prefetchw(skb);
 
-		if (!get_dma_ops(&pdev->dev)->sync_single_for_cpu) {
-			next_rx_buf =
-				&rxr->rx_buf_ring[
-					RX_RING_IDX(NEXT_RX_BD(sw_cons))];
-			prefetch(next_rx_buf->desc);
-		}
+		next_rx_buf =
+			&rxr->rx_buf_ring[RX_RING_IDX(NEXT_RX_BD(sw_cons))];
+		prefetch(next_rx_buf->desc);
+
 		rx_buf->skb = NULL;
 
 		dma_addr = dma_unmap_addr(rx_buf, mapping);
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index fe925663d39a..80471269977a 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -3919,8 +3919,9 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)
 		HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS;
 	context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID;
 
-	context->xstorm_st_context.statistics_data = (cli |
-				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
+	if (cli < MAX_X_STAT_COUNTER_ID)
+		context->xstorm_st_context.statistics_data = cli |
+				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE;
 
 	context->xstorm_ag_context.cdu_reserved =
 		CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func),
@@ -3928,10 +3929,12 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev)
 					ETH_CONNECTION_TYPE);
 
 	/* reset xstorm per client statistics */
-	val = BAR_XSTRORM_INTMEM +
-	      XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
-	for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++)
-		CNIC_WR(dev, val + i * 4, 0);
+	if (cli < MAX_X_STAT_COUNTER_ID) {
+		val = BAR_XSTRORM_INTMEM +
+		      XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
+		for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++)
+			CNIC_WR(dev, val + i * 4, 0);
+	}
 
 	cp->tx_cons_ptr =
 		&cp->bnx2x_def_status_blk->c_def_status_block.index_values[
@@ -3978,9 +3981,11 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)
 						BNX2X_ISCSI_RX_SB_INDEX_NUM;
 	context->ustorm_st_context.common.clientId = cli;
 	context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID;
-	context->ustorm_st_context.common.flags =
-		USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS;
-	context->ustorm_st_context.common.statistics_counter_id = cli;
+	if (cli < MAX_U_STAT_COUNTER_ID) {
+		context->ustorm_st_context.common.flags =
+			USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS;
+		context->ustorm_st_context.common.statistics_counter_id = cli;
+	}
 	context->ustorm_st_context.common.mc_alignment_log_size = 0;
 	context->ustorm_st_context.common.bd_buff_size =
 						cp->l2_single_buf_size;
@@ -4011,10 +4016,13 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)
 
 	/* client tstorm info */
 	tstorm_client.mtu = cp->l2_single_buf_size - 14;
-	tstorm_client.config_flags =
-			(TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE |
-			TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE);
-	tstorm_client.statistics_counter_id = cli;
+	tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE;
+
+	if (cli < MAX_T_STAT_COUNTER_ID) {
+		tstorm_client.config_flags |=
+				TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+		tstorm_client.statistics_counter_id = cli;
+	}
 
 	CNIC_WR(dev, BAR_TSTRORM_INTMEM +
 		   TSTORM_CLIENT_CONFIG_OFFSET(port, cli),
@@ -4024,16 +4032,21 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev)
 		   ((u32 *)&tstorm_client)[1]);
 
 	/* reset tstorm per client statistics */
-	val = BAR_TSTRORM_INTMEM +
-	      TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
-	for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++)
-		CNIC_WR(dev, val + i * 4, 0);
+	if (cli < MAX_T_STAT_COUNTER_ID) {
+
+		val = BAR_TSTRORM_INTMEM +
+		      TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
+		for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++)
+			CNIC_WR(dev, val + i * 4, 0);
+	}
 
 	/* reset ustorm per client statistics */
-	val = BAR_USTRORM_INTMEM +
-	      USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
-	for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++)
-		CNIC_WR(dev, val + i * 4, 0);
+	if (cli < MAX_U_STAT_COUNTER_ID) {
+		val = BAR_USTRORM_INTMEM +
+		      USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli);
+		for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++)
+			CNIC_WR(dev, val + i * 4, 0);
+	}
 
 	cp->rx_cons_ptr =
 		&cp->bnx2x_def_status_blk->u_def_status_block.index_values[
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 3c58db595285..23786ee34bed 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -1181,7 +1181,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 		if (netif_msg_drv(priv))
 			printk(KERN_ERR "%s: Could not attach to PHY\n",
 			       dev->name);
-		return PTR_ERR(priv->phy);
+		rc = PTR_ERR(priv->phy);
+		goto fail;
 	}
 
 	if ((rc = register_netdev(dev))) {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index ebdea0891665..68a80893dce1 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1047,15 +1047,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 		goto err_register;
 
 	/* print bus type/speed/width info */
-	e_info("(PCI%s:%s:%s) ",
-		((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
-		((hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
-		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
-		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
-		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
-		((hw->bus_width == e1000_bus_width_64) ? "64-bit" : "32-bit"));
-
-	e_info("%pM\n", netdev->dev_addr);
+	e_info("(PCI%s:%dMHz:%d-bit) %pM\n",
+	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
+	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
+		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
+		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
+		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
+	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
+	       netdev->dev_addr);
 
 	/* carrier off reporting is important to ethtool even BEFORE open */
 	netif_carrier_off(netdev);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 0630980a2722..0060e422f171 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0103"
+#define DRV_VERSION	"EHEA_0105"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index f547894ff48f..8b92acb448c2 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -867,6 +867,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
 		ehea_reset_cq_ep(pr->send_cq);
 		ehea_reset_cq_n1(pr->recv_cq);
 		ehea_reset_cq_n1(pr->send_cq);
+		rmb();
 		cqe = ehea_poll_rq1(pr->qp, &wqe_index);
 		cqe_skb = ehea_poll_cq(pr->send_cq);
 
@@ -2859,6 +2860,7 @@ static void ehea_reset_port(struct work_struct *work)
 		container_of(work, struct ehea_port, reset_task);
 	struct net_device *dev = port->netdev;
 
+	mutex_lock(&dlpar_mem_lock);
 	port->resets++;
 	mutex_lock(&port->port_lock);
 	netif_stop_queue(dev);
@@ -2881,6 +2883,7 @@ static void ehea_reset_port(struct work_struct *work)
 	netif_wake_queue(dev);
 out:
 	mutex_unlock(&port->port_lock);
+	mutex_unlock(&dlpar_mem_lock);
 }
 
 static void ehea_rereg_mrs(struct work_struct *work)
@@ -3542,10 +3545,7 @@ static int ehea_mem_notifier(struct notifier_block *nb,
 	int ret = NOTIFY_BAD;
 	struct memory_notify *arg = data;
 
-	if (!mutex_trylock(&dlpar_mem_lock)) {
-		ehea_info("ehea_mem_notifier must not be called parallelized");
-		goto out;
-	}
+	mutex_lock(&dlpar_mem_lock);
 
 	switch (action) {
 	case MEM_CANCEL_OFFLINE:
@@ -3574,7 +3574,6 @@ static int ehea_mem_notifier(struct notifier_block *nb,
 
 out_unlock:
 	mutex_unlock(&dlpar_mem_lock);
-out:
 	return ret;
 }
 
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 2b3e16db5c82..e0d33281ec98 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -709,7 +709,7 @@ int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)
 {
 	u64 a0, a1 = len;
 	int wait = 1000;
-	u64 prov_pa;
+	dma_addr_t prov_pa;
 	void *prov_buf;
 	int ret;
 
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 46c69cd06553..28b53d1cd4f1 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -381,10 +381,14 @@ static void gfar_init_mac(struct net_device *ndev)
 	/* Insert receive time stamps into padding alignment bytes */
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) {
 		rctrl &= ~RCTRL_PAL_MASK;
-		rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE | RCTRL_PADDING(8);
+		rctrl |= RCTRL_PADDING(8);
 		priv->padding = 8;
 	}
 
+	/* Enable HW time stamping if requested from user space */
+	if (priv->hwts_rx_en)
+		rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE;
+
 	/* keep vlan related bits if it's enabled */
 	if (priv->vlgrp) {
 		rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
@@ -747,7 +751,8 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
 			FSL_GIANFAR_DEV_HAS_CSUM |
 			FSL_GIANFAR_DEV_HAS_VLAN |
 			FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
-			FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
+			FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
+			FSL_GIANFAR_DEV_HAS_TIMER;
 
 	ctype = of_get_property(np, "phy-connection-type", NULL);
 
@@ -805,12 +810,20 @@ static int gfar_hwtstamp_ioctl(struct net_device *netdev,
 
 	switch (config.rx_filter) {
 	case HWTSTAMP_FILTER_NONE:
-		priv->hwts_rx_en = 0;
+		if (priv->hwts_rx_en) {
+			stop_gfar(netdev);
+			priv->hwts_rx_en = 0;
+			startup_gfar(netdev);
+		}
 		break;
 	default:
 		if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER))
 			return -ERANGE;
-		priv->hwts_rx_en = 1;
+		if (!priv->hwts_rx_en) {
+			stop_gfar(netdev);
+			priv->hwts_rx_en = 1;
+			startup_gfar(netdev);
+		}
 		config.rx_filter = HWTSTAMP_FILTER_ALL;
 		break;
 	}
@@ -2642,6 +2655,10 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
 		dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
 				priv->rx_buffer_size, DMA_FROM_DEVICE);
 
+		if (unlikely(!(bdp->status & RXBD_ERR) &&
+				bdp->length > priv->rx_buffer_size))
+			bdp->status = RXBD_LARGE;
+
 		/* We drop the frame if we failed to allocate a new buffer */
 		if (unlikely(!newskb || !(bdp->status & RXBD_LAST) ||
 				 bdp->status & RXBD_ERR)) {
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index c50a7541ffec..3a93a81872b8 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -2077,25 +2077,6 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
 	return 0;
 }
 
-/*
- * this function must be called before setting the new value of
- * rx_itr_setting
- */
-static bool ixgbe_reenable_rsc(struct ixgbe_adapter *adapter,
-                               struct ethtool_coalesce *ec)
-{
-	/* check the old value and enable RSC if necessary */
-	if ((adapter->rx_itr_setting == 0) &&
-	    (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) {
-		adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
-		adapter->netdev->features |= NETIF_F_LRO;
-		DPRINTK(PROBE, INFO, "rx-usecs set to %d, re-enabling RSC\n",
-		        ec->rx_coalesce_usecs);
-		return true;
-	}
-	return false;
-}
-
 static int ixgbe_set_coalesce(struct net_device *netdev,
                               struct ethtool_coalesce *ec)
 {
@@ -2124,9 +2105,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
 		    (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))
 			return -EINVAL;
 
-		/* check the old value and enable RSC if necessary */
-		need_reset = ixgbe_reenable_rsc(adapter, ec);
-
 		/* store the value in ints/second */
 		adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs;
 
@@ -2135,9 +2113,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
 		/* clear the lower bit as its used for dynamic state */
 		adapter->rx_itr_setting &= ~1;
 	} else if (ec->rx_coalesce_usecs == 1) {
-		/* check the old value and enable RSC if necessary */
-		need_reset = ixgbe_reenable_rsc(adapter, ec);
-
 		/* 1 means dynamic mode */
 		adapter->rx_eitr_param = 20000;
 		adapter->rx_itr_setting = 1;
@@ -2157,10 +2132,11 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
 		 */
 		if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
 			adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED;
-			netdev->features &= ~NETIF_F_LRO;
-			DPRINTK(PROBE, INFO,
-			        "rx-usecs set to 0, disabling RSC\n");
-
+			if (netdev->features & NETIF_F_LRO) {
+				netdev->features &= ~NETIF_F_LRO;
+				DPRINTK(PROBE, INFO, "rx-usecs set to 0, "
+					"disabling LRO/RSC\n");
+			}
 			need_reset = true;
 		}
 	}
@@ -2255,6 +2231,9 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
 			}
 		} else if (!adapter->rx_itr_setting) {
 			netdev->features &= ~ETH_FLAG_LRO;
+			if (data & ETH_FLAG_LRO)
+				DPRINTK(PROBE, INFO, "rx-usecs set to 0, "
+					"LRO/RSC cannot be enabled.\n");
 		}
 	}
 
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index b2af2f67f604..ce30c62a97f7 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -5282,6 +5282,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 	u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
 	u64 non_eop_descs = 0, restart_queue = 0;
 
+	if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+	    test_bit(__IXGBE_RESETTING, &adapter->state))
+		return;
+
 	if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
 		u64 rsc_count = 0;
 		u64 rsc_flush = 0;
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 09e1911ff510..48325a5beff2 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -575,6 +575,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 		 * 4    SFP_DA_CORE1 - 82599-specific
 		 * 5    SFP_SR/LR_CORE0 - 82599-specific
 		 * 6    SFP_SR/LR_CORE1 - 82599-specific
+		 * 7    SFP_act_lmt_DA_CORE0 - 82599-specific
+		 * 8    SFP_act_lmt_DA_CORE1 - 82599-specific
 		 */
 		if (hw->mac.type == ixgbe_mac_82598EB) {
 			if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index ce5d6e909218..c27f4291b350 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -1343,7 +1343,7 @@ static void set_multicast_list(struct net_device *dev)
 	DEB(DEB_MULTI,
 	    printk(KERN_DEBUG
 		   "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
-		   dev->name, dev->mc_count,
+		   dev->name, netdev_mc_count(dev),
 		   dev->flags & IFF_PROMISC ? "ON" : "OFF",
 		   dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
 
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 8e9704f5c122..869f0ea43a5b 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -247,7 +247,7 @@ static const struct net_device_ops mipsnet_netdev_ops = {
 	.ndo_set_mac_address	= eth_mac_addr,
 };
 
-static int __init mipsnet_probe(struct platform_device *dev)
+static int __devinit mipsnet_probe(struct platform_device *dev)
 {
 	struct net_device *netdev;
 	int err;
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index f26e54716c88..3a41b6a84a68 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -629,7 +629,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 	if (addr == NULL) {
 		dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
 				netdev->name);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_out_free;
 	}
 
 	tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 5c496f8d7c49..29d7b93d0493 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1159,9 +1159,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off)
 
 	window = CRB_HI(off);
 
-	if (adapter->ahw.crb_win == window)
-		return;
-
 	writel(window, addr);
 	if (readl(addr) != window) {
 		if (printk_ratelimit())
@@ -1169,7 +1166,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off)
 				"failed to set CRB window to %d off 0x%lx\n",
 				window, off);
 	}
-	adapter->ahw.crb_win = window;
 }
 
 static void __iomem *
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 045a7c8f5bdf..c865dda2adf1 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -218,7 +218,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 	if (cmd_buf_arr == NULL) {
 		dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",
 		       netdev->name);
-		return -ENOMEM;
+		goto err_out;
 	}
 	memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
 	tx_ring->cmd_buf_arr = cmd_buf_arr;
@@ -230,7 +230,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 	if (rds_ring == NULL) {
 		dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n",
 		       netdev->name);
-		return -ENOMEM;
+		goto err_out;
 	}
 	recv_ctx->rds_rings = rds_ring;
 
@@ -1805,9 +1805,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 	netxen_ctx_msg msg = 0;
 	struct list_head *head;
 
+	spin_lock(&rds_ring->lock);
+
 	producer = rds_ring->producer;
 
-	spin_lock(&rds_ring->lock);
 	head = &rds_ring->free_list;
 	while (!list_empty(head)) {
 
@@ -1829,7 +1830,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 
 		producer = get_next_index(producer, rds_ring->num_desc);
 	}
-	spin_unlock(&rds_ring->lock);
 
 	if (count) {
 		rds_ring->producer = producer;
@@ -1853,6 +1853,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 					NETXEN_RCV_PRODUCER_OFFSET), msg);
 		}
 	}
+
+	spin_unlock(&rds_ring->lock);
 }
 
 static void
@@ -1864,10 +1866,11 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
 	int producer, count = 0;
 	struct list_head *head;
 
-	producer = rds_ring->producer;
 	if (!spin_trylock(&rds_ring->lock))
 		return;
 
+	producer = rds_ring->producer;
+
 	head = &rds_ring->free_list;
 	while (!list_empty(head)) {
 
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 6f77a768ba88..bfdef72c5d5e 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1727,6 +1727,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 64e6a84bbbbe..307cd1721e91 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1505,12 +1505,20 @@ irq_done:
 	writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_LAN + CISREG_COR);
 	writeb(cor, smc->base + MOT_LAN + CISREG_COR);
     }
-#ifdef DOES_NOT_WORK
-    if (smc->base != NULL) { /* Megahertz MFC's */
-	readb(smc->base+MEGAHERTZ_ISR);
-	readb(smc->base+MEGAHERTZ_ISR);
+
+    if ((smc->base != NULL) &&  /* Megahertz MFC's */
+	(smc->manfid == MANFID_MEGAHERTZ) &&
+	(smc->cardid == PRODID_MEGAHERTZ_EM3288)) {
+
+	u_char tmp;
+	tmp = readb(smc->base+MEGAHERTZ_ISR);
+	tmp = readb(smc->base+MEGAHERTZ_ISR);
+
+	/* Retrigger interrupt if needed */
+	writeb(tmp, smc->base + MEGAHERTZ_ISR);
+	writeb(tmp, smc->base + MEGAHERTZ_ISR);
     }
-#endif
+
     spin_unlock(&smc->lock);
     return IRQ_RETVAL(handled);
 }
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index dbd003453737..29c39ff85de5 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -226,6 +226,7 @@ module_exit(lxt_exit);
 static struct mdio_device_id lxt_tbl[] = {
 	{ 0x78100000, 0xfffffff0 },
 	{ 0x001378e0, 0xfffffff0 },
+	{ 0x00137a10, 0xfffffff0 },
 	{ }
 };
 
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 2111c7bbf578..7985165e84fc 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -717,11 +717,24 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 }
 
+/* Enable Rx/Tx */
+static void sky2_enable_rx_tx(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 reg;
+
+	reg = gma_read16(hw, port, GM_GP_CTRL);
+	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+}
+
 /* Force a renegotiation */
 static void sky2_phy_reinit(struct sky2_port *sky2)
 {
 	spin_lock_bh(&sky2->phy_lock);
 	sky2_phy_init(sky2->hw, sky2->port);
+	sky2_enable_rx_tx(sky2);
 	spin_unlock_bh(&sky2->phy_lock);
 }
 
@@ -2040,7 +2053,6 @@ static void sky2_link_up(struct sky2_port *sky2)
 {
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
-	u16 reg;
 	static const char *fc_name[] = {
 		[FC_NONE]	= "none",
 		[FC_TX]		= "tx",
@@ -2048,10 +2060,7 @@ static void sky2_link_up(struct sky2_port *sky2)
 		[FC_BOTH]	= "both",
 	};
 
-	/* enable Rx/Tx */
-	reg = gma_read16(hw, port, GM_GP_CTRL);
-	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
-	gma_write16(hw, port, GM_GP_CTRL, reg);
+	sky2_enable_rx_tx(sky2);
 
 	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
 
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 4a34833b85dd..807470e156af 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3215,6 +3215,8 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
 					   __func__, __LINE__, (u32) skb);
 			if (skb) {
 				skb->data = skb->head + NET_SKB_PAD;
+				skb->len = 0;
+				skb_reset_tail_pointer(skb);
 				__skb_queue_head(&ugeth->rx_recycle, skb);
 			}
 
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 0a3c41faea9c..4dd23513c5af 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1334,7 +1334,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
 	/* check for port already opened, if not set the termios */
 	serial->open_count++;
 	if (serial->open_count == 1) {
-		tty->low_latency = 1;
 		serial->rx_state = RX_IDLE;
 		/* Force default termio settings */
 		_hso_serial_set_termios(tty, NULL);
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index b504bd561362..d14e207de1df 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -2262,7 +2262,8 @@ start:
 		vxge_debug_init(VXGE_ERR,
 			"%s: memory allocation failed",
 			VXGE_DRIVER_NAME);
-		return  -ENOMEM;
+		ret = -ENOMEM;
+		goto alloc_entries_failed;
 	}
 
 	vdev->vxge_entries =
@@ -2271,8 +2272,8 @@ start:
 	if (!vdev->vxge_entries) {
 		vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",
 			VXGE_DRIVER_NAME);
-		kfree(vdev->entries);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto alloc_vxge_entries_failed;
 	}
 
 	for (i = 0, j = 0; i < vdev->no_of_vpath; i++) {
@@ -2303,22 +2304,32 @@ start:
 		vxge_debug_init(VXGE_ERR,
 			"%s: MSI-X enable failed for %d vectors, ret: %d",
 			VXGE_DRIVER_NAME, vdev->intr_cnt, ret);
+		if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) {
+			ret = -ENODEV;
+			goto enable_msix_failed;
+		}
+
 		kfree(vdev->entries);
 		kfree(vdev->vxge_entries);
 		vdev->entries = NULL;
 		vdev->vxge_entries = NULL;
-
-		if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3))
-			return -ENODEV;
 		/* Try with less no of vector by reducing no of vpaths count */
 		temp = (ret - 1)/2;
 		vxge_close_vpaths(vdev, temp);
 		vdev->no_of_vpath = temp;
 		goto start;
-	} else if (ret < 0)
-		return -ENODEV;
-
+	} else if (ret < 0) {
+		ret = -ENODEV;
+		goto enable_msix_failed;
+	}
 	return 0;
+
+enable_msix_failed:
+	kfree(vdev->vxge_entries);
+alloc_vxge_entries_failed:
+	kfree(vdev->entries);
+alloc_entries_failed:
+	return ret;
 }
 
 static int vxge_enable_msix(struct vxgedev *vdev)
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index e0c244b02f05..31c008042bfe 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -126,6 +126,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
 	ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
 	ah->ah_noise_floor = -95;	/* until first NF calibration is run */
 	sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
+	ah->ah_current_channel = &sc->channels[0];
 
 	/*
 	 * Find the mac version
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index db72461c486b..29b31a694b59 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -594,6 +594,7 @@ static int prism2_config(struct pcmcia_device *link)
 	local_info_t *local;
 	int ret = 1;
 	struct hostap_cs_priv *hw_priv;
+	unsigned long flags;
 
 	PDEBUG(DEBUG_FLOW, "prism2_config()\n");
 
@@ -625,9 +626,15 @@ static int prism2_config(struct pcmcia_device *link)
 	local->hw_priv = hw_priv;
 	hw_priv->link = link;
 
+	/*
+	 * Make sure the IRQ handler cannot proceed until at least
+	 * dev->base_addr is initialized.
+	 */
+	spin_lock_irqsave(&local->irq_init_lock, flags);
+
 	ret = pcmcia_request_irq(link, prism2_interrupt);
 	if (ret)
-		goto failed;
+		goto failed_unlock;
 
 	/*
 	 * This actually configures the PCMCIA socket -- setting up
@@ -636,11 +643,13 @@ static int prism2_config(struct pcmcia_device *link)
 	 */
 	ret = pcmcia_request_configuration(link, &link->conf);
 	if (ret)
-		goto failed;
+		goto failed_unlock;
 
 	dev->irq = link->irq;
 	dev->base_addr = link->io.BasePort1;
 
+	spin_unlock_irqrestore(&local->irq_init_lock, flags);
+
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x: ",
 	       dev_info, link->conf.ConfigIndex);
@@ -667,6 +676,8 @@ static int prism2_config(struct pcmcia_device *link)
 
 	return ret;
 
+ failed_unlock:
+	 spin_unlock_irqrestore(&local->irq_init_lock, flags);
  failed:
 	kfree(hw_priv);
 	prism2_release((u_long)link);
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index ff9b5c882184..2f999fc94f60 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -2621,6 +2621,18 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)
 	iface = netdev_priv(dev);
 	local = iface->local;
 
+	/* Detect early interrupt before driver is fully configued */
+	spin_lock(&local->irq_init_lock);
+	if (!dev->base_addr) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n",
+			       dev->name);
+		}
+		spin_unlock(&local->irq_init_lock);
+		return IRQ_HANDLED;
+	}
+	spin_unlock(&local->irq_init_lock);
+
 	prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
 
 	if (local->func->card_present && !local->func->card_present(local)) {
@@ -3138,6 +3150,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
 	spin_lock_init(&local->cmdlock);
 	spin_lock_init(&local->baplock);
 	spin_lock_init(&local->lock);
+	spin_lock_init(&local->irq_init_lock);
 	mutex_init(&local->rid_bap_mtx);
 
 	if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES)
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index 3d238917af07..1ba33be98b25 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -654,7 +654,7 @@ struct local_info {
 	rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock
 			      * when removing entries from the list.
 			      * TX and RX paths can use read lock. */
-	spinlock_t cmdlock, baplock, lock;
+	spinlock_t cmdlock, baplock, lock, irq_init_lock;
 	struct mutex rid_bap_mtx;
 	u16 infofid; /* MAC buffer id for info frame */
 	/* txfid, intransmitfid, next_txtid, and next_alloc are protected by
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index a732f1094e5d..7d614c4d3c62 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -1299,6 +1299,11 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 	sta_id = ba_resp->sta_id;
 	tid = ba_resp->tid;
 	agg = &priv->stations[sta_id].tid[tid].agg;
+	if (unlikely(agg->txq_id != scd_flow)) {
+		IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n",
+			scd_flow, agg->txq_id);
+		return;
+	}
 
 	/* Find index just before block-ack window */
 	index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 7726e67044c0..24aff654fa9c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3391,10 +3391,12 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
 	int ret;
 	u8 sta_id;
 
-	sta_priv->common.sta_id = IWL_INVALID_STATION;
-
 	IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
 			sta->addr);
+	mutex_lock(&priv->mutex);
+	IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
+			sta->addr);
+	sta_priv->common.sta_id = IWL_INVALID_STATION;
 
 	atomic_set(&sta_priv->pending_frames, 0);
 	if (vif->type == NL80211_IFTYPE_AP)
@@ -3406,6 +3408,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
 		IWL_ERR(priv, "Unable to add station %pM (%d)\n",
 			sta->addr, ret);
 		/* Should we return success if return code is EEXIST ? */
+		mutex_unlock(&priv->mutex);
 		return ret;
 	}
 
@@ -3415,6 +3418,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
 	IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
 		       sta->addr);
 	iwl_rs_rate_init(priv, sta, sta_id);
+	mutex_unlock(&priv->mutex);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 5d3f51ff2f0d..386c5f96eff8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -491,6 +491,7 @@ void iwl_bg_abort_scan(struct work_struct *work)
 
 	mutex_lock(&priv->mutex);
 
+	cancel_delayed_work_sync(&priv->scan_check);
 	set_bit(STATUS_SCAN_ABORTING, &priv->status);
 	iwl_send_scan_abort(priv);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 83a26361a9b5..c27c13fbb1ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1373,10 +1373,14 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
 
 	IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
 			sta->addr);
+	mutex_lock(&priv->mutex);
+	IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
+			sta->addr);
 	ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
 	if (ret)
 		IWL_ERR(priv, "Error removing station %pM\n",
 			sta->addr);
+	mutex_unlock(&priv->mutex);
 	return ret;
 }
 EXPORT_SYMBOL(iwl_mac_sta_remove);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6c353cacc8d6..a27872de4106 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3437,10 +3437,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
 	bool is_ap = vif->type == NL80211_IFTYPE_STATION;
 	u8 sta_id;
 
-	sta_priv->common.sta_id = IWL_INVALID_STATION;
-
 	IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
 			sta->addr);
+	mutex_lock(&priv->mutex);
+	IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
+			sta->addr);
+	sta_priv->common.sta_id = IWL_INVALID_STATION;
+
 
 	ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
 				     &sta_id);
@@ -3448,6 +3451,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
 		IWL_ERR(priv, "Unable to add station %pM (%d)\n",
 			sta->addr, ret);
 		/* Should we return success if return code is EEXIST ? */
+		mutex_unlock(&priv->mutex);
 		return ret;
 	}
 
@@ -3457,6 +3461,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
 	IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
 		       sta->addr);
 	iwl3945_rs_rate_init(priv, sta, sta_id);
+	mutex_unlock(&priv->mutex);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 6a04c2157f73..817fffc0de4b 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -549,7 +549,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
 
 	prxpd = (struct rxpd *) skb->data;
 
-	stats.flag = 0;
+	memset(&stats, 0, sizeof(stats));
 	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
 		stats.flag |= RX_FLAG_FAILED_FCS_CRC;
 	stats.freq = priv->cur_freq;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 07c4528f6e6b..a5ea89cde8c4 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -41,6 +41,8 @@ static DEFINE_PCI_DEVICE_TABLE(p54p_table) = {
 	{ PCI_DEVICE(0x1260, 0x3877) },
 	/* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
 	{ PCI_DEVICE(0x1260, 0x3886) },
+	/* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */
+	{ PCI_DEVICE(0x1260, 0xffff) },
 	{ },
 };
 
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 526307368f8b..ab17c08ddc03 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -821,6 +821,7 @@ static struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
 	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),