18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/* Copyright(c) 2013 - 2018 Intel Corporation. */
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include "i40e.h"
58c2ecf20Sopenharmony_ci#include "i40e_osdep.h"
68c2ecf20Sopenharmony_ci#include "i40e_register.h"
78c2ecf20Sopenharmony_ci#include "i40e_status.h"
88c2ecf20Sopenharmony_ci#include "i40e_alloc.h"
98c2ecf20Sopenharmony_ci#include "i40e_hmc.h"
108c2ecf20Sopenharmony_ci#include "i40e_type.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/**
138c2ecf20Sopenharmony_ci * i40e_add_sd_table_entry - Adds a segment descriptor to the table
148c2ecf20Sopenharmony_ci * @hw: pointer to our hw struct
158c2ecf20Sopenharmony_ci * @hmc_info: pointer to the HMC configuration information struct
168c2ecf20Sopenharmony_ci * @sd_index: segment descriptor index to manipulate
178c2ecf20Sopenharmony_ci * @type: what type of segment descriptor we're manipulating
188c2ecf20Sopenharmony_ci * @direct_mode_sz: size to alloc in direct mode
198c2ecf20Sopenharmony_ci **/
208c2ecf20Sopenharmony_cii40e_status i40e_add_sd_table_entry(struct i40e_hw *hw,
218c2ecf20Sopenharmony_ci					      struct i40e_hmc_info *hmc_info,
228c2ecf20Sopenharmony_ci					      u32 sd_index,
238c2ecf20Sopenharmony_ci					      enum i40e_sd_entry_type type,
248c2ecf20Sopenharmony_ci					      u64 direct_mode_sz)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	enum i40e_memory_type mem_type __attribute__((unused));
278c2ecf20Sopenharmony_ci	struct i40e_hmc_sd_entry *sd_entry;
288c2ecf20Sopenharmony_ci	bool dma_mem_alloc_done = false;
298c2ecf20Sopenharmony_ci	struct i40e_dma_mem mem;
308c2ecf20Sopenharmony_ci	i40e_status ret_code = I40E_SUCCESS;
318c2ecf20Sopenharmony_ci	u64 alloc_len;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	if (NULL == hmc_info->sd_table.sd_entry) {
348c2ecf20Sopenharmony_ci		ret_code = I40E_ERR_BAD_PTR;
358c2ecf20Sopenharmony_ci		hw_dbg(hw, "i40e_add_sd_table_entry: bad sd_entry\n");
368c2ecf20Sopenharmony_ci		goto exit;
378c2ecf20Sopenharmony_ci	}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	if (sd_index >= hmc_info->sd_table.sd_cnt) {
408c2ecf20Sopenharmony_ci		ret_code = I40E_ERR_INVALID_SD_INDEX;
418c2ecf20Sopenharmony_ci		hw_dbg(hw, "i40e_add_sd_table_entry: bad sd_index\n");
428c2ecf20Sopenharmony_ci		goto exit;
438c2ecf20Sopenharmony_ci	}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	sd_entry = &hmc_info->sd_table.sd_entry[sd_index];
468c2ecf20Sopenharmony_ci	if (!sd_entry->valid) {
478c2ecf20Sopenharmony_ci		if (I40E_SD_TYPE_PAGED == type) {
488c2ecf20Sopenharmony_ci			mem_type = i40e_mem_pd;
498c2ecf20Sopenharmony_ci			alloc_len = I40E_HMC_PAGED_BP_SIZE;
508c2ecf20Sopenharmony_ci		} else {
518c2ecf20Sopenharmony_ci			mem_type = i40e_mem_bp_jumbo;
528c2ecf20Sopenharmony_ci			alloc_len = direct_mode_sz;
538c2ecf20Sopenharmony_ci		}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci		/* allocate a 4K pd page or 2M backing page */
568c2ecf20Sopenharmony_ci		ret_code = i40e_allocate_dma_mem(hw, &mem, mem_type, alloc_len,
578c2ecf20Sopenharmony_ci						 I40E_HMC_PD_BP_BUF_ALIGNMENT);
588c2ecf20Sopenharmony_ci		if (ret_code)
598c2ecf20Sopenharmony_ci			goto exit;
608c2ecf20Sopenharmony_ci		dma_mem_alloc_done = true;
618c2ecf20Sopenharmony_ci		if (I40E_SD_TYPE_PAGED == type) {
628c2ecf20Sopenharmony_ci			ret_code = i40e_allocate_virt_mem(hw,
638c2ecf20Sopenharmony_ci					&sd_entry->u.pd_table.pd_entry_virt_mem,
648c2ecf20Sopenharmony_ci					sizeof(struct i40e_hmc_pd_entry) * 512);
658c2ecf20Sopenharmony_ci			if (ret_code)
668c2ecf20Sopenharmony_ci				goto exit;
678c2ecf20Sopenharmony_ci			sd_entry->u.pd_table.pd_entry =
688c2ecf20Sopenharmony_ci				(struct i40e_hmc_pd_entry *)
698c2ecf20Sopenharmony_ci				sd_entry->u.pd_table.pd_entry_virt_mem.va;
708c2ecf20Sopenharmony_ci			sd_entry->u.pd_table.pd_page_addr = mem;
718c2ecf20Sopenharmony_ci		} else {
728c2ecf20Sopenharmony_ci			sd_entry->u.bp.addr = mem;
738c2ecf20Sopenharmony_ci			sd_entry->u.bp.sd_pd_index = sd_index;
748c2ecf20Sopenharmony_ci		}
758c2ecf20Sopenharmony_ci		/* initialize the sd entry */
768c2ecf20Sopenharmony_ci		hmc_info->sd_table.sd_entry[sd_index].entry_type = type;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci		/* increment the ref count */
798c2ecf20Sopenharmony_ci		I40E_INC_SD_REFCNT(&hmc_info->sd_table);
808c2ecf20Sopenharmony_ci	}
818c2ecf20Sopenharmony_ci	/* Increment backing page reference count */
828c2ecf20Sopenharmony_ci	if (I40E_SD_TYPE_DIRECT == sd_entry->entry_type)
838c2ecf20Sopenharmony_ci		I40E_INC_BP_REFCNT(&sd_entry->u.bp);
848c2ecf20Sopenharmony_ciexit:
858c2ecf20Sopenharmony_ci	if (ret_code)
868c2ecf20Sopenharmony_ci		if (dma_mem_alloc_done)
878c2ecf20Sopenharmony_ci			i40e_free_dma_mem(hw, &mem);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	return ret_code;
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/**
938c2ecf20Sopenharmony_ci * i40e_add_pd_table_entry - Adds page descriptor to the specified table
948c2ecf20Sopenharmony_ci * @hw: pointer to our HW structure
958c2ecf20Sopenharmony_ci * @hmc_info: pointer to the HMC configuration information structure
968c2ecf20Sopenharmony_ci * @pd_index: which page descriptor index to manipulate
978c2ecf20Sopenharmony_ci * @rsrc_pg: if not NULL, use preallocated page instead of allocating new one.
988c2ecf20Sopenharmony_ci *
998c2ecf20Sopenharmony_ci * This function:
1008c2ecf20Sopenharmony_ci *	1. Initializes the pd entry
1018c2ecf20Sopenharmony_ci *	2. Adds pd_entry in the pd_table
1028c2ecf20Sopenharmony_ci *	3. Mark the entry valid in i40e_hmc_pd_entry structure
1038c2ecf20Sopenharmony_ci *	4. Initializes the pd_entry's ref count to 1
1048c2ecf20Sopenharmony_ci * assumptions:
1058c2ecf20Sopenharmony_ci *	1. The memory for pd should be pinned down, physically contiguous and
1068c2ecf20Sopenharmony_ci *	   aligned on 4K boundary and zeroed memory.
1078c2ecf20Sopenharmony_ci *	2. It should be 4K in size.
1088c2ecf20Sopenharmony_ci **/
1098c2ecf20Sopenharmony_cii40e_status i40e_add_pd_table_entry(struct i40e_hw *hw,
1108c2ecf20Sopenharmony_ci					      struct i40e_hmc_info *hmc_info,
1118c2ecf20Sopenharmony_ci					      u32 pd_index,
1128c2ecf20Sopenharmony_ci					      struct i40e_dma_mem *rsrc_pg)
1138c2ecf20Sopenharmony_ci{
1148c2ecf20Sopenharmony_ci	i40e_status ret_code = 0;
1158c2ecf20Sopenharmony_ci	struct i40e_hmc_pd_table *pd_table;
1168c2ecf20Sopenharmony_ci	struct i40e_hmc_pd_entry *pd_entry;
1178c2ecf20Sopenharmony_ci	struct i40e_dma_mem mem;
1188c2ecf20Sopenharmony_ci	struct i40e_dma_mem *page = &mem;
1198c2ecf20Sopenharmony_ci	u32 sd_idx, rel_pd_idx;
1208c2ecf20Sopenharmony_ci	u64 *pd_addr;
1218c2ecf20Sopenharmony_ci	u64 page_desc;
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	if (pd_index / I40E_HMC_PD_CNT_IN_SD >= hmc_info->sd_table.sd_cnt) {
1248c2ecf20Sopenharmony_ci		ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX;
1258c2ecf20Sopenharmony_ci		hw_dbg(hw, "i40e_add_pd_table_entry: bad pd_index\n");
1268c2ecf20Sopenharmony_ci		goto exit;
1278c2ecf20Sopenharmony_ci	}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	/* find corresponding sd */
1308c2ecf20Sopenharmony_ci	sd_idx = (pd_index / I40E_HMC_PD_CNT_IN_SD);
1318c2ecf20Sopenharmony_ci	if (I40E_SD_TYPE_PAGED !=
1328c2ecf20Sopenharmony_ci	    hmc_info->sd_table.sd_entry[sd_idx].entry_type)
1338c2ecf20Sopenharmony_ci		goto exit;
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	rel_pd_idx = (pd_index % I40E_HMC_PD_CNT_IN_SD);
1368c2ecf20Sopenharmony_ci	pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
1378c2ecf20Sopenharmony_ci	pd_entry = &pd_table->pd_entry[rel_pd_idx];
1388c2ecf20Sopenharmony_ci	if (!pd_entry->valid) {
1398c2ecf20Sopenharmony_ci		if (rsrc_pg) {
1408c2ecf20Sopenharmony_ci			pd_entry->rsrc_pg = true;
1418c2ecf20Sopenharmony_ci			page = rsrc_pg;
1428c2ecf20Sopenharmony_ci		} else {
1438c2ecf20Sopenharmony_ci			/* allocate a 4K backing page */
1448c2ecf20Sopenharmony_ci			ret_code = i40e_allocate_dma_mem(hw, page, i40e_mem_bp,
1458c2ecf20Sopenharmony_ci						I40E_HMC_PAGED_BP_SIZE,
1468c2ecf20Sopenharmony_ci						I40E_HMC_PD_BP_BUF_ALIGNMENT);
1478c2ecf20Sopenharmony_ci			if (ret_code)
1488c2ecf20Sopenharmony_ci				goto exit;
1498c2ecf20Sopenharmony_ci			pd_entry->rsrc_pg = false;
1508c2ecf20Sopenharmony_ci		}
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci		pd_entry->bp.addr = *page;
1538c2ecf20Sopenharmony_ci		pd_entry->bp.sd_pd_index = pd_index;
1548c2ecf20Sopenharmony_ci		pd_entry->bp.entry_type = I40E_SD_TYPE_PAGED;
1558c2ecf20Sopenharmony_ci		/* Set page address and valid bit */
1568c2ecf20Sopenharmony_ci		page_desc = page->pa | 0x1;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci		pd_addr = (u64 *)pd_table->pd_page_addr.va;
1598c2ecf20Sopenharmony_ci		pd_addr += rel_pd_idx;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci		/* Add the backing page physical address in the pd entry */
1628c2ecf20Sopenharmony_ci		memcpy(pd_addr, &page_desc, sizeof(u64));
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci		pd_entry->sd_index = sd_idx;
1658c2ecf20Sopenharmony_ci		pd_entry->valid = true;
1668c2ecf20Sopenharmony_ci		I40E_INC_PD_REFCNT(pd_table);
1678c2ecf20Sopenharmony_ci	}
1688c2ecf20Sopenharmony_ci	I40E_INC_BP_REFCNT(&pd_entry->bp);
1698c2ecf20Sopenharmony_ciexit:
1708c2ecf20Sopenharmony_ci	return ret_code;
1718c2ecf20Sopenharmony_ci}
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci/**
1748c2ecf20Sopenharmony_ci * i40e_remove_pd_bp - remove a backing page from a page descriptor
1758c2ecf20Sopenharmony_ci * @hw: pointer to our HW structure
1768c2ecf20Sopenharmony_ci * @hmc_info: pointer to the HMC configuration information structure
1778c2ecf20Sopenharmony_ci * @idx: the page index
1788c2ecf20Sopenharmony_ci *
1798c2ecf20Sopenharmony_ci * This function:
1808c2ecf20Sopenharmony_ci *	1. Marks the entry in pd tabe (for paged address mode) or in sd table
1818c2ecf20Sopenharmony_ci *	   (for direct address mode) invalid.
1828c2ecf20Sopenharmony_ci *	2. Write to register PMPDINV to invalidate the backing page in FV cache
1838c2ecf20Sopenharmony_ci *	3. Decrement the ref count for the pd _entry
1848c2ecf20Sopenharmony_ci * assumptions:
1858c2ecf20Sopenharmony_ci *	1. Caller can deallocate the memory used by backing storage after this
1868c2ecf20Sopenharmony_ci *	   function returns.
1878c2ecf20Sopenharmony_ci **/
1888c2ecf20Sopenharmony_cii40e_status i40e_remove_pd_bp(struct i40e_hw *hw,
1898c2ecf20Sopenharmony_ci					struct i40e_hmc_info *hmc_info,
1908c2ecf20Sopenharmony_ci					u32 idx)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	i40e_status ret_code = 0;
1938c2ecf20Sopenharmony_ci	struct i40e_hmc_pd_entry *pd_entry;
1948c2ecf20Sopenharmony_ci	struct i40e_hmc_pd_table *pd_table;
1958c2ecf20Sopenharmony_ci	struct i40e_hmc_sd_entry *sd_entry;
1968c2ecf20Sopenharmony_ci	u32 sd_idx, rel_pd_idx;
1978c2ecf20Sopenharmony_ci	u64 *pd_addr;
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	/* calculate index */
2008c2ecf20Sopenharmony_ci	sd_idx = idx / I40E_HMC_PD_CNT_IN_SD;
2018c2ecf20Sopenharmony_ci	rel_pd_idx = idx % I40E_HMC_PD_CNT_IN_SD;
2028c2ecf20Sopenharmony_ci	if (sd_idx >= hmc_info->sd_table.sd_cnt) {
2038c2ecf20Sopenharmony_ci		ret_code = I40E_ERR_INVALID_PAGE_DESC_INDEX;
2048c2ecf20Sopenharmony_ci		hw_dbg(hw, "i40e_remove_pd_bp: bad idx\n");
2058c2ecf20Sopenharmony_ci		goto exit;
2068c2ecf20Sopenharmony_ci	}
2078c2ecf20Sopenharmony_ci	sd_entry = &hmc_info->sd_table.sd_entry[sd_idx];
2088c2ecf20Sopenharmony_ci	if (I40E_SD_TYPE_PAGED != sd_entry->entry_type) {
2098c2ecf20Sopenharmony_ci		ret_code = I40E_ERR_INVALID_SD_TYPE;
2108c2ecf20Sopenharmony_ci		hw_dbg(hw, "i40e_remove_pd_bp: wrong sd_entry type\n");
2118c2ecf20Sopenharmony_ci		goto exit;
2128c2ecf20Sopenharmony_ci	}
2138c2ecf20Sopenharmony_ci	/* get the entry and decrease its ref counter */
2148c2ecf20Sopenharmony_ci	pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
2158c2ecf20Sopenharmony_ci	pd_entry = &pd_table->pd_entry[rel_pd_idx];
2168c2ecf20Sopenharmony_ci	I40E_DEC_BP_REFCNT(&pd_entry->bp);
2178c2ecf20Sopenharmony_ci	if (pd_entry->bp.ref_cnt)
2188c2ecf20Sopenharmony_ci		goto exit;
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	/* mark the entry invalid */
2218c2ecf20Sopenharmony_ci	pd_entry->valid = false;
2228c2ecf20Sopenharmony_ci	I40E_DEC_PD_REFCNT(pd_table);
2238c2ecf20Sopenharmony_ci	pd_addr = (u64 *)pd_table->pd_page_addr.va;
2248c2ecf20Sopenharmony_ci	pd_addr += rel_pd_idx;
2258c2ecf20Sopenharmony_ci	memset(pd_addr, 0, sizeof(u64));
2268c2ecf20Sopenharmony_ci	I40E_INVALIDATE_PF_HMC_PD(hw, sd_idx, idx);
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	/* free memory here */
2298c2ecf20Sopenharmony_ci	if (!pd_entry->rsrc_pg)
2308c2ecf20Sopenharmony_ci		ret_code = i40e_free_dma_mem(hw, &pd_entry->bp.addr);
2318c2ecf20Sopenharmony_ci	if (ret_code)
2328c2ecf20Sopenharmony_ci		goto exit;
2338c2ecf20Sopenharmony_ci	if (!pd_table->ref_cnt)
2348c2ecf20Sopenharmony_ci		i40e_free_virt_mem(hw, &pd_table->pd_entry_virt_mem);
2358c2ecf20Sopenharmony_ciexit:
2368c2ecf20Sopenharmony_ci	return ret_code;
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci/**
2408c2ecf20Sopenharmony_ci * i40e_prep_remove_sd_bp - Prepares to remove a backing page from a sd entry
2418c2ecf20Sopenharmony_ci * @hmc_info: pointer to the HMC configuration information structure
2428c2ecf20Sopenharmony_ci * @idx: the page index
2438c2ecf20Sopenharmony_ci **/
2448c2ecf20Sopenharmony_cii40e_status i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info,
2458c2ecf20Sopenharmony_ci					     u32 idx)
2468c2ecf20Sopenharmony_ci{
2478c2ecf20Sopenharmony_ci	i40e_status ret_code = 0;
2488c2ecf20Sopenharmony_ci	struct i40e_hmc_sd_entry *sd_entry;
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci	/* get the entry and decrease its ref counter */
2518c2ecf20Sopenharmony_ci	sd_entry = &hmc_info->sd_table.sd_entry[idx];
2528c2ecf20Sopenharmony_ci	I40E_DEC_BP_REFCNT(&sd_entry->u.bp);
2538c2ecf20Sopenharmony_ci	if (sd_entry->u.bp.ref_cnt) {
2548c2ecf20Sopenharmony_ci		ret_code = I40E_ERR_NOT_READY;
2558c2ecf20Sopenharmony_ci		goto exit;
2568c2ecf20Sopenharmony_ci	}
2578c2ecf20Sopenharmony_ci	I40E_DEC_SD_REFCNT(&hmc_info->sd_table);
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	/* mark the entry invalid */
2608c2ecf20Sopenharmony_ci	sd_entry->valid = false;
2618c2ecf20Sopenharmony_ciexit:
2628c2ecf20Sopenharmony_ci	return ret_code;
2638c2ecf20Sopenharmony_ci}
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci/**
2668c2ecf20Sopenharmony_ci * i40e_remove_sd_bp_new - Removes a backing page from a segment descriptor
2678c2ecf20Sopenharmony_ci * @hw: pointer to our hw struct
2688c2ecf20Sopenharmony_ci * @hmc_info: pointer to the HMC configuration information structure
2698c2ecf20Sopenharmony_ci * @idx: the page index
2708c2ecf20Sopenharmony_ci * @is_pf: used to distinguish between VF and PF
2718c2ecf20Sopenharmony_ci **/
2728c2ecf20Sopenharmony_cii40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw,
2738c2ecf20Sopenharmony_ci					    struct i40e_hmc_info *hmc_info,
2748c2ecf20Sopenharmony_ci					    u32 idx, bool is_pf)
2758c2ecf20Sopenharmony_ci{
2768c2ecf20Sopenharmony_ci	struct i40e_hmc_sd_entry *sd_entry;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci	if (!is_pf)
2798c2ecf20Sopenharmony_ci		return I40E_NOT_SUPPORTED;
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	/* get the entry and decrease its ref counter */
2828c2ecf20Sopenharmony_ci	sd_entry = &hmc_info->sd_table.sd_entry[idx];
2838c2ecf20Sopenharmony_ci	I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_DIRECT);
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci	return i40e_free_dma_mem(hw, &sd_entry->u.bp.addr);
2868c2ecf20Sopenharmony_ci}
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci/**
2898c2ecf20Sopenharmony_ci * i40e_prep_remove_pd_page - Prepares to remove a PD page from sd entry.
2908c2ecf20Sopenharmony_ci * @hmc_info: pointer to the HMC configuration information structure
2918c2ecf20Sopenharmony_ci * @idx: segment descriptor index to find the relevant page descriptor
2928c2ecf20Sopenharmony_ci **/
2938c2ecf20Sopenharmony_cii40e_status i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info,
2948c2ecf20Sopenharmony_ci					       u32 idx)
2958c2ecf20Sopenharmony_ci{
2968c2ecf20Sopenharmony_ci	i40e_status ret_code = 0;
2978c2ecf20Sopenharmony_ci	struct i40e_hmc_sd_entry *sd_entry;
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci	sd_entry = &hmc_info->sd_table.sd_entry[idx];
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	if (sd_entry->u.pd_table.ref_cnt) {
3028c2ecf20Sopenharmony_ci		ret_code = I40E_ERR_NOT_READY;
3038c2ecf20Sopenharmony_ci		goto exit;
3048c2ecf20Sopenharmony_ci	}
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	/* mark the entry invalid */
3078c2ecf20Sopenharmony_ci	sd_entry->valid = false;
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	I40E_DEC_SD_REFCNT(&hmc_info->sd_table);
3108c2ecf20Sopenharmony_ciexit:
3118c2ecf20Sopenharmony_ci	return ret_code;
3128c2ecf20Sopenharmony_ci}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci/**
3158c2ecf20Sopenharmony_ci * i40e_remove_pd_page_new - Removes a PD page from sd entry.
3168c2ecf20Sopenharmony_ci * @hw: pointer to our hw struct
3178c2ecf20Sopenharmony_ci * @hmc_info: pointer to the HMC configuration information structure
3188c2ecf20Sopenharmony_ci * @idx: segment descriptor index to find the relevant page descriptor
3198c2ecf20Sopenharmony_ci * @is_pf: used to distinguish between VF and PF
3208c2ecf20Sopenharmony_ci **/
3218c2ecf20Sopenharmony_cii40e_status i40e_remove_pd_page_new(struct i40e_hw *hw,
3228c2ecf20Sopenharmony_ci					      struct i40e_hmc_info *hmc_info,
3238c2ecf20Sopenharmony_ci					      u32 idx, bool is_pf)
3248c2ecf20Sopenharmony_ci{
3258c2ecf20Sopenharmony_ci	struct i40e_hmc_sd_entry *sd_entry;
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	if (!is_pf)
3288c2ecf20Sopenharmony_ci		return I40E_NOT_SUPPORTED;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	sd_entry = &hmc_info->sd_table.sd_entry[idx];
3318c2ecf20Sopenharmony_ci	I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_PAGED);
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	return  i40e_free_dma_mem(hw, &sd_entry->u.pd_table.pd_page_addr);
3348c2ecf20Sopenharmony_ci}
335