blob: 0ac561916e2cac15733ddfec89701aea440511e7 [file] [log] [blame]
Yuval Mintz32a47e72016-05-11 16:36:12 +03001/* QLogic qed NIC Driver
2 * Copyright (c) 2015 QLogic Corporation
3 *
4 * This software is available under the terms of the GNU General Public License
5 * (GPL) Version 2, available from the file COPYING in the main directory of
6 * this source tree.
7 */
8
9#ifndef _QED_SRIOV_H
10#define _QED_SRIOV_H
11#include <linux/types.h>
12#include "qed_vf.h"
13#define QED_VF_ARRAY_LENGTH (3)
14
15#define IS_VF(cdev) ((cdev)->b_is_vf)
16#define IS_PF(cdev) (!((cdev)->b_is_vf))
17#ifdef CONFIG_QED_SRIOV
18#define IS_PF_SRIOV(p_hwfn) (!!((p_hwfn)->cdev->p_iov_info))
19#else
20#define IS_PF_SRIOV(p_hwfn) (0)
21#endif
22#define IS_PF_SRIOV_ALLOC(p_hwfn) (!!((p_hwfn)->pf_iov_info))
23
24/* This struct is part of qed_dev and contains data relevant to all hwfns;
25 * Initialized only if SR-IOV cpabability is exposed in PCIe config space.
26 */
27struct qed_hw_sriov_info {
28 int pos; /* capability position */
29 int nres; /* number of resources */
30 u32 cap; /* SR-IOV Capabilities */
31 u16 ctrl; /* SR-IOV Control */
32 u16 total_vfs; /* total VFs associated with the PF */
33 u16 num_vfs; /* number of vfs that have been started */
34 u16 initial_vfs; /* initial VFs associated with the PF */
35 u16 nr_virtfn; /* number of VFs available */
36 u16 offset; /* first VF Routing ID offset */
37 u16 stride; /* following VF stride */
38 u16 vf_device_id; /* VF device id */
39 u32 pgsz; /* page size for BAR alignment */
40 u8 link; /* Function Dependency Link */
41
42 u32 first_vf_in_pf;
43};
44
45/* This mailbox is maintained per VF in its PF contains all information
46 * required for sending / receiving a message.
47 */
48struct qed_iov_vf_mbx {
49 union vfpf_tlvs *req_virt;
50 dma_addr_t req_phys;
51 union pfvf_tlvs *reply_virt;
52 dma_addr_t reply_phys;
53};
54
55enum vf_state {
56 VF_STOPPED /* VF, Stopped */
57};
58
59/* PFs maintain an array of this structure, per VF */
60struct qed_vf_info {
61 struct qed_iov_vf_mbx vf_mbx;
62 enum vf_state state;
63 bool b_init;
64
65 struct qed_bulletin bulletin;
66 dma_addr_t vf_bulletin;
67
68 u32 concrete_fid;
69 u16 opaque_fid;
70
71 u8 vport_id;
72 u8 relative_vf_id;
73 u8 abs_vf_id;
74#define QED_VF_ABS_ID(p_hwfn, p_vf) (QED_PATH_ID(p_hwfn) ? \
75 (p_vf)->abs_vf_id + MAX_NUM_VFS_BB : \
76 (p_vf)->abs_vf_id)
77};
78
79/* This structure is part of qed_hwfn and used only for PFs that have sriov
80 * capability enabled.
81 */
82struct qed_pf_iov {
83 struct qed_vf_info vfs_array[MAX_NUM_VFS];
84 u64 pending_events[QED_VF_ARRAY_LENGTH];
85 u64 pending_flr[QED_VF_ARRAY_LENGTH];
86
87 /* Allocate message address continuosuly and split to each VF */
88 void *mbx_msg_virt_addr;
89 dma_addr_t mbx_msg_phys_addr;
90 u32 mbx_msg_size;
91 void *mbx_reply_virt_addr;
92 dma_addr_t mbx_reply_phys_addr;
93 u32 mbx_reply_size;
94 void *p_bulletins;
95 dma_addr_t bulletins_phys;
96 u32 bulletins_size;
97};
98
99#ifdef CONFIG_QED_SRIOV
100/**
101 * @brief - Given a VF index, return index of next [including that] active VF.
102 *
103 * @param p_hwfn
104 * @param rel_vf_id
105 *
106 * @return MAX_NUM_VFS in case no further active VFs, otherwise index.
107 */
108u16 qed_iov_get_next_active_vf(struct qed_hwfn *p_hwfn, u16 rel_vf_id);
109
110/**
111 * @brief Read sriov related information and allocated resources
112 * reads from configuraiton space, shmem, etc.
113 *
114 * @param p_hwfn
115 *
116 * @return int
117 */
118int qed_iov_hw_info(struct qed_hwfn *p_hwfn);
119
120/**
121 * @brief qed_iov_alloc - allocate sriov related resources
122 *
123 * @param p_hwfn
124 *
125 * @return int
126 */
127int qed_iov_alloc(struct qed_hwfn *p_hwfn);
128
129/**
130 * @brief qed_iov_setup - setup sriov related resources
131 *
132 * @param p_hwfn
133 * @param p_ptt
134 */
135void qed_iov_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
136
137/**
138 * @brief qed_iov_free - free sriov related resources
139 *
140 * @param p_hwfn
141 */
142void qed_iov_free(struct qed_hwfn *p_hwfn);
143
144/**
145 * @brief free sriov related memory that was allocated during hw_prepare
146 *
147 * @param cdev
148 */
149void qed_iov_free_hw_info(struct qed_dev *cdev);
150#else
151static inline u16 qed_iov_get_next_active_vf(struct qed_hwfn *p_hwfn,
152 u16 rel_vf_id)
153{
154 return MAX_NUM_VFS;
155}
156
157static inline int qed_iov_hw_info(struct qed_hwfn *p_hwfn)
158{
159 return 0;
160}
161
162static inline int qed_iov_alloc(struct qed_hwfn *p_hwfn)
163{
164 return 0;
165}
166
167static inline void qed_iov_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
168{
169}
170
171static inline void qed_iov_free(struct qed_hwfn *p_hwfn)
172{
173}
174
175static inline void qed_iov_free_hw_info(struct qed_dev *cdev)
176{
177}
178#endif
179
180#define qed_for_each_vf(_p_hwfn, _i) \
181 for (_i = qed_iov_get_next_active_vf(_p_hwfn, 0); \
182 _i < MAX_NUM_VFS; \
183 _i = qed_iov_get_next_active_vf(_p_hwfn, _i + 1))
184
185#endif