Skip to content

Commit 937317c

Browse files
Govindarajulu Varadarajandavem330
authored andcommitted
enic: do hang reset only in case of tx timeout
The current code invokes hang reset in case of error interrupt. We should hang reset only in case of tx timeout. This because of the way hang reset is implemented in firmware. Hang reset takes more firmware resources than soft reset. Adaptor does not generate error interrupt in case of tx timeout. Hang reset only in case of tx timeout, in .ndo_tx_timeout. Do soft reset otherwise. Introduce deferred work, enic_tx_hang_reset, to do hang reset. Signed-off-by: Govindarajulu Varadarajan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cc80923 commit 937317c

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

drivers/net/ethernet/cisco/enic/enic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ struct enic {
143143
struct vnic_dev *vdev;
144144
struct timer_list notify_timer;
145145
struct work_struct reset;
146+
struct work_struct tx_hang_reset;
146147
struct work_struct change_mtu_work;
147148
struct msix_entry msix_entry[ENIC_INTR_MAX];
148149
struct enic_msix_entry msix[ENIC_INTR_MAX];

drivers/net/ethernet/cisco/enic/enic_main.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ static void enic_set_rx_mode(struct net_device *netdev)
808808
static void enic_tx_timeout(struct net_device *netdev)
809809
{
810810
struct enic *enic = netdev_priv(netdev);
811-
schedule_work(&enic->reset);
811+
schedule_work(&enic->tx_hang_reset);
812812
}
813813

814814
static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
@@ -1928,6 +1928,19 @@ static int enic_dev_open(struct enic *enic)
19281928
return err;
19291929
}
19301930

1931+
static int enic_dev_soft_reset(struct enic *enic)
1932+
{
1933+
int err;
1934+
1935+
err = enic_dev_wait(enic->vdev, vnic_dev_soft_reset,
1936+
vnic_dev_soft_reset_done, 0);
1937+
if (err)
1938+
netdev_err(enic->netdev, "vNIC soft reset failed, err %d\n",
1939+
err);
1940+
1941+
return err;
1942+
}
1943+
19311944
static int enic_dev_hang_reset(struct enic *enic)
19321945
{
19331946
int err;
@@ -2063,6 +2076,26 @@ static void enic_reset(struct work_struct *work)
20632076

20642077
rtnl_lock();
20652078

2079+
spin_lock(&enic->enic_api_lock);
2080+
enic_stop(enic->netdev);
2081+
enic_dev_soft_reset(enic);
2082+
enic_reset_addr_lists(enic);
2083+
enic_init_vnic_resources(enic);
2084+
enic_set_rss_nic_cfg(enic);
2085+
enic_dev_set_ig_vlan_rewrite_mode(enic);
2086+
enic_open(enic->netdev);
2087+
spin_unlock(&enic->enic_api_lock);
2088+
call_netdevice_notifiers(NETDEV_REBOOT, enic->netdev);
2089+
2090+
rtnl_unlock();
2091+
}
2092+
2093+
static void enic_tx_hang_reset(struct work_struct *work)
2094+
{
2095+
struct enic *enic = container_of(work, struct enic, tx_hang_reset);
2096+
2097+
rtnl_lock();
2098+
20662099
spin_lock(&enic->enic_api_lock);
20672100
enic_dev_hang_notify(enic);
20682101
enic_stop(enic->netdev);
@@ -2587,6 +2620,7 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
25872620

25882621
enic_set_rx_coal_setting(enic);
25892622
INIT_WORK(&enic->reset, enic_reset);
2623+
INIT_WORK(&enic->tx_hang_reset, enic_tx_hang_reset);
25902624
INIT_WORK(&enic->change_mtu_work, enic_change_mtu_work);
25912625

25922626
for (i = 0; i < enic->wq_count; i++)

drivers/net/ethernet/cisco/enic/vnic_dev.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,14 +659,14 @@ int vnic_dev_open_done(struct vnic_dev *vdev, int *done)
659659
return 0;
660660
}
661661

662-
static int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
662+
int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
663663
{
664664
u64 a0 = (u32)arg, a1 = 0;
665665
int wait = 1000;
666666
return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait);
667667
}
668668

669-
static int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
669+
int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
670670
{
671671
u64 a0 = 0, a1 = 0;
672672
int wait = 1000;

drivers/net/ethernet/cisco/enic/vnic_dev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ int vnic_dev_deinit(struct vnic_dev *vdev);
155155
void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev);
156156
int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev);
157157
int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
158+
int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg);
158159
int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
160+
int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
159161
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
160162
enum vnic_dev_intr_mode intr_mode);
161163
enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);

0 commit comments

Comments
 (0)