Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/2 scsi-post-merge] cxgb3i: support of private MAC address in iSCSI
From: Mike Christie @ 2009-09-26  0:36 UTC (permalink / raw)
  To: kxie
  Cc: James.Bottomley, davem, swise, divy, rakesh, linux-scsi,
	open-iscsi, linux-kernel, netdev
In-Reply-To: <200909252225.n8PMPaa4031752@localhost.localdomain>

kxie@chelsio.com wrote:
> [PATCH v2 2/2 scsi-post-merge] cxgb3i: private MAC address for iSCSI
> 
> From: Karen Xie <kxie@chelsio.com>
>         
> This patch updated the use of private MAC address per port in iscsi.
> 
> This patch is generated against scsi-post-merge.
>              
> Signed-off-by: Karen Xie <kxie@chelsio.com>
> --- 
>  drivers/scsi/cxgb3i/cxgb3i_offload.h |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
> index 6a1d86b..f585ece 100644
> --- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
> +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
> @@ -234,9 +234,9 @@ struct sge_opaque_hdr {
>   * get and set private ip for iscsi traffic
>   */
>  #define cxgb3i_get_private_ipv4addr(ndev) \
> -	(((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr)
> +	(((struct port_info *)(netdev_priv(ndev)))->iscsic.ipv4_addr)
>  #define cxgb3i_set_private_ipv4addr(ndev, addr) \
> -	(((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr) = addr
> +	(((struct port_info *)(netdev_priv(ndev)))->iscsic.ipv4_addr) = addr
>  

This looks ok.

Reviewed-by Mike Christie <michaelc@cs.wisc.edu>

^ permalink raw reply

* RE:
From: Irish News Center @ 2009-09-25 23:16 UTC (permalink / raw)


You've won £750,000.Send:Name,Age,Country


^ permalink raw reply

* Re: r8169, enabling TX checksumming breaks things?
From: Denys Fedoryschenko @ 2009-09-25 23:18 UTC (permalink / raw)
  To: David Dillow; +Cc: romieu, netdev
In-Reply-To: <1253754752.13176.19.camel@obelisk.thedillows.org>

>
> This is the patch I have against HEAD, which Works For Me (TM). If I
> recall correctly the list in rtl8169_set_tso_csum() is from combing the
> vendor drivers, but I'm not 100% on that. Too much time has passed.
>
> I added the MAC version to the driver banner, which should make it
> easier to figure out which MAC you have, and to change that function if
> it does not work for you out of the box. It seems that some chips don't
> work with this at all, based on testing by Michael Riepe (XID 3c4000c0).
>
> As should be obvious, this isn't ready to go anywhere near upstream yet
> I think.
>
Applied to 2.6.31.1 (i cannot run latest git, it is loaded proxy, too much 
risk) (one reject only, fixed by hand).

[    0.793643] r8169 Gigabit Ethernet driver 2.3LK-NAPI-TSO loaded
[    0.793734] r8169 0000:03:00.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
[    0.793842] r8169 0000:03:00.0: setting latency timer to 64
[    0.793898] r8169 0000:03:00.0: irq 27 for MSI/MSI-X
[    0.794188] eth0: RTL8168d/8111d (25) at 0xf8420000, 00:1c:c0:c2:4d:df, XID 
281000c0 IRQ 27
[    2.110317] r8169: eth0: link down
[    2.110396] r8169: eth0: link down
[    3.872590] r8169: eth0: link up

Working fine now, now when i enable TX checksumming it doesn't fail. I will 
run for a while with tx checksumming, and then i will run the rest and will 
do some performance measurements (by perf tool) and i will try on a little 
bit other model of motherboard.
Thanks a lot for your patch!

^ permalink raw reply

* [net-2.6 PATCH 3/3] net: fix double skb free in dcbnl
From: Jeff Kirsher @ 2009-09-25 23:12 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, John Fastabend, Jeff Kirsher
In-Reply-To: <20090925231124.23450.94680.stgit@localhost.localdomain>

From: John Fastabend <john.r.fastabend@intel.com>

netlink_unicast() calls kfree_skb even in the error case.

dcbnl calls netlink_unicast() which when it fails free's the
skb and returns an error value.  dcbnl is free'ing the skb
again when this error occurs.  This patch removes the double
free.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 net/dcb/dcbnl.c |   15 +++++++--------
 1 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index e0879bf..ac1205d 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -194,7 +194,7 @@ static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
 	nlmsg_end(dcbnl_skb, nlh);
 	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
 	if (ret)
-		goto err;
+		return -EINVAL;
 
 	return 0;
 nlmsg_failure:
@@ -275,7 +275,7 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb,
 
 	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
 	if (ret)
-		goto err;
+		goto err_out;
 
 	return 0;
 nlmsg_failure:
@@ -316,12 +316,11 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb,
 
 	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
 	if (ret)
-		goto err;
+		goto err_out;
 
 	return 0;
 
 nlmsg_failure:
-err:
 	kfree_skb(dcbnl_skb);
 err_out:
 	return -EINVAL;
@@ -383,7 +382,7 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb,
 
 	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
 	if (ret)
-		goto err;
+		goto err_out;
 
 	return 0;
 nlmsg_failure:
@@ -460,7 +459,7 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb,
 	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
 	if (ret) {
 		ret = -EINVAL;
-		goto err;
+		goto err_out;
 	}
 
 	return 0;
@@ -799,7 +798,7 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb,
 
 	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
 	if (ret)
-		goto err;
+		goto err_out;
 
 	return 0;
 
@@ -1063,7 +1062,7 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb,
 
 	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
 	if (ret)
-		goto err;
+		goto err_out;
 
 	return 0;
 


^ permalink raw reply related

* [net-2.6 PATCH 2/3] net: fix nlmsg len size for skb when error bit is set.
From: Jeff Kirsher @ 2009-09-25 23:11 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, John Fastabend, Jeff Kirsher
In-Reply-To: <20090925231124.23450.94680.stgit@localhost.localdomain>

From: John Fastabend <john.r.fastabend@intel.com>

Currently, the nlmsg->len field is not set correctly in  netlink_ack()
for ack messages that include the nlmsg of the error frame.  This
corrects the length field passed to __nlmsg_put to use the correct
payload size.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 net/netlink/af_netlink.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index a4bafbf..dd85320 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1788,7 +1788,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
 	}
 
 	rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
-			  NLMSG_ERROR, sizeof(struct nlmsgerr), 0);
+			  NLMSG_ERROR, payload, 0);
 	errmsg = nlmsg_data(rep);
 	errmsg->error = err;
 	memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh));


^ permalink raw reply related

* [net-2.6 PATCH 1/3] net: fix vlan_get_size to include vlan_flags size
From: Jeff Kirsher @ 2009-09-25 23:11 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, John Fastabend, Jeff Kirsher

From: John Fastabend <john.r.fastabend@intel.com>

Fix vlan_get_size to include vlan->flags.  Currently, the
size of the vlan flags is not included in the nlmsg size.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 net/8021q/vlan_netlink.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 343146e..a915048 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -169,6 +169,7 @@ static size_t vlan_get_size(const struct net_device *dev)
 	struct vlan_dev_info *vlan = vlan_dev_info(dev);
 
 	return nla_total_size(2) +	/* IFLA_VLAN_ID */
+	       sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */
 	       vlan_qos_map_size(vlan->nr_ingress_mappings) +
 	       vlan_qos_map_size(vlan->nr_egress_mappings);
 }


^ permalink raw reply related

* Re: Getting physical packet counts with LRO enabled with ixgbe?
From: Peter P Waskiewicz Jr @ 2009-09-25 22:40 UTC (permalink / raw)
  To: Ben Greear; +Cc: Herbert Xu, David Miller, netdev@vger.kernel.org
In-Reply-To: <4ABD405D.2030106@candelatech.com>

On Fri, 2009-09-25 at 15:12 -0700, Ben Greear wrote:
> On 09/25/2009 03:01 PM, Herbert Xu wrote:
> > On Fri, Sep 25, 2009 at 02:59:15PM -0700, David Miller wrote:
> >> From: Ben Greear<greearb@candelatech.com>
> >> Date: Fri, 25 Sep 2009 14:50:44 -0700
> >>
> >>> I get aggregate 18Gbps with LRO v/s 12Gbps without, so it's very
> >>> much a useful feature for me.
> >>
> >> And it'll stay like that until you work with Herbert to fix
> >> that performance difference.
> >
> > Actually I believe he's talking about hardware LRO which is a
> > different beast.
> >
> > AFAICS the ixgbe driver doesn't use software LRO anymore.
> >
> > So if it is hardware LRO then what we need is for the hardware
> > to switch over :)
> 
> Either way, I will be happy to test & benchmark patches of this nature
> if someone wants to post them.
> 

I can't post a patch that changes my hardware behavior.  :-)

So to be clear, ixgbe uses GRO, and does not use software LRO.  In 82599
adapters, we have a HW LRO engine.  So we run HW LRO and GRO together.
What Herbert is referring to is that we change our HW design of the HW
LRO engine to do more of what GRO is doing today.  That would require a
silicon spin, so that wouldn't happen soon unfortunately.

-PJ


^ permalink raw reply

* RE: [PATCH v2 0/2] cxgb3/cxgb3i: added support of private MAC address and provisioning packet handler for iSCSI
From: Karen Xie @ 2009-09-25 22:34 UTC (permalink / raw)
  To: David Miller
  Cc: michaelc, James.Bottomley, Steve Wise, Divy Le Ray, Rakesh Ranjan,
	linux-scsi, open-iscsi, linux-kernel, netdev
In-Reply-To: <20090925.152430.119503066.davem@davemloft.net>

Hmm, I am wondering how could this merge activity to be coordinated? If
only the driver/scsi change is merged, then it won't compile either,
since it requires the driver/net change.

Is it possible to merge both patches to the scsi or net tree?

Thanks,
Karen

-----Original Message-----
From: David Miller [mailto:davem@davemloft.net] 
Sent: Friday, September 25, 2009 3:25 PM
To: Karen Xie
Cc: michaelc@cs.wisc.edu; James.Bottomley@HansenPartnership.com; Steve
Wise; Divy Le Ray; Rakesh Ranjan; linux-scsi@vger.kernel.org;
open-iscsi@googlegroups.com; linux-kernel@vger.kernel.org;
netdev@vger.kernel.org
Subject: Re: [PATCH v2 0/2] cxgb3/cxgb3i: added support of private MAC
address and provisioning packet handler for iSCSI

From: kxie@chelsio.com
Date: Fri, 25 Sep 2009 15:25:36 -0700

> From: Karen Xie <kxie@chelsio.com>
> 
> The two patches added support of private MAC address, which is derived
from
> the network (i.e., public) MAC address, and provisioning packet
handler for
> iSCSI traffic only.

I think I'm going to ask you to resubmit the drivers/net patch
after the necessary drivers/scsi changes get merged by the scsi
folks.

Thank you.

^ permalink raw reply

* RE: [PATCH net-next-2.6] cxgb3: Added private MAC address and provisioning packet handler for iSCSI
From: Karen Xie @ 2009-09-25 22:30 UTC (permalink / raw)
  To: David Miller
  Cc: Steve Wise, Divy Le Ray, Rakesh Ranjan, James.Bottomley, michaelc,
	linux-kernel, netdev
In-Reply-To: <20090925.134239.193728924.davem@davemloft.net>

Hi, Dave,

We are extremely sorry.

There is a 2nd patch that is going to the scsi git tree, which address the compilation issues you encountered.

I've re-submitted both patches as a series, so it could be applied together.

Thanks a lot,
Karen


-----Original Message-----
From: David Miller [mailto:davem@davemloft.net] 
Sent: Friday, September 25, 2009 1:43 PM
To: Karen Xie
Cc: Steve Wise; Divy Le Ray; Rakesh Ranjan; James.Bottomley@HansenPartnership.com; michaelc@cs.wisc.edu; linux-kernel@vger.kernel.org; netdev@vger.kernel.org
Subject: Re: [PATCH net-next-2.6] cxgb3: Added private MAC address and provisioning packet handler for iSCSI

From: David Miller <davem@davemloft.net>
Date: Fri, 25 Sep 2009 12:12:42 -0700 (PDT)

> From: kxie@chelsio.com
> Date: Thu, 24 Sep 2009 18:33:10 -0700
> 
>> 00c487ed661c0904757a21b7c958eba59e68482a
>> [PATCH net-next-2.6] cxgb3: Added private MAC address and provisioning packet handler for iSCSI
>> 
>> This patch added support of private MAC address per port and provisioning
>> packet handler for iSCSI traffic only.
>> 
>> Acked-by: Karen Xie <kxie@chelsio.com>
>> Acked-by: Divy Le Ray <divy@chelsio.com>
>> Signed-off-by: Rakesh Ranjan <rranjan@chelsio.com>
> 
> Applied, thanks.

This doesn't even build, reverting:

drivers/scsi/cxgb3i/cxgb3i_iscsi.c: In function ‘cxgb3i_host_set_param’:
drivers/scsi/cxgb3i/cxgb3i_iscsi.c:718: error: ‘struct port_info’ has no member named ‘iscsi_ipv4addr’
drivers/scsi/cxgb3i/cxgb3i_iscsi.c: In function ‘cxgb3i_host_get_param’:
drivers/scsi/cxgb3i/cxgb3i_iscsi.c:755: error: ‘struct port_info’ has no member named ‘iscsi_ipv4addr’
make[3]: *** [drivers/scsi/cxgb3i/cxgb3i_iscsi.o] Error 1

^ permalink raw reply

* [PATCH v2 1/2 net-next-2.6] cxgb3: added private MAC address and provisioning packet handler for iSCSI
From: kxie @ 2009-09-25 22:25 UTC (permalink / raw)
  To: michaelc, James.Bottomley, davem
  Cc: swise, divy, rakesh, kxie, linux-scsi, open-iscsi, linux-kernel,
	netdev

[PATCH v2 1/2 net-next-2.6] cxgb3: Added private MAC address and provisioning packet handler for iSCSI

This patch added support of private MAC address per port and provisioning
packet handler for iSCSI traffic only.

This patch is generated against net-next-2.6.

Acked-by: Karen Xie <kxie@chelsio.com>
Acked-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: Rakesh Ranjan <rranjan@chelsio.com>
---
 drivers/net/cxgb3/adapter.h       |   18 +++++++++++++++++-
 drivers/net/cxgb3/cxgb3_main.c    |   22 ++++++++++++++++++----
 drivers/net/cxgb3/cxgb3_offload.c |    2 +-
 drivers/net/cxgb3/sge.c           |   30 ++++++++++++++++++++----------
 4 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 2b1aea6..3f3083a 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -48,12 +48,28 @@
 struct vlan_group;
 struct adapter;
 struct sge_qset;
+struct port_info;
 
 enum {			/* rx_offload flags */
 	T3_RX_CSUM	= 1 << 0,
 	T3_LRO		= 1 << 1,
 };
 
+enum {
+	LAN_MAC_IDX	= 0,
+	SAN_MAC_IDX,
+
+	MAX_MAC_IDX
+};
+
+struct iscsi_config {
+	__be32	ipv4_addr;
+	__u8	mac_addr[ETH_ALEN];
+	__u32	flags;
+	int (*send)(struct port_info *pi, struct sk_buff **skb);
+	int (*recv)(struct port_info *pi, struct sk_buff *skb);
+};
+
 struct port_info {
 	struct adapter *adapter;
 	struct vlan_group *vlan_grp;
@@ -67,7 +83,7 @@ struct port_info {
 	struct link_config link_config;
 	struct net_device_stats netstats;
 	int activity;
-	__be32 iscsi_ipv4addr;
+	struct iscsi_config iscsic;
 
 	int link_fault; /* link fault was detected */
 };
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 34e776c..c9113d3 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -344,8 +344,10 @@ static void link_start(struct net_device *dev)
 
 	init_rx_mode(&rm, dev, dev->mc_list);
 	t3_mac_reset(mac);
+	t3_mac_set_num_ucast(mac, MAX_MAC_IDX);
 	t3_mac_set_mtu(mac, dev->mtu);
-	t3_mac_set_address(mac, 0, dev->dev_addr);
+	t3_mac_set_address(mac, LAN_MAC_IDX, dev->dev_addr);
+	t3_mac_set_address(mac, SAN_MAC_IDX, pi->iscsic.mac_addr);
 	t3_mac_set_rx_mode(mac, &rm);
 	t3_link_start(&pi->phy, mac, &pi->link_config);
 	t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
@@ -903,6 +905,7 @@ static inline int offload_tx(struct t3cdev *tdev, struct sk_buff *skb)
 static int write_smt_entry(struct adapter *adapter, int idx)
 {
 	struct cpl_smt_write_req *req;
+	struct port_info *pi = netdev_priv(adapter->port[idx]);
 	struct sk_buff *skb = alloc_skb(sizeof(*req), GFP_KERNEL);
 
 	if (!skb)
@@ -913,8 +916,8 @@ static int write_smt_entry(struct adapter *adapter, int idx)
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx));
 	req->mtu_idx = NMTUS - 1;	/* should be 0 but there's a T3 bug */
 	req->iff = idx;
-	memset(req->src_mac1, 0, sizeof(req->src_mac1));
 	memcpy(req->src_mac0, adapter->port[idx]->dev_addr, ETH_ALEN);
+	memcpy(req->src_mac1, pi->iscsic.mac_addr, ETH_ALEN);
 	skb->priority = 1;
 	offload_tx(&adapter->tdev, skb);
 	return 0;
@@ -2516,7 +2519,7 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)
 		return -EINVAL;
 
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-	t3_mac_set_address(&pi->mac, 0, dev->dev_addr);
+	t3_mac_set_address(&pi->mac, LAN_MAC_IDX, dev->dev_addr);
 	if (offload_running(adapter))
 		write_smt_entry(adapter, pi->port_id);
 	return 0;
@@ -2654,7 +2657,7 @@ static void check_t3b2_mac(struct adapter *adapter)
 			struct cmac *mac = &p->mac;
 
 			t3_mac_set_mtu(mac, dev->mtu);
-			t3_mac_set_address(mac, 0, dev->dev_addr);
+			t3_mac_set_address(mac, LAN_MAC_IDX, dev->dev_addr);
 			cxgb_set_rxmode(dev);
 			t3_link_start(&p->phy, mac, &p->link_config);
 			t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
@@ -3112,6 +3115,14 @@ static const struct net_device_ops cxgb_netdev_ops = {
 #endif
 };
 
+static void __devinit cxgb3_init_iscsi_mac(struct net_device *dev)
+{
+	struct port_info *pi = netdev_priv(dev);
+
+	memcpy(pi->iscsic.mac_addr, dev->dev_addr, ETH_ALEN);
+	pi->iscsic.mac_addr[3] |= 0x80;
+}
+
 static int __devinit init_one(struct pci_dev *pdev,
 			      const struct pci_device_id *ent)
 {
@@ -3270,6 +3281,9 @@ static int __devinit init_one(struct pci_dev *pdev,
 		goto out_free_dev;
 	}
 
+	for_each_port(adapter, i)
+		cxgb3_init_iscsi_mac(adapter->port[i]);
+
 	/* Driver's ready. Reflect it on LEDs */
 	t3_led_ready(adapter);
 
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 75064ee..7f314c3 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -447,7 +447,7 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data)
 	case GET_ISCSI_IPV4ADDR: {
 		struct iscsi_ipv4addr *p = data;
 		struct port_info *pi = netdev_priv(p->dev);
-		p->ipv4addr = pi->iscsi_ipv4addr;
+		p->ipv4addr = pi->iscsic.ipv4_addr;
 		break;
 	}
 	case GET_EMBEDDED_INFO: {
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index f866128..a911363 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1946,10 +1946,9 @@ static void restart_tx(struct sge_qset *qs)
  *	Check if the ARP request is probing the private IP address
  *	dedicated to iSCSI, generate an ARP reply if so.
  */
-static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb)
+static void cxgb3_arp_process(struct port_info *pi, struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
-	struct port_info *pi;
 	struct arphdr *arp;
 	unsigned char *arp_ptr;
 	unsigned char *sha;
@@ -1972,12 +1971,11 @@ static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb)
 	arp_ptr += dev->addr_len;
 	memcpy(&tip, arp_ptr, sizeof(tip));
 
-	pi = netdev_priv(dev);
-	if (tip != pi->iscsi_ipv4addr)
+	if (tip != pi->iscsic.ipv4_addr)
 		return;
 
 	arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
-		 dev->dev_addr, sha);
+		 pi->iscsic.mac_addr, sha);
 
 }
 
@@ -1986,6 +1984,19 @@ static inline int is_arp(struct sk_buff *skb)
 	return skb->protocol == htons(ETH_P_ARP);
 }
 
+static void cxgb3_process_iscsi_prov_pack(struct port_info *pi,
+					struct sk_buff *skb)
+{
+	if (is_arp(skb)) {
+		cxgb3_arp_process(pi, skb);
+		return;
+	}
+
+	if (pi->iscsic.recv)
+		pi->iscsic.recv(pi, skb);
+
+}
+
 /**
  *	rx_eth - process an ingress ethernet packet
  *	@adap: the adapter
@@ -2024,13 +2035,12 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
 				vlan_gro_receive(&qs->napi, grp,
 						 ntohs(p->vlan), skb);
 			else {
-				if (unlikely(pi->iscsi_ipv4addr &&
-				    is_arp(skb))) {
+				if (unlikely(pi->iscsic.flags)) {
 					unsigned short vtag = ntohs(p->vlan) &
 								VLAN_VID_MASK;
 					skb->dev = vlan_group_get_device(grp,
 									 vtag);
-					cxgb3_arp_process(adap, skb);
+					cxgb3_process_iscsi_prov_pack(pi, skb);
 				}
 				__vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
 					  	  rq->polling);
@@ -2041,8 +2051,8 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
 		if (lro)
 			napi_gro_receive(&qs->napi, skb);
 		else {
-			if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
-				cxgb3_arp_process(adap, skb);
+			if (unlikely(pi->iscsic.flags))
+				cxgb3_process_iscsi_prov_pack(pi, skb);
 			netif_receive_skb(skb);
 		}
 	} else
-- 
1.6.0.6

^ permalink raw reply related

* [PATCH v2 2/2 scsi-post-merge] cxgb3i: support of private MAC address in iSCSI
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2009-09-25 22:25 UTC (permalink / raw)
  To: michaelc-hcNo3dDEHLuVc3sceRu5cw,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW,
	divy-ut6Up61K2wZBDgjK7y7TUQ, rakesh-ut6Up61K2wZBDgjK7y7TUQ,
	kxie-ut6Up61K2wZBDgjK7y7TUQ, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA


[PATCH v2 2/2 scsi-post-merge] cxgb3i: private MAC address for iSCSI

From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
        
This patch updated the use of private MAC address per port in iscsi.

This patch is generated against scsi-post-merge.
             
Signed-off-by: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
--- 
 drivers/scsi/cxgb3i/cxgb3i_offload.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)


diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
index 6a1d86b..f585ece 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
@@ -234,9 +234,9 @@ struct sge_opaque_hdr {
  * get and set private ip for iscsi traffic
  */
 #define cxgb3i_get_private_ipv4addr(ndev) \
-	(((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr)
+	(((struct port_info *)(netdev_priv(ndev)))->iscsic.ipv4_addr)
 #define cxgb3i_set_private_ipv4addr(ndev, addr) \
-	(((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr) = addr
+	(((struct port_info *)(netdev_priv(ndev)))->iscsic.ipv4_addr) = addr
 
 /* max. connections per adapter */
 #define CXGB3I_MAX_CONN		16384

^ permalink raw reply related

* [PATCH v2 0/2] cxgb3/cxgb3i: added support of private MAC address and provisioning packet handler for iSCSI
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2009-09-25 22:25 UTC (permalink / raw)
  To: michaelc-hcNo3dDEHLuVc3sceRu5cw,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW,
	divy-ut6Up61K2wZBDgjK7y7TUQ, rakesh-ut6Up61K2wZBDgjK7y7TUQ,
	kxie-ut6Up61K2wZBDgjK7y7TUQ, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA


From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>

The two patches added support of private MAC address, which is derived from
the network (i.e., public) MAC address, and provisioning packet handler for
iSCSI traffic only.

Best regards,
Karen

^ permalink raw reply

* Re: [PATCH v2 0/2] cxgb3/cxgb3i: added support of private MAC address and provisioning packet handler for iSCSI
From: David Miller @ 2009-09-25 22:24 UTC (permalink / raw)
  To: kxie
  Cc: michaelc, James.Bottomley, swise, divy, rakesh, linux-scsi,
	open-iscsi, linux-kernel, netdev
In-Reply-To: <200909252225.n8PMPaqI031748@localhost.localdomain>

From: kxie@chelsio.com
Date: Fri, 25 Sep 2009 15:25:36 -0700

> From: Karen Xie <kxie@chelsio.com>
> 
> The two patches added support of private MAC address, which is derived from
> the network (i.e., public) MAC address, and provisioning packet handler for
> iSCSI traffic only.

I think I'm going to ask you to resubmit the drivers/net patch
after the necessary drivers/scsi changes get merged by the scsi
folks.

Thank you.

^ permalink raw reply

* [net-2.6 PATCH 13/13] e1000: cleanup unused prototype
From: Jeff Kirsher @ 2009-09-25 22:20 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Don Skidmore <donald.c.skidmore@intel.com>

The function e1000_enable_tx_pkt_filtering() was removed in
a previous cleanup patch.  this removes the no longer used
prototype.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_hw.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 2e42341..9acfddb 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -365,7 +365,6 @@ struct e1000_host_mng_dhcp_cookie {
 #endif
 
 bool e1000_check_mng_mode(struct e1000_hw *hw);
-bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
 s32 e1000_read_eeprom(struct e1000_hw *hw, u16 reg, u16 words, u16 * data);
 s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw);
 s32 e1000_update_eeprom_checksum(struct e1000_hw *hw);


^ permalink raw reply related

* [net-2.6 PATCH 12/13] e1000: fix namespacecheck warnings
From: Jeff Kirsher @ 2009-09-25 22:20 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

a couple of functions needed to be removed/declared static

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_hw.c   |    2 +-
 drivers/net/e1000/e1000_main.c |   14 --------------
 2 files changed, 1 insertions(+), 15 deletions(-)

diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 50114cd..8d7d87f 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -2190,7 +2190,7 @@ static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
  * Checks for link up on the hardware.  If link is not up and we have
  * a signal, then we need to force link up.
  */
-s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
+static s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
 {
 	u32 rxcw;
 	u32 ctrl;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 8302e18..bcd192c 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4349,20 +4349,6 @@ void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
 	pcix_set_mmrbc(adapter->pdev, mmrbc);
 }
 
-s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
-{
-    struct e1000_adapter *adapter = hw->back;
-    u16 cap_offset;
-
-    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
-    if (!cap_offset)
-        return -E1000_ERR_CONFIG;
-
-    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
-
-    return E1000_SUCCESS;
-}
-
 void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
 {
 	outl(value, port);


^ permalink raw reply related

* [net-2.6 PATCH 11/13] e1000: drop unused functionality for eeprom write/read
From: Jeff Kirsher @ 2009-09-25 22:20 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

eerd and eewr don't exist on pre PCIe devices

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_hw.c |  121 +-----------------------------------------
 drivers/net/e1000/e1000_hw.h |    2 -
 2 files changed, 3 insertions(+), 120 deletions(-)

diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 6aba883..50114cd 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -49,11 +49,6 @@ static s32 e1000_id_led_init(struct e1000_hw *hw);
 static void e1000_init_rx_addrs(struct e1000_hw *hw);
 static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
 				  struct e1000_phy_info *phy_info);
-static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words,
-				  u16 *data);
-static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
-				   u16 *data);
-static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
 static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
 				  struct e1000_phy_info *phy_info);
 static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
@@ -3339,8 +3334,6 @@ s32 e1000_init_eeprom_params(struct e1000_hw *hw)
 		eeprom->opcode_bits = 3;
 		eeprom->address_bits = 6;
 		eeprom->delay_usec = 50;
-		eeprom->use_eerd = false;
-		eeprom->use_eewr = false;
 		break;
 	case e1000_82540:
 	case e1000_82545:
@@ -3357,8 +3350,6 @@ s32 e1000_init_eeprom_params(struct e1000_hw *hw)
 			eeprom->word_size = 64;
 			eeprom->address_bits = 6;
 		}
-		eeprom->use_eerd = false;
-		eeprom->use_eewr = false;
 		break;
 	case e1000_82541:
 	case e1000_82541_rev_2:
@@ -3387,8 +3378,6 @@ s32 e1000_init_eeprom_params(struct e1000_hw *hw)
 				eeprom->address_bits = 6;
 			}
 		}
-		eeprom->use_eerd = false;
-		eeprom->use_eewr = false;
 		break;
 	default:
 		break;
@@ -3773,15 +3762,9 @@ static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
 	 * directly. In this case, we need to acquire the EEPROM so that
 	 * FW or other port software does not interrupt.
 	 */
-	if (!hw->eeprom.use_eerd) {
-		/* Prepare the EEPROM for bit-bang reading */
-		if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
-			return -E1000_ERR_EEPROM;
-	}
-
-	/* Eerd register EEPROM access requires no eeprom aquire/release */
-	if (eeprom->use_eerd)
-		return e1000_read_eeprom_eerd(hw, offset, words, data);
+	/* Prepare the EEPROM for bit-bang reading */
+	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+		return -E1000_ERR_EEPROM;
 
 	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
 	 * acquired the EEPROM at this point, so any returns should release it */
@@ -3837,101 +3820,6 @@ static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
 }
 
 /**
- * Reads a 16 bit word from the EEPROM using the EERD register.
- *
- * @hw: Struct containing variables accessed by shared code
- * offset - offset of  word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- */
-static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words,
-				  u16 *data)
-{
-	u32 i, eerd = 0;
-	s32 error = 0;
-
-	for (i = 0; i < words; i++) {
-		eerd = ((offset + i) << E1000_EEPROM_RW_ADDR_SHIFT) +
-		    E1000_EEPROM_RW_REG_START;
-
-		ew32(EERD, eerd);
-		error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
-
-		if (error) {
-			break;
-		}
-		data[i] = (er32(EERD) >> E1000_EEPROM_RW_REG_DATA);
-
-	}
-
-	return error;
-}
-
-/**
- * Writes a 16 bit word from the EEPROM using the EEWR register.
- *
- * @hw: Struct containing variables accessed by shared code
- * offset - offset of  word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- */
-static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
-				   u16 *data)
-{
-	u32 register_value = 0;
-	u32 i = 0;
-	s32 error = 0;
-
-	for (i = 0; i < words; i++) {
-		register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) |
-		    ((offset + i) << E1000_EEPROM_RW_ADDR_SHIFT) |
-		    E1000_EEPROM_RW_REG_START;
-
-		error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
-		if (error) {
-			break;
-		}
-
-		ew32(EEWR, register_value);
-
-		error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
-
-		if (error) {
-			break;
-		}
-	}
-
-	return error;
-}
-
-/**
- * Polls the status bit (bit 1) of the EERD to determine when the read is done.
- *
- * @hw: Struct containing variables accessed by shared code
- */
-static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
-{
-	u32 attempts = 100000;
-	u32 i, reg = 0;
-	s32 done = E1000_ERR_EEPROM;
-
-	for (i = 0; i < attempts; i++) {
-		if (eerd == E1000_EEPROM_POLL_READ)
-			reg = er32(EERD);
-		else
-			reg = er32(EEWR);
-
-		if (reg & E1000_EEPROM_RW_REG_DONE) {
-			done = E1000_SUCCESS;
-			break;
-		}
-		udelay(5);
-	}
-
-	return done;
-}
-
-/**
  * e1000_validate_eeprom_checksum - Verifies that the EEPROM has a valid checksum
  * @hw: Struct containing variables accessed by shared code
  *
@@ -4031,9 +3919,6 @@ static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
 		return -E1000_ERR_EEPROM;
 	}
 
-	if (eeprom->use_eewr)
-		return e1000_write_eeprom_eewr(hw, offset, words, data);
-
 	/* Prepare the EEPROM for writing  */
 	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
 		return -E1000_ERR_EEPROM;
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 4bfdf32..2e42341 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -256,8 +256,6 @@ struct e1000_eeprom_info {
 	u16 address_bits;
 	u16 delay_usec;
 	u16 page_size;
-	bool use_eerd;
-	bool use_eewr;
 };
 
 /* Flex ASF Information */


^ permalink raw reply related

* [net-2.6 PATCH 09/13] e1000: drop redunant line of code, cleanup
From: Jeff Kirsher @ 2009-09-25 22:19 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

adapter was being assigned twice, also clarified variable name and unwrapped
line.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_main.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 2178e0d..d7dea69 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3394,17 +3394,13 @@ static irqreturn_t e1000_intr(int irq, void *data)
 static int e1000_clean(struct napi_struct *napi, int budget)
 {
 	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
-	struct net_device *poll_dev = adapter->netdev;
-	int tx_cleaned = 0, work_done = 0;
+	int tx_clean_complete = 0, work_done = 0;
 
-	adapter = netdev_priv(poll_dev);
+	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
 
-	tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
+	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
 
-	adapter->clean_rx(adapter, &adapter->rx_ring[0],
-	                  &work_done, budget);
-
-	if (!tx_cleaned)
+	if (!tx_clean_complete)
 		work_done = budget;
 
 	/* If budget not fully consumed, exit the polling mode */


^ permalink raw reply related

* [net-2.6 PATCH 08/13] e1000: remove races when changing mtu
From: Jeff Kirsher @ 2009-09-25 22:19 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

this patch fixes a bug that occurs when routing packets and simultaneously
changing the mtu.  the rx_buffer_len variable is used during the rx cleanup
and if that changes on the fly without stopping traffic bad things happen

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_main.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index cdbf4fb..2178e0d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3141,6 +3141,13 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 		break;
 	}
 
+	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
+		msleep(1);
+	/* e1000_down has a dependency on max_frame_size */
+	hw->max_frame_size = max_frame;
+	if (netif_running(netdev))
+		e1000_down(adapter);
+
 	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
 	 * means we reserve 2 more, this pushes us to allocate from the next
 	 * larger slab size.
@@ -3169,11 +3176,16 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
 		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
 
+	printk(KERN_INFO "e1000: %s changing MTU from %d to %d\n",
+	       netdev->name, netdev->mtu, new_mtu);
 	netdev->mtu = new_mtu;
-	hw->max_frame_size = max_frame;
 
 	if (netif_running(netdev))
-		e1000_reinit_locked(adapter);
+		e1000_up(adapter);
+	else
+		e1000_reset(adapter);
+
+	clear_bit(__E1000_RESETTING, &adapter->flags);
 
 	return 0;
 }


^ permalink raw reply related

* [net-2.6 PATCH 07/13] e1000: two workarounds were incomplete, fix them
From: Jeff Kirsher @ 2009-09-25 22:18 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

1) 82544 does not need last_tx_tso workaround, it interferes with the 82544
workaround too
2) 82544 hang workaround was using the address of the page struct instead of
the physical address as its "workaround decider" not sure how that ever worked

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_main.c |   17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 8c64363..cdbf4fb 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2416,6 +2416,11 @@ enum latency_range {
 
 /**
  * e1000_update_itr - update the dynamic ITR value based on statistics
+ * @adapter: pointer to adapter
+ * @itr_setting: current adapter->itr
+ * @packets: the number of packets during this measurement interval
+ * @bytes: the number of bytes during this measurement interval
+ *
  *      Stores a new ITR value based on packets and byte
  *      counts during the last interrupt.  The advantage of per interrupt
  *      computation is faster updates and more accurate ITR for the current
@@ -2425,10 +2430,6 @@ enum latency_range {
  *      while increasing bulk throughput.
  *      this functionality is controlled by the InterruptThrottleRate module
  *      parameter (see e1000_param.c)
- * @adapter: pointer to adapter
- * @itr_setting: current adapter->itr
- * @packets: the number of packets during this measurement interval
- * @bytes: the number of bytes during this measurement interval
  **/
 static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
 				     u16 itr_setting, int packets, int bytes)
@@ -2770,8 +2771,9 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 			 * Avoid terminating buffers within evenly-aligned
 			 * dwords. */
 			if (unlikely(adapter->pcix_82544 &&
-			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
-			   size > 4))
+			    !((unsigned long)(page_to_phys(frag->page) + offset
+			                      + size - 1) & 4) &&
+			    size > 4))
 				size -= 4;
 
 			buffer_info->length = size;
@@ -3042,7 +3044,8 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 	}
 
 	if (likely(tso)) {
-		tx_ring->last_tx_tso = 1;
+		if (likely(hw->mac_type != e1000_82544))
+			tx_ring->last_tx_tso = 1;
 		tx_flags |= E1000_TX_FLAGS_TSO;
 	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
 		tx_flags |= E1000_TX_FLAGS_CSUM;


^ permalink raw reply related

* Re: [RFC] skb align patch
From: Herbert Xu @ 2009-09-25 22:18 UTC (permalink / raw)
  To: Thomas Graf
  Cc: davem, eric.dumazet, shemminger, jesse.brandeburg, hawk, netdev
In-Reply-To: <20090923054748.GA24045@bombadil.infradead.org>

Thomas Graf <tgraf@infradead.org> wrote:
>
> As I pointed out to Herbert already, this alignment change may actually
> make things worse or even break things as long as compare_ether_header()
> used in __napi_gro_receive() expects the IP header to be aligned to 4
> bytes. That can be fixed of course, just wanted to mention it.

Well this particular patch doesn't because x86-64 is fine with
unaligned access :)

But yeah we need to fix up GRO to not do that for other arches.
It's on my list.

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [net-2.6 PATCH 06/13] e1000: fix tx waking queue after queue stopped during shutdown
From: Jeff Kirsher @ 2009-09-25 22:18 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

This fix closes a race where the adapter can be shutting down while
hard_start_xmit is being called and interrupts are being handled.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_main.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 11508af..8c64363 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2733,8 +2733,9 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 			size -= 4;
 
 		buffer_info->length = size;
-		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
+		/* set time_stamp *before* dma to help avoid a possible race */
 		buffer_info->time_stamp = jiffies;
+		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
 		buffer_info->next_to_watch = i;
 
 		len -= size;
@@ -2774,8 +2775,8 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 				size -= 4;
 
 			buffer_info->length = size;
-			buffer_info->dma = map[f] + offset;
 			buffer_info->time_stamp = jiffies;
+			buffer_info->dma = map[f] + offset;
 			buffer_info->next_to_watch = i;
 
 			len -= size;
@@ -3459,7 +3460,9 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 		 * sees the new next_to_clean.
 		 */
 		smp_mb();
-		if (netif_queue_stopped(netdev)) {
+
+		if (netif_queue_stopped(netdev) &&
+		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
 			netif_wake_queue(netdev);
 			++adapter->restart_queue;
 		}
@@ -3469,8 +3472,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 		/* Detect a transmit hang in hardware, this serializes the
 		 * check with the clearing of time_stamp and movement of i */
 		adapter->detect_tx_hung = false;
-		if (tx_ring->buffer_info[i].time_stamp &&
-		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
+		if (tx_ring->buffer_info[eop].time_stamp &&
+		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
 		               (adapter->tx_timeout_factor * HZ))
 		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
 
@@ -3492,7 +3495,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 				readl(hw->hw_addr + tx_ring->tdt),
 				tx_ring->next_to_use,
 				tx_ring->next_to_clean,
-				tx_ring->buffer_info[i].time_stamp,
+				tx_ring->buffer_info[eop].time_stamp,
 				eop,
 				jiffies,
 				eop_desc->upper.fields.status);


^ permalink raw reply related

* [net-2.6 PATCH 05/13] e1000: test link state conclusively
From: Jeff Kirsher @ 2009-09-25 22:17 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

e1000 was using one particular way to detect link, but with the advent
of some of the newer hardware designs using SERDES connections, tests
for link must completely cover all cases.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_ethtool.c |    4 -
 drivers/net/e1000/e1000_hw.c      |  179 +++++++++++++++++++++++--------------
 drivers/net/e1000/e1000_hw.h      |    2 
 drivers/net/e1000/e1000_main.c    |   49 ++++++++--
 4 files changed, 157 insertions(+), 77 deletions(-)

diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index f2e756f..490b2b7 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1481,13 +1481,13 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
 	*data = 0;
 	if (hw->media_type == e1000_media_type_internal_serdes) {
 		int i = 0;
-		hw->serdes_link_down = true;
+		hw->serdes_has_link = false;
 
 		/* On some blade server designs, link establishment
 		 * could take as long as 2-3 minutes */
 		do {
 			e1000_check_for_link(hw);
-			if (!hw->serdes_link_down)
+			if (hw->serdes_has_link)
 				return *data;
 			msleep(20);
 		} while (i++ < 3750);
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 765fd71..076db19 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -2136,6 +2136,116 @@ static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
     return E1000_SUCCESS;
 }
 
+/**
+ *  e1000_check_for_serdes_link_generic - Check for link (Serdes)
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks for link up on the hardware.  If link is not up and we have
+ *  a signal, then we need to force link up.
+ **/
+s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
+{
+	u32 rxcw;
+	u32 ctrl;
+	u32 status;
+	s32 ret_val = E1000_SUCCESS;
+
+	DEBUGFUNC("e1000_check_for_serdes_link_generic");
+
+	ctrl = er32(CTRL);
+	status = er32(STATUS);
+	rxcw = er32(RXCW);
+
+	/*
+	 * If we don't have link (auto-negotiation failed or link partner
+	 * cannot auto-negotiate), and our link partner is not trying to
+	 * auto-negotiate with us (we are receiving idles or data),
+	 * we need to force link up. We also need to give auto-negotiation
+	 * time to complete.
+	 */
+	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
+	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
+		if (hw->autoneg_failed == 0) {
+			hw->autoneg_failed = 1;
+			goto out;
+		}
+		DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
+
+		/* Disable auto-negotiation in the TXCW register */
+		ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
+
+		/* Force link-up and also force full-duplex. */
+		ctrl = er32(CTRL);
+		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+		ew32(CTRL, ctrl);
+
+		/* Configure Flow Control after forcing link up. */
+		ret_val = e1000_config_fc_after_link_up(hw);
+		if (ret_val) {
+			DEBUGOUT("Error configuring flow control\n");
+			goto out;
+		}
+	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
+		/*
+		 * If we are forcing link and we are receiving /C/ ordered
+		 * sets, re-enable auto-negotiation in the TXCW register
+		 * and disable forced link in the Device Control register
+		 * in an attempt to auto-negotiate with our link partner.
+		 */
+		DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
+		ew32(TXCW, hw->txcw);
+		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
+
+		hw->serdes_has_link = true;
+	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
+		/*
+		 * If we force link for non-auto-negotiation switch, check
+		 * link status based on MAC synchronization for internal
+		 * serdes media type.
+		 */
+		/* SYNCH bit and IV bit are sticky. */
+		udelay(10);
+		rxcw = er32(RXCW);
+		if (rxcw & E1000_RXCW_SYNCH) {
+			if (!(rxcw & E1000_RXCW_IV)) {
+				hw->serdes_has_link = true;
+				DEBUGOUT("SERDES: Link up - forced.\n");
+			}
+		} else {
+			hw->serdes_has_link = false;
+			DEBUGOUT("SERDES: Link down - force failed.\n");
+		}
+	}
+
+	if (E1000_TXCW_ANE & er32(TXCW)) {
+		status = er32(STATUS);
+		if (status & E1000_STATUS_LU) {
+			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
+			udelay(10);
+			rxcw = er32(RXCW);
+			if (rxcw & E1000_RXCW_SYNCH) {
+				if (!(rxcw & E1000_RXCW_IV)) {
+					hw->serdes_has_link = true;
+					DEBUGOUT("SERDES: Link up - autoneg "
+					   "completed sucessfully.\n");
+				} else {
+					hw->serdes_has_link = false;
+					DEBUGOUT("SERDES: Link down - invalid"
+					   "codewords detected in autoneg.\n");
+				}
+			} else {
+				hw->serdes_has_link = false;
+				DEBUGOUT("SERDES: Link down - no sync.\n");
+			}
+		} else {
+			hw->serdes_has_link = false;
+			DEBUGOUT("SERDES: Link down - autoneg failed\n");
+		}
+	}
+
+out:
+	return ret_val;
+}
 /******************************************************************************
  * Checks to see if the link status of the hardware has changed.
  *
@@ -2300,74 +2410,11 @@ s32 e1000_check_for_link(struct e1000_hw *hw)
             }
         }
     }
-    /* If we don't have link (auto-negotiation failed or link partner cannot
-     * auto-negotiate), the cable is plugged in (we have signal), and our
-     * link partner is not trying to auto-negotiate with us (we are receiving
-     * idles or data), we need to force link up. We also need to give
-     * auto-negotiation time to complete, in case the cable was just plugged
-     * in. The autoneg_failed flag does this.
-     */
-    else if ((((hw->media_type == e1000_media_type_fiber) &&
-              ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
-              (hw->media_type == e1000_media_type_internal_serdes)) &&
-              (!(status & E1000_STATUS_LU)) &&
-              (!(rxcw & E1000_RXCW_C))) {
-        if (hw->autoneg_failed == 0) {
-            hw->autoneg_failed = 1;
-            return 0;
-        }
-        DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
-
-        /* Disable auto-negotiation in the TXCW register */
-        ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
 
-        /* Force link-up and also force full-duplex. */
-        ctrl = er32(CTRL);
-        ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
-        ew32(CTRL, ctrl);
-
-        /* Configure Flow Control after forcing link up. */
-        ret_val = e1000_config_fc_after_link_up(hw);
-        if (ret_val) {
-            DEBUGOUT("Error configuring flow control\n");
-            return ret_val;
-        }
-    }
-    /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
-     * auto-negotiation in the TXCW register and disable forced link in the
-     * Device Control register in an attempt to auto-negotiate with our link
-     * partner.
-     */
-    else if (((hw->media_type == e1000_media_type_fiber) ||
-              (hw->media_type == e1000_media_type_internal_serdes)) &&
-              (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-        DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
-        ew32(TXCW, hw->txcw);
-        ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
+    if ((hw->media_type == e1000_media_type_fiber) ||
+        (hw->media_type == e1000_media_type_internal_serdes))
+        e1000_check_for_serdes_link_generic(hw);
 
-        hw->serdes_link_down = false;
-    }
-    /* If we force link for non-auto-negotiation switch, check link status
-     * based on MAC synchronization for internal serdes media type.
-     */
-    else if ((hw->media_type == e1000_media_type_internal_serdes) &&
-             !(E1000_TXCW_ANE & er32(TXCW))) {
-        /* SYNCH bit and IV bit are sticky. */
-        udelay(10);
-        if (E1000_RXCW_SYNCH & er32(RXCW)) {
-            if (!(rxcw & E1000_RXCW_IV)) {
-                hw->serdes_link_down = false;
-                DEBUGOUT("SERDES: Link is up.\n");
-            }
-        } else {
-            hw->serdes_link_down = true;
-            DEBUGOUT("SERDES: Link is down.\n");
-        }
-    }
-    if ((hw->media_type == e1000_media_type_internal_serdes) &&
-        (E1000_TXCW_ANE & er32(TXCW))) {
-        hw->serdes_link_down = !(E1000_STATUS_LU & er32(STATUS));
-    }
     return E1000_SUCCESS;
 }
 
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 1a8a000..1c782d2 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1372,7 +1372,7 @@ struct e1000_hw {
 	e1000_smart_speed	smart_speed;
 	e1000_dsp_config	dsp_config_state;
 	bool			get_link_status;
-	bool			serdes_link_down;
+	bool			serdes_has_link;
 	bool			tbi_compatibility_en;
 	bool			tbi_compatibility_on;
 	bool			laa_is_present;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7af3255..11508af 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2251,6 +2251,41 @@ static void e1000_82547_tx_fifo_stall(unsigned long data)
 	}
 }
 
+static bool e1000_has_link(struct e1000_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	bool link_active = false;
+	s32 ret_val = 0;
+
+	/* get_link_status is set on LSC (link status) interrupt or
+	 * rx sequence error interrupt.  get_link_status will stay
+	 * false until the e1000_check_for_link establishes link
+	 * for copper adapters ONLY
+	 */
+	switch (hw->media_type) {
+	case e1000_media_type_copper:
+		if (hw->get_link_status) {
+			ret_val = e1000_check_for_link(hw);
+			link_active = !hw->get_link_status;
+		} else {
+			link_active = true;
+		}
+		break;
+	case e1000_media_type_fiber:
+		ret_val = e1000_check_for_link(hw);
+		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
+		break;
+	case e1000_media_type_internal_serdes:
+		ret_val = e1000_check_for_link(hw);
+		link_active = hw->serdes_has_link;
+		break;
+	default:
+		break;
+	}
+
+	return link_active;
+}
+
 /**
  * e1000_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
@@ -2263,18 +2298,15 @@ static void e1000_watchdog(unsigned long data)
 	struct e1000_tx_ring *txdr = adapter->tx_ring;
 	u32 link, tctl;
 
-	e1000_check_for_link(hw);
-
-	if ((hw->media_type == e1000_media_type_internal_serdes) &&
-	   !(er32(TXCW) & E1000_TXCW_ANE))
-		link = !hw->serdes_link_down;
-	else
-		link = er32(STATUS) & E1000_STATUS_LU;
+	link = e1000_has_link(adapter);
+	if ((netif_carrier_ok(netdev)) && link)
+		goto link_up;
 
 	if (link) {
 		if (!netif_carrier_ok(netdev)) {
 			u32 ctrl;
 			bool txb2b = true;
+			/* update snapshot of PHY registers on LSC */
 			e1000_get_speed_and_duplex(hw,
 			                           &adapter->link_speed,
 			                           &adapter->link_duplex);
@@ -2299,7 +2331,7 @@ static void e1000_watchdog(unsigned long data)
 			case SPEED_10:
 				txb2b = false;
 				netdev->tx_queue_len = 10;
-				adapter->tx_timeout_factor = 8;
+				adapter->tx_timeout_factor = 16;
 				break;
 			case SPEED_100:
 				txb2b = false;
@@ -2335,6 +2367,7 @@ static void e1000_watchdog(unsigned long data)
 		e1000_smartspeed(adapter);
 	}
 
+link_up:
 	e1000_update_stats(adapter);
 
 	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;


^ permalink raw reply related

* [net-2.6 PATCH 04/13] e1000: stop timers at appropriate times
From: Jeff Kirsher @ 2009-09-25 22:17 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

there were some hotplug cases that made timers still run after the driver
had been removed, make sure to stop all the timers and not allow racy
reschedules.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_main.c |   26 +++++++++++++++++++-------
 1 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 4d6677e..7af3255 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1098,6 +1098,11 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
+	set_bit(__E1000_DOWN, &adapter->flags);
+	del_timer_sync(&adapter->tx_fifo_stall_timer);
+	del_timer_sync(&adapter->watchdog_timer);
+	del_timer_sync(&adapter->phy_info_timer);
+
 	cancel_work_sync(&adapter->reset_task);
 
 	e1000_release_manageability(adapter);
@@ -2240,7 +2245,7 @@ static void e1000_82547_tx_fifo_stall(unsigned long data)
 			adapter->tx_fifo_head = 0;
 			atomic_set(&adapter->tx_fifo_stall, 0);
 			netif_wake_queue(netdev);
-		} else {
+		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
 			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
 		}
 	}
@@ -2309,8 +2314,9 @@ static void e1000_watchdog(unsigned long data)
 			ew32(TCTL, tctl);
 
 			netif_carrier_on(netdev);
-			mod_timer(&adapter->phy_info_timer,
-			          round_jiffies(jiffies + 2 * HZ));
+			if (!test_bit(__E1000_DOWN, &adapter->flags))
+				mod_timer(&adapter->phy_info_timer,
+				          round_jiffies(jiffies + 2 * HZ));
 			adapter->smartspeed = 0;
 		}
 	} else {
@@ -2320,8 +2326,10 @@ static void e1000_watchdog(unsigned long data)
 			printk(KERN_INFO "e1000: %s NIC Link is Down\n",
 			       netdev->name);
 			netif_carrier_off(netdev);
-			mod_timer(&adapter->phy_info_timer,
-			          round_jiffies(jiffies + 2 * HZ));
+
+			if (!test_bit(__E1000_DOWN, &adapter->flags))
+				mod_timer(&adapter->phy_info_timer,
+				          round_jiffies(jiffies + 2 * HZ));
 		}
 
 		e1000_smartspeed(adapter);
@@ -2361,7 +2369,9 @@ static void e1000_watchdog(unsigned long data)
 	adapter->detect_tx_hung = true;
 
 	/* Reset the timer */
-	mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
+	if (!test_bit(__E1000_DOWN, &adapter->flags))
+		mod_timer(&adapter->watchdog_timer,
+		          round_jiffies(jiffies + 2 * HZ));
 }
 
 enum latency_range {
@@ -2977,7 +2987,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 	if (unlikely(hw->mac_type == e1000_82547)) {
 		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
 			netif_stop_queue(netdev);
-			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
+			if (!test_bit(__E1000_DOWN, &adapter->flags))
+				mod_timer(&adapter->tx_fifo_stall_timer,
+				          jiffies + 1);
 			return NETDEV_TX_BUSY;
 		}
 	}


^ permalink raw reply related

* [net-2.6 PATCH 03/13] e1000: use netif_tx_disable
From: Jeff Kirsher @ 2009-09-25 22:17 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

we can use netif_tx_disable now because LLTX has been removed.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_main.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index cad6f65..4d6677e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -485,8 +485,7 @@ void e1000_down(struct e1000_adapter *adapter)
 	ew32(RCTL, rctl & ~E1000_RCTL_EN);
 	/* flush and sleep below */
 
-	/* can be netif_tx_disable when NETIF_F_LLTX is removed */
-	netif_stop_queue(netdev);
+	netif_tx_disable(netdev);
 
 	/* disable transmits in the hardware */
 	tctl = er32(TCTL);


^ permalink raw reply related

* [net-2.6 PATCH 02/13] e1000: remove unused functions
From: Jeff Kirsher @ 2009-09-25 22:16 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Jesse Brandeburg, Don Skidmore, Jeff Kirsher
In-Reply-To: <20090925221613.26715.66796.stgit@localhost.localdomain>

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

after removal of pcie, need to remove some unnecessary functions

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_hw.c |  174 ------------------------------------------
 drivers/net/e1000/e1000_hw.h |    2 
 2 files changed, 2 insertions(+), 174 deletions(-)

diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 74aa599..765fd71 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -33,9 +33,6 @@
 
 #include "e1000_hw.h"
 
-static s32 e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask);
-static void e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask);
-
 static s32 e1000_check_downshift(struct e1000_hw *hw);
 static s32 e1000_check_polarity(struct e1000_hw *hw,
 				e1000_rev_polarity *polarity);
@@ -48,7 +45,6 @@ static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
 static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
 static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
 				  u16 *max_length);
-static s32 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
 static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
 static s32 e1000_id_led_init(struct e1000_hw *hw);
 static void e1000_init_rx_addrs(struct e1000_hw *hw);
@@ -61,7 +57,6 @@ static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
 static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
 static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
 				  struct e1000_phy_info *phy_info);
-static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
 static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
 static s32 e1000_wait_autoneg(struct e1000_hw *hw);
 static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
@@ -2607,70 +2602,6 @@ static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
     return data;
 }
 
-static s32 e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask)
-{
-    u32 swfw_sync = 0;
-    u32 swmask = mask;
-    u32 fwmask = mask << 16;
-    s32 timeout = 200;
-
-    DEBUGFUNC("e1000_swfw_sync_acquire");
-
-    if (!hw->swfw_sync_present)
-        return e1000_get_hw_eeprom_semaphore(hw);
-
-    while (timeout) {
-            if (e1000_get_hw_eeprom_semaphore(hw))
-                return -E1000_ERR_SWFW_SYNC;
-
-            swfw_sync = er32(SW_FW_SYNC);
-            if (!(swfw_sync & (fwmask | swmask))) {
-                break;
-            }
-
-            /* firmware currently using resource (fwmask) */
-            /* or other software thread currently using resource (swmask) */
-            e1000_put_hw_eeprom_semaphore(hw);
-            mdelay(5);
-            timeout--;
-    }
-
-    if (!timeout) {
-        DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
-        return -E1000_ERR_SWFW_SYNC;
-    }
-
-    swfw_sync |= swmask;
-    ew32(SW_FW_SYNC, swfw_sync);
-
-    e1000_put_hw_eeprom_semaphore(hw);
-    return E1000_SUCCESS;
-}
-
-static void e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
-{
-    u32 swfw_sync;
-    u32 swmask = mask;
-
-    DEBUGFUNC("e1000_swfw_sync_release");
-
-    if (!hw->swfw_sync_present) {
-        e1000_put_hw_eeprom_semaphore(hw);
-        return;
-    }
-
-    /* if (e1000_get_hw_eeprom_semaphore(hw))
-     *    return -E1000_ERR_SWFW_SYNC; */
-    while (e1000_get_hw_eeprom_semaphore(hw) != E1000_SUCCESS);
-        /* empty */
-
-    swfw_sync = er32(SW_FW_SYNC);
-    swfw_sync &= ~swmask;
-    ew32(SW_FW_SYNC, swfw_sync);
-
-    e1000_put_hw_eeprom_semaphore(hw);
-}
-
 /*****************************************************************************
 * Reads the value from a PHY register, if the value is on a specific non zero
 * page, sets the page first.
@@ -2680,28 +2611,19 @@ static void e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
 s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
 {
     u32 ret_val;
-    u16 swfw;
 
     DEBUGFUNC("e1000_read_phy_reg");
 
-    swfw = E1000_SWFW_PHY0_SM;
-    if (e1000_swfw_sync_acquire(hw, swfw))
-        return -E1000_ERR_SWFW_SYNC;
-
     if ((hw->phy_type == e1000_phy_igp) &&
         (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
         ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                          (u16)reg_addr);
-        if (ret_val) {
-            e1000_swfw_sync_release(hw, swfw);
+        if (ret_val)
             return ret_val;
-        }
     }
 
     ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                     phy_data);
-
-    e1000_swfw_sync_release(hw, swfw);
     return ret_val;
 }
 
@@ -2787,28 +2709,20 @@ static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
 s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
 {
     u32 ret_val;
-    u16 swfw;
 
     DEBUGFUNC("e1000_write_phy_reg");
 
-    swfw = E1000_SWFW_PHY0_SM;
-    if (e1000_swfw_sync_acquire(hw, swfw))
-        return -E1000_ERR_SWFW_SYNC;
-
     if ((hw->phy_type == e1000_phy_igp) &&
         (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
         ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                          (u16)reg_addr);
-        if (ret_val) {
-            e1000_swfw_sync_release(hw, swfw);
+        if (ret_val)
             return ret_val;
-        }
     }
 
     ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                      phy_data);
 
-    e1000_swfw_sync_release(hw, swfw);
     return ret_val;
 }
 
@@ -2883,18 +2797,12 @@ s32 e1000_phy_hw_reset(struct e1000_hw *hw)
     u32 ctrl, ctrl_ext;
     u32 led_ctrl;
     s32 ret_val;
-    u16 swfw;
 
     DEBUGFUNC("e1000_phy_hw_reset");
 
     DEBUGOUT("Resetting Phy...\n");
 
     if (hw->mac_type > e1000_82543) {
-        swfw = E1000_SWFW_PHY0_SM;
-        if (e1000_swfw_sync_acquire(hw, swfw)) {
-            DEBUGOUT("Unable to acquire swfw sync\n");
-            return -E1000_ERR_SWFW_SYNC;
-        }
         /* Read the device control register and assert the E1000_CTRL_PHY_RST
          * bit. Then, take it out of reset.
          * For e1000 hardware, we delay for 10ms between the assert
@@ -2908,8 +2816,6 @@ s32 e1000_phy_hw_reset(struct e1000_hw *hw)
 
         ew32(CTRL, ctrl);
         E1000_WRITE_FLUSH();
-
-        e1000_swfw_sync_release(hw, swfw);
     } else {
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
          * bit to put the PHY into reset. Then, take it out of reset.
@@ -3515,8 +3421,6 @@ static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_acquire_eeprom");
 
-    if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
-        return -E1000_ERR_SWFW_SYNC;
     eecd = er32(EECD);
 
     /* Request EEPROM Access */
@@ -3534,7 +3438,6 @@ static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
             eecd &= ~E1000_EECD_REQ;
             ew32(EECD, eecd);
             DEBUGOUT("Could not acquire EEPROM grant\n");
-            e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
             return -E1000_ERR_EEPROM;
         }
     }
@@ -3653,8 +3556,6 @@ static void e1000_release_eeprom(struct e1000_hw *hw)
         eecd &= ~E1000_EECD_REQ;
         ew32(EECD, eecd);
     }
-
-    e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
 }
 
 /******************************************************************************
@@ -3847,8 +3748,6 @@ static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
     u32    i              = 0;
     s32     error          = 0;
 
-    if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
-        return -E1000_ERR_SWFW_SYNC;
 
     for (i = 0; i < words; i++) {
         register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) |
@@ -3869,7 +3768,6 @@ static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
         }
     }
 
-    e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
     return error;
 }
 
@@ -5681,71 +5579,3 @@ static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
     mdelay(10);
     return E1000_SUCCESS;
 }
-
-/***************************************************************************
- *
- * Using the combination of SMBI and SWESMBI semaphore bits when resetting
- * adapter or Eeprom access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_EEPROM if fail to access EEPROM.
- *            E1000_SUCCESS at any other case.
- *
- ***************************************************************************/
-static s32 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
-{
-    s32 timeout;
-    u32 swsm;
-
-    DEBUGFUNC("e1000_get_hw_eeprom_semaphore");
-
-    if (!hw->eeprom_semaphore_present)
-        return E1000_SUCCESS;
-
-    /* Get the FW semaphore. */
-    timeout = hw->eeprom.word_size + 1;
-    while (timeout) {
-        swsm = er32(SWSM);
-        swsm |= E1000_SWSM_SWESMBI;
-        ew32(SWSM, swsm);
-        /* if we managed to set the bit we got the semaphore. */
-        swsm = er32(SWSM);
-        if (swsm & E1000_SWSM_SWESMBI)
-            break;
-
-        udelay(50);
-        timeout--;
-    }
-
-    if (!timeout) {
-        /* Release semaphores */
-        e1000_put_hw_eeprom_semaphore(hw);
-        DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n");
-        return -E1000_ERR_EEPROM;
-    }
-
-    return E1000_SUCCESS;
-}
-
-/***************************************************************************
- * This function clears HW semaphore bits.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - None.
- *
- ***************************************************************************/
-static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
-{
-    u32 swsm;
-
-    DEBUGFUNC("e1000_put_hw_eeprom_semaphore");
-
-    if (!hw->eeprom_semaphore_present)
-        return;
-
-    swsm = er32(SWSM);
-    swsm &= ~(E1000_SWSM_SWESMBI);
-    ew32(SWSM, swsm);
-}
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 243dad2..1a8a000 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -284,7 +284,6 @@ typedef enum {
 #define E1000_ERR_MASTER_REQUESTS_PENDING 10
 #define E1000_ERR_HOST_INTERFACE_COMMAND 11
 #define E1000_BLK_PHY_RESET   12
-#define E1000_ERR_SWFW_SYNC 13
 
 #define E1000_BYTE_SWAP_WORD(_value) ((((_value) & 0x00ff) << 8) | \
                                      (((_value) & 0xff00) >> 8))
@@ -1327,7 +1326,6 @@ struct e1000_hw {
 	e1000_ffe_config	ffe_config_state;
 	u32		asf_firmware_present;
 	u32		eeprom_semaphore_present;
-	u32             swfw_sync_present;
 	unsigned long		io_base;
 	u32		phy_id;
 	u32		phy_revision;


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox