All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Desnes Augusto Nunes do Rosário" <desnesn@linux.vnet.ibm.com>
To: Nathan Fontenot <nfont@linux.vnet.ibm.com>, netdev@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org, tlfalcon@linux.vnet.ibm.com,
	jallen@linux.vnet.ibm.com
Subject: Re: [PATCH] [net-next,v3] ibmvnic: Feature implementation of Vital Product Data (VPD) for the ibmvnic driver
Date: Fri, 10 Nov 2017 12:41:25 -0200	[thread overview]
Message-ID: <f48a18a5-f87d-2344-e2a1-4ddd5f05a561@linux.vnet.ibm.com> (raw)
In-Reply-To: <a7877d35-90d5-4fa1-2e45-91c3ee239435@linux.vnet.ibm.com>



On 11/09/2017 06:31 PM, Nathan Fontenot wrote:
> On 11/09/2017 01:00 PM, Desnes Augusto Nunes do Rosario wrote:
>> This patch implements and enables VDP support for the ibmvnic driver.
>> Moreover, it includes the implementation of suitable structs, signal
>>   transmission/handling and functions which allows the retrival of firmware
>>   information from the ibmvnic card through the ethtool command.
>>
>> Signed-off-by: Desnes A. Nunes do Rosario <desnesn@linux.vnet.ibm.com>
>> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
>> ---
>>   drivers/net/ethernet/ibm/ibmvnic.c | 149 ++++++++++++++++++++++++++++++++++++-
>>   drivers/net/ethernet/ibm/ibmvnic.h |  27 ++++++-
>>   2 files changed, 173 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
>> index d0cff28..693b502 100644
>> --- a/drivers/net/ethernet/ibm/ibmvnic.c
>> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
>> @@ -573,6 +573,15 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
>>   	return 0;
>>   }
>>
>> +static void release_vpd_data(struct ibmvnic_adapter *adapter)
>> +{
>> +	if (!adapter->vpd)
>> +		return;
>> +
>> +	kfree(adapter->vpd->buff);
>> +	kfree(adapter->vpd);
>> +}
>> +
>>   static void release_tx_pools(struct ibmvnic_adapter *adapter)
>>   {
>>   	struct ibmvnic_tx_pool *tx_pool;
>> @@ -753,6 +762,8 @@ static void release_resources(struct ibmvnic_adapter *adapter)
>>   {
>>   	int i;
>>
>> +	release_vpd_data(adapter);
>> +
>>   	release_tx_pools(adapter);
>>   	release_rx_pools(adapter);
>>
>> @@ -833,6 +844,53 @@ static int set_real_num_queues(struct net_device *netdev)
>>   	return rc;
>>   }
>>
>> +static int ibmvnic_get_vpd(struct ibmvnic_adapter *adapter)
>> +{
>> +	struct device *dev = &adapter->vdev->dev;
>> +	union ibmvnic_crq crq;
>> +	dma_addr_t dma_addr;
>> +	int len;
>> +
>> +	if (adapter->vpd->buff)
>> +		len = adapter->vpd->len;
>> +
>> +	reinit_completion(&adapter->fw_done);
>> +	crq.get_vpd_size.first = IBMVNIC_CRQ_CMD;
>> +	crq.get_vpd_size.cmd = GET_VPD_SIZE;
>> +	ibmvnic_send_crq(adapter, &crq);
>> +	wait_for_completion(&adapter->fw_done);
>> +
> 
> Shouldn't there be a check for the return code when getting the
> vpd size?

Hello Nathan,

This check is already being performed on the handle_vpd_size_rsp() 
function down below.

In short, a GET_VPD_SIZE signal is sent here through a ibmvnic_crq union 
in ibmvnic_send_crq(), whereas handle_query_ip_offload_rsp() receives 
from the VNIC adapter a GET_VPD_SIZE_RSP containing a ibmvnic_crq union 
with the vpd size information and the rc.code. If successful, a 
&adapter->fw_done is sent and this part of the code continues; however 
if not, a dev_error() is thrown. Same logic applies to GET_VPD/GET_VPD_RSP.

What I am adding on the next version of the patch is a check if 
adapter->vpd->len is different than 0 before allocating 
adapter->vpd->buff, since that in a case of a failure, adapter->vpd->len 
will be 0.

Best Regards,

> 
> 
>> +	if (!adapter->vpd->buff)
>> +		adapter->vpd->buff = kzalloc(adapter->vpd->len, GFP_KERNEL);
>> +	else if (adapter->vpd->len != len)
>> +		adapter->vpd->buff =
>> +			krealloc(adapter->vpd->buff,
>> +				 adapter->vpd->len, GFP_KERNEL);
>> +
>> +	if (!adapter->vpd->buff) {
>> +		dev_err(dev, "Could allocate VPD buffer\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	adapter->vpd->dma_addr =
>> +		dma_map_single(dev, adapter->vpd->buff, adapter->vpd->len,
>> +			       DMA_FROM_DEVICE);
>> +	if (dma_mapping_error(dev, dma_addr)) {
>> +		dev_err(dev, "Could not map VPD buffer\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	reinit_completion(&adapter->fw_done);
>> +	crq.get_vpd.first = IBMVNIC_CRQ_CMD;
>> +	crq.get_vpd.cmd = GET_VPD;
>> +	crq.get_vpd.ioba = cpu_to_be32(adapter->vpd->dma_addr);
>> +	crq.get_vpd.len = cpu_to_be32((u32)adapter->vpd->len);
>> +	ibmvnic_send_crq(adapter, &crq);
>> +	wait_for_completion(&adapter->fw_done);
>> +
>> +	return 0;
>> +}
>> +
>>   static int init_resources(struct ibmvnic_adapter *adapter)
>>   {
>>   	struct net_device *netdev = adapter->netdev;
>> @@ -850,6 +908,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
>>   	if (rc)
>>   		return rc;
>>
>> +	adapter->vpd = kzalloc(sizeof(*adapter->vpd), GFP_KERNEL);
>> +	if (!adapter->vpd)
>> +		return -ENOMEM;
>> +
>>   	adapter->map_id = 1;
>>   	adapter->napi = kcalloc(adapter->req_rx_queues,
>>   				sizeof(struct napi_struct), GFP_KERNEL);
>> @@ -950,6 +1012,10 @@ static int ibmvnic_open(struct net_device *netdev)
>>
>>   	rc = __ibmvnic_open(netdev);
>>   	netif_carrier_on(netdev);
>> +
>> +	/* Vital Product Data (VPD) */
>> +	ibmvnic_get_vpd(adapter);
>> +
>>   	mutex_unlock(&adapter->reset_lock);
>>
>>   	return rc;
>> @@ -1878,11 +1944,15 @@ static int ibmvnic_get_link_ksettings(struct net_device *netdev,
>>   	return 0;
>>   }
>>
>> -static void ibmvnic_get_drvinfo(struct net_device *dev,
>> +static void ibmvnic_get_drvinfo(struct net_device *netdev,
>>   				struct ethtool_drvinfo *info)
>>   {
>> +	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
>> +
>>   	strlcpy(info->driver, ibmvnic_driver_name, sizeof(info->driver));
>>   	strlcpy(info->version, IBMVNIC_DRIVER_VERSION, sizeof(info->version));
>> +	strlcpy(info->fw_version, adapter->fw_version,
>> +		sizeof(info->fw_version));
>>   }
>>
>>   static u32 ibmvnic_get_msglevel(struct net_device *netdev)
>> @@ -3076,6 +3146,77 @@ static void send_cap_queries(struct ibmvnic_adapter *adapter)
>>   	ibmvnic_send_crq(adapter, &crq);
>>   }
>>
>> +static void handle_vpd_size_rsp(union ibmvnic_crq *crq,
>> +				struct ibmvnic_adapter *adapter)
>> +{
>> +	struct device *dev = &adapter->vdev->dev;
>> +
>> +	if (crq->get_vpd_size_rsp.rc.code) {
>> +		dev_err(dev, "Error retrieving VPD size, rc=%x\n",
>> +			crq->get_vpd_size_rsp.rc.code);
>> +		complete(&adapter->fw_done);
>> +		return;
>> +	}
>> +
>> +	adapter->vpd->len = be64_to_cpu(crq->get_vpd_size_rsp.len);
>> +	complete(&adapter->fw_done);
>> +}
>> +
>> +static void handle_vpd_rsp(union ibmvnic_crq *crq,
>> +			   struct ibmvnic_adapter *adapter)
>> +{
>> +	struct device *dev = &adapter->vdev->dev;
>> +	unsigned char *substr = NULL, *ptr = NULL;
>> +	u8 fw_level_len = 0;
>> +
>> +	dma_unmap_single(dev, adapter->vpd->dma_addr, adapter->vpd->len,
>> +			 DMA_FROM_DEVICE);
>> +
>> +	if (crq->get_vpd_rsp.rc.code) {
>> +		dev_err(dev, "Error retrieving VPD from device, rc=%x\n",
>> +			crq->get_vpd_rsp.rc.code);
>> +		memset(adapter->fw_version, 0, 32);
>> +		goto complete;
>> +	}
>> +
>> +	/* get the position of the firmware version info
>> +	 * located after the ASCII 'RM' substring in the buffer
>> +	 */
>> +	substr = strnstr(adapter->vpd->buff, "RM", adapter->vpd->len);
>> +	if (!substr) {
>> +		dev_info(dev, "No FW level provided by VPD\n");
>> +		memset(adapter->fw_version, 0, 32);
>> +		goto complete;
>> +	}
>> +
>> +	/* get length of firmware level ASCII substring */
>> +	if ((substr + 2) < (adapter->vpd->buff + adapter->vpd->len)) {
>> +		fw_level_len = *(substr + 2);
>> +	} else {
>> +		dev_info(dev, "Length of FW substr extrapolated VDP buff\n");
>> +		memset(adapter->fw_version, 0, 32);
>> +		goto complete;
>> +	}
>> +
>> +	/* copy firmware version string from vpd into adapter */
>> +	if ((substr + 3 + fw_level_len) <
>> +	    (adapter->vpd->buff + adapter->vpd->len)) {
>> +		ptr = strncpy((char *)adapter->fw_version,
>> +			      substr + 3, fw_level_len);
>> +
>> +		if (!ptr) {
>> +			dev_err(dev, "Failed to isolate FW level string\n");
>> +			memset(adapter->fw_version, 0, 32);
>> +		}
>> +	} else {
>> +		dev_info(dev, "FW substr extrapolated VPD buff\n");
>> +		memset(adapter->fw_version, 0, 32);
>> +	}
>> +
>> +complete:
>> +	complete(&adapter->fw_done);
>> +}
>> +
>>   static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
>>   {
>>   	struct device *dev = &adapter->vdev->dev;
>> @@ -3807,6 +3948,12 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
>>   		netdev_dbg(netdev, "Got Collect firmware trace Response\n");
>>   		complete(&adapter->fw_done);
>>   		break;
>> +	case GET_VPD_SIZE_RSP:
>> +		handle_vpd_size_rsp(crq, adapter);
>> +		break;
>> +	case GET_VPD_RSP:
>> +		handle_vpd_rsp(crq, adapter);
>> +		break;
>>   	default:
>>   		netdev_err(netdev, "Got an invalid cmd type 0x%02x\n",
>>   			   gen_crq->cmd);
>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
>> index 4670af8..d3a6959 100644
>> --- a/drivers/net/ethernet/ibm/ibmvnic.h
>> +++ b/drivers/net/ethernet/ibm/ibmvnic.h
>> @@ -558,6 +558,12 @@ struct ibmvnic_multicast_ctrl {
>>   	struct ibmvnic_rc rc;
>>   } __packed __aligned(8);
>>
>> +struct ibmvnic_get_vpd_size {
>> +	u8 first;
>> +	u8 cmd;
>> +	u8 reserved[14];
>> +} __packed __aligned(8);
>> +
>>   struct ibmvnic_get_vpd_size_rsp {
>>   	u8 first;
>>   	u8 cmd;
>> @@ -575,6 +581,13 @@ struct ibmvnic_get_vpd {
>>   	u8 reserved[4];
>>   } __packed __aligned(8);
>>
>> +struct ibmvnic_get_vpd_rsp {
>> +	u8 first;
>> +	u8 cmd;
>> +	u8 reserved[10];
>> +	struct ibmvnic_rc rc;
>> +} __packed __aligned(8);
>> +
>>   struct ibmvnic_acl_change_indication {
>>   	u8 first;
>>   	u8 cmd;
>> @@ -700,10 +713,10 @@ union ibmvnic_crq {
>>   	struct ibmvnic_change_mac_addr change_mac_addr_rsp;
>>   	struct ibmvnic_multicast_ctrl multicast_ctrl;
>>   	struct ibmvnic_multicast_ctrl multicast_ctrl_rsp;
>> -	struct ibmvnic_generic_crq get_vpd_size;
>> +	struct ibmvnic_get_vpd_size get_vpd_size;
>>   	struct ibmvnic_get_vpd_size_rsp get_vpd_size_rsp;
>>   	struct ibmvnic_get_vpd get_vpd;
>> -	struct ibmvnic_generic_crq get_vpd_rsp;
>> +	struct ibmvnic_get_vpd_rsp get_vpd_rsp;
>>   	struct ibmvnic_acl_change_indication acl_change_indication;
>>   	struct ibmvnic_acl_query acl_query;
>>   	struct ibmvnic_generic_crq acl_query_rsp;
>> @@ -937,6 +950,12 @@ struct ibmvnic_error_buff {
>>   	__be32 error_id;
>>   };
>>
>> +struct ibmvnic_vpd {
>> +	unsigned char *buff;
>> +	dma_addr_t dma_addr;
>> +	u64 len;
>> +};
>> +
>>   enum vnic_state {VNIC_PROBING = 1,
>>   		 VNIC_PROBED,
>>   		 VNIC_OPENING,
>> @@ -978,6 +997,10 @@ struct ibmvnic_adapter {
>>   	dma_addr_t ip_offload_ctrl_tok;
>>   	u32 msg_enable;
>>
>> +	/* Vital Product Data (VPD) */
>> +	struct ibmvnic_vpd *vpd;
>> +	char fw_version[32];
>> +
>>   	/* Statistics */
>>   	struct ibmvnic_statistics stats;
>>   	dma_addr_t stats_token;
>>

-- 
Desnes Augusto Nunes do Rosário
------------------------------------------

Linux Developer - IBM / Brazil
M.Sc. in Electrical and Computer Engineering - UFRN

desnesn@br.ibm.com

  reply	other threads:[~2017-11-10 14:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-09 19:00 [PATCH] [net-next,v3] ibmvnic: Feature implementation of Vital Product Data (VPD) for the ibmvnic driver Desnes Augusto Nunes do Rosario
2017-11-09 19:00 ` [PATCH] [net-next, v3] " Desnes Augusto Nunes do Rosario
2017-11-09 19:20 ` [PATCH] [net-next,v3] " Tushar Dave
2017-11-09 20:31 ` Nathan Fontenot
2017-11-10 14:41   ` Desnes Augusto Nunes do Rosário [this message]
2017-11-10 14:54     ` Nathan Fontenot
2017-11-10 19:13       ` Desnes Augusto Nunes do Rosário
2017-11-13 14:58         ` Nathan Fontenot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f48a18a5-f87d-2344-e2a1-4ddd5f05a561@linux.vnet.ibm.com \
    --to=desnesn@linux.vnet.ibm.com \
    --cc=jallen@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=netdev@vger.kernel.org \
    --cc=nfont@linux.vnet.ibm.com \
    --cc=tlfalcon@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.