aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVasanthy Kolluri <vkolluri@cisco.com>2010-06-24 06:50:00 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-25 23:46:01 -0400
commit99ef563901a18d44a6c2eadd2b958e2e83aeca51 (patch)
tree29bbf0fe2457effbaa62281eca6aff2191cc9f75 /drivers
parentf8cac14acff870203ea7f61f1a92c5486d1774fa (diff)
enic: Use a lighter reset operation for enic devices
The port profile information for a dynamic enic device is set by the upper layers, that are oblivious to the device reset operation. We do not want a reset operation erase the network state of a dynamic enic device as there is no way to set up the port profile information again. Hence a lighter reset operation called hang reset is used. Hang reset, unlike soft reset does not reset the network state and resets the host side state only. Signed-off-by: Scott Feldman <scofeldm@cisco.com> Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/enic/enic_main.c16
-rw-r--r--drivers/net/enic/vnic_dev.c38
-rw-r--r--drivers/net/enic/vnic_dev.h2
-rw-r--r--drivers/net/enic/vnic_devcmd.h7
4 files changed, 55 insertions, 8 deletions
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 7f98af1eb1ea..d7434b7b4c52 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -812,9 +812,10 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev)
812 return net_stats; 812 return net_stats;
813} 813}
814 814
815static void enic_reset_mcaddrs(struct enic *enic) 815static void enic_reset_multicast_list(struct enic *enic)
816{ 816{
817 enic->mc_count = 0; 817 enic->mc_count = 0;
818 enic->flags = 0;
818} 819}
819 820
820static int enic_set_mac_addr(struct net_device *netdev, char *addr) 821static int enic_set_mac_addr(struct net_device *netdev, char *addr)
@@ -1847,15 +1848,15 @@ static int enic_dev_open(struct enic *enic)
1847 return err; 1848 return err;
1848} 1849}
1849 1850
1850static int enic_dev_soft_reset(struct enic *enic) 1851static int enic_dev_hang_reset(struct enic *enic)
1851{ 1852{
1852 int err; 1853 int err;
1853 1854
1854 err = enic_dev_wait(enic->vdev, vnic_dev_soft_reset, 1855 err = enic_dev_wait(enic->vdev, vnic_dev_hang_reset,
1855 vnic_dev_soft_reset_done, 0); 1856 vnic_dev_hang_reset_done, 0);
1856 if (err) 1857 if (err)
1857 printk(KERN_ERR PFX 1858 printk(KERN_ERR PFX
1858 "vNIC soft reset failed, err %d.\n", err); 1859 "vNIC hang reset failed, err %d.\n", err);
1859 1860
1860 return err; 1861 return err;
1861} 1862}
@@ -1906,9 +1907,8 @@ static void enic_reset(struct work_struct *work)
1906 spin_unlock(&enic->devcmd_lock); 1907 spin_unlock(&enic->devcmd_lock);
1907 1908
1908 enic_stop(enic->netdev); 1909 enic_stop(enic->netdev);
1909 enic_dev_soft_reset(enic); 1910 enic_dev_hang_reset(enic);
1910 vnic_dev_init(enic->vdev, 0); 1911 enic_reset_multicast_list(enic);
1911 enic_reset_mcaddrs(enic);
1912 enic_init_vnic_resources(enic); 1912 enic_init_vnic_resources(enic);
1913 enic_set_niccfg(enic); 1913 enic_set_niccfg(enic);
1914 enic_dev_set_ig_vlan_rewrite_mode(enic); 1914 enic_dev_set_ig_vlan_rewrite_mode(enic);
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index e3742faa06fe..c93012f2faa9 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -486,6 +486,44 @@ int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
486 return 0; 486 return 0;
487} 487}
488 488
489int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg)
490{
491 u64 a0 = (u32)arg, a1 = 0;
492 int wait = 1000;
493 int err;
494
495 err = vnic_dev_cmd(vdev, CMD_HANG_RESET, &a0, &a1, wait);
496 if (err == ERR_ECMDUNKNOWN) {
497 err = vnic_dev_soft_reset(vdev, arg);
498 if (err)
499 return err;
500
501 return vnic_dev_init(vdev, 0);
502 }
503
504 return err;
505}
506
507int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done)
508{
509 u64 a0 = 0, a1 = 0;
510 int wait = 1000;
511 int err;
512
513 *done = 0;
514
515 err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, &a0, &a1, wait);
516 if (err) {
517 if (err == ERR_ECMDUNKNOWN)
518 return vnic_dev_soft_reset_done(vdev, done);
519 return err;
520 }
521
522 *done = (a0 == 0);
523
524 return 0;
525}
526
489int vnic_dev_hang_notify(struct vnic_dev *vdev) 527int vnic_dev_hang_notify(struct vnic_dev *vdev)
490{ 528{
491 u64 a0, a1; 529 u64 a0, a1;
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 780c3cd73292..4980615fcee2 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -129,6 +129,8 @@ int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len);
129int vnic_dev_deinit(struct vnic_dev *vdev); 129int vnic_dev_deinit(struct vnic_dev *vdev);
130int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg); 130int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg);
131int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done); 131int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
132int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
133int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
132void vnic_dev_set_intr_mode(struct vnic_dev *vdev, 134void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
133 enum vnic_dev_intr_mode intr_mode); 135 enum vnic_dev_intr_mode intr_mode);
134enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev); 136enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index c5ff4ff2ed26..1c4fb35671fa 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -212,6 +212,13 @@ enum vnic_devcmd_cmd {
212 */ 212 */
213 CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38), 213 CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38),
214 214
215 /* initiate hangreset, like softreset after hang detected */
216 CMD_HANG_RESET = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 39),
217
218 /* hangreset status:
219 * out: a0=0 reset complete, a0=1 reset in progress */
220 CMD_HANG_RESET_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 40),
221
215 /* 222 /*
216 * Set hw ingress packet vlan rewrite mode: 223 * Set hw ingress packet vlan rewrite mode:
217 * in: (u32)a0=new vlan rewrite mode 224 * in: (u32)a0=new vlan rewrite mode