13126df22SRasesh Mody /* SPDX-License-Identifier: BSD-3-Clause 29adde217SRasesh Mody * Copyright (c) 2016 - 2018 Cavium Inc. 386a2265eSRasesh Mody * All rights reserved. 49adde217SRasesh Mody * www.cavium.com 586a2265eSRasesh Mody */ 686a2265eSRasesh Mody 786a2265eSRasesh Mody #ifndef __ECORE_SRIOV_API_H__ 886a2265eSRasesh Mody #define __ECORE_SRIOV_API_H__ 986a2265eSRasesh Mody 1022d07d93SRasesh Mody #include "common_hsi.h" 1186a2265eSRasesh Mody #include "ecore_status.h" 1286a2265eSRasesh Mody 1322d07d93SRasesh Mody #define ECORE_ETH_VF_NUM_MAC_FILTERS 1 1422d07d93SRasesh Mody #define ECORE_ETH_VF_NUM_VLAN_FILTERS 2 1586a2265eSRasesh Mody #define ECORE_VF_ARRAY_LENGTH (3) 1686a2265eSRasesh Mody 17*d459b043SManish Chopra #define ECORE_VF_ARRAY_GET_VFID(arr, vfid) \ 18*d459b043SManish Chopra (((arr)[(vfid) / 64]) & (1ULL << ((vfid) % 64))) 19*d459b043SManish Chopra 2086a2265eSRasesh Mody #define IS_VF(p_dev) ((p_dev)->b_is_vf) 2186a2265eSRasesh Mody #define IS_PF(p_dev) (!((p_dev)->b_is_vf)) 2286a2265eSRasesh Mody #ifdef CONFIG_ECORE_SRIOV 2322d07d93SRasesh Mody #define IS_PF_SRIOV(p_hwfn) (!!((p_hwfn)->p_dev->p_iov_info)) 2486a2265eSRasesh Mody #else 2586a2265eSRasesh Mody #define IS_PF_SRIOV(p_hwfn) (0) 2686a2265eSRasesh Mody #endif 2786a2265eSRasesh Mody #define IS_PF_SRIOV_ALLOC(p_hwfn) (!!((p_hwfn)->pf_iov_info)) 2886a2265eSRasesh Mody #define IS_PF_PDA(p_hwfn) 0 /* @@TBD Michalk */ 2986a2265eSRasesh Mody 3086a2265eSRasesh Mody /* @@@ TBD MichalK - what should this number be*/ 3186a2265eSRasesh Mody #define ECORE_MAX_VF_CHAINS_PER_PF 16 3286a2265eSRasesh Mody 3386a2265eSRasesh Mody /* vport update extended feature tlvs flags */ 3486a2265eSRasesh Mody enum ecore_iov_vport_update_flag { 3586a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_ACTIVATE = 0, 3686a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_VLAN_STRIP = 1, 3786a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_TX_SWITCH = 2, 3886a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_MCAST = 3, 3986a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_ACCEPT_PARAM = 4, 4086a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_RSS = 5, 4186a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_ACCEPT_ANY_VLAN = 6, 4286a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_SGE_TPA = 7, 4386a2265eSRasesh Mody ECORE_IOV_VP_UPDATE_MAX = 8, 4486a2265eSRasesh Mody }; 4586a2265eSRasesh Mody 4622d07d93SRasesh Mody /* PF to VF STATUS is part of vfpf-channel API 4722d07d93SRasesh Mody * and must be forward compatible 4822d07d93SRasesh Mody */ 4922d07d93SRasesh Mody enum ecore_iov_pf_to_vf_status { 5022d07d93SRasesh Mody PFVF_STATUS_WAITING = 0, 5122d07d93SRasesh Mody PFVF_STATUS_SUCCESS, 5222d07d93SRasesh Mody PFVF_STATUS_FAILURE, 5322d07d93SRasesh Mody PFVF_STATUS_NOT_SUPPORTED, 5422d07d93SRasesh Mody PFVF_STATUS_NO_RESOURCE, 5522d07d93SRasesh Mody PFVF_STATUS_FORCED, 5647b302d6SRasesh Mody PFVF_STATUS_MALICIOUS, 57f44ca48cSManish Chopra PFVF_STATUS_ACQUIRED, 5822d07d93SRasesh Mody }; 5922d07d93SRasesh Mody 6086a2265eSRasesh Mody struct ecore_mcp_link_params; 6186a2265eSRasesh Mody struct ecore_mcp_link_state; 6286a2265eSRasesh Mody struct ecore_mcp_link_capabilities; 6386a2265eSRasesh Mody 6486a2265eSRasesh Mody /* These defines are used by the hw-channel; should never change order */ 6586a2265eSRasesh Mody #define VFPF_ACQUIRE_OS_LINUX (0) 6686a2265eSRasesh Mody #define VFPF_ACQUIRE_OS_WINDOWS (1) 6786a2265eSRasesh Mody #define VFPF_ACQUIRE_OS_ESX (2) 6886a2265eSRasesh Mody #define VFPF_ACQUIRE_OS_SOLARIS (3) 6986a2265eSRasesh Mody #define VFPF_ACQUIRE_OS_LINUX_USERSPACE (4) 7086a2265eSRasesh Mody 7186a2265eSRasesh Mody struct ecore_vf_acquire_sw_info { 7286a2265eSRasesh Mody u32 driver_version; 7386a2265eSRasesh Mody u8 os_type; 749455b556SRasesh Mody 759455b556SRasesh Mody /* We have several close releases that all use ~same FW with different 769455b556SRasesh Mody * versions [making it incompatible as the versioning scheme is still 779455b556SRasesh Mody * tied directly to FW version], allow to override the checking. Only 789455b556SRasesh Mody * those versions would actually support this feature [so it would not 799455b556SRasesh Mody * break forward compatibility with newer HV drivers that are no longer 809455b556SRasesh Mody * suited]. 819455b556SRasesh Mody */ 8286a2265eSRasesh Mody bool override_fw_version; 8386a2265eSRasesh Mody }; 8486a2265eSRasesh Mody 8586a2265eSRasesh Mody struct ecore_public_vf_info { 8686a2265eSRasesh Mody /* These copies will later be reflected in the bulletin board, 8786a2265eSRasesh Mody * but this copy should be newer. 8886a2265eSRasesh Mody */ 8986a2265eSRasesh Mody u8 forced_mac[ETH_ALEN]; 9086a2265eSRasesh Mody u16 forced_vlan; 912cf7a0faSShahed Shaikh 922cf7a0faSShahed Shaikh /* Trusted VFs can configure promiscuous mode and 932cf7a0faSShahed Shaikh * set MAC address inspite PF has set forced MAC. 942cf7a0faSShahed Shaikh * Also store shadow promisc configuration if needed. 952cf7a0faSShahed Shaikh */ 962cf7a0faSShahed Shaikh bool is_trusted_configured; 972cf7a0faSShahed Shaikh bool is_trusted_request; 9886a2265eSRasesh Mody }; 9986a2265eSRasesh Mody 100a55e422eSRasesh Mody struct ecore_iov_vf_init_params { 101a55e422eSRasesh Mody u16 rel_vf_id; 102a55e422eSRasesh Mody 103a55e422eSRasesh Mody /* Number of requested Queues; Currently, don't support different 104a55e422eSRasesh Mody * number of Rx/Tx queues. 105a55e422eSRasesh Mody */ 106a55e422eSRasesh Mody /* TODO - remove this limitation */ 107a55e422eSRasesh Mody u16 num_queues; 108a55e422eSRasesh Mody 109a55e422eSRasesh Mody /* Allow the client to choose which qzones to use for Rx/Tx, 110a55e422eSRasesh Mody * and which queue_base to use for Tx queues on a per-queue basis. 111a55e422eSRasesh Mody * Notice values should be relative to the PF resources. 112a55e422eSRasesh Mody */ 113a55e422eSRasesh Mody u16 req_rx_queue[ECORE_MAX_VF_CHAINS_PER_PF]; 114a55e422eSRasesh Mody u16 req_tx_queue[ECORE_MAX_VF_CHAINS_PER_PF]; 11535da9596SRasesh Mody 11635da9596SRasesh Mody u8 vport_id; 11735da9596SRasesh Mody 11835da9596SRasesh Mody /* Should be set in case RSS is going to be used for VF */ 11935da9596SRasesh Mody u8 rss_eng_id; 120a55e422eSRasesh Mody }; 121a55e422eSRasesh Mody 12286a2265eSRasesh Mody #ifdef CONFIG_ECORE_SW_CHANNEL 12386a2265eSRasesh Mody /* This is SW channel related only... */ 12486a2265eSRasesh Mody enum mbx_state { 12586a2265eSRasesh Mody VF_PF_UNKNOWN_STATE = 0, 12686a2265eSRasesh Mody VF_PF_WAIT_FOR_START_REQUEST = 1, 12786a2265eSRasesh Mody VF_PF_WAIT_FOR_NEXT_CHUNK_OF_REQUEST = 2, 12886a2265eSRasesh Mody VF_PF_REQUEST_IN_PROCESSING = 3, 12986a2265eSRasesh Mody VF_PF_RESPONSE_READY = 4, 13086a2265eSRasesh Mody }; 13186a2265eSRasesh Mody 13286a2265eSRasesh Mody struct ecore_iov_sw_mbx { 13386a2265eSRasesh Mody enum mbx_state mbx_state; 13486a2265eSRasesh Mody 13586a2265eSRasesh Mody u32 request_size; 13686a2265eSRasesh Mody u32 request_offset; 13786a2265eSRasesh Mody 13886a2265eSRasesh Mody u32 response_size; 13986a2265eSRasesh Mody u32 response_offset; 14086a2265eSRasesh Mody }; 14186a2265eSRasesh Mody 14286a2265eSRasesh Mody /** 14386a2265eSRasesh Mody * @brief Get the vf sw mailbox params 14486a2265eSRasesh Mody * 14586a2265eSRasesh Mody * @param p_hwfn 14686a2265eSRasesh Mody * @param rel_vf_id 14786a2265eSRasesh Mody * 14886a2265eSRasesh Mody * @return struct ecore_iov_sw_mbx* 14986a2265eSRasesh Mody */ 15022d07d93SRasesh Mody struct ecore_iov_sw_mbx* 15122d07d93SRasesh Mody ecore_iov_get_vf_sw_mbx(struct ecore_hwfn *p_hwfn, 15286a2265eSRasesh Mody u16 rel_vf_id); 15386a2265eSRasesh Mody #endif 15486a2265eSRasesh Mody 15522d07d93SRasesh Mody /* This struct is part of ecore_dev and contains data relevant to all hwfns; 15622d07d93SRasesh Mody * Initialized only if SR-IOV cpabability is exposed in PCIe config space. 15722d07d93SRasesh Mody */ 15822d07d93SRasesh Mody struct ecore_hw_sriov_info { 15922d07d93SRasesh Mody /* standard SRIOV capability fields, mostly for debugging */ 16022d07d93SRasesh Mody int pos; /* capability position */ 16122d07d93SRasesh Mody int nres; /* number of resources */ 16222d07d93SRasesh Mody u32 cap; /* SR-IOV Capabilities */ 16322d07d93SRasesh Mody u16 ctrl; /* SR-IOV Control */ 16422d07d93SRasesh Mody u16 total_vfs; /* total VFs associated with the PF */ 16522d07d93SRasesh Mody u16 num_vfs; /* number of vfs that have been started */ 16622d07d93SRasesh Mody u16 initial_vfs; /* initial VFs associated with the PF */ 16722d07d93SRasesh Mody u16 nr_virtfn; /* number of VFs available */ 16822d07d93SRasesh Mody u16 offset; /* first VF Routing ID offset */ 16922d07d93SRasesh Mody u16 stride; /* following VF stride */ 17022d07d93SRasesh Mody u16 vf_device_id; /* VF device id */ 17122d07d93SRasesh Mody u32 pgsz; /* page size for BAR alignment */ 17222d07d93SRasesh Mody u8 link; /* Function Dependency Link */ 17322d07d93SRasesh Mody 17422d07d93SRasesh Mody u32 first_vf_in_pf; 17522d07d93SRasesh Mody }; 17622d07d93SRasesh Mody 17786a2265eSRasesh Mody #ifdef CONFIG_ECORE_SRIOV 17822d07d93SRasesh Mody #ifndef LINUX_REMOVE 17986a2265eSRasesh Mody /** 18086a2265eSRasesh Mody * @brief mark/clear all VFs before/after an incoming PCIe sriov 18186a2265eSRasesh Mody * disable. 18286a2265eSRasesh Mody * 18322d07d93SRasesh Mody * @param p_dev 18486a2265eSRasesh Mody * @param to_disable 18586a2265eSRasesh Mody */ 18622d07d93SRasesh Mody void ecore_iov_set_vfs_to_disable(struct ecore_dev *p_dev, 18722d07d93SRasesh Mody u8 to_disable); 18886a2265eSRasesh Mody 18986a2265eSRasesh Mody /** 19022d07d93SRasesh Mody * @brief mark/clear chosen VF before/after an incoming PCIe 19186a2265eSRasesh Mody * sriov disable. 19286a2265eSRasesh Mody * 19322d07d93SRasesh Mody * @param p_dev 19422d07d93SRasesh Mody * @param rel_vf_id 19586a2265eSRasesh Mody * @param to_disable 19686a2265eSRasesh Mody */ 19722d07d93SRasesh Mody void ecore_iov_set_vf_to_disable(struct ecore_dev *p_dev, 19822d07d93SRasesh Mody u16 rel_vf_id, 19922d07d93SRasesh Mody u8 to_disable); 20086a2265eSRasesh Mody 20186a2265eSRasesh Mody /** 20286a2265eSRasesh Mody * @brief ecore_iov_init_hw_for_vf - initialize the HW for 20386a2265eSRasesh Mody * enabling access of a VF. Also includes preparing the 20486a2265eSRasesh Mody * IGU for VF access. This needs to be called AFTER hw is 20586a2265eSRasesh Mody * initialized and BEFORE VF is loaded inside the VM. 20686a2265eSRasesh Mody * 20786a2265eSRasesh Mody * @param p_hwfn 20886a2265eSRasesh Mody * @param p_ptt 209a55e422eSRasesh Mody * @param p_params 21086a2265eSRasesh Mody * 21186a2265eSRasesh Mody * @return enum _ecore_status_t 21286a2265eSRasesh Mody */ 21386a2265eSRasesh Mody enum _ecore_status_t ecore_iov_init_hw_for_vf(struct ecore_hwfn *p_hwfn, 21486a2265eSRasesh Mody struct ecore_ptt *p_ptt, 215a55e422eSRasesh Mody struct ecore_iov_vf_init_params 216a55e422eSRasesh Mody *p_params); 21786a2265eSRasesh Mody 21886a2265eSRasesh Mody /** 21986a2265eSRasesh Mody * @brief ecore_iov_process_mbx_req - process a request received 22086a2265eSRasesh Mody * from the VF 22186a2265eSRasesh Mody * 22286a2265eSRasesh Mody * @param p_hwfn 22386a2265eSRasesh Mody * @param p_ptt 22486a2265eSRasesh Mody * @param vfid 22586a2265eSRasesh Mody */ 22686a2265eSRasesh Mody void ecore_iov_process_mbx_req(struct ecore_hwfn *p_hwfn, 2279455b556SRasesh Mody struct ecore_ptt *p_ptt, 2289455b556SRasesh Mody int vfid); 22986a2265eSRasesh Mody 23086a2265eSRasesh Mody /** 23186a2265eSRasesh Mody * @brief ecore_iov_release_hw_for_vf - called once upper layer 23286a2265eSRasesh Mody * knows VF is done with - can release any resources 23386a2265eSRasesh Mody * allocated for VF at this point. this must be done once 23486a2265eSRasesh Mody * we know VF is no longer loaded in VM. 23586a2265eSRasesh Mody * 23686a2265eSRasesh Mody * @param p_hwfn 23786a2265eSRasesh Mody * @param p_ptt 23886a2265eSRasesh Mody * @param rel_vf_id 23986a2265eSRasesh Mody * 24086a2265eSRasesh Mody * @return enum _ecore_status_t 24186a2265eSRasesh Mody */ 24286a2265eSRasesh Mody enum _ecore_status_t ecore_iov_release_hw_for_vf(struct ecore_hwfn *p_hwfn, 24386a2265eSRasesh Mody struct ecore_ptt *p_ptt, 24486a2265eSRasesh Mody u16 rel_vf_id); 24586a2265eSRasesh Mody 24686a2265eSRasesh Mody /** 24786a2265eSRasesh Mody * @brief ecore_iov_set_vf_ctx - set a context for a given VF 24886a2265eSRasesh Mody * 24986a2265eSRasesh Mody * @param p_hwfn 25086a2265eSRasesh Mody * @param vf_id 25186a2265eSRasesh Mody * @param ctx 25286a2265eSRasesh Mody * 25386a2265eSRasesh Mody * @return enum _ecore_status_t 25486a2265eSRasesh Mody */ 25586a2265eSRasesh Mody enum _ecore_status_t ecore_iov_set_vf_ctx(struct ecore_hwfn *p_hwfn, 25622d07d93SRasesh Mody u16 vf_id, 25722d07d93SRasesh Mody void *ctx); 25886a2265eSRasesh Mody 25986a2265eSRasesh Mody /** 26086a2265eSRasesh Mody * @brief FLR cleanup for all VFs 26186a2265eSRasesh Mody * 26286a2265eSRasesh Mody * @param p_hwfn 26386a2265eSRasesh Mody * @param p_ptt 26486a2265eSRasesh Mody * 26586a2265eSRasesh Mody * @return enum _ecore_status_t 26686a2265eSRasesh Mody */ 26786a2265eSRasesh Mody enum _ecore_status_t ecore_iov_vf_flr_cleanup(struct ecore_hwfn *p_hwfn, 26886a2265eSRasesh Mody struct ecore_ptt *p_ptt); 26986a2265eSRasesh Mody 27086a2265eSRasesh Mody /** 27186a2265eSRasesh Mody * @brief FLR cleanup for single VF 27286a2265eSRasesh Mody * 27386a2265eSRasesh Mody * @param p_hwfn 27486a2265eSRasesh Mody * @param p_ptt 27586a2265eSRasesh Mody * @param rel_vf_id 27686a2265eSRasesh Mody * 27786a2265eSRasesh Mody * @return enum _ecore_status_t 27886a2265eSRasesh Mody */ 27986a2265eSRasesh Mody enum _ecore_status_t 28086a2265eSRasesh Mody ecore_iov_single_vf_flr_cleanup(struct ecore_hwfn *p_hwfn, 2819455b556SRasesh Mody struct ecore_ptt *p_ptt, 2829455b556SRasesh Mody u16 rel_vf_id); 28386a2265eSRasesh Mody 28486a2265eSRasesh Mody /** 28586a2265eSRasesh Mody * @brief Update the bulletin with link information. Notice this does NOT 28686a2265eSRasesh Mody * send a bulletin update, only updates the PF's bulletin. 28786a2265eSRasesh Mody * 28886a2265eSRasesh Mody * @param p_hwfn 28986a2265eSRasesh Mody * @param p_vf 29086a2265eSRasesh Mody * @param params - the link params to use for the VF link configuration 29186a2265eSRasesh Mody * @param link - the link output to use for the VF link configuration 29286a2265eSRasesh Mody * @param p_caps - the link default capabilities. 29386a2265eSRasesh Mody */ 29486a2265eSRasesh Mody void ecore_iov_set_link(struct ecore_hwfn *p_hwfn, 29586a2265eSRasesh Mody u16 vfid, 29686a2265eSRasesh Mody struct ecore_mcp_link_params *params, 29786a2265eSRasesh Mody struct ecore_mcp_link_state *link, 29886a2265eSRasesh Mody struct ecore_mcp_link_capabilities *p_caps); 29986a2265eSRasesh Mody 30086a2265eSRasesh Mody /** 30186a2265eSRasesh Mody * @brief Returns link information as perceived by VF. 30286a2265eSRasesh Mody * 30386a2265eSRasesh Mody * @param p_hwfn 30486a2265eSRasesh Mody * @param p_vf 30586a2265eSRasesh Mody * @param p_params - the link params visible to vf. 30686a2265eSRasesh Mody * @param p_link - the link state visible to vf. 30786a2265eSRasesh Mody * @param p_caps - the link default capabilities visible to vf. 30886a2265eSRasesh Mody */ 30986a2265eSRasesh Mody void ecore_iov_get_link(struct ecore_hwfn *p_hwfn, 31086a2265eSRasesh Mody u16 vfid, 31186a2265eSRasesh Mody struct ecore_mcp_link_params *params, 31286a2265eSRasesh Mody struct ecore_mcp_link_state *link, 31386a2265eSRasesh Mody struct ecore_mcp_link_capabilities *p_caps); 31486a2265eSRasesh Mody 31586a2265eSRasesh Mody /** 31686a2265eSRasesh Mody * @brief return if the VF is pending FLR 31786a2265eSRasesh Mody * 31886a2265eSRasesh Mody * @param p_hwfn 31986a2265eSRasesh Mody * @param rel_vf_id 32086a2265eSRasesh Mody * 32186a2265eSRasesh Mody * @return bool 32286a2265eSRasesh Mody */ 3239455b556SRasesh Mody bool ecore_iov_is_vf_pending_flr(struct ecore_hwfn *p_hwfn, 3249455b556SRasesh Mody u16 rel_vf_id); 32586a2265eSRasesh Mody 32686a2265eSRasesh Mody /** 32786a2265eSRasesh Mody * @brief Check if given VF ID @vfid is valid 32886a2265eSRasesh Mody * w.r.t. @b_enabled_only value 32986a2265eSRasesh Mody * if b_enabled_only = true - only enabled VF id is valid 33086a2265eSRasesh Mody * else any VF id less than max_vfs is valid 33186a2265eSRasesh Mody * 33286a2265eSRasesh Mody * @param p_hwfn 33386a2265eSRasesh Mody * @param rel_vf_id - Relative VF ID 33486a2265eSRasesh Mody * @param b_enabled_only - consider only enabled VF 33547b302d6SRasesh Mody * @param b_non_malicious - true iff we want to validate vf isn't malicious. 33686a2265eSRasesh Mody * 33786a2265eSRasesh Mody * @return bool - true for valid VF ID 33886a2265eSRasesh Mody */ 33986a2265eSRasesh Mody bool ecore_iov_is_valid_vfid(struct ecore_hwfn *p_hwfn, 3409455b556SRasesh Mody int rel_vf_id, 34147b302d6SRasesh Mody bool b_enabled_only, bool b_non_malicious); 34286a2265eSRasesh Mody 34386a2265eSRasesh Mody /** 34486a2265eSRasesh Mody * @brief Get VF's public info structure 34586a2265eSRasesh Mody * 34686a2265eSRasesh Mody * @param p_hwfn 34786a2265eSRasesh Mody * @param vfid - Relative VF ID 34886a2265eSRasesh Mody * @param b_enabled_only - false if want to access even if vf is disabled 34986a2265eSRasesh Mody * 35086a2265eSRasesh Mody * @return struct ecore_public_vf_info * 35186a2265eSRasesh Mody */ 3529455b556SRasesh Mody struct ecore_public_vf_info* 3539455b556SRasesh Mody ecore_iov_get_public_vf_info(struct ecore_hwfn *p_hwfn, 3549455b556SRasesh Mody u16 vfid, bool b_enabled_only); 35586a2265eSRasesh Mody 35686a2265eSRasesh Mody /** 3574be18885SRasesh Mody * @brief fills a bitmask of all VFs which have pending unhandled 3584be18885SRasesh Mody * messages. 35986a2265eSRasesh Mody * 36086a2265eSRasesh Mody * @param p_hwfn 36186a2265eSRasesh Mody */ 3624be18885SRasesh Mody void ecore_iov_pf_get_pending_events(struct ecore_hwfn *p_hwfn, 36386a2265eSRasesh Mody u64 *events); 36486a2265eSRasesh Mody 36586a2265eSRasesh Mody /** 36686a2265eSRasesh Mody * @brief Copy VF's message to PF's buffer 36786a2265eSRasesh Mody * 36886a2265eSRasesh Mody * @param p_hwfn 36986a2265eSRasesh Mody * @param ptt 37086a2265eSRasesh Mody * @param vfid 37186a2265eSRasesh Mody * 37286a2265eSRasesh Mody * @return enum _ecore_status_t 37386a2265eSRasesh Mody */ 37486a2265eSRasesh Mody enum _ecore_status_t ecore_iov_copy_vf_msg(struct ecore_hwfn *p_hwfn, 3759455b556SRasesh Mody struct ecore_ptt *ptt, 3769455b556SRasesh Mody int vfid); 37786a2265eSRasesh Mody /** 37886a2265eSRasesh Mody * @brief Set forced MAC address in PFs copy of bulletin board 37986a2265eSRasesh Mody * and configures FW/HW to support the configuration. 38086a2265eSRasesh Mody * 38186a2265eSRasesh Mody * @param p_hwfn 38286a2265eSRasesh Mody * @param mac 38386a2265eSRasesh Mody * @param vfid 38486a2265eSRasesh Mody */ 38586a2265eSRasesh Mody void ecore_iov_bulletin_set_forced_mac(struct ecore_hwfn *p_hwfn, 38686a2265eSRasesh Mody u8 *mac, int vfid); 38786a2265eSRasesh Mody 38886a2265eSRasesh Mody /** 38986a2265eSRasesh Mody * @brief Set MAC address in PFs copy of bulletin board without 39086a2265eSRasesh Mody * configuring FW/HW. 39186a2265eSRasesh Mody * 39286a2265eSRasesh Mody * @param p_hwfn 39386a2265eSRasesh Mody * @param mac 39486a2265eSRasesh Mody * @param vfid 39586a2265eSRasesh Mody */ 39686a2265eSRasesh Mody enum _ecore_status_t ecore_iov_bulletin_set_mac(struct ecore_hwfn *p_hwfn, 39786a2265eSRasesh Mody u8 *mac, int vfid); 39886a2265eSRasesh Mody 39986a2265eSRasesh Mody /** 40086a2265eSRasesh Mody * @brief Set default behaviour of VF in case no vlans are configured for it 40186a2265eSRasesh Mody * whether to accept only untagged traffic or all. 40286a2265eSRasesh Mody * Must be called prior to the VF vport-start. 40386a2265eSRasesh Mody * 40486a2265eSRasesh Mody * @param p_hwfn 40586a2265eSRasesh Mody * @param b_untagged_only 40686a2265eSRasesh Mody * @param vfid 40786a2265eSRasesh Mody * 40886a2265eSRasesh Mody * @return ECORE_SUCCESS if configuration would stick. 40986a2265eSRasesh Mody */ 41086a2265eSRasesh Mody enum _ecore_status_t 41186a2265eSRasesh Mody ecore_iov_bulletin_set_forced_untagged_default(struct ecore_hwfn *p_hwfn, 4129455b556SRasesh Mody bool b_untagged_only, 4139455b556SRasesh Mody int vfid); 4149455b556SRasesh Mody 41586a2265eSRasesh Mody /** 41686a2265eSRasesh Mody * @brief Get VFs opaque fid. 41786a2265eSRasesh Mody * 41886a2265eSRasesh Mody * @param p_hwfn 41986a2265eSRasesh Mody * @param vfid 42086a2265eSRasesh Mody * @param opaque_fid 42186a2265eSRasesh Mody */ 42286a2265eSRasesh Mody void ecore_iov_get_vfs_opaque_fid(struct ecore_hwfn *p_hwfn, int vfid, 42386a2265eSRasesh Mody u16 *opaque_fid); 42486a2265eSRasesh Mody 42586a2265eSRasesh Mody /** 42622d07d93SRasesh Mody * @brief Set forced VLAN [pvid] in PFs copy of bulletin board 42722d07d93SRasesh Mody * and configures FW/HW to support the configuration. 42822d07d93SRasesh Mody * Setting of pvid 0 would clear the feature. 42922d07d93SRasesh Mody * @param p_hwfn 43022d07d93SRasesh Mody * @param pvid 43122d07d93SRasesh Mody * @param vfid 43222d07d93SRasesh Mody */ 43322d07d93SRasesh Mody void ecore_iov_bulletin_set_forced_vlan(struct ecore_hwfn *p_hwfn, 43422d07d93SRasesh Mody u16 pvid, int vfid); 43522d07d93SRasesh Mody 43622d07d93SRasesh Mody /** 43786a2265eSRasesh Mody * @brief Check if VF has VPORT instance. This can be used 43886a2265eSRasesh Mody * to check if VPORT is active. 43986a2265eSRasesh Mody * 44086a2265eSRasesh Mody * @param p_hwfn 44186a2265eSRasesh Mody */ 44286a2265eSRasesh Mody bool ecore_iov_vf_has_vport_instance(struct ecore_hwfn *p_hwfn, int vfid); 44386a2265eSRasesh Mody 44486a2265eSRasesh Mody /** 44586a2265eSRasesh Mody * @brief PF posts the bulletin to the VF 44686a2265eSRasesh Mody * 44786a2265eSRasesh Mody * @param p_hwfn 44886a2265eSRasesh Mody * @param p_vf 44986a2265eSRasesh Mody * @param p_ptt 45086a2265eSRasesh Mody * 45186a2265eSRasesh Mody * @return enum _ecore_status_t 45286a2265eSRasesh Mody */ 45386a2265eSRasesh Mody enum _ecore_status_t ecore_iov_post_vf_bulletin(struct ecore_hwfn *p_hwfn, 45486a2265eSRasesh Mody int vfid, 45586a2265eSRasesh Mody struct ecore_ptt *p_ptt); 45686a2265eSRasesh Mody 45786a2265eSRasesh Mody /** 45886a2265eSRasesh Mody * @brief Check if given VF (@vfid) is marked as stopped 45986a2265eSRasesh Mody * 46086a2265eSRasesh Mody * @param p_hwfn 46186a2265eSRasesh Mody * @param vfid 46286a2265eSRasesh Mody * 46386a2265eSRasesh Mody * @return bool : true if stopped 46486a2265eSRasesh Mody */ 46586a2265eSRasesh Mody bool ecore_iov_is_vf_stopped(struct ecore_hwfn *p_hwfn, int vfid); 46686a2265eSRasesh Mody 46786a2265eSRasesh Mody /** 46886a2265eSRasesh Mody * @brief Configure VF anti spoofing 46986a2265eSRasesh Mody * 47086a2265eSRasesh Mody * @param p_hwfn 47186a2265eSRasesh Mody * @param vfid 47286a2265eSRasesh Mody * @param val - spoofchk value - true/false 47386a2265eSRasesh Mody * 47486a2265eSRasesh Mody * @return enum _ecore_status_t 47586a2265eSRasesh Mody */ 47686a2265eSRasesh Mody enum _ecore_status_t ecore_iov_spoofchk_set(struct ecore_hwfn *p_hwfn, 47786a2265eSRasesh Mody int vfid, bool val); 47886a2265eSRasesh Mody 47986a2265eSRasesh Mody /** 48086a2265eSRasesh Mody * @brief Get VF's configured spoof value. 48186a2265eSRasesh Mody * 48286a2265eSRasesh Mody * @param p_hwfn 48386a2265eSRasesh Mody * @param vfid 48486a2265eSRasesh Mody * 48586a2265eSRasesh Mody * @return bool - spoofchk value - true/false 48686a2265eSRasesh Mody */ 48786a2265eSRasesh Mody bool ecore_iov_spoofchk_get(struct ecore_hwfn *p_hwfn, int vfid); 48886a2265eSRasesh Mody 48986a2265eSRasesh Mody /** 49086a2265eSRasesh Mody * @brief Check for SRIOV sanity by PF. 49186a2265eSRasesh Mody * 49286a2265eSRasesh Mody * @param p_hwfn 49386a2265eSRasesh Mody * @param vfid 49486a2265eSRasesh Mody * 49586a2265eSRasesh Mody * @return bool - true if sanity checks passes, else false 49686a2265eSRasesh Mody */ 49786a2265eSRasesh Mody bool ecore_iov_pf_sanity_check(struct ecore_hwfn *p_hwfn, int vfid); 49886a2265eSRasesh Mody 49986a2265eSRasesh Mody /** 50086a2265eSRasesh Mody * @brief Get the num of VF chains. 50186a2265eSRasesh Mody * 50286a2265eSRasesh Mody * @param p_hwfn 50386a2265eSRasesh Mody * 50486a2265eSRasesh Mody * @return u8 50586a2265eSRasesh Mody */ 50686a2265eSRasesh Mody u8 ecore_iov_vf_chains_per_pf(struct ecore_hwfn *p_hwfn); 50786a2265eSRasesh Mody 50886a2265eSRasesh Mody /** 50986a2265eSRasesh Mody * @brief Get vf request mailbox params 51086a2265eSRasesh Mody * 51186a2265eSRasesh Mody * @param p_hwfn 51286a2265eSRasesh Mody * @param rel_vf_id 51386a2265eSRasesh Mody * @param pp_req_virt_addr 51486a2265eSRasesh Mody * @param p_req_virt_size 51586a2265eSRasesh Mody */ 51686a2265eSRasesh Mody void ecore_iov_get_vf_req_virt_mbx_params(struct ecore_hwfn *p_hwfn, 51786a2265eSRasesh Mody u16 rel_vf_id, 51886a2265eSRasesh Mody void **pp_req_virt_addr, 51986a2265eSRasesh Mody u16 *p_req_virt_size); 52086a2265eSRasesh Mody 52186a2265eSRasesh Mody /** 52286a2265eSRasesh Mody * @brief Get vf mailbox params 52386a2265eSRasesh Mody * 52486a2265eSRasesh Mody * @param p_hwfn 52586a2265eSRasesh Mody * @param rel_vf_id 52686a2265eSRasesh Mody * @param pp_reply_virt_addr 52786a2265eSRasesh Mody * @param p_reply_virt_size 52886a2265eSRasesh Mody */ 52986a2265eSRasesh Mody void ecore_iov_get_vf_reply_virt_mbx_params(struct ecore_hwfn *p_hwfn, 53086a2265eSRasesh Mody u16 rel_vf_id, 53186a2265eSRasesh Mody void **pp_reply_virt_addr, 53286a2265eSRasesh Mody u16 *p_reply_virt_size); 53386a2265eSRasesh Mody 53486a2265eSRasesh Mody /** 53586a2265eSRasesh Mody * @brief Validate if the given length is a valid vfpf message 53686a2265eSRasesh Mody * length 53786a2265eSRasesh Mody * 53886a2265eSRasesh Mody * @param length 53986a2265eSRasesh Mody * 54086a2265eSRasesh Mody * @return bool 54186a2265eSRasesh Mody */ 54286a2265eSRasesh Mody bool ecore_iov_is_valid_vfpf_msg_length(u32 length); 54386a2265eSRasesh Mody 54486a2265eSRasesh Mody /** 54586a2265eSRasesh Mody * @brief Return the max pfvf message length 54686a2265eSRasesh Mody * 54786a2265eSRasesh Mody * @return u32 54886a2265eSRasesh Mody */ 54986a2265eSRasesh Mody u32 ecore_iov_pfvf_msg_length(void); 55086a2265eSRasesh Mody 55186a2265eSRasesh Mody /** 552d5050d4dSRasesh Mody * @brief Returns MAC address if one is configured 553d5050d4dSRasesh Mody * 554d5050d4dSRasesh Mody * @parm p_hwfn 555d5050d4dSRasesh Mody * @parm rel_vf_id 556d5050d4dSRasesh Mody * 557d5050d4dSRasesh Mody * @return OSAL_NULL if mac isn't set; Otherwise, returns MAC. 558d5050d4dSRasesh Mody */ 559d5050d4dSRasesh Mody u8 *ecore_iov_bulletin_get_mac(struct ecore_hwfn *p_hwfn, 560d5050d4dSRasesh Mody u16 rel_vf_id); 561d5050d4dSRasesh Mody 562d5050d4dSRasesh Mody /** 56386a2265eSRasesh Mody * @brief Returns forced MAC address if one is configured 56486a2265eSRasesh Mody * 56586a2265eSRasesh Mody * @parm p_hwfn 56686a2265eSRasesh Mody * @parm rel_vf_id 56786a2265eSRasesh Mody * 56886a2265eSRasesh Mody * @return OSAL_NULL if mac isn't forced; Otherwise, returns MAC. 56986a2265eSRasesh Mody */ 5709455b556SRasesh Mody u8 *ecore_iov_bulletin_get_forced_mac(struct ecore_hwfn *p_hwfn, 5719455b556SRasesh Mody u16 rel_vf_id); 57286a2265eSRasesh Mody 57386a2265eSRasesh Mody /** 57486a2265eSRasesh Mody * @brief Returns pvid if one is configured 57586a2265eSRasesh Mody * 57686a2265eSRasesh Mody * @parm p_hwfn 57786a2265eSRasesh Mody * @parm rel_vf_id 57886a2265eSRasesh Mody * 57986a2265eSRasesh Mody * @return 0 if no pvid is configured, otherwise the pvid. 58086a2265eSRasesh Mody */ 58186a2265eSRasesh Mody u16 ecore_iov_bulletin_get_forced_vlan(struct ecore_hwfn *p_hwfn, 58286a2265eSRasesh Mody u16 rel_vf_id); 58386a2265eSRasesh Mody /** 58486a2265eSRasesh Mody * @brief Configure VFs tx rate 58586a2265eSRasesh Mody * 58686a2265eSRasesh Mody * @param p_hwfn 58786a2265eSRasesh Mody * @param p_ptt 58886a2265eSRasesh Mody * @param vfid 58986a2265eSRasesh Mody * @param val - tx rate value in Mb/sec. 59086a2265eSRasesh Mody * 59186a2265eSRasesh Mody * @return enum _ecore_status_t 59286a2265eSRasesh Mody */ 59386a2265eSRasesh Mody enum _ecore_status_t ecore_iov_configure_tx_rate(struct ecore_hwfn *p_hwfn, 59486a2265eSRasesh Mody struct ecore_ptt *p_ptt, 59586a2265eSRasesh Mody int vfid, int val); 59686a2265eSRasesh Mody 59786a2265eSRasesh Mody /** 59886a2265eSRasesh Mody * @brief - Retrieves the statistics associated with a VF 59986a2265eSRasesh Mody * 60086a2265eSRasesh Mody * @param p_hwfn 60186a2265eSRasesh Mody * @param p_ptt 60286a2265eSRasesh Mody * @param vfid 60386a2265eSRasesh Mody * @param p_stats - this will be filled with the VF statistics 60486a2265eSRasesh Mody * 60586a2265eSRasesh Mody * @return ECORE_SUCCESS iff statistics were retrieved. Error otherwise. 60686a2265eSRasesh Mody */ 60786a2265eSRasesh Mody enum _ecore_status_t ecore_iov_get_vf_stats(struct ecore_hwfn *p_hwfn, 60886a2265eSRasesh Mody struct ecore_ptt *p_ptt, 60986a2265eSRasesh Mody int vfid, 61086a2265eSRasesh Mody struct ecore_eth_stats *p_stats); 61186a2265eSRasesh Mody 61286a2265eSRasesh Mody /** 61386a2265eSRasesh Mody * @brief - Retrieves num of rxqs chains 61486a2265eSRasesh Mody * 61586a2265eSRasesh Mody * @param p_hwfn 61686a2265eSRasesh Mody * @param rel_vf_id 61786a2265eSRasesh Mody * 61886a2265eSRasesh Mody * @return num of rxqs chains. 61986a2265eSRasesh Mody */ 6209455b556SRasesh Mody u8 ecore_iov_get_vf_num_rxqs(struct ecore_hwfn *p_hwfn, 6219455b556SRasesh Mody u16 rel_vf_id); 62286a2265eSRasesh Mody 62386a2265eSRasesh Mody /** 62486a2265eSRasesh Mody * @brief - Retrieves num of active rxqs chains 62586a2265eSRasesh Mody * 62686a2265eSRasesh Mody * @param p_hwfn 62786a2265eSRasesh Mody * @param rel_vf_id 62886a2265eSRasesh Mody * 62986a2265eSRasesh Mody * @return 63086a2265eSRasesh Mody */ 6319455b556SRasesh Mody u8 ecore_iov_get_vf_num_active_rxqs(struct ecore_hwfn *p_hwfn, 6329455b556SRasesh Mody u16 rel_vf_id); 63386a2265eSRasesh Mody 63486a2265eSRasesh Mody /** 63586a2265eSRasesh Mody * @brief - Retrieves ctx pointer 63686a2265eSRasesh Mody * 63786a2265eSRasesh Mody * @param p_hwfn 63886a2265eSRasesh Mody * @param rel_vf_id 63986a2265eSRasesh Mody * 64086a2265eSRasesh Mody * @return 64186a2265eSRasesh Mody */ 6429455b556SRasesh Mody void *ecore_iov_get_vf_ctx(struct ecore_hwfn *p_hwfn, 6439455b556SRasesh Mody u16 rel_vf_id); 64486a2265eSRasesh Mody 64586a2265eSRasesh Mody /** 64686a2265eSRasesh Mody * @brief - Retrieves VF`s num sbs 64786a2265eSRasesh Mody * 64886a2265eSRasesh Mody * @param p_hwfn 64986a2265eSRasesh Mody * @param rel_vf_id 65086a2265eSRasesh Mody * 65186a2265eSRasesh Mody * @return 65286a2265eSRasesh Mody */ 6539455b556SRasesh Mody u8 ecore_iov_get_vf_num_sbs(struct ecore_hwfn *p_hwfn, 6549455b556SRasesh Mody u16 rel_vf_id); 65586a2265eSRasesh Mody 65686a2265eSRasesh Mody /** 65786a2265eSRasesh Mody * @brief - Returm true if VF is waiting for acquire 65886a2265eSRasesh Mody * 65986a2265eSRasesh Mody * @param p_hwfn 66086a2265eSRasesh Mody * @param rel_vf_id 66186a2265eSRasesh Mody * 66286a2265eSRasesh Mody * @return 66386a2265eSRasesh Mody */ 6649455b556SRasesh Mody bool ecore_iov_is_vf_wait_for_acquire(struct ecore_hwfn *p_hwfn, 6659455b556SRasesh Mody u16 rel_vf_id); 66686a2265eSRasesh Mody 66786a2265eSRasesh Mody /** 66886a2265eSRasesh Mody * @brief - Returm true if VF is acquired but not initialized 66986a2265eSRasesh Mody * 67086a2265eSRasesh Mody * @param p_hwfn 67186a2265eSRasesh Mody * @param rel_vf_id 67286a2265eSRasesh Mody * 67386a2265eSRasesh Mody * @return 67486a2265eSRasesh Mody */ 67586a2265eSRasesh Mody bool ecore_iov_is_vf_acquired_not_initialized(struct ecore_hwfn *p_hwfn, 67686a2265eSRasesh Mody u16 rel_vf_id); 67786a2265eSRasesh Mody 67886a2265eSRasesh Mody /** 67986a2265eSRasesh Mody * @brief - Returm true if VF is acquired and initialized 68086a2265eSRasesh Mody * 68186a2265eSRasesh Mody * @param p_hwfn 68286a2265eSRasesh Mody * @param rel_vf_id 68386a2265eSRasesh Mody * 68486a2265eSRasesh Mody * @return 68586a2265eSRasesh Mody */ 6869455b556SRasesh Mody bool ecore_iov_is_vf_initialized(struct ecore_hwfn *p_hwfn, 6879455b556SRasesh Mody u16 rel_vf_id); 68886a2265eSRasesh Mody 68986a2265eSRasesh Mody /** 690869c47d0SRasesh Mody * @brief - Returm true if VF has started in FW 691869c47d0SRasesh Mody * 692869c47d0SRasesh Mody * @param p_hwfn 693869c47d0SRasesh Mody * @param rel_vf_id 694869c47d0SRasesh Mody * 695869c47d0SRasesh Mody * @return 696869c47d0SRasesh Mody */ 697869c47d0SRasesh Mody bool ecore_iov_is_vf_started(struct ecore_hwfn *p_hwfn, 698869c47d0SRasesh Mody u16 rel_vf_id); 699869c47d0SRasesh Mody 700869c47d0SRasesh Mody /** 70186a2265eSRasesh Mody * @brief - Get VF's vport min rate configured. 70286a2265eSRasesh Mody * @param p_hwfn 70386a2265eSRasesh Mody * @param rel_vf_id 70486a2265eSRasesh Mody * 70586a2265eSRasesh Mody * @return - rate in Mbps 70686a2265eSRasesh Mody */ 70786a2265eSRasesh Mody int ecore_iov_get_vf_min_rate(struct ecore_hwfn *p_hwfn, int vfid); 708be973769SRasesh Mody 709cf84de86SRasesh Mody /** 710cf84de86SRasesh Mody * @brief - Configure min rate for VF's vport. 711cf84de86SRasesh Mody * @param p_dev 712cf84de86SRasesh Mody * @param vfid 713cf84de86SRasesh Mody * @param - rate in Mbps 714cf84de86SRasesh Mody * 715cf84de86SRasesh Mody * @return 716cf84de86SRasesh Mody */ 717cf84de86SRasesh Mody enum _ecore_status_t ecore_iov_configure_min_tx_rate(struct ecore_dev *p_dev, 718cf84de86SRasesh Mody int vfid, u32 rate); 71986a2265eSRasesh Mody #endif 72022d07d93SRasesh Mody 72122d07d93SRasesh Mody /** 722be973769SRasesh Mody * @brief ecore_pf_configure_vf_queue_coalesce - PF configure coalesce 723be973769SRasesh Mody * parameters of VFs for Rx and Tx queue. 724be973769SRasesh Mody * While the API allows setting coalescing per-qid, all queues sharing a SB 725be973769SRasesh Mody * should be in same range [i.e., either 0-0x7f, 0x80-0xff or 0x100-0x1ff] 726be973769SRasesh Mody * otherwise configuration would break. 727be973769SRasesh Mody * 728be973769SRasesh Mody * @param p_hwfn 729be973769SRasesh Mody * @param rx_coal - Rx Coalesce value in micro seconds. 730be973769SRasesh Mody * @param tx_coal - TX Coalesce value in micro seconds. 731be973769SRasesh Mody * @param vf_id 732be973769SRasesh Mody * @param qid 733be973769SRasesh Mody * 734be973769SRasesh Mody * @return int 735be973769SRasesh Mody **/ 736be973769SRasesh Mody enum _ecore_status_t 737be973769SRasesh Mody ecore_iov_pf_configure_vf_queue_coalesce(struct ecore_hwfn *p_hwfn, 738be973769SRasesh Mody u16 rx_coal, u16 tx_coal, 739be973769SRasesh Mody u16 vf_id, u16 qid); 740be973769SRasesh Mody 741be973769SRasesh Mody /** 74222d07d93SRasesh Mody * @brief - Given a VF index, return index of next [including that] active VF. 74322d07d93SRasesh Mody * 74422d07d93SRasesh Mody * @param p_hwfn 74522d07d93SRasesh Mody * @param rel_vf_id 74622d07d93SRasesh Mody * 74752fa735cSRasesh Mody * @return MAX_NUM_VFS_K2 in case no further active VFs, otherwise index. 74822d07d93SRasesh Mody */ 74922d07d93SRasesh Mody u16 ecore_iov_get_next_active_vf(struct ecore_hwfn *p_hwfn, u16 rel_vf_id); 75022d07d93SRasesh Mody 7514727343dSRasesh Mody void ecore_iov_bulletin_set_udp_ports(struct ecore_hwfn *p_hwfn, int vfid, 7524727343dSRasesh Mody u16 vxlan_port, u16 geneve_port); 75301491d29SRasesh Mody 75401491d29SRasesh Mody #ifdef CONFIG_ECORE_SW_CHANNEL 75501491d29SRasesh Mody /** 75601491d29SRasesh Mody * @brief Set whether PF should communicate with VF using SW/HW channel 75701491d29SRasesh Mody * Needs to be called for an enabled VF before acquire is over 75801491d29SRasesh Mody * [latest good point for doing that is OSAL_IOV_VF_ACQUIRE()] 75901491d29SRasesh Mody * 76001491d29SRasesh Mody * @param p_hwfn 76101491d29SRasesh Mody * @param vfid - relative vf index 76201491d29SRasesh Mody * @param b_is_hw - true iff PF is to use HW channel for communication 76301491d29SRasesh Mody */ 76401491d29SRasesh Mody void ecore_iov_set_vf_hw_channel(struct ecore_hwfn *p_hwfn, int vfid, 76501491d29SRasesh Mody bool b_is_hw); 76601491d29SRasesh Mody #endif 76722d07d93SRasesh Mody #endif /* CONFIG_ECORE_SRIOV */ 76822d07d93SRasesh Mody 76922d07d93SRasesh Mody #define ecore_for_each_vf(_p_hwfn, _i) \ 77022d07d93SRasesh Mody for (_i = ecore_iov_get_next_active_vf(_p_hwfn, 0); \ 77152fa735cSRasesh Mody _i < MAX_NUM_VFS_K2; \ 77222d07d93SRasesh Mody _i = ecore_iov_get_next_active_vf(_p_hwfn, _i + 1)) 77322d07d93SRasesh Mody 77486a2265eSRasesh Mody #endif 775