src/dpdk/drivers/net/qede/base/ecore_mcp.c
enum _ecore_status_t ecore_mcp_nvm_write(struct ecore_dev *p_dev, u32 cmd,
					 u32 addr, u8 *p_buf, u32 len)
{
	u32 buf_idx, buf_size, nvm_cmd, nvm_offset;
	u32 resp = FW_MSG_CODE_ERROR, param;
	struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(p_dev);
	enum _ecore_status_t rc = ECORE_INVAL;
	struct ecore_ptt *p_ptt;

	p_ptt = ecore_ptt_acquire(p_hwfn);
	if (!p_ptt)
		return ECORE_BUSY;

	switch (cmd) {
	case ECORE_PUT_FILE_DATA:
		nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_DATA;
		break;
	case ECORE_NVM_WRITE_NVRAM:
		nvm_cmd = DRV_MSG_CODE_NVM_WRITE_NVRAM;
		break;
	case ECORE_EXT_PHY_FW_UPGRADE:
		nvm_cmd = DRV_MSG_CODE_EXT_PHY_FW_UPGRADE;
		break;
	default:
		DP_NOTICE(p_hwfn, true, "Invalid nvm write command 0x%x\n",
			  cmd);
		rc = ECORE_INVAL;
		goto out;
	}

	buf_idx = 0;
	while (buf_idx < len) {
		buf_size = OSAL_MIN_T(u32, (len - buf_idx),
				      MCP_DRV_NVM_BUF_LEN);
		nvm_offset = ((buf_size << DRV_MB_PARAM_NVM_LEN_OFFSET) |
			      addr) +
			     buf_idx;
		rc = ecore_mcp_nvm_wr_cmd(p_hwfn, p_ptt, nvm_cmd, nvm_offset,
					  &resp, &param, buf_size,
					  (u32 *)&p_buf[buf_idx]);
		if (rc != ECORE_SUCCESS) {
			DP_NOTICE(p_dev, false,
				  "ecore_mcp_nvm_write() failed, rc = %d\n",
				  rc);
			resp = FW_MSG_CODE_ERROR;
			break;
		}

		if (resp != FW_MSG_CODE_OK &&
		    resp != FW_MSG_CODE_NVM_OK &&
		    resp != FW_MSG_CODE_NVM_PUT_FILE_FINISH_OK) {
			DP_NOTICE(p_dev, false,
				  "nvm write failed, resp = 0x%08x\n", resp);
			rc = ECORE_UNKNOWN_ERROR;
			break;
		}

		/* This can be a lengthy process, and it's possible scheduler
		 * isn't preemptible. Sleep a bit to prevent CPU hogging.
		 */
		if (buf_idx % 0x1000 >
		    (buf_idx + buf_size) % 0x1000)
			OSAL_MSLEEP(1);

		buf_idx += buf_size;
	}

	p_dev->mcp_nvm_resp = resp;
out:
	ecore_ptt_release(p_hwfn, p_ptt);

	return rc;
}
/* rc receives ECORE_INVAL as default parameter because
 * it might not enter the while loop if the len is 0
 */
rc receives ECORE_INVAL as default parameter because
it might not enter the while loop if the len is 0
rc receives ECORE_INVAL as default parameter because it might not enter the while loop if the len is 0
enum _ecore_status_t ecore_mcp_nvm_write(struct ecore_dev *p_dev, u32 cmd,
					 u32 addr, u8 *p_buf, u32 len)
{
	u32 buf_idx, buf_size, nvm_cmd, nvm_offset;
	u32 resp = FW_MSG_CODE_ERROR, param;
	struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(p_dev);
	enum _ecore_status_t rc = ECORE_INVAL;
	struct ecore_ptt *p_ptt;
	p_ptt = ecore_ptt_acquire(p_hwfn);
	if (!p_ptt)
		return ECORE_BUSY;
	switch (cmd) {
	case ECORE_PUT_FILE_DATA:
		nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_DATA;
		break;
	case ECORE_NVM_WRITE_NVRAM:
		nvm_cmd = DRV_MSG_CODE_NVM_WRITE_NVRAM;
		break;
	case ECORE_EXT_PHY_FW_UPGRADE:
		nvm_cmd = DRV_MSG_CODE_EXT_PHY_FW_UPGRADE;
		break;
	default:
		DP_NOTICE(p_hwfn, true, "Invalid nvm write command 0x%x\n",
			  cmd);
		rc = ECORE_INVAL;
		goto out;
	}
	buf_idx = 0;
	while (buf_idx < len) {
		buf_size = OSAL_MIN_T(u32, (len - buf_idx),
				      MCP_DRV_NVM_BUF_LEN);
		nvm_offset = ((buf_size << DRV_MB_PARAM_NVM_LEN_OFFSET) |
			      addr) +
			     buf_idx;
		rc = ecore_mcp_nvm_wr_cmd(p_hwfn, p_ptt, nvm_cmd, nvm_offset,
					  &resp, &param, buf_size,
					  (u32 *)&p_buf[buf_idx]);
		if (rc != ECORE_SUCCESS) {
			DP_NOTICE(p_dev, false,
				  "ecore_mcp_nvm_write() failed, rc = %d\n",
				  rc);
			resp = FW_MSG_CODE_ERROR;
			break;
		}
		if (resp != FW_MSG_CODE_OK &&
		    resp != FW_MSG_CODE_NVM_OK &&
		    resp != FW_MSG_CODE_NVM_PUT_FILE_FINISH_OK) {
			DP_NOTICE(p_dev, false,
				  "nvm write failed, resp = 0x%08x\n", resp);
			rc = ECORE_UNKNOWN_ERROR;
			break;
		}
		if (buf_idx % 0x1000 >
		    (buf_idx + buf_size) % 0x1000)
			OSAL_MSLEEP(1);
		buf_idx += buf_size;
	}
	p_dev->mcp_nvm_resp = resp;
out:
	ecore_ptt_release(p_hwfn, p_ptt);
	return rc;
}
enum _ecore_status_t ecore_mcp_nvm_write ( struct ecore_dev * p_dev , u32 cmd , u32 addr , u8 * p_buf , u32 len ) { u32 buf_idx , buf_size , nvm_cmd , nvm_offset ; u32 resp = FW_MSG_CODE_ERROR , param ; struct ecore_hwfn * p_hwfn = ECORE_LEADING_HWFN ( p_dev ) ; enum _ecore_status_t rc = ECORE_INVAL ; struct ecore_ptt * p_ptt ; p_ptt = ecore_ptt_acquire ( p_hwfn ) ; if ( ! p_ptt ) return ECORE_BUSY ; switch ( cmd ) { case ECORE_PUT_FILE_DATA : nvm_cmd = DRV_MSG_CODE_NVM_PUT_FILE_DATA ; break ; case ECORE_NVM_WRITE_NVRAM : nvm_cmd = DRV_MSG_CODE_NVM_WRITE_NVRAM ; break ; case ECORE_EXT_PHY_FW_UPGRADE : nvm_cmd = DRV_MSG_CODE_EXT_PHY_FW_UPGRADE ; break ; default : DP_NOTICE ( p_hwfn , true , " \n " , cmd ) ; rc = ECORE_INVAL ; goto out ; } buf_idx = 0 ; while ( buf_idx < len ) { buf_size = OSAL_MIN_T ( u32 , ( len - buf_idx ) , MCP_DRV_NVM_BUF_LEN ) ; nvm_offset = ( ( buf_size << DRV_MB_PARAM_NVM_LEN_OFFSET ) | addr ) + buf_idx ; rc = ecore_mcp_nvm_wr_cmd ( p_hwfn , p_ptt , nvm_cmd , nvm_offset , & resp , & param , buf_size , ( u32 * ) & p_buf [ buf_idx ] ) ; if ( rc != ECORE_SUCCESS ) { DP_NOTICE ( p_dev , false , " \n " , rc ) ; resp = FW_MSG_CODE_ERROR ; break ; } if ( resp != FW_MSG_CODE_OK && resp != FW_MSG_CODE_NVM_OK && resp != FW_MSG_CODE_NVM_PUT_FILE_FINISH_OK ) { DP_NOTICE ( p_dev , false , " \n " , resp ) ; rc = ECORE_UNKNOWN_ERROR ; break ; } if ( buf_idx % 0x1000 > ( buf_idx + buf_size ) % 0x1000 ) OSAL_MSLEEP ( 1 ) ; buf_idx += buf_size ; } p_dev -> mcp_nvm_resp = resp ; out : ecore_ptt_release ( p_hwfn , p_ptt ) ; return rc ; }
rc receives ECORE_INVAL as default parameter because
 it might not enter the while loop if the len is 0
rc receives ECORE_INVAL as default parameter because it might not enter the while loop if the len is 0
/* This can be a lengthy process, and it's possible scheduler
		 * isn't preemptible. Sleep a bit to prevent CPU hogging.
		 */