aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:31 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:06 -0500
commit290ca2bb456d4214f00ba0b83fcb9793963fe007 (patch)
treefe4412f38b50e1a5db4749fe6cf1f34c5431889d /drivers/net/ethernet/broadcom
parentdc1ba591463ca0f7ba2ac9af6ee4a5305f27ca1f (diff)
bnx2x: Allocate VF database in PF when VFs are present
When A PF determines that it may have to manage SRIOV VFs it allocates a database for this purpose. The database is intended to keep track of the VF state, the resources allocated for each VF (queues, interrupt vectors, etc), the state of the VF's queues. When the VF loads the database is updated accordingly. When A VF closes the database is consulted to determine which resources need to be released (close queues against device, reclaim interrupt vectors, etc). Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/Makefile2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h8
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c28
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h9
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c304
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h220
6 files changed, 570 insertions, 1 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/Makefile b/drivers/net/ethernet/broadcom/bnx2x/Makefile
index d862ea699e9f..2ef6803a0fa7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/Makefile
+++ b/drivers/net/ethernet/broadcom/bnx2x/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-$(CONFIG_BNX2X) += bnx2x.o 5obj-$(CONFIG_BNX2X) += bnx2x.o
6 6
7bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o bnx2x_sp.o bnx2x_vfpf.o 7bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o bnx2x_sp.o bnx2x_vfpf.o bnx2x_sriov.o
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 2fe1908e94d7..027a4a31dd20 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -13,9 +13,12 @@
13 13
14#ifndef BNX2X_H 14#ifndef BNX2X_H
15#define BNX2X_H 15#define BNX2X_H
16
17#include <linux/pci.h>
16#include <linux/netdevice.h> 18#include <linux/netdevice.h>
17#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
18#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/pci_regs.h>
19 22
20/* compilation time flags */ 23/* compilation time flags */
21 24
@@ -966,6 +969,7 @@ extern struct workqueue_struct *bnx2x_wq;
966#define BNX2X_MAX_NUM_OF_VFS 64 969#define BNX2X_MAX_NUM_OF_VFS 64
967#define BNX2X_VF_CID_WND 0 970#define BNX2X_VF_CID_WND 0
968#define BNX2X_CIDS_PER_VF (1 << BNX2X_VF_CID_WND) 971#define BNX2X_CIDS_PER_VF (1 << BNX2X_VF_CID_WND)
972#define BNX2X_FIRST_VF_CID 256
969#define BNX2X_VF_CIDS (BNX2X_MAX_NUM_OF_VFS * BNX2X_CIDS_PER_VF) 973#define BNX2X_VF_CIDS (BNX2X_MAX_NUM_OF_VFS * BNX2X_CIDS_PER_VF)
970#define BNX2X_VF_ID_INVALID 0xFF 974#define BNX2X_VF_ID_INVALID 0xFF
971 975
@@ -1117,6 +1121,7 @@ struct hw_context {
1117/* forward */ 1121/* forward */
1118struct bnx2x_ilt; 1122struct bnx2x_ilt;
1119 1123
1124struct bnx2x_vfdb;
1120 1125
1121enum bnx2x_recovery_state { 1126enum bnx2x_recovery_state {
1122 BNX2X_RECOVERY_DONE, 1127 BNX2X_RECOVERY_DONE,
@@ -1606,6 +1611,9 @@ struct bnx2x {
1606 char fw_ver[32]; 1611 char fw_ver[32];
1607 const struct firmware *firmware; 1612 const struct firmware *firmware;
1608 1613
1614 struct bnx2x_vfdb *vfdb;
1615#define IS_SRIOV(bp) ((bp)->vfdb)
1616
1609 /* DCB support on/off */ 1617 /* DCB support on/off */
1610 u16 dcb_state; 1618 u16 dcb_state;
1611#define BNX2X_DCB_STATE_OFF 0 1619#define BNX2X_DCB_STATE_OFF 0
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index aafcaf610c15..6188ec68b45d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -7270,12 +7270,21 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
7270 ilt = BP_ILT(bp); 7270 ilt = BP_ILT(bp);
7271 cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; 7271 cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start;
7272 7272
7273 if (IS_SRIOV(bp))
7274 cdu_ilt_start += BNX2X_FIRST_VF_CID/ILT_PAGE_CIDS;
7275 cdu_ilt_start = bnx2x_iov_init_ilt(bp, cdu_ilt_start);
7276
7277 /* since BNX2X_FIRST_VF_CID > 0 the PF L2 cids precedes
7278 * those of the VFs, so start line should be reset
7279 */
7280 cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start;
7273 for (i = 0; i < L2_ILT_LINES(bp); i++) { 7281 for (i = 0; i < L2_ILT_LINES(bp); i++) {
7274 ilt->lines[cdu_ilt_start + i].page = bp->context[i].vcxt; 7282 ilt->lines[cdu_ilt_start + i].page = bp->context[i].vcxt;
7275 ilt->lines[cdu_ilt_start + i].page_mapping = 7283 ilt->lines[cdu_ilt_start + i].page_mapping =
7276 bp->context[i].cxt_mapping; 7284 bp->context[i].cxt_mapping;
7277 ilt->lines[cdu_ilt_start + i].size = bp->context[i].size; 7285 ilt->lines[cdu_ilt_start + i].size = bp->context[i].size;
7278 } 7286 }
7287
7279 bnx2x_ilt_init_op(bp, INITOP_SET); 7288 bnx2x_ilt_init_op(bp, INITOP_SET);
7280 7289
7281 if (!CONFIGURE_NIC_MODE(bp)) { 7290 if (!CONFIGURE_NIC_MODE(bp)) {
@@ -7881,6 +7890,8 @@ int bnx2x_set_int_mode(struct bnx2x *bp)
7881/* must be called prior to any HW initializations */ 7890/* must be called prior to any HW initializations */
7882static inline u16 bnx2x_cid_ilt_lines(struct bnx2x *bp) 7891static inline u16 bnx2x_cid_ilt_lines(struct bnx2x *bp)
7883{ 7892{
7893 if (IS_SRIOV(bp))
7894 return (BNX2X_FIRST_VF_CID + BNX2X_VF_CIDS)/ILT_PAGE_CIDS;
7884 return L2_ILT_LINES(bp); 7895 return L2_ILT_LINES(bp);
7885} 7896}
7886 7897
@@ -12106,8 +12117,12 @@ static int bnx2x_set_qm_cid_count(struct bnx2x *bp)
12106{ 12117{
12107 int cid_count = BNX2X_L2_MAX_CID(bp); 12118 int cid_count = BNX2X_L2_MAX_CID(bp);
12108 12119
12120 if (IS_SRIOV(bp))
12121 cid_count += BNX2X_VF_CIDS;
12122
12109 if (CNIC_SUPPORT(bp)) 12123 if (CNIC_SUPPORT(bp))
12110 cid_count += CNIC_CID_MAX; 12124 cid_count += CNIC_CID_MAX;
12125
12111 return roundup(cid_count, QM_CID_ROUND); 12126 return roundup(cid_count, QM_CID_ROUND);
12112} 12127}
12113 12128
@@ -12312,6 +12327,16 @@ static int bnx2x_init_one(struct pci_dev *pdev,
12312 goto init_one_exit; 12327 goto init_one_exit;
12313 } 12328 }
12314 12329
12330 /* Enable SRIOV if capability found in configuration space.
12331 * Once the generic SR-IOV framework makes it in from the
12332 * pci tree this will be revised, to allow dynamic control
12333 * over the number of VFs. Right now, change the num of vfs
12334 * param below to enable SR-IOV.
12335 */
12336 rc = bnx2x_iov_init_one(bp, int_mode, 0/*num vfs*/);
12337 if (rc)
12338 goto init_one_exit;
12339
12315 /* calc qm_cid_count */ 12340 /* calc qm_cid_count */
12316 bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); 12341 bp->qm_cid_count = bnx2x_set_qm_cid_count(bp);
12317 BNX2X_DEV_INFO("qm_cid_count %d\n", bp->qm_cid_count); 12342 BNX2X_DEV_INFO("qm_cid_count %d\n", bp->qm_cid_count);
@@ -12435,6 +12460,9 @@ static void bnx2x_remove_one(struct pci_dev *pdev)
12435 12460
12436 /* Make sure RESET task is not scheduled before continuing */ 12461 /* Make sure RESET task is not scheduled before continuing */
12437 cancel_delayed_work_sync(&bp->sp_rtnl_task); 12462 cancel_delayed_work_sync(&bp->sp_rtnl_task);
12463
12464 bnx2x_iov_remove_one(bp);
12465
12438 /* send message via vfpf channel to release the resources of this vf */ 12466 /* send message via vfpf channel to release the resources of this vf */
12439 if (IS_VF(bp)) 12467 if (IS_VF(bp))
12440 bnx2x_vfpf_release(bp); 12468 bnx2x_vfpf_release(bp);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index 3f01526dec2a..00e439891241 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -6305,6 +6305,15 @@
6305#define PCI_PM_DATA_B 0x414 6305#define PCI_PM_DATA_B 0x414
6306#define PCI_ID_VAL1 0x434 6306#define PCI_ID_VAL1 0x434
6307#define PCI_ID_VAL2 0x438 6307#define PCI_ID_VAL2 0x438
6308#define GRC_CONFIG_REG_PF_INIT_VF 0x624
6309#define GRC_CR_PF_INIT_VF_PF_FIRST_VF_NUM_MASK 0xf
6310/* First VF_NUM for PF is encoded in this register.
6311 * The number of VFs assigned to a PF is assumed to be a multiple of 8.
6312 * Software should program these bits based on Total Number of VFs \
6313 * programmed for each PF.
6314 * Since registers from 0x000-0x7ff are split across functions, each PF will
6315 * have the same location for the same 4 bits
6316 */
6308 6317
6309#define PXPCS_TL_CONTROL_5 0x814 6318#define PXPCS_TL_CONTROL_5 0x814
6310#define PXPCS_TL_CONTROL_5_UNKNOWNTYPE_ERR_ATTN (1 << 29) /*WC*/ 6319#define PXPCS_TL_CONTROL_5_UNKNOWNTYPE_ERR_ATTN (1 << 29) /*WC*/
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
new file mode 100644
index 000000000000..f92bf8b738fb
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -0,0 +1,304 @@
1/* bnx2x_sriov.c: Broadcom Everest network driver.
2 *
3 * Copyright 2009-2012 Broadcom Corporation
4 *
5 * Unless you and Broadcom execute a separate written software license
6 * agreement governing use of this software, this software is licensed to you
7 * under the terms of the GNU General Public License version 2, available
8 * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
9 *
10 * Notwithstanding the above, under no circumstances may you combine this
11 * software in any way with any other Broadcom software provided under a
12 * license other than the GPL, without Broadcom's express prior written
13 * consent.
14 *
15 * Maintained by: Eilon Greenstein <eilong@broadcom.com>
16 * Written by: Shmulik Ravid <shmulikr@broadcom.com>
17 * Ariel Elior <ariele@broadcom.com>
18 *
19 */
20#include "bnx2x.h"
21#include "bnx2x_init.h"
22#include "bnx2x_sriov.h"
23int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid)
24{
25 int idx;
26
27 for_each_vf(bp, idx)
28 if (bnx2x_vf(bp, idx, abs_vfid) == abs_vfid)
29 break;
30 return idx;
31}
32
33static
34struct bnx2x_virtf *bnx2x_vf_by_abs_fid(struct bnx2x *bp, u16 abs_vfid)
35{
36 u16 idx = (u16)bnx2x_vf_idx_by_abs_fid(bp, abs_vfid);
37 return (idx < BNX2X_NR_VIRTFN(bp)) ? BP_VF(bp, idx) : NULL;
38}
39
40static int bnx2x_ari_enabled(struct pci_dev *dev)
41{
42 return dev->bus->self && dev->bus->self->ari_enabled;
43}
44
45static void
46bnx2x_vf_set_igu_info(struct bnx2x *bp, u8 igu_sb_id, u8 abs_vfid)
47{
48 struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
49 if (vf) {
50 if (!vf_sb_count(vf))
51 vf->igu_base_id = igu_sb_id;
52 ++vf_sb_count(vf);
53 }
54}
55
56static void
57bnx2x_get_vf_igu_cam_info(struct bnx2x *bp)
58{
59 int sb_id;
60 u32 val;
61 u8 fid;
62
63 /* IGU in normal mode - read CAM */
64 for (sb_id = 0; sb_id < IGU_REG_MAPPING_MEMORY_SIZE; sb_id++) {
65 val = REG_RD(bp, IGU_REG_MAPPING_MEMORY + sb_id * 4);
66 if (!(val & IGU_REG_MAPPING_MEMORY_VALID))
67 continue;
68 fid = GET_FIELD((val), IGU_REG_MAPPING_MEMORY_FID);
69 if (!(fid & IGU_FID_ENCODE_IS_PF))
70 bnx2x_vf_set_igu_info(bp, sb_id,
71 (fid & IGU_FID_VF_NUM_MASK));
72
73 DP(BNX2X_MSG_IOV, "%s[%d], igu_sb_id=%d, msix=%d\n",
74 ((fid & IGU_FID_ENCODE_IS_PF) ? "PF" : "VF"),
75 ((fid & IGU_FID_ENCODE_IS_PF) ? (fid & IGU_FID_PF_NUM_MASK) :
76 (fid & IGU_FID_VF_NUM_MASK)), sb_id,
77 GET_FIELD((val), IGU_REG_MAPPING_MEMORY_VECTOR));
78 }
79}
80
81static void __bnx2x_iov_free_vfdb(struct bnx2x *bp)
82{
83 if (bp->vfdb) {
84 kfree(bp->vfdb->vfqs);
85 kfree(bp->vfdb->vfs);
86 kfree(bp->vfdb);
87 }
88 bp->vfdb = NULL;
89}
90
91static int bnx2x_sriov_pci_cfg_info(struct bnx2x *bp, struct bnx2x_sriov *iov)
92{
93 int pos;
94 struct pci_dev *dev = bp->pdev;
95
96 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
97 if (!pos) {
98 BNX2X_ERR("failed to find SRIOV capability in device\n");
99 return -ENODEV;
100 }
101
102 iov->pos = pos;
103 DP(BNX2X_MSG_IOV, "sriov ext pos %d\n", pos);
104 pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &iov->ctrl);
105 pci_read_config_word(dev, pos + PCI_SRIOV_TOTAL_VF, &iov->total);
106 pci_read_config_word(dev, pos + PCI_SRIOV_INITIAL_VF, &iov->initial);
107 pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &iov->offset);
108 pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &iov->stride);
109 pci_read_config_dword(dev, pos + PCI_SRIOV_SUP_PGSIZE, &iov->pgsz);
110 pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
111 pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
112
113 return 0;
114}
115
116static int bnx2x_sriov_info(struct bnx2x *bp, struct bnx2x_sriov *iov)
117{
118 u32 val;
119
120 /* read the SRIOV capability structure
121 * The fields can be read via configuration read or
122 * directly from the device (starting at offset PCICFG_OFFSET)
123 */
124 if (bnx2x_sriov_pci_cfg_info(bp, iov))
125 return -ENODEV;
126
127 /* get the number of SRIOV bars */
128 iov->nres = 0;
129
130 /* read the first_vfid */
131 val = REG_RD(bp, PCICFG_OFFSET + GRC_CONFIG_REG_PF_INIT_VF);
132 iov->first_vf_in_pf = ((val & GRC_CR_PF_INIT_VF_PF_FIRST_VF_NUM_MASK)
133 * 8) - (BNX2X_MAX_NUM_OF_VFS * BP_PATH(bp));
134
135 DP(BNX2X_MSG_IOV,
136 "IOV info[%d]: first vf %d, nres %d, cap 0x%x, ctrl 0x%x, total %d, initial %d, num vfs %d, offset %d, stride %d, page size 0x%x\n",
137 BP_FUNC(bp),
138 iov->first_vf_in_pf, iov->nres, iov->cap, iov->ctrl, iov->total,
139 iov->initial, iov->nr_virtfn, iov->offset, iov->stride, iov->pgsz);
140
141 return 0;
142}
143
144static u8 bnx2x_iov_get_max_queue_count(struct bnx2x *bp)
145{
146 int i;
147 u8 queue_count = 0;
148
149 if (IS_SRIOV(bp))
150 for_each_vf(bp, i)
151 queue_count += bnx2x_vf(bp, i, alloc_resc.num_sbs);
152
153 return queue_count;
154}
155
156/* must be called after PF bars are mapped */
157int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param,
158 int num_vfs_param)
159{
160 int err, i, qcount;
161 struct bnx2x_sriov *iov;
162 struct pci_dev *dev = bp->pdev;
163
164 bp->vfdb = NULL;
165
166 /* verify sriov capability is present in configuration space */
167 if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV)) {
168 DP(BNX2X_MSG_IOV, "no sriov - capability not found\n");
169 return 0;
170 }
171
172 /* verify is pf */
173 if (IS_VF(bp))
174 return 0;
175
176 /* verify chip revision */
177 if (CHIP_IS_E1x(bp))
178 return 0;
179
180 /* check if SRIOV support is turned off */
181 if (!num_vfs_param)
182 return 0;
183
184 /* SRIOV assumes that num of PF CIDs < BNX2X_FIRST_VF_CID */
185 if (BNX2X_L2_MAX_CID(bp) >= BNX2X_FIRST_VF_CID) {
186 BNX2X_ERR("PF cids %d are overspilling into vf space (starts at %d). Abort SRIOV\n",
187 BNX2X_L2_MAX_CID(bp), BNX2X_FIRST_VF_CID);
188 return 0;
189 }
190
191 /* SRIOV can be enabled only with MSIX */
192 if (int_mode_param == BNX2X_INT_MODE_MSI ||
193 int_mode_param == BNX2X_INT_MODE_INTX) {
194 BNX2X_ERR("Forced MSI/INTx mode is incompatible with SRIOV\n");
195 return 0;
196 }
197
198 /* verify ari is enabled */
199 if (!bnx2x_ari_enabled(bp->pdev)) {
200 BNX2X_ERR("ARI not supported, SRIOV can not be enabled\n");
201 return 0;
202 }
203
204 /* verify igu is in normal mode */
205 if (CHIP_INT_MODE_IS_BC(bp)) {
206 BNX2X_ERR("IGU not normal mode, SRIOV can not be enabled\n");
207 return 0;
208 }
209
210 /* allocate the vfs database */
211 bp->vfdb = kzalloc(sizeof(*(bp->vfdb)), GFP_KERNEL);
212 if (!bp->vfdb) {
213 BNX2X_ERR("failed to allocate vf database\n");
214 err = -ENOMEM;
215 goto failed;
216 }
217
218 /* get the sriov info - Linux already collected all the pertinent
219 * information, however the sriov structure is for the private use
220 * of the pci module. Also we want this information regardless
221 * of the hyper-visor.
222 */
223 iov = &(bp->vfdb->sriov);
224 err = bnx2x_sriov_info(bp, iov);
225 if (err)
226 goto failed;
227
228 /* SR-IOV capability was enabled but there are no VFs*/
229 if (iov->total == 0)
230 goto failed;
231
232 /* calcuate the actual number of VFs */
233 iov->nr_virtfn = min_t(u16, iov->total, (u16)num_vfs_param);
234
235 /* allcate the vf array */
236 bp->vfdb->vfs = kzalloc(sizeof(struct bnx2x_virtf) *
237 BNX2X_NR_VIRTFN(bp), GFP_KERNEL);
238 if (!bp->vfdb->vfs) {
239 BNX2X_ERR("failed to allocate vf array\n");
240 err = -ENOMEM;
241 goto failed;
242 }
243
244 /* Initial VF init - index and abs_vfid - nr_virtfn must be set */
245 for_each_vf(bp, i) {
246 bnx2x_vf(bp, i, index) = i;
247 bnx2x_vf(bp, i, abs_vfid) = iov->first_vf_in_pf + i;
248 bnx2x_vf(bp, i, state) = VF_FREE;
249 INIT_LIST_HEAD(&bnx2x_vf(bp, i, op_list_head));
250 mutex_init(&bnx2x_vf(bp, i, op_mutex));
251 bnx2x_vf(bp, i, op_current) = CHANNEL_TLV_NONE;
252 }
253
254 /* re-read the IGU CAM for VFs - index and abs_vfid must be set */
255 bnx2x_get_vf_igu_cam_info(bp);
256
257 /* get the total queue count and allocate the global queue arrays */
258 qcount = bnx2x_iov_get_max_queue_count(bp);
259
260 /* allocate the queue arrays for all VFs */
261 bp->vfdb->vfqs = kzalloc(qcount * sizeof(struct bnx2x_vf_queue),
262 GFP_KERNEL);
263 if (!bp->vfdb->vfqs) {
264 BNX2X_ERR("failed to allocate vf queue array\n");
265 err = -ENOMEM;
266 goto failed;
267 }
268
269 return 0;
270failed:
271 DP(BNX2X_MSG_IOV, "Failed err=%d\n", err);
272 __bnx2x_iov_free_vfdb(bp);
273 return err;
274}
275
276/* called by bnx2x_init_hw_func, returns the next ilt line */
277int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line)
278{
279 int i;
280 struct bnx2x_ilt *ilt = BP_ILT(bp);
281
282 if (!IS_SRIOV(bp))
283 return line;
284
285 /* set vfs ilt lines */
286 for (i = 0; i < BNX2X_VF_CIDS/ILT_PAGE_CIDS; i++) {
287 struct hw_dma *hw_cxt = BP_VF_CXT_PAGE(bp, i);
288
289 ilt->lines[line+i].page = hw_cxt->addr;
290 ilt->lines[line+i].page_mapping = hw_cxt->mapping;
291 ilt->lines[line+i].size = hw_cxt->size; /* doesn't matter */
292 }
293 return line + i;
294}
295
296void bnx2x_iov_remove_one(struct bnx2x *bp)
297{
298 /* if SRIOV is not enabled there's nothing to do */
299 if (!IS_SRIOV(bp))
300 return;
301
302 /* free vf database */
303 __bnx2x_iov_free_vfdb(bp);
304}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index 6d0df334124a..97275aa08ca9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -19,11 +19,231 @@
19#ifndef BNX2X_SRIOV_H 19#ifndef BNX2X_SRIOV_H
20#define BNX2X_SRIOV_H 20#define BNX2X_SRIOV_H
21 21
22/* The bnx2x device structure holds vfdb structure described below.
23 * The VF array is indexed by the relative vfid.
24 */
25struct bnx2x_sriov {
26 u32 first_vf_in_pf;
27
28 /* standard SRIOV capability fields, mostly for debugging */
29 int pos; /* capability position */
30 int nres; /* number of resources */
31 u32 cap; /* SR-IOV Capabilities */
32 u16 ctrl; /* SR-IOV Control */
33 u16 total; /* total VFs associated with the PF */
34 u16 initial; /* 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 u32 pgsz; /* page size for BAR alignment */
39 u8 link; /* Function Dependency Link */
40};
41
42/* bars */
43struct bnx2x_vf_bar {
44 u64 bar;
45 u32 size;
46};
47
48/* vf queue (used both for rx or tx) */
49struct bnx2x_vf_queue {
50 struct eth_context *cxt;
51
52 /* MACs object */
53 struct bnx2x_vlan_mac_obj mac_obj;
54
55 /* VLANs object */
56 struct bnx2x_vlan_mac_obj vlan_obj;
57 atomic_t vlan_count; /* 0 means vlan-0 is set ~ untagged */
58
59 /* Queue Slow-path State object */
60 struct bnx2x_queue_sp_obj sp_obj;
61
62 u32 cid;
63 u16 index;
64 u16 sb_idx;
65};
66
67/* struct bnx2x_vfop_qctor_params - prepare queue construction parameters:
68 * q-init, q-setup and SB index
69 */
70struct bnx2x_vfop_qctor_params {
71 struct bnx2x_queue_state_params qstate;
72 struct bnx2x_queue_setup_params prep_qsetup;
73};
74
75/* VFOP parameters (one copy per VF) */
76union bnx2x_vfop_params {
77 struct bnx2x_vlan_mac_ramrod_params vlan_mac;
78 struct bnx2x_rx_mode_ramrod_params rx_mode;
79 struct bnx2x_mcast_ramrod_params mcast;
80 struct bnx2x_config_rss_params rss;
81 struct bnx2x_vfop_qctor_params qctor;
82};
83
84/* forward */
85struct bnx2x_virtf;
86/* vf context */
87struct bnx2x_virtf {
88 u16 cfg_flags;
89#define VF_CFG_STATS 0x0001
90#define VF_CFG_FW_FC 0x0002
91#define VF_CFG_TPA 0x0004
92#define VF_CFG_INT_SIMD 0x0008
93#define VF_CACHE_LINE 0x0010
94
95 u8 state;
96#define VF_FREE 0 /* VF ready to be acquired holds no resc */
97#define VF_ACQUIRED 1 /* VF aquired, but not initalized */
98#define VF_ENABLED 2 /* VF Enabled */
99#define VF_RESET 3 /* VF FLR'd, pending cleanup */
100
101 /* non 0 during flr cleanup */
102 u8 flr_clnup_stage;
103#define VF_FLR_CLN 1 /* reclaim resources and do 'final cleanup'
104 * sans the end-wait
105 */
106#define VF_FLR_ACK 2 /* ACK flr notification */
107#define VF_FLR_EPILOG 3 /* wait for VF remnants to dissipate in the HW
108 * ~ final cleanup' end wait
109 */
110
111 /* dma */
112 dma_addr_t fw_stat_map; /* valid iff VF_CFG_STATS */
113 dma_addr_t spq_map;
114 dma_addr_t bulletin_map;
115
116 /* Allocated resources counters. Before the VF is acquired, the
117 * counters hold the following values:
118 *
119 * - xxq_count = 0 as the queues memory is not allocated yet.
120 *
121 * - sb_count = The number of status blocks configured for this VF in
122 * the IGU CAM. Initially read during probe.
123 *
124 * - xx_rules_count = The number of rules statically and equally
125 * allocated for each VF, during PF load.
126 */
127 struct vf_pf_resc_request alloc_resc;
128#define vf_rxq_count(vf) ((vf)->alloc_resc.num_rxqs)
129#define vf_txq_count(vf) ((vf)->alloc_resc.num_txqs)
130#define vf_sb_count(vf) ((vf)->alloc_resc.num_sbs)
131#define vf_mac_rules_cnt(vf) ((vf)->alloc_resc.num_mac_filters)
132#define vf_vlan_rules_cnt(vf) ((vf)->alloc_resc.num_vlan_filters)
133#define vf_mc_rules_cnt(vf) ((vf)->alloc_resc.num_mc_filters)
134
135 u8 sb_count; /* actual number of SBs */
136 u8 igu_base_id; /* base igu status block id */
137
138 struct bnx2x_vf_queue *vfqs;
139#define bnx2x_vfq(vf, nr, var) ((vf)->vfqs[(nr)].var)
140
141 u8 index; /* index in the vf array */
142 u8 abs_vfid;
143 u8 sp_cl_id;
144 u32 error; /* 0 means all's-well */
145
146 /* BDF */
147 unsigned int bus;
148 unsigned int devfn;
149
150 /* bars */
151 struct bnx2x_vf_bar bars[PCI_SRIOV_NUM_BARS];
152
153 /* set-mac ramrod state 1-pending, 0-done */
154 unsigned long filter_state;
155
156 /* leading rss client id ~~ the client id of the first rxq, must be
157 * set for each txq.
158 */
159 int leading_rss;
160
161 /* MCAST object */
162 struct bnx2x_mcast_obj mcast_obj;
163
164 /* RSS configuration object */
165 struct bnx2x_rss_config_obj rss_conf_obj;
166
167 /* slow-path operations */
168 atomic_t op_in_progress;
169 int op_rc;
170 bool op_wait_blocking;
171 struct list_head op_list_head;
172 union bnx2x_vfop_params op_params;
173 struct mutex op_mutex; /* one vfop at a time mutex */
174 enum channel_tlvs op_current;
175};
176
177#define BNX2X_NR_VIRTFN(bp) ((bp)->vfdb->sriov.nr_virtfn)
178
179#define for_each_vf(bp, var) \
180 for ((var) = 0; (var) < BNX2X_NR_VIRTFN(bp); (var)++)
181
22struct bnx2x_vf_mbx_msg { 182struct bnx2x_vf_mbx_msg {
23 union vfpf_tlvs req; 183 union vfpf_tlvs req;
24 union pfvf_tlvs resp; 184 union pfvf_tlvs resp;
25}; 185};
26 186
187struct bnx2x_vf_mbx {
188 struct bnx2x_vf_mbx_msg *msg;
189 dma_addr_t msg_mapping;
190
191 /* VF GPA address */
192 u32 vf_addr_lo;
193 u32 vf_addr_hi;
194
195 struct vfpf_first_tlv first_tlv; /* saved VF request header */
196
197 u8 flags;
198#define VF_MSG_INPROCESS 0x1 /* failsafe - the FW should prevent
199 * more then one pending msg
200 */
201};
202
203struct hw_dma {
204 void *addr;
205 dma_addr_t mapping;
206 size_t size;
207};
208
209struct bnx2x_vfdb {
210#define BP_VFDB(bp) ((bp)->vfdb)
211 /* vf array */
212 struct bnx2x_virtf *vfs;
213#define BP_VF(bp, idx) (&((bp)->vfdb->vfs[(idx)]))
214#define bnx2x_vf(bp, idx, var) ((bp)->vfdb->vfs[(idx)].var)
215
216 /* queue array - for all vfs */
217 struct bnx2x_vf_queue *vfqs;
218
219 /* vf HW contexts */
220 struct hw_dma context[BNX2X_VF_CIDS/ILT_PAGE_CIDS];
221#define BP_VF_CXT_PAGE(bp, i) (&(bp)->vfdb->context[(i)])
222
223 /* SR-IOV information */
224 struct bnx2x_sriov sriov;
225 struct hw_dma mbx_dma;
226#define BP_VF_MBX_DMA(bp) (&((bp)->vfdb->mbx_dma))
227 struct bnx2x_vf_mbx mbxs[BNX2X_MAX_NUM_OF_VFS];
228#define BP_VF_MBX(bp, vfid) (&((bp)->vfdb->mbxs[(vfid)]))
229
230 struct hw_dma sp_dma;
231#define bnx2x_vf_sp(bp, vf, field) ((bp)->vfdb->sp_dma.addr + \
232 (vf)->index * sizeof(struct bnx2x_vf_sp) + \
233 offsetof(struct bnx2x_vf_sp, field))
234#define bnx2x_vf_sp_map(bp, vf, field) ((bp)->vfdb->sp_dma.mapping + \
235 (vf)->index * sizeof(struct bnx2x_vf_sp) + \
236 offsetof(struct bnx2x_vf_sp, field))
237
238#define FLRD_VFS_DWORDS (BNX2X_MAX_NUM_OF_VFS / 32)
239 u32 flrd_vfs[FLRD_VFS_DWORDS];
240};
241
242/* global iov routines */
243int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line);
244int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, int num_vfs_param);
245void bnx2x_iov_remove_one(struct bnx2x *bp);
246int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid);
27void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type, 247void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type,
28 u16 length); 248 u16 length);
29void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, 249void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv,