diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 57 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 399 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | 56 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 38 |
8 files changed, 535 insertions, 51 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 027a4a31dd20..af34ee36dab8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -1633,6 +1633,10 @@ struct bnx2x { | |||
1633 | int dcb_version; | 1633 | int dcb_version; |
1634 | 1634 | ||
1635 | /* CAM credit pools */ | 1635 | /* CAM credit pools */ |
1636 | |||
1637 | /* used only in sriov */ | ||
1638 | struct bnx2x_credit_pool_obj vlans_pool; | ||
1639 | |||
1636 | struct bnx2x_credit_pool_obj macs_pool; | 1640 | struct bnx2x_credit_pool_obj macs_pool; |
1637 | 1641 | ||
1638 | /* RX_MODE object */ | 1642 | /* RX_MODE object */ |
@@ -1847,12 +1851,14 @@ int bnx2x_del_all_macs(struct bnx2x *bp, | |||
1847 | 1851 | ||
1848 | /* Init Function API */ | 1852 | /* Init Function API */ |
1849 | void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p); | 1853 | void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p); |
1854 | u32 bnx2x_get_pretend_reg(struct bnx2x *bp); | ||
1850 | int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); | 1855 | int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); |
1851 | int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); | 1856 | int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); |
1852 | int bnx2x_set_mult_gpio(struct bnx2x *bp, u8 pins, u32 mode); | 1857 | int bnx2x_set_mult_gpio(struct bnx2x *bp, u8 pins, u32 mode); |
1853 | int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); | 1858 | int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); |
1854 | void bnx2x_read_mf_cfg(struct bnx2x *bp); | 1859 | void bnx2x_read_mf_cfg(struct bnx2x *bp); |
1855 | 1860 | ||
1861 | int bnx2x_pretend_func(struct bnx2x *bp, u16 pretend_func_val); | ||
1856 | 1862 | ||
1857 | /* dmae */ | 1863 | /* dmae */ |
1858 | void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); | 1864 | void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); |
@@ -1864,6 +1870,7 @@ u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); | |||
1864 | u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, | 1870 | u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, |
1865 | bool with_comp, u8 comp_type); | 1871 | bool with_comp, u8 comp_type); |
1866 | 1872 | ||
1873 | u8 bnx2x_is_pcie_pending(struct pci_dev *dev); | ||
1867 | 1874 | ||
1868 | void bnx2x_calc_fc_adv(struct bnx2x *bp); | 1875 | void bnx2x_calc_fc_adv(struct bnx2x *bp); |
1869 | int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, | 1876 | int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, |
@@ -1888,6 +1895,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, | |||
1888 | return val; | 1895 | return val; |
1889 | } | 1896 | } |
1890 | 1897 | ||
1898 | void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, | ||
1899 | bool is_pf); | ||
1900 | |||
1891 | #define BNX2X_ILT_ZALLOC(x, y, size) \ | 1901 | #define BNX2X_ILT_ZALLOC(x, y, size) \ |
1892 | do { \ | 1902 | do { \ |
1893 | x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ | 1903 | x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 18baf7531f05..e8bb146747ec 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -27,8 +27,7 @@ | |||
27 | #include "bnx2x_cmn.h" | 27 | #include "bnx2x_cmn.h" |
28 | #include "bnx2x_init.h" | 28 | #include "bnx2x_init.h" |
29 | #include "bnx2x_sp.h" | 29 | #include "bnx2x_sp.h" |
30 | 30 | #include "bnx2x_sriov.h" | |
31 | |||
32 | 31 | ||
33 | /** | 32 | /** |
34 | * bnx2x_move_fp - move content of the fastpath structure. | 33 | * bnx2x_move_fp - move content of the fastpath structure. |
@@ -2524,7 +2523,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2524 | /* Init per-function objects */ | 2523 | /* Init per-function objects */ |
2525 | if (IS_PF(bp)) { | 2524 | if (IS_PF(bp)) { |
2526 | bnx2x_init_bp_objs(bp); | 2525 | bnx2x_init_bp_objs(bp); |
2527 | 2526 | bnx2x_iov_nic_init(bp); | |
2528 | 2527 | ||
2529 | /* Set AFEX default VLAN tag to an invalid value */ | 2528 | /* Set AFEX default VLAN tag to an invalid value */ |
2530 | bp->afex_def_vlan_tag = -1; | 2529 | bp->afex_def_vlan_tag = -1; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 6b0add22641d..9ee67fa0dd94 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -1106,6 +1106,9 @@ static inline void bnx2x_init_bp_objs(struct bnx2x *bp) | |||
1106 | bnx2x_init_mac_credit_pool(bp, &bp->macs_pool, BP_FUNC(bp), | 1106 | bnx2x_init_mac_credit_pool(bp, &bp->macs_pool, BP_FUNC(bp), |
1107 | bnx2x_get_path_func_num(bp)); | 1107 | bnx2x_get_path_func_num(bp)); |
1108 | 1108 | ||
1109 | bnx2x_init_vlan_credit_pool(bp, &bp->vlans_pool, BP_ABS_FUNC(bp)>>1, | ||
1110 | bnx2x_get_path_func_num(bp)); | ||
1111 | |||
1109 | /* RSS configuration object */ | 1112 | /* RSS configuration object */ |
1110 | bnx2x_init_rss_config_obj(bp, &bp->rss_conf_obj, bp->fp->cl_id, | 1113 | bnx2x_init_rss_config_obj(bp, &bp->rss_conf_obj, bp->fp->cl_id, |
1111 | bp->fp->cid, BP_FUNC(bp), BP_FUNC(bp), | 1114 | bp->fp->cid, BP_FUNC(bp), BP_FUNC(bp), |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 6188ec68b45d..e55de72a05ca 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -1171,7 +1171,7 @@ static int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, | |||
1171 | return ret; | 1171 | return ret; |
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | static u8 bnx2x_is_pcie_pending(struct pci_dev *dev) | 1174 | u8 bnx2x_is_pcie_pending(struct pci_dev *dev) |
1175 | { | 1175 | { |
1176 | u16 status; | 1176 | u16 status; |
1177 | 1177 | ||
@@ -6269,49 +6269,6 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) | |||
6269 | REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); | 6269 | REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); |
6270 | } | 6270 | } |
6271 | 6271 | ||
6272 | static void bnx2x_pretend_func(struct bnx2x *bp, u8 pretend_func_num) | ||
6273 | { | ||
6274 | u32 offset = 0; | ||
6275 | |||
6276 | if (CHIP_IS_E1(bp)) | ||
6277 | return; | ||
6278 | if (CHIP_IS_E1H(bp) && (pretend_func_num >= E1H_FUNC_MAX)) | ||
6279 | return; | ||
6280 | |||
6281 | switch (BP_ABS_FUNC(bp)) { | ||
6282 | case 0: | ||
6283 | offset = PXP2_REG_PGL_PRETEND_FUNC_F0; | ||
6284 | break; | ||
6285 | case 1: | ||
6286 | offset = PXP2_REG_PGL_PRETEND_FUNC_F1; | ||
6287 | break; | ||
6288 | case 2: | ||
6289 | offset = PXP2_REG_PGL_PRETEND_FUNC_F2; | ||
6290 | break; | ||
6291 | case 3: | ||
6292 | offset = PXP2_REG_PGL_PRETEND_FUNC_F3; | ||
6293 | break; | ||
6294 | case 4: | ||
6295 | offset = PXP2_REG_PGL_PRETEND_FUNC_F4; | ||
6296 | break; | ||
6297 | case 5: | ||
6298 | offset = PXP2_REG_PGL_PRETEND_FUNC_F5; | ||
6299 | break; | ||
6300 | case 6: | ||
6301 | offset = PXP2_REG_PGL_PRETEND_FUNC_F6; | ||
6302 | break; | ||
6303 | case 7: | ||
6304 | offset = PXP2_REG_PGL_PRETEND_FUNC_F7; | ||
6305 | break; | ||
6306 | default: | ||
6307 | return; | ||
6308 | } | ||
6309 | |||
6310 | REG_WR(bp, offset, pretend_func_num); | ||
6311 | REG_RD(bp, offset); | ||
6312 | DP(NETIF_MSG_HW, "Pretending to func %d\n", pretend_func_num); | ||
6313 | } | ||
6314 | |||
6315 | void bnx2x_pf_disable(struct bnx2x *bp) | 6272 | void bnx2x_pf_disable(struct bnx2x *bp) |
6316 | { | 6273 | { |
6317 | u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); | 6274 | u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); |
@@ -6568,6 +6525,8 @@ static int bnx2x_init_hw_common(struct bnx2x *bp) | |||
6568 | 6525 | ||
6569 | bnx2x_init_block(bp, BLOCK_DMAE, PHASE_COMMON); | 6526 | bnx2x_init_block(bp, BLOCK_DMAE, PHASE_COMMON); |
6570 | 6527 | ||
6528 | bnx2x_iov_init_dmae(bp); | ||
6529 | |||
6571 | /* clean the DMAE memory */ | 6530 | /* clean the DMAE memory */ |
6572 | bp->dmae_ready = 1; | 6531 | bp->dmae_ready = 1; |
6573 | bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8, 1); | 6532 | bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8, 1); |
@@ -7053,15 +7012,14 @@ static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) | |||
7053 | REG_WR_DMAE(bp, reg, wb_write, 2); | 7012 | REG_WR_DMAE(bp, reg, wb_write, 2); |
7054 | } | 7013 | } |
7055 | 7014 | ||
7056 | static void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, | 7015 | void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, bool is_pf) |
7057 | u8 idu_sb_id, bool is_Pf) | ||
7058 | { | 7016 | { |
7059 | u32 data, ctl, cnt = 100; | 7017 | u32 data, ctl, cnt = 100; |
7060 | u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA; | 7018 | u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA; |
7061 | u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL; | 7019 | u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL; |
7062 | u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4; | 7020 | u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4; |
7063 | u32 sb_bit = 1 << (idu_sb_id%32); | 7021 | u32 sb_bit = 1 << (idu_sb_id%32); |
7064 | u32 func_encode = func | (is_Pf ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT; | 7022 | u32 func_encode = func | (is_pf ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT; |
7065 | u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id; | 7023 | u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id; |
7066 | 7024 | ||
7067 | /* Not supported in BC mode */ | 7025 | /* Not supported in BC mode */ |
@@ -7357,6 +7315,9 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) | |||
7357 | 7315 | ||
7358 | bnx2x_init_block(bp, BLOCK_TM, init_phase); | 7316 | bnx2x_init_block(bp, BLOCK_TM, init_phase); |
7359 | bnx2x_init_block(bp, BLOCK_DORQ, init_phase); | 7317 | bnx2x_init_block(bp, BLOCK_DORQ, init_phase); |
7318 | |||
7319 | bnx2x_iov_init_dq(bp); | ||
7320 | |||
7360 | bnx2x_init_block(bp, BLOCK_BRB1, init_phase); | 7321 | bnx2x_init_block(bp, BLOCK_BRB1, init_phase); |
7361 | bnx2x_init_block(bp, BLOCK_PRS, init_phase); | 7322 | bnx2x_init_block(bp, BLOCK_PRS, init_phase); |
7362 | bnx2x_init_block(bp, BLOCK_TSDM, init_phase); | 7323 | bnx2x_init_block(bp, BLOCK_TSDM, init_phase); |
@@ -9459,7 +9420,7 @@ period_task_exit: | |||
9459 | * Init service functions | 9420 | * Init service functions |
9460 | */ | 9421 | */ |
9461 | 9422 | ||
9462 | static u32 bnx2x_get_pretend_reg(struct bnx2x *bp) | 9423 | u32 bnx2x_get_pretend_reg(struct bnx2x *bp) |
9463 | { | 9424 | { |
9464 | u32 base = PXP2_REG_PGL_PRETEND_FUNC_F0; | 9425 | u32 base = PXP2_REG_PGL_PRETEND_FUNC_F0; |
9465 | u32 stride = PXP2_REG_PGL_PRETEND_FUNC_F1 - base; | 9426 | u32 stride = PXP2_REG_PGL_PRETEND_FUNC_F1 - base; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 00e439891241..cefe4480e587 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | |||
@@ -825,6 +825,7 @@ | |||
825 | /* [RW 28] The value sent to CM header in the case of CFC load error. */ | 825 | /* [RW 28] The value sent to CM header in the case of CFC load error. */ |
826 | #define DORQ_REG_ERR_CMHEAD 0x170058 | 826 | #define DORQ_REG_ERR_CMHEAD 0x170058 |
827 | #define DORQ_REG_IF_EN 0x170004 | 827 | #define DORQ_REG_IF_EN 0x170004 |
828 | #define DORQ_REG_MAX_RVFID_SIZE 0x1701ec | ||
828 | #define DORQ_REG_MODE_ACT 0x170008 | 829 | #define DORQ_REG_MODE_ACT 0x170008 |
829 | /* [RW 5] The normal mode CID extraction offset. */ | 830 | /* [RW 5] The normal mode CID extraction offset. */ |
830 | #define DORQ_REG_NORM_CID_OFST 0x17002c | 831 | #define DORQ_REG_NORM_CID_OFST 0x17002c |
@@ -847,6 +848,22 @@ | |||
847 | writes the same initial credit to the rspa_crd_cnt and rspb_crd_cnt. The | 848 | writes the same initial credit to the rspa_crd_cnt and rspb_crd_cnt. The |
848 | read reads this written value. */ | 849 | read reads this written value. */ |
849 | #define DORQ_REG_RSP_INIT_CRD 0x170048 | 850 | #define DORQ_REG_RSP_INIT_CRD 0x170048 |
851 | #define DORQ_REG_RSPB_CRD_CNT 0x1700b0 | ||
852 | #define DORQ_REG_VF_NORM_CID_BASE 0x1701a0 | ||
853 | #define DORQ_REG_VF_NORM_CID_OFST 0x1701f4 | ||
854 | #define DORQ_REG_VF_NORM_CID_WND_SIZE 0x1701a4 | ||
855 | #define DORQ_REG_VF_NORM_MAX_CID_COUNT 0x1701e4 | ||
856 | #define DORQ_REG_VF_NORM_VF_BASE 0x1701a8 | ||
857 | /* [RW 10] VF type validation mask value */ | ||
858 | #define DORQ_REG_VF_TYPE_MASK_0 0x170218 | ||
859 | /* [RW 17] VF type validation Min MCID value */ | ||
860 | #define DORQ_REG_VF_TYPE_MAX_MCID_0 0x1702d8 | ||
861 | /* [RW 17] VF type validation Max MCID value */ | ||
862 | #define DORQ_REG_VF_TYPE_MIN_MCID_0 0x170298 | ||
863 | /* [RW 10] VF type validation comp value */ | ||
864 | #define DORQ_REG_VF_TYPE_VALUE_0 0x170258 | ||
865 | #define DORQ_REG_VF_USAGE_CT_LIMIT 0x170340 | ||
866 | |||
850 | /* [RW 4] Initial activity counter value on the load request; when the | 867 | /* [RW 4] Initial activity counter value on the load request; when the |
851 | shortcut is done. */ | 868 | shortcut is done. */ |
852 | #define DORQ_REG_SHRT_ACT_CNT 0x170070 | 869 | #define DORQ_REG_SHRT_ACT_CNT 0x170070 |
@@ -2571,6 +2588,7 @@ | |||
2571 | current task in process). */ | 2588 | current task in process). */ |
2572 | #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c | 2589 | #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c |
2573 | #define PBF_REG_DISABLE_PF 0x1402e8 | 2590 | #define PBF_REG_DISABLE_PF 0x1402e8 |
2591 | #define PBF_REG_DISABLE_VF 0x1402ec | ||
2574 | /* [RW 18] For port 0: For each client that is subject to WFQ (the | 2592 | /* [RW 18] For port 0: For each client that is subject to WFQ (the |
2575 | * corresponding bit is 1); indicates to which of the credit registers this | 2593 | * corresponding bit is 1); indicates to which of the credit registers this |
2576 | * client is mapped. For clients which are not credit blocked; their mapping | 2594 | * client is mapped. For clients which are not credit blocked; their mapping |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index f92bf8b738fb..d833a2d418ea 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
@@ -19,7 +19,36 @@ | |||
19 | */ | 19 | */ |
20 | #include "bnx2x.h" | 20 | #include "bnx2x.h" |
21 | #include "bnx2x_init.h" | 21 | #include "bnx2x_init.h" |
22 | #include "bnx2x_cmn.h" | ||
22 | #include "bnx2x_sriov.h" | 23 | #include "bnx2x_sriov.h" |
24 | |||
25 | /* General service functions */ | ||
26 | static void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, | ||
27 | u16 pf_id) | ||
28 | { | ||
29 | REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), | ||
30 | pf_id); | ||
31 | REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), | ||
32 | pf_id); | ||
33 | REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), | ||
34 | pf_id); | ||
35 | REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), | ||
36 | pf_id); | ||
37 | } | ||
38 | |||
39 | static void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, | ||
40 | u8 enable) | ||
41 | { | ||
42 | REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), | ||
43 | enable); | ||
44 | REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), | ||
45 | enable); | ||
46 | REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), | ||
47 | enable); | ||
48 | REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), | ||
49 | enable); | ||
50 | } | ||
51 | |||
23 | int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid) | 52 | int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid) |
24 | { | 53 | { |
25 | int idx; | 54 | int idx; |
@@ -272,6 +301,376 @@ failed: | |||
272 | __bnx2x_iov_free_vfdb(bp); | 301 | __bnx2x_iov_free_vfdb(bp); |
273 | return err; | 302 | return err; |
274 | } | 303 | } |
304 | /* VF enable primitives | ||
305 | * when pretend is required the caller is responsible | ||
306 | * for calling pretend prior to calling these routines | ||
307 | */ | ||
308 | |||
309 | /* called only on E1H or E2. | ||
310 | * When pretending to be PF, the pretend value is the function number 0...7 | ||
311 | * When pretending to be VF, the pretend val is the PF-num:VF-valid:ABS-VFID | ||
312 | * combination | ||
313 | */ | ||
314 | int bnx2x_pretend_func(struct bnx2x *bp, u16 pretend_func_val) | ||
315 | { | ||
316 | u32 pretend_reg; | ||
317 | |||
318 | if (CHIP_IS_E1H(bp) && pretend_func_val > E1H_FUNC_MAX) | ||
319 | return -1; | ||
320 | |||
321 | /* get my own pretend register */ | ||
322 | pretend_reg = bnx2x_get_pretend_reg(bp); | ||
323 | REG_WR(bp, pretend_reg, pretend_func_val); | ||
324 | REG_RD(bp, pretend_reg); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | /* internal vf enable - until vf is enabled internally all transactions | ||
329 | * are blocked. this routine should always be called last with pretend. | ||
330 | */ | ||
331 | static void bnx2x_vf_enable_internal(struct bnx2x *bp, u8 enable) | ||
332 | { | ||
333 | REG_WR(bp, PGLUE_B_REG_INTERNAL_VFID_ENABLE, enable ? 1 : 0); | ||
334 | } | ||
335 | |||
336 | /* clears vf error in all semi blocks */ | ||
337 | static void bnx2x_vf_semi_clear_err(struct bnx2x *bp, u8 abs_vfid) | ||
338 | { | ||
339 | REG_WR(bp, TSEM_REG_VFPF_ERR_NUM, abs_vfid); | ||
340 | REG_WR(bp, USEM_REG_VFPF_ERR_NUM, abs_vfid); | ||
341 | REG_WR(bp, CSEM_REG_VFPF_ERR_NUM, abs_vfid); | ||
342 | REG_WR(bp, XSEM_REG_VFPF_ERR_NUM, abs_vfid); | ||
343 | } | ||
344 | |||
345 | static void bnx2x_vf_pglue_clear_err(struct bnx2x *bp, u8 abs_vfid) | ||
346 | { | ||
347 | u32 was_err_group = (2 * BP_PATH(bp) + abs_vfid) >> 5; | ||
348 | u32 was_err_reg = 0; | ||
349 | |||
350 | switch (was_err_group) { | ||
351 | case 0: | ||
352 | was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_31_0_CLR; | ||
353 | break; | ||
354 | case 1: | ||
355 | was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_63_32_CLR; | ||
356 | break; | ||
357 | case 2: | ||
358 | was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_95_64_CLR; | ||
359 | break; | ||
360 | case 3: | ||
361 | was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_127_96_CLR; | ||
362 | break; | ||
363 | } | ||
364 | REG_WR(bp, was_err_reg, 1 << (abs_vfid & 0x1f)); | ||
365 | } | ||
366 | |||
367 | void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid) | ||
368 | { | ||
369 | /* set the VF-PF association in the FW */ | ||
370 | storm_memset_vf_to_pf(bp, FW_VF_HANDLE(abs_vfid), BP_FUNC(bp)); | ||
371 | storm_memset_func_en(bp, FW_VF_HANDLE(abs_vfid), 1); | ||
372 | |||
373 | /* clear vf errors*/ | ||
374 | bnx2x_vf_semi_clear_err(bp, abs_vfid); | ||
375 | bnx2x_vf_pglue_clear_err(bp, abs_vfid); | ||
376 | |||
377 | /* internal vf-enable - pretend */ | ||
378 | bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, abs_vfid)); | ||
379 | DP(BNX2X_MSG_IOV, "enabling internal access for vf %x\n", abs_vfid); | ||
380 | bnx2x_vf_enable_internal(bp, true); | ||
381 | bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); | ||
382 | } | ||
383 | |||
384 | static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) | ||
385 | { | ||
386 | struct pci_dev *dev; | ||
387 | struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid); | ||
388 | |||
389 | if (!vf) | ||
390 | goto unknown_dev; | ||
391 | |||
392 | dev = pci_get_bus_and_slot(vf->bus, vf->devfn); | ||
393 | if (dev) | ||
394 | return bnx2x_is_pcie_pending(dev); | ||
395 | |||
396 | unknown_dev: | ||
397 | BNX2X_ERR("Unknown device\n"); | ||
398 | return false; | ||
399 | } | ||
400 | |||
401 | int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid) | ||
402 | { | ||
403 | /* Wait 100ms */ | ||
404 | msleep(100); | ||
405 | |||
406 | /* Verify no pending pci transactions */ | ||
407 | if (bnx2x_vf_is_pcie_pending(bp, abs_vfid)) | ||
408 | BNX2X_ERR("PCIE Transactions still pending\n"); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | /* must be called after the number of PF queues and the number of VFs are | ||
414 | * both known | ||
415 | */ | ||
416 | static void | ||
417 | bnx2x_iov_static_resc(struct bnx2x *bp, struct vf_pf_resc_request *resc) | ||
418 | { | ||
419 | u16 vlan_count = 0; | ||
420 | |||
421 | /* will be set only during VF-ACQUIRE */ | ||
422 | resc->num_rxqs = 0; | ||
423 | resc->num_txqs = 0; | ||
424 | |||
425 | /* no credit calculcis for macs (just yet) */ | ||
426 | resc->num_mac_filters = 1; | ||
427 | |||
428 | /* divvy up vlan rules */ | ||
429 | vlan_count = bp->vlans_pool.check(&bp->vlans_pool); | ||
430 | vlan_count = 1 << ilog2(vlan_count); | ||
431 | resc->num_vlan_filters = vlan_count / BNX2X_NR_VIRTFN(bp); | ||
432 | |||
433 | /* no real limitation */ | ||
434 | resc->num_mc_filters = 0; | ||
435 | |||
436 | /* num_sbs already set */ | ||
437 | } | ||
438 | |||
439 | /* IOV global initialization routines */ | ||
440 | void bnx2x_iov_init_dq(struct bnx2x *bp) | ||
441 | { | ||
442 | if (!IS_SRIOV(bp)) | ||
443 | return; | ||
444 | |||
445 | /* Set the DQ such that the CID reflect the abs_vfid */ | ||
446 | REG_WR(bp, DORQ_REG_VF_NORM_VF_BASE, 0); | ||
447 | REG_WR(bp, DORQ_REG_MAX_RVFID_SIZE, ilog2(BNX2X_MAX_NUM_OF_VFS)); | ||
448 | |||
449 | /* Set VFs starting CID. If its > 0 the preceding CIDs are belong to | ||
450 | * the PF L2 queues | ||
451 | */ | ||
452 | REG_WR(bp, DORQ_REG_VF_NORM_CID_BASE, BNX2X_FIRST_VF_CID); | ||
453 | |||
454 | /* The VF window size is the log2 of the max number of CIDs per VF */ | ||
455 | REG_WR(bp, DORQ_REG_VF_NORM_CID_WND_SIZE, BNX2X_VF_CID_WND); | ||
456 | |||
457 | /* The VF doorbell size 0 - *B, 4 - 128B. We set it here to match | ||
458 | * the Pf doorbell size although the 2 are independent. | ||
459 | */ | ||
460 | REG_WR(bp, DORQ_REG_VF_NORM_CID_OFST, | ||
461 | BNX2X_DB_SHIFT - BNX2X_DB_MIN_SHIFT); | ||
462 | |||
463 | /* No security checks for now - | ||
464 | * configure single rule (out of 16) mask = 0x1, value = 0x0, | ||
465 | * CID range 0 - 0x1ffff | ||
466 | */ | ||
467 | REG_WR(bp, DORQ_REG_VF_TYPE_MASK_0, 1); | ||
468 | REG_WR(bp, DORQ_REG_VF_TYPE_VALUE_0, 0); | ||
469 | REG_WR(bp, DORQ_REG_VF_TYPE_MIN_MCID_0, 0); | ||
470 | REG_WR(bp, DORQ_REG_VF_TYPE_MAX_MCID_0, 0x1ffff); | ||
471 | |||
472 | /* set the number of VF alllowed doorbells to the full DQ range */ | ||
473 | REG_WR(bp, DORQ_REG_VF_NORM_MAX_CID_COUNT, 0x20000); | ||
474 | |||
475 | /* set the VF doorbell threshold */ | ||
476 | REG_WR(bp, DORQ_REG_VF_USAGE_CT_LIMIT, 4); | ||
477 | } | ||
478 | |||
479 | void bnx2x_iov_init_dmae(struct bnx2x *bp) | ||
480 | { | ||
481 | DP(BNX2X_MSG_IOV, "SRIOV is %s\n", IS_SRIOV(bp) ? "ON" : "OFF"); | ||
482 | if (!IS_SRIOV(bp)) | ||
483 | return; | ||
484 | |||
485 | REG_WR(bp, DMAE_REG_BACKWARD_COMP_EN, 0); | ||
486 | } | ||
487 | |||
488 | static int bnx2x_vf_bus(struct bnx2x *bp, int vfid) | ||
489 | { | ||
490 | struct pci_dev *dev = bp->pdev; | ||
491 | struct bnx2x_sriov *iov = &bp->vfdb->sriov; | ||
492 | |||
493 | return dev->bus->number + ((dev->devfn + iov->offset + | ||
494 | iov->stride * vfid) >> 8); | ||
495 | } | ||
496 | |||
497 | static int bnx2x_vf_devfn(struct bnx2x *bp, int vfid) | ||
498 | { | ||
499 | struct pci_dev *dev = bp->pdev; | ||
500 | struct bnx2x_sriov *iov = &bp->vfdb->sriov; | ||
501 | |||
502 | return (dev->devfn + iov->offset + iov->stride * vfid) & 0xff; | ||
503 | } | ||
504 | |||
505 | static void bnx2x_vf_set_bars(struct bnx2x *bp, struct bnx2x_virtf *vf) | ||
506 | { | ||
507 | int i, n; | ||
508 | struct pci_dev *dev = bp->pdev; | ||
509 | struct bnx2x_sriov *iov = &bp->vfdb->sriov; | ||
510 | |||
511 | for (i = 0, n = 0; i < PCI_SRIOV_NUM_BARS; i += 2, n++) { | ||
512 | u64 start = pci_resource_start(dev, PCI_IOV_RESOURCES + i); | ||
513 | u32 size = pci_resource_len(dev, PCI_IOV_RESOURCES + i); | ||
514 | |||
515 | do_div(size, iov->total); | ||
516 | vf->bars[n].bar = start + size * vf->abs_vfid; | ||
517 | vf->bars[n].size = size; | ||
518 | } | ||
519 | } | ||
520 | |||
521 | void bnx2x_iov_free_mem(struct bnx2x *bp) | ||
522 | { | ||
523 | int i; | ||
524 | |||
525 | if (!IS_SRIOV(bp)) | ||
526 | return; | ||
527 | |||
528 | /* free vfs hw contexts */ | ||
529 | for (i = 0; i < BNX2X_VF_CIDS/ILT_PAGE_CIDS; i++) { | ||
530 | struct hw_dma *cxt = &bp->vfdb->context[i]; | ||
531 | BNX2X_PCI_FREE(cxt->addr, cxt->mapping, cxt->size); | ||
532 | } | ||
533 | |||
534 | BNX2X_PCI_FREE(BP_VFDB(bp)->sp_dma.addr, | ||
535 | BP_VFDB(bp)->sp_dma.mapping, | ||
536 | BP_VFDB(bp)->sp_dma.size); | ||
537 | |||
538 | BNX2X_PCI_FREE(BP_VF_MBX_DMA(bp)->addr, | ||
539 | BP_VF_MBX_DMA(bp)->mapping, | ||
540 | BP_VF_MBX_DMA(bp)->size); | ||
541 | } | ||
542 | |||
543 | int bnx2x_iov_alloc_mem(struct bnx2x *bp) | ||
544 | { | ||
545 | size_t tot_size; | ||
546 | int i, rc = 0; | ||
547 | |||
548 | if (!IS_SRIOV(bp)) | ||
549 | return rc; | ||
550 | |||
551 | /* allocate vfs hw contexts */ | ||
552 | tot_size = (BP_VFDB(bp)->sriov.first_vf_in_pf + BNX2X_NR_VIRTFN(bp)) * | ||
553 | BNX2X_CIDS_PER_VF * sizeof(union cdu_context); | ||
554 | |||
555 | for (i = 0; i < BNX2X_VF_CIDS/ILT_PAGE_CIDS; i++) { | ||
556 | struct hw_dma *cxt = BP_VF_CXT_PAGE(bp, i); | ||
557 | cxt->size = min_t(size_t, tot_size, CDU_ILT_PAGE_SZ); | ||
558 | |||
559 | if (cxt->size) { | ||
560 | BNX2X_PCI_ALLOC(cxt->addr, &cxt->mapping, cxt->size); | ||
561 | } else { | ||
562 | cxt->addr = NULL; | ||
563 | cxt->mapping = 0; | ||
564 | } | ||
565 | tot_size -= cxt->size; | ||
566 | } | ||
567 | |||
568 | /* allocate vfs ramrods dma memory - client_init and set_mac */ | ||
569 | tot_size = BNX2X_NR_VIRTFN(bp) * sizeof(struct bnx2x_vf_sp); | ||
570 | BNX2X_PCI_ALLOC(BP_VFDB(bp)->sp_dma.addr, &BP_VFDB(bp)->sp_dma.mapping, | ||
571 | tot_size); | ||
572 | BP_VFDB(bp)->sp_dma.size = tot_size; | ||
573 | |||
574 | /* allocate mailboxes */ | ||
575 | tot_size = BNX2X_NR_VIRTFN(bp) * MBX_MSG_ALIGNED_SIZE; | ||
576 | BNX2X_PCI_ALLOC(BP_VF_MBX_DMA(bp)->addr, &BP_VF_MBX_DMA(bp)->mapping, | ||
577 | tot_size); | ||
578 | BP_VF_MBX_DMA(bp)->size = tot_size; | ||
579 | |||
580 | return 0; | ||
581 | |||
582 | alloc_mem_err: | ||
583 | return -ENOMEM; | ||
584 | } | ||
585 | |||
586 | /* called by bnx2x_nic_load */ | ||
587 | int bnx2x_iov_nic_init(struct bnx2x *bp) | ||
588 | { | ||
589 | int vfid, qcount, i; | ||
590 | |||
591 | if (!IS_SRIOV(bp)) { | ||
592 | DP(BNX2X_MSG_IOV, "vfdb was not allocated\n"); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | DP(BNX2X_MSG_IOV, "num of vfs: %d\n", (bp)->vfdb->sriov.nr_virtfn); | ||
597 | |||
598 | /* initialize vf database */ | ||
599 | for_each_vf(bp, vfid) { | ||
600 | struct bnx2x_virtf *vf = BP_VF(bp, vfid); | ||
601 | |||
602 | int base_vf_cid = (BP_VFDB(bp)->sriov.first_vf_in_pf + vfid) * | ||
603 | BNX2X_CIDS_PER_VF; | ||
604 | |||
605 | union cdu_context *base_cxt = (union cdu_context *) | ||
606 | BP_VF_CXT_PAGE(bp, base_vf_cid/ILT_PAGE_CIDS)->addr + | ||
607 | (base_vf_cid & (ILT_PAGE_CIDS-1)); | ||
608 | |||
609 | DP(BNX2X_MSG_IOV, | ||
610 | "VF[%d] Max IGU SBs: %d, base vf cid 0x%x, base cid 0x%x, base cxt %p\n", | ||
611 | vf->abs_vfid, vf_sb_count(vf), base_vf_cid, | ||
612 | BNX2X_FIRST_VF_CID + base_vf_cid, base_cxt); | ||
613 | |||
614 | /* init statically provisioned resources */ | ||
615 | bnx2x_iov_static_resc(bp, &vf->alloc_resc); | ||
616 | |||
617 | /* queues are initialized during VF-ACQUIRE */ | ||
618 | |||
619 | /* reserve the vf vlan credit */ | ||
620 | bp->vlans_pool.get(&bp->vlans_pool, vf_vlan_rules_cnt(vf)); | ||
621 | |||
622 | vf->filter_state = 0; | ||
623 | vf->sp_cl_id = bnx2x_fp(bp, 0, cl_id); | ||
624 | |||
625 | /* init mcast object - This object will be re-initialized | ||
626 | * during VF-ACQUIRE with the proper cl_id and cid. | ||
627 | * It needs to be initialized here so that it can be safely | ||
628 | * handled by a subsequent FLR flow. | ||
629 | */ | ||
630 | bnx2x_init_mcast_obj(bp, &vf->mcast_obj, 0xFF, | ||
631 | 0xFF, 0xFF, 0xFF, | ||
632 | bnx2x_vf_sp(bp, vf, mcast_rdata), | ||
633 | bnx2x_vf_sp_map(bp, vf, mcast_rdata), | ||
634 | BNX2X_FILTER_MCAST_PENDING, | ||
635 | &vf->filter_state, | ||
636 | BNX2X_OBJ_TYPE_RX_TX); | ||
637 | |||
638 | /* set the mailbox message addresses */ | ||
639 | BP_VF_MBX(bp, vfid)->msg = (struct bnx2x_vf_mbx_msg *) | ||
640 | (((u8 *)BP_VF_MBX_DMA(bp)->addr) + vfid * | ||
641 | MBX_MSG_ALIGNED_SIZE); | ||
642 | |||
643 | BP_VF_MBX(bp, vfid)->msg_mapping = BP_VF_MBX_DMA(bp)->mapping + | ||
644 | vfid * MBX_MSG_ALIGNED_SIZE; | ||
645 | |||
646 | /* Enable vf mailbox */ | ||
647 | bnx2x_vf_enable_mbx(bp, vf->abs_vfid); | ||
648 | } | ||
649 | |||
650 | /* Final VF init */ | ||
651 | qcount = 0; | ||
652 | for_each_vf(bp, i) { | ||
653 | struct bnx2x_virtf *vf = BP_VF(bp, i); | ||
654 | |||
655 | /* fill in the BDF and bars */ | ||
656 | vf->bus = bnx2x_vf_bus(bp, i); | ||
657 | vf->devfn = bnx2x_vf_devfn(bp, i); | ||
658 | bnx2x_vf_set_bars(bp, vf); | ||
659 | |||
660 | DP(BNX2X_MSG_IOV, | ||
661 | "VF info[%d]: bus 0x%x, devfn 0x%x, bar0 [0x%x, %d], bar1 [0x%x, %d], bar2 [0x%x, %d]\n", | ||
662 | vf->abs_vfid, vf->bus, vf->devfn, | ||
663 | (unsigned)vf->bars[0].bar, vf->bars[0].size, | ||
664 | (unsigned)vf->bars[1].bar, vf->bars[1].size, | ||
665 | (unsigned)vf->bars[2].bar, vf->bars[2].size); | ||
666 | |||
667 | /* set local queue arrays */ | ||
668 | vf->vfqs = &bp->vfdb->vfqs[qcount]; | ||
669 | qcount += bnx2x_vf(bp, i, alloc_resc.num_sbs); | ||
670 | } | ||
671 | |||
672 | return 0; | ||
673 | } | ||
275 | 674 | ||
276 | /* called by bnx2x_init_hw_func, returns the next ilt line */ | 675 | /* called by bnx2x_init_hw_func, returns the next ilt line */ |
277 | int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line) | 676 | int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 97275aa08ca9..0e521b0275e0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | |||
@@ -179,6 +179,25 @@ struct bnx2x_virtf { | |||
179 | #define for_each_vf(bp, var) \ | 179 | #define for_each_vf(bp, var) \ |
180 | for ((var) = 0; (var) < BNX2X_NR_VIRTFN(bp); (var)++) | 180 | for ((var) = 0; (var) < BNX2X_NR_VIRTFN(bp); (var)++) |
181 | 181 | ||
182 | #define HW_VF_HANDLE(bp, abs_vfid) \ | ||
183 | (u16)(BP_ABS_FUNC((bp)) | (1<<3) | ((u16)(abs_vfid) << 4)) | ||
184 | |||
185 | #define FW_PF_MAX_HANDLE 8 | ||
186 | |||
187 | #define FW_VF_HANDLE(abs_vfid) \ | ||
188 | (abs_vfid + FW_PF_MAX_HANDLE) | ||
189 | |||
190 | /* VF mail box (aka vf-pf channel) */ | ||
191 | |||
192 | /* a container for the bi-directional vf<-->pf messages. | ||
193 | * The actual response will be placed according to the offset parameter | ||
194 | * provided in the request | ||
195 | */ | ||
196 | |||
197 | #define MBX_MSG_ALIGN 8 | ||
198 | #define MBX_MSG_ALIGNED_SIZE (roundup(sizeof(struct bnx2x_vf_mbx_msg), \ | ||
199 | MBX_MSG_ALIGN)) | ||
200 | |||
182 | struct bnx2x_vf_mbx_msg { | 201 | struct bnx2x_vf_mbx_msg { |
183 | union vfpf_tlvs req; | 202 | union vfpf_tlvs req; |
184 | union pfvf_tlvs resp; | 203 | union pfvf_tlvs resp; |
@@ -200,6 +219,29 @@ struct bnx2x_vf_mbx { | |||
200 | */ | 219 | */ |
201 | }; | 220 | }; |
202 | 221 | ||
222 | struct bnx2x_vf_sp { | ||
223 | union { | ||
224 | struct eth_classify_rules_ramrod_data e2; | ||
225 | } mac_rdata; | ||
226 | |||
227 | union { | ||
228 | struct eth_classify_rules_ramrod_data e2; | ||
229 | } vlan_rdata; | ||
230 | |||
231 | union { | ||
232 | struct eth_filter_rules_ramrod_data e2; | ||
233 | } rx_mode_rdata; | ||
234 | |||
235 | union { | ||
236 | struct eth_multicast_rules_ramrod_data e2; | ||
237 | } mcast_rdata; | ||
238 | |||
239 | union { | ||
240 | struct client_init_ramrod_data init_data; | ||
241 | struct client_update_ramrod_data update_data; | ||
242 | } q_data; | ||
243 | }; | ||
244 | |||
203 | struct hw_dma { | 245 | struct hw_dma { |
204 | void *addr; | 246 | void *addr; |
205 | dma_addr_t mapping; | 247 | dma_addr_t mapping; |
@@ -239,11 +281,25 @@ struct bnx2x_vfdb { | |||
239 | u32 flrd_vfs[FLRD_VFS_DWORDS]; | 281 | u32 flrd_vfs[FLRD_VFS_DWORDS]; |
240 | }; | 282 | }; |
241 | 283 | ||
284 | static inline u8 vf_igu_sb(struct bnx2x_virtf *vf, u16 sb_idx) | ||
285 | { | ||
286 | return vf->igu_base_id + sb_idx; | ||
287 | } | ||
288 | |||
242 | /* global iov routines */ | 289 | /* global iov routines */ |
243 | int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line); | 290 | int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line); |
244 | int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, int num_vfs_param); | 291 | int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, int num_vfs_param); |
245 | void bnx2x_iov_remove_one(struct bnx2x *bp); | 292 | void bnx2x_iov_remove_one(struct bnx2x *bp); |
293 | void bnx2x_iov_free_mem(struct bnx2x *bp); | ||
294 | int bnx2x_iov_alloc_mem(struct bnx2x *bp); | ||
295 | int bnx2x_iov_nic_init(struct bnx2x *bp); | ||
296 | void bnx2x_iov_init_dq(struct bnx2x *bp); | ||
297 | void bnx2x_iov_init_dmae(struct bnx2x *bp); | ||
298 | void bnx2x_vf_enable_mbx(struct bnx2x *bp, u8 abs_vfid); | ||
246 | int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid); | 299 | int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid); |
300 | /* VF FLR helpers */ | ||
301 | int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid); | ||
302 | void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid); | ||
247 | void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type, | 303 | void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type, |
248 | u16 length); | 304 | u16 length); |
249 | void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, | 305 | void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index 55dd6a9287a1..d1a8644200d9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | |||
@@ -78,3 +78,41 @@ void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list) | |||
78 | DP(BNX2X_MSG_IOV, "TLV number %d: type %d, length %d\n", i, | 78 | DP(BNX2X_MSG_IOV, "TLV number %d: type %d, length %d\n", i, |
79 | tlv->type, tlv->length); | 79 | tlv->type, tlv->length); |
80 | } | 80 | } |
81 | |||
82 | /* General service functions */ | ||
83 | static void storm_memset_vf_mbx_ack(struct bnx2x *bp, u16 abs_fid) | ||
84 | { | ||
85 | u32 addr = BAR_CSTRORM_INTMEM + | ||
86 | CSTORM_VF_PF_CHANNEL_STATE_OFFSET(abs_fid); | ||
87 | |||
88 | REG_WR8(bp, addr, VF_PF_CHANNEL_STATE_READY); | ||
89 | } | ||
90 | |||
91 | static void storm_memset_vf_mbx_valid(struct bnx2x *bp, u16 abs_fid) | ||
92 | { | ||
93 | u32 addr = BAR_CSTRORM_INTMEM + | ||
94 | CSTORM_VF_PF_CHANNEL_VALID_OFFSET(abs_fid); | ||
95 | |||
96 | REG_WR8(bp, addr, 1); | ||
97 | } | ||
98 | |||
99 | static inline void bnx2x_set_vf_mbxs_valid(struct bnx2x *bp) | ||
100 | { | ||
101 | int i; | ||
102 | |||
103 | for_each_vf(bp, i) | ||
104 | storm_memset_vf_mbx_valid(bp, bnx2x_vf(bp, i, abs_vfid)); | ||
105 | } | ||
106 | |||
107 | /* enable vf_pf mailbox (aka vf-pf-chanell) */ | ||
108 | void bnx2x_vf_enable_mbx(struct bnx2x *bp, u8 abs_vfid) | ||
109 | { | ||
110 | bnx2x_vf_flr_clnup_epilog(bp, abs_vfid); | ||
111 | |||
112 | /* enable the mailbox in the FW */ | ||
113 | storm_memset_vf_mbx_ack(bp, abs_vfid); | ||
114 | storm_memset_vf_mbx_valid(bp, abs_vfid); | ||
115 | |||
116 | /* enable the VF access to the mailbox */ | ||
117 | bnx2x_vf_enable_access(bp, abs_vfid); | ||
118 | } | ||