Commit 99ef563901a18d44a6c2eadd2b958e2e83aeca51

Authored by Vasanthy Kolluri
Committed by David S. Miller
1 parent f8cac14acf

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>

Showing 4 changed files with 55 additions and 8 deletions Side-by-side Diff

drivers/net/enic/enic_main.c
... ... @@ -812,9 +812,10 @@
812 812 return net_stats;
813 813 }
814 814  
815   -static void enic_reset_mcaddrs(struct enic *enic)
  815 +static void enic_reset_multicast_list(struct enic *enic)
816 816 {
817 817 enic->mc_count = 0;
  818 + enic->flags = 0;
818 819 }
819 820  
820 821 static int enic_set_mac_addr(struct net_device *netdev, char *addr)
821 822  
822 823  
... ... @@ -1847,15 +1848,15 @@
1847 1848 return err;
1848 1849 }
1849 1850  
1850   -static int enic_dev_soft_reset(struct enic *enic)
  1851 +static int enic_dev_hang_reset(struct enic *enic)
1851 1852 {
1852 1853 int err;
1853 1854  
1854   - err = enic_dev_wait(enic->vdev, vnic_dev_soft_reset,
1855   - vnic_dev_soft_reset_done, 0);
  1855 + err = enic_dev_wait(enic->vdev, vnic_dev_hang_reset,
  1856 + vnic_dev_hang_reset_done, 0);
1856 1857 if (err)
1857 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 1861 return err;
1861 1862 }
... ... @@ -1906,9 +1907,8 @@
1906 1907 spin_unlock(&enic->devcmd_lock);
1907 1908  
1908 1909 enic_stop(enic->netdev);
1909   - enic_dev_soft_reset(enic);
1910   - vnic_dev_init(enic->vdev, 0);
1911   - enic_reset_mcaddrs(enic);
  1910 + enic_dev_hang_reset(enic);
  1911 + enic_reset_multicast_list(enic);
1912 1912 enic_init_vnic_resources(enic);
1913 1913 enic_set_niccfg(enic);
1914 1914 enic_dev_set_ig_vlan_rewrite_mode(enic);
drivers/net/enic/vnic_dev.c
... ... @@ -486,6 +486,44 @@
486 486 return 0;
487 487 }
488 488  
  489 +int 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 +
  507 +int 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 +
489 527 int vnic_dev_hang_notify(struct vnic_dev *vdev)
490 528 {
491 529 u64 a0, a1;
drivers/net/enic/vnic_dev.h
... ... @@ -129,6 +129,8 @@
129 129 int vnic_dev_deinit(struct vnic_dev *vdev);
130 130 int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg);
131 131 int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
  132 +int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
  133 +int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
132 134 void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
133 135 enum vnic_dev_intr_mode intr_mode);
134 136 enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
drivers/net/enic/vnic_devcmd.h
... ... @@ -212,6 +212,13 @@
212 212 */
213 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 223 * Set hw ingress packet vlan rewrite mode:
217 224 * in: (u32)a0=new vlan rewrite mode