From: Dany Madden <d...@linux.ibm.com> Currently ibmvnic does not support the disable vnic command from the Hardware Management Console. This patch enables ibmvnic to process CRQ message 0x07, disable vnic adapter.
Signed-off-by: Dany Madden <d...@linux.ibm.com> --- drivers/net/ethernet/ibm/ibmvnic.c | 40 ++++++++++++++++++++++++++++++ drivers/net/ethernet/ibm/ibmvnic.h | 3 ++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index dcb23015b6b4..82074e503ba9 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -109,6 +109,8 @@ static void release_crq_queue(struct ibmvnic_adapter *); static int __ibmvnic_set_mac(struct net_device *, u8 *); static int init_crq_queue(struct ibmvnic_adapter *adapter); static int send_query_phys_parms(struct ibmvnic_adapter *adapter); +static void ibmvnic_disable(struct ibmvnic_adapter *adapter); +static int ibmvnic_close(struct net_device *netdev); struct ibmvnic_stat { char name[ETH_GSTRING_LEN]; @@ -1209,6 +1211,42 @@ static int ibmvnic_open(struct net_device *netdev) return rc; } +static void ibmvnic_disable(struct ibmvnic_adapter *adapter) +{ + struct list_head *entry, *tmp_entry; + struct net_device *netdev = adapter->netdev; + int rc = 0; + + /* cancel all pending resets in the queue */ + if (!list_empty(&adapter->rwi_list)) { + list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) + list_del(entry); + } + + /* wait for current reset to finish */ + flush_work(&adapter->ibmvnic_reset); + flush_delayed_work(&adapter->ibmvnic_delayed_reset); + + if (test_bit(0, &adapter->resetting) || + adapter->state == VNIC_PROBED || + adapter->state == VNIC_OPEN || + adapter->state == VNIC_OPENING) { + rc = ibmvnic_close(netdev); + /* Expect -EINVAL when crq is no longer active. Set link down + * would fail. + */ + if (rc && rc != -EINVAL) { + netdev_err(netdev, "Failed to disable adapter, rc=%d\n", rc); + return; + } + } else { + netdev_dbg(netdev, "Disable adapter request ignored (state=%d)\n", adapter->state); + return; + } + + netdev_dbg(netdev, "Adapter disabled\n"); +} + static void clean_rx_pools(struct ibmvnic_adapter *adapter) { struct ibmvnic_rx_pool *rx_pool; @@ -4789,6 +4827,8 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, } else if (gen_crq->cmd == IBMVNIC_DEVICE_FAILOVER) { dev_info(dev, "Backing device failover detected\n"); adapter->failover_pending = true; + } else if (gen_crq->cmd == IBMVNIC_DEVICE_DISABLE) { + ibmvnic_disable(adapter); } else { /* The adapter lost the connection */ dev_err(dev, "Virtual Adapter failed (rc=%d)\n", diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h index 217dcc7ded70..af68f85534bc 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.h +++ b/drivers/net/ethernet/ibm/ibmvnic.h @@ -834,10 +834,11 @@ enum ibmvnic_crq_type { IBMVNIC_CRQ_XPORT_EVENT = 0xFF, }; -enum ibmvfc_crq_format { +enum ibmvnic_crq_format { IBMVNIC_CRQ_INIT = 0x01, IBMVNIC_CRQ_INIT_COMPLETE = 0x02, IBMVNIC_PARTITION_MIGRATED = 0x06, + IBMVNIC_DEVICE_DISABLE = 0x07, IBMVNIC_DEVICE_FAILOVER = 0x08, }; -- 2.23.0