15129044dSC.J. Collier/*******************************************************************************
25129044dSC.J. Collier
35129044dSC.J. CollierCopyright (c) 2013 - 2015, Intel Corporation
45129044dSC.J. CollierAll rights reserved.
55129044dSC.J. Collier
65129044dSC.J. CollierRedistribution and use in source and binary forms, with or without
75129044dSC.J. Colliermodification, are permitted provided that the following conditions are met:
85129044dSC.J. Collier
95129044dSC.J. Collier 1. Redistributions of source code must retain the above copyright notice,
105129044dSC.J. Collier    this list of conditions and the following disclaimer.
115129044dSC.J. Collier
125129044dSC.J. Collier 2. Redistributions in binary form must reproduce the above copyright
135129044dSC.J. Collier    notice, this list of conditions and the following disclaimer in the
145129044dSC.J. Collier    documentation and/or other materials provided with the distribution.
155129044dSC.J. Collier
165129044dSC.J. Collier 3. Neither the name of the Intel Corporation nor the names of its
175129044dSC.J. Collier    contributors may be used to endorse or promote products derived from
185129044dSC.J. Collier    this software without specific prior written permission.
195129044dSC.J. Collier
205129044dSC.J. CollierTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
215129044dSC.J. CollierAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
225129044dSC.J. CollierIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
235129044dSC.J. CollierARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
245129044dSC.J. CollierLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
255129044dSC.J. CollierCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
265129044dSC.J. CollierSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
275129044dSC.J. CollierINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
285129044dSC.J. CollierCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
295129044dSC.J. CollierARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
305129044dSC.J. CollierPOSSIBILITY OF SUCH DAMAGE.
315129044dSC.J. Collier
325129044dSC.J. Collier***************************************************************************/
335129044dSC.J. Collier
345129044dSC.J. Collier#include "i40e_osdep.h"
355129044dSC.J. Collier#include "i40e_register.h"
365129044dSC.J. Collier#include "i40e_status.h"
375129044dSC.J. Collier#include "i40e_alloc.h"
385129044dSC.J. Collier#include "i40e_hmc.h"
395129044dSC.J. Collier#include "i40e_type.h"
405129044dSC.J. Collier
415129044dSC.J. Collier/**
425129044dSC.J. Collier * i40e_add_sd_table_entry - Adds a segment descriptor to the table
435129044dSC.J. Collier * @hw: pointer to our hw struct
445129044dSC.J. Collier * @hmc_info: pointer to the HMC configuration information struct
455129044dSC.J. Collier * @sd_index: segment descriptor index to manipulate
465129044dSC.J. Collier * @type: what type of segment descriptor we're manipulating
475129044dSC.J. Collier * @direct_mode_sz: size to alloc in direct mode
485129044dSC.J. Collier **/
495129044dSC.J. Collierenum i40e_status_code i40e_add_sd_table_entry(struct i40e_hw *hw,
505129044dSC.J. Collier					      struct i40e_hmc_info *hmc_info,
515129044dSC.J. Collier					      u32 sd_index,
525129044dSC.J. Collier					      enum i40e_sd_entry_type type,
535129044dSC.J. Collier					      u64 direct_mode_sz)
545129044dSC.J. Collier{
555129044dSC.J. Collier	enum i40e_status_code ret_code = I40E_SUCCESS;
565129044dSC.J. Collier	struct i40e_hmc_sd_entry *sd_entry;
575129044dSC.J. Collier	enum   i40e_memory_type mem_type;
585129044dSC.J. Collier	bool dma_mem_alloc_done = false;
595129044dSC.J. Collier	struct i40e_dma_mem mem;
605129044dSC.J. Collier	u64 alloc_len;
615129044dSC.J. Collier
625129044dSC.J. Collier	if (NULL == hmc_info->sd_table.sd_entry) {
635129044dSC.J. Collier		ret_code = I40E_ERR_BAD_PTR;
645129044dSC.J. Collier		DEBUGOUT("i40e_add_sd_table_entry: bad sd_entry\n");
655129044dSC.J. Collier		goto exit;
665129044dSC.J. Collier	}
675129044dSC.J. Collier
685129044dSC.J. Collier	if (sd_index >= hmc_info->sd_table.sd_cnt) {
695129044dSC.J. Collier		ret_code = I40E_ERR_INVALID_SD_INDEX;
705129044dSC.J. Collier		DEBUGOUT("i40e_add_sd_table_entry: bad sd_index\n");
715129044dSC.J. Collier		goto exit;
725129044dSC.J. Collier	}
735129044dSC.J. Collier
745129044dSC.J. Collier	sd_entry = &hmc_info->sd_table.sd_entry[sd_index];
755129044dSC.J. Collier	if (!sd_entry->valid) {
765129044dSC.J. Collier		if (I40E_SD_TYPE_PAGED == type) {
775129044dSC.J. Collier			mem_type = i40e_mem_pd;
785129044dSC.J. Collier			alloc_len = I40E_HMC_PAGED_BP_SIZE;
795129044dSC.J. Collier		} else {
805129044dSC.J. Collier			mem_type = i40e_mem_bp_jumbo;
815129044dSC.J. Collier			alloc_len = direct_mode_sz;
825129044dSC.J. Collier		}
835129044dSC.J. Collier
845129044dSC.J. Collier		/* allocate a 4K pd page or 2M backing page */
855129044dSC.J. Collier		ret_code = i40e_allocate_dma_mem(hw, &mem, mem_type, alloc_len,
865129044dSC.J. Collier						 I40E_HMC_PD_BP_BUF_ALIGNMENT);
875129044dSC.J. Collier		if (ret_code)
885129044dSC.J. Collier			goto exit;
895129044dSC.J. Collier		dma_mem_alloc_done = true;
905129044dSC.J. Collier		if (I40E_SD_TYPE_PAGED == type) {
915129044dSC.J. Collier			ret_code = i40e_allocate_virt_mem(hw,
925129044dSC.J. Collier					&sd_entry->u.pd_table.pd_entry_virt_mem,
935129044dSC.J. Collier					sizeof(struct i40e_hmc_pd_entry) * 512);
945129044dSC.J. Collier			if (ret_code)
955129044dSC.J. Collier				goto exit;
965129044dSC.J. Collier			sd_entry->u.pd_table.pd_entry =
975129044dSC.J. Collier				(struct i40e_hmc_pd_entry *)
985129044dSC.J. Collier				sd_entry->u.pd_table.pd_entry_virt_mem.va;
995129044dSC.J. Collier			i40e_memcpy(&sd_entry->u.pd_table.pd_page_addr,
1005129044dSC.J. Collier				    &mem, sizeof(struct i40e_dma_mem),
1015129044dSC.J. Collier				    I40E_NONDMA_TO_NONDMA);
1025129044dSC.J. Collier		} else {
1035129044dSC.J. Collier			i40e_memcpy(&sd_entry->u.bp.addr,
1045129044dSC.J. Collier				    &mem, sizeof(struct i40e_dma_mem),
1055129044dSC.J. Collier				    I40E_NONDMA_TO_NONDMA);
1065129044dSC.J. Collier			sd_entry->u.bp.sd_pd_index = sd_index;
1075129044dSC.J. Collier		}
1085129044dSC.J. Collier		/* initialize the sd entry */
1095129044dSC.J. Collier		hmc_info->sd_table.sd_entry[sd_index].entry_type = type;
1105129044dSC.J. Collier
1115129044dSC.J. Collier		/* increment the ref count */
1125129044dSC.J. Collier		I40E_INC_SD_REFCNT(&hmc_info->sd_table);
1135129044dSC.J. Collier	}
1145129044dSC.J. Collier	/* Increment backing page reference count */
1155129044dSC.J. Collier	if (I40E_SD_TYPE_DIRECT == sd_entry->entry_type)
1165129044dSC.J. Collier		I40E_INC_BP_REFCNT(&sd_entry->u.bp);
1175129044dSC.J. Collierexit:
1185129044dSC.J. Collier	if (I40E_SUCCESS != ret_code)
1195129044dSC.J. Collier		if (dma_mem_alloc_done)
1205129044dSC.J. Collier			i40e_free_dma_mem(hw, &mem);
1215129044dSC.J. Collier
1225129044dSC.J. Collier	return ret_code;
1235129044dSC.J. Collier}
1245129044dSC.J. Collier
1255129044dSC.J. Collier/**
1265129044dSC.J. Collier * i40e_add_pd_table_entry - Adds page descriptor to the specified table
1275129044dSC.J. Collier * @hw: pointer to our HW structure
1285129044dSC.J. Collier * @hmc_info: pointer to the HMC configuration information structure
1295129044dSC.J. Collier * @pd_index: which page descriptor index to manipulate
1305129044dSC.J. Collier * @rsrc_pg: if not NULL, use preallocated page instead of allocating new one.
1315129044dSC.J. Collier *
1325129044dSC.J. Collier * This function:
1335129044dSC.J. Collier *	1. Initializes the pd entry
1345129044dSC.J. Collier *	2. Adds pd_entry in the pd_table
1355129044dSC.J. Collier *	3. Mark the entry valid in i40e_hmc_pd_entry structure
1365129044dSC.J. Collier *	4. Initializes the pd_entry's ref count to 1
1375129044dSC.J. Collier * assumptions:
1385129044dSC.J. Collier *	1. The memory for pd should be pinned down, physically contiguous and
1395129044dSC.J. Collier *	   aligned on 4K boundary and zeroed memory.
1405129044dSC.J. Collier *	2. It should be 4K in size.
1415129044dSC.J. Collier **/
1425129044dSC.J. Collierenum i40e_status_code i40e_add_pd_table_entry(struct i40e_hw *hw,
1435129044dSC.J. Collier					      struct i40e_hmc_info *hmc_info,
1445129044dSC.J. Collier					      u32 pd_index,
1455129044dSC.J. Collier					      struct i40e_dma_mem *rsrc_pg)
1465129044dSC.J. Collier{
1475129044dSC.J. Collier	enum i40e_status_code ret_code = I40E_SUCCESS;
1485129044dSC.J. Collier	struct i40e_hmc_pd_table *pd_table;
1495129044dSC.J. Collier	struct i40e_hmc_pd_entry *pd_entry;
1505129044dSC.J. Collier	struct i40e_dma_mem mem;
1515129044dSC.J. Collier	struct i40e_dma_mem *page = &mem;
1525129044dSC.J. Collier	u32 sd_idx, rel_pd_idx;
1535129044dSC.J. Collier	u64 *pd_addr;
1545129044dSC.J. Collier	u64 page_desc;
1555129044dSC.J. Collier
1565129044dSC.J. Collier	if (pd_index / I40E_HMC_PD_CNT_IN_SD >= hmc_info->sd_table.sd_cnt) {
1575129044dSC.J. Collier		ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX;
1585129044dSC.J. Collier		DEBUGOUT("i40e_add_pd_table_entry: bad pd_index\n");
1595129044dSC.J. Collier		goto exit;
1605129044dSC.J. Collier	}
1615129044dSC.J. Collier
1625129044dSC.J. Collier	/* find corresponding sd */
1635129044dSC.J. Collier	sd_idx = (pd_index / I40E_HMC_PD_CNT_IN_SD);
1645129044dSC.J. Collier	if (I40E_SD_TYPE_PAGED !=
1655129044dSC.J. Collier	    hmc_info->sd_table.sd_entry[sd_idx].entry_type)
1665129044dSC.J. Collier		goto exit;
1675129044dSC.J. Collier
1685129044dSC.J. Collier	rel_pd_idx = (pd_index % I40E_HMC_PD_CNT_IN_SD);
1695129044dSC.J. Collier	pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
1705129044dSC.J. Collier	pd_entry = &pd_table->pd_entry[rel_pd_idx];
1715129044dSC.J. Collier	if (!pd_entry->valid) {
1725129044dSC.J. Collier		if (rsrc_pg) {
1735129044dSC.J. Collier			pd_entry->rsrc_pg = true;
1745129044dSC.J. Collier			page = rsrc_pg;
1755129044dSC.J. Collier		} else {
1765129044dSC.J. Collier			/* allocate a 4K backing page */
1775129044dSC.J. Collier			ret_code = i40e_allocate_dma_mem(hw, page, i40e_mem_bp,
1785129044dSC.J. Collier						I40E_HMC_PAGED_BP_SIZE,
1795129044dSC.J. Collier						I40E_HMC_PD_BP_BUF_ALIGNMENT);
1805129044dSC.J. Collier			if (ret_code)
1815129044dSC.J. Collier				goto exit;
1825129044dSC.J. Collier			pd_entry->rsrc_pg = false;
1835129044dSC.J. Collier		}
1845129044dSC.J. Collier
1855129044dSC.J. Collier		i40e_memcpy(&pd_entry->bp.addr, page,
1865129044dSC.J. Collier			    sizeof(struct i40e_dma_mem), I40E_NONDMA_TO_NONDMA);
1875129044dSC.J. Collier		pd_entry->bp.sd_pd_index = pd_index;
1885129044dSC.J. Collier		pd_entry->bp.entry_type = I40E_SD_TYPE_PAGED;
1895129044dSC.J. Collier		/* Set page address and valid bit */
1905129044dSC.J. Collier		page_desc = page->pa | 0x1;
1915129044dSC.J. Collier
1925129044dSC.J. Collier		pd_addr = (u64 *)pd_table->pd_page_addr.va;
1935129044dSC.J. Collier		pd_addr += rel_pd_idx;
1945129044dSC.J. Collier
1955129044dSC.J. Collier		/* Add the backing page physical address in the pd entry */
1965129044dSC.J. Collier		i40e_memcpy(pd_addr, &page_desc, sizeof(u64),
1975129044dSC.J. Collier			    I40E_NONDMA_TO_DMA);
1985129044dSC.J. Collier
1995129044dSC.J. Collier		pd_entry->sd_index = sd_idx;
2005129044dSC.J. Collier		pd_entry->valid = true;
2015129044dSC.J. Collier		I40E_INC_PD_REFCNT(pd_table);
2025129044dSC.J. Collier	}
2035129044dSC.J. Collier	I40E_INC_BP_REFCNT(&pd_entry->bp);
2045129044dSC.J. Collierexit:
2055129044dSC.J. Collier	return ret_code;
2065129044dSC.J. Collier}
2075129044dSC.J. Collier
2085129044dSC.J. Collier/**
2095129044dSC.J. Collier * i40e_remove_pd_bp - remove a backing page from a page descriptor
2105129044dSC.J. Collier * @hw: pointer to our HW structure
2115129044dSC.J. Collier * @hmc_info: pointer to the HMC configuration information structure
2125129044dSC.J. Collier * @idx: the page index
2135129044dSC.J. Collier * @is_pf: distinguishes a VF from a PF
2145129044dSC.J. Collier *
2155129044dSC.J. Collier * This function:
2165129044dSC.J. Collier *	1. Marks the entry in pd tabe (for paged address mode) or in sd table
2175129044dSC.J. Collier *	   (for direct address mode) invalid.
2185129044dSC.J. Collier *	2. Write to register PMPDINV to invalidate the backing page in FV cache
2195129044dSC.J. Collier *	3. Decrement the ref count for the pd _entry
2205129044dSC.J. Collier * assumptions:
2215129044dSC.J. Collier *	1. Caller can deallocate the memory used by backing storage after this
2225129044dSC.J. Collier *	   function returns.
2235129044dSC.J. Collier **/
2245129044dSC.J. Collierenum i40e_status_code i40e_remove_pd_bp(struct i40e_hw *hw,
2255129044dSC.J. Collier					struct i40e_hmc_info *hmc_info,
2265129044dSC.J. Collier					u32 idx)
2275129044dSC.J. Collier{
2285129044dSC.J. Collier	enum i40e_status_code ret_code = I40E_SUCCESS;
2295129044dSC.J. Collier	struct i40e_hmc_pd_entry *pd_entry;
2305129044dSC.J. Collier	struct i40e_hmc_pd_table *pd_table;
2315129044dSC.J. Collier	struct i40e_hmc_sd_entry *sd_entry;
2325129044dSC.J. Collier	u32 sd_idx, rel_pd_idx;
2335129044dSC.J. Collier	u64 *pd_addr;
2345129044dSC.J. Collier
2355129044dSC.J. Collier	/* calculate index */
2365129044dSC.J. Collier	sd_idx = idx / I40E_HMC_PD_CNT_IN_SD;
2375129044dSC.J. Collier	rel_pd_idx = idx % I40E_HMC_PD_CNT_IN_SD;
2385129044dSC.J. Collier	if (sd_idx >= hmc_info->sd_table.sd_cnt) {
2395129044dSC.J. Collier		ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX;
2405129044dSC.J. Collier		DEBUGOUT("i40e_remove_pd_bp: bad idx\n");
2415129044dSC.J. Collier		goto exit;
2425129044dSC.J. Collier	}
2435129044dSC.J. Collier	sd_entry = &hmc_info->sd_table.sd_entry[sd_idx];
2445129044dSC.J. Collier	if (I40E_SD_TYPE_PAGED != sd_entry->entry_type) {
2455129044dSC.J. Collier		ret_code = I40E_ERR_INVALID_SD_TYPE;
2465129044dSC.J. Collier		DEBUGOUT("i40e_remove_pd_bp: wrong sd_entry type\n");
2475129044dSC.J. Collier		goto exit;
2485129044dSC.J. Collier	}
2495129044dSC.J. Collier	/* get the entry and decrease its ref counter */
2505129044dSC.J. Collier	pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
2515129044dSC.J. Collier	pd_entry = &pd_table->pd_entry[rel_pd_idx];
2525129044dSC.J. Collier	I40E_DEC_BP_REFCNT(&pd_entry->bp);
2535129044dSC.J. Collier	if (pd_entry->bp.ref_cnt)
2545129044dSC.J. Collier		goto exit;
2555129044dSC.J. Collier
2565129044dSC.J. Collier	/* mark the entry invalid */
2575129044dSC.J. Collier	pd_entry->valid = false;
2585129044dSC.J. Collier	I40E_DEC_PD_REFCNT(pd_table);
2595129044dSC.J. Collier	pd_addr = (u64 *)pd_table->pd_page_addr.va;
2605129044dSC.J. Collier	pd_addr += rel_pd_idx;
2615129044dSC.J. Collier	i40e_memset(pd_addr, 0, sizeof(u64), I40E_DMA_MEM);
2625129044dSC.J. Collier	I40E_INVALIDATE_PF_HMC_PD(hw, sd_idx, idx);
2635129044dSC.J. Collier
2645129044dSC.J. Collier	/* free memory here */
2655129044dSC.J. Collier	if (!pd_entry->rsrc_pg)
2665129044dSC.J. Collier		ret_code = i40e_free_dma_mem(hw, &(pd_entry->bp.addr));
2675129044dSC.J. Collier	if (I40E_SUCCESS != ret_code)
2685129044dSC.J. Collier		goto exit;
2695129044dSC.J. Collier	if (!pd_table->ref_cnt)
2705129044dSC.J. Collier		i40e_free_virt_mem(hw, &pd_table->pd_entry_virt_mem);
2715129044dSC.J. Collierexit:
2725129044dSC.J. Collier	return ret_code;
2735129044dSC.J. Collier}
2745129044dSC.J. Collier
2755129044dSC.J. Collier/**
2765129044dSC.J. Collier * i40e_prep_remove_sd_bp - Prepares to remove a backing page from a sd entry
2775129044dSC.J. Collier * @hmc_info: pointer to the HMC configuration information structure
2785129044dSC.J. Collier * @idx: the page index
2795129044dSC.J. Collier **/
2805129044dSC.J. Collierenum i40e_status_code i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info,
2815129044dSC.J. Collier					     u32 idx)
2825129044dSC.J. Collier{
2835129044dSC.J. Collier	enum i40e_status_code ret_code = I40E_SUCCESS;
2845129044dSC.J. Collier	struct i40e_hmc_sd_entry *sd_entry;
2855129044dSC.J. Collier
2865129044dSC.J. Collier	/* get the entry and decrease its ref counter */
2875129044dSC.J. Collier	sd_entry = &hmc_info->sd_table.sd_entry[idx];
2885129044dSC.J. Collier	I40E_DEC_BP_REFCNT(&sd_entry->u.bp);
2895129044dSC.J. Collier	if (sd_entry->u.bp.ref_cnt) {
2905129044dSC.J. Collier		ret_code = I40E_ERR_NOT_READY;
2915129044dSC.J. Collier		goto exit;
2925129044dSC.J. Collier	}
2935129044dSC.J. Collier	I40E_DEC_SD_REFCNT(&hmc_info->sd_table);
2945129044dSC.J. Collier
2955129044dSC.J. Collier	/* mark the entry invalid */
2965129044dSC.J. Collier	sd_entry->valid = false;
2975129044dSC.J. Collierexit:
2985129044dSC.J. Collier	return ret_code;
2995129044dSC.J. Collier}
3005129044dSC.J. Collier
3015129044dSC.J. Collier/**
3025129044dSC.J. Collier * i40e_remove_sd_bp_new - Removes a backing page from a segment descriptor
3035129044dSC.J. Collier * @hw: pointer to our hw struct
3045129044dSC.J. Collier * @hmc_info: pointer to the HMC configuration information structure
3055129044dSC.J. Collier * @idx: the page index
3065129044dSC.J. Collier * @is_pf: used to distinguish between VF and PF
3075129044dSC.J. Collier **/
3085129044dSC.J. Collierenum i40e_status_code i40e_remove_sd_bp_new(struct i40e_hw *hw,
3095129044dSC.J. Collier					    struct i40e_hmc_info *hmc_info,
3105129044dSC.J. Collier					    u32 idx, bool is_pf)
3115129044dSC.J. Collier{
3125129044dSC.J. Collier	struct i40e_hmc_sd_entry *sd_entry;
3135129044dSC.J. Collier
3145129044dSC.J. Collier	if (!is_pf)
3155129044dSC.J. Collier		return I40E_NOT_SUPPORTED;
3165129044dSC.J. Collier
3175129044dSC.J. Collier	/* get the entry and decrease its ref counter */
3185129044dSC.J. Collier	sd_entry = &hmc_info->sd_table.sd_entry[idx];
3195129044dSC.J. Collier	I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_DIRECT);
3205129044dSC.J. Collier
3215129044dSC.J. Collier	return i40e_free_dma_mem(hw, &(sd_entry->u.bp.addr));
3225129044dSC.J. Collier}
3235129044dSC.J. Collier
3245129044dSC.J. Collier/**
3255129044dSC.J. Collier * i40e_prep_remove_pd_page - Prepares to remove a PD page from sd entry.
3265129044dSC.J. Collier * @hmc_info: pointer to the HMC configuration information structure
3275129044dSC.J. Collier * @idx: segment descriptor index to find the relevant page descriptor
3285129044dSC.J. Collier **/
3295129044dSC.J. Collierenum i40e_status_code i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info,
3305129044dSC.J. Collier					       u32 idx)
3315129044dSC.J. Collier{
3325129044dSC.J. Collier	enum i40e_status_code ret_code = I40E_SUCCESS;
3335129044dSC.J. Collier	struct i40e_hmc_sd_entry *sd_entry;
3345129044dSC.J. Collier
3355129044dSC.J. Collier	sd_entry = &hmc_info->sd_table.sd_entry[idx];
3365129044dSC.J. Collier
3375129044dSC.J. Collier	if (sd_entry->u.pd_table.ref_cnt) {
3385129044dSC.J. Collier		ret_code = I40E_ERR_NOT_READY;
3395129044dSC.J. Collier		goto exit;
3405129044dSC.J. Collier	}
3415129044dSC.J. Collier
3425129044dSC.J. Collier	/* mark the entry invalid */
3435129044dSC.J. Collier	sd_entry->valid = false;
3445129044dSC.J. Collier
3455129044dSC.J. Collier	I40E_DEC_SD_REFCNT(&hmc_info->sd_table);
3465129044dSC.J. Collierexit:
3475129044dSC.J. Collier	return ret_code;
3485129044dSC.J. Collier}
3495129044dSC.J. Collier
3505129044dSC.J. Collier/**
3515129044dSC.J. Collier * i40e_remove_pd_page_new - Removes a PD page from sd entry.
3525129044dSC.J. Collier * @hw: pointer to our hw struct
3535129044dSC.J. Collier * @hmc_info: pointer to the HMC configuration information structure
3545129044dSC.J. Collier * @idx: segment descriptor index to find the relevant page descriptor
3555129044dSC.J. Collier * @is_pf: used to distinguish between VF and PF
3565129044dSC.J. Collier **/
3575129044dSC.J. Collierenum i40e_status_code i40e_remove_pd_page_new(struct i40e_hw *hw,
3585129044dSC.J. Collier					      struct i40e_hmc_info *hmc_info,
3595129044dSC.J. Collier					      u32 idx, bool is_pf)
3605129044dSC.J. Collier{
3615129044dSC.J. Collier	struct i40e_hmc_sd_entry *sd_entry;
3625129044dSC.J. Collier
3635129044dSC.J. Collier	if (!is_pf)
3645129044dSC.J. Collier		return I40E_NOT_SUPPORTED;
3655129044dSC.J. Collier
3665129044dSC.J. Collier	sd_entry = &hmc_info->sd_table.sd_entry[idx];
3675129044dSC.J. Collier	I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_PAGED);
3685129044dSC.J. Collier
3695129044dSC.J. Collier	return i40e_free_dma_mem(hw, &(sd_entry->u.pd_table.pd_page_addr));
3705129044dSC.J. Collier}
371