diff options
author | David S. Miller <davem@davemloft.net> | 2015-11-05 16:33:10 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-11-05 16:33:10 -0500 |
commit | 432599d7a7062ad7e37e72601607dc35596afe40 (patch) | |
tree | ee700f7eb3c31f92b3bcfd292e56c1891ea06982 | |
parent | 49a496c97d035f2eab7cef4894dd46202184fc81 (diff) | |
parent | 4bb6cdce386d620d10d2588ea5bf4093a3b21ab9 (diff) |
Merge branch 'bnxt_en-fixes'
Michael Chan says:
====================
bnxt_en: Bug fixes.
Miscellaneous small bug fixes.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.h | 26 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 40 |
3 files changed, 64 insertions, 30 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 6c2e0c622831..db15c5ee09c5 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -1292,8 +1292,6 @@ static inline int bnxt_has_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr) | |||
1292 | return TX_CMP_VALID(txcmp, raw_cons); | 1292 | return TX_CMP_VALID(txcmp, raw_cons); |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | #define CAG_LEGACY_INT_STATUS 0x2014 | ||
1296 | |||
1297 | static irqreturn_t bnxt_inta(int irq, void *dev_instance) | 1295 | static irqreturn_t bnxt_inta(int irq, void *dev_instance) |
1298 | { | 1296 | { |
1299 | struct bnxt_napi *bnapi = dev_instance; | 1297 | struct bnxt_napi *bnapi = dev_instance; |
@@ -1305,7 +1303,7 @@ static irqreturn_t bnxt_inta(int irq, void *dev_instance) | |||
1305 | prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]); | 1303 | prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]); |
1306 | 1304 | ||
1307 | if (!bnxt_has_work(bp, cpr)) { | 1305 | if (!bnxt_has_work(bp, cpr)) { |
1308 | int_status = readl(bp->bar0 + CAG_LEGACY_INT_STATUS); | 1306 | int_status = readl(bp->bar0 + BNXT_CAG_REG_LEGACY_INT_STATUS); |
1309 | /* return if erroneous interrupt */ | 1307 | /* return if erroneous interrupt */ |
1310 | if (!(int_status & (0x10000 << cpr->cp_ring_struct.fw_ring_id))) | 1308 | if (!(int_status & (0x10000 << cpr->cp_ring_struct.fw_ring_id))) |
1311 | return IRQ_NONE; | 1309 | return IRQ_NONE; |
@@ -4527,10 +4525,25 @@ static int bnxt_update_phy_setting(struct bnxt *bp) | |||
4527 | return rc; | 4525 | return rc; |
4528 | } | 4526 | } |
4529 | 4527 | ||
4528 | /* Common routine to pre-map certain register block to different GRC window. | ||
4529 | * A PF has 16 4K windows and a VF has 4 4K windows. However, only 15 windows | ||
4530 | * in PF and 3 windows in VF that can be customized to map in different | ||
4531 | * register blocks. | ||
4532 | */ | ||
4533 | static void bnxt_preset_reg_win(struct bnxt *bp) | ||
4534 | { | ||
4535 | if (BNXT_PF(bp)) { | ||
4536 | /* CAG registers map to GRC window #4 */ | ||
4537 | writel(BNXT_CAG_REG_BASE, | ||
4538 | bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 12); | ||
4539 | } | ||
4540 | } | ||
4541 | |||
4530 | static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) | 4542 | static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) |
4531 | { | 4543 | { |
4532 | int rc = 0; | 4544 | int rc = 0; |
4533 | 4545 | ||
4546 | bnxt_preset_reg_win(bp); | ||
4534 | netif_carrier_off(bp->dev); | 4547 | netif_carrier_off(bp->dev); |
4535 | if (irq_re_init) { | 4548 | if (irq_re_init) { |
4536 | rc = bnxt_setup_int_mode(bp); | 4549 | rc = bnxt_setup_int_mode(bp); |
@@ -5294,7 +5307,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, | |||
5294 | struct bnxt_ntuple_filter *fltr, *new_fltr; | 5307 | struct bnxt_ntuple_filter *fltr, *new_fltr; |
5295 | struct flow_keys *fkeys; | 5308 | struct flow_keys *fkeys; |
5296 | struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb); | 5309 | struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb); |
5297 | int rc = 0, idx; | 5310 | int rc = 0, idx, bit_id; |
5298 | struct hlist_head *head; | 5311 | struct hlist_head *head; |
5299 | 5312 | ||
5300 | if (skb->encapsulation) | 5313 | if (skb->encapsulation) |
@@ -5332,14 +5345,15 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, | |||
5332 | rcu_read_unlock(); | 5345 | rcu_read_unlock(); |
5333 | 5346 | ||
5334 | spin_lock_bh(&bp->ntp_fltr_lock); | 5347 | spin_lock_bh(&bp->ntp_fltr_lock); |
5335 | new_fltr->sw_id = bitmap_find_free_region(bp->ntp_fltr_bmap, | 5348 | bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, |
5336 | BNXT_NTP_FLTR_MAX_FLTR, 0); | 5349 | BNXT_NTP_FLTR_MAX_FLTR, 0); |
5337 | if (new_fltr->sw_id < 0) { | 5350 | if (bit_id < 0) { |
5338 | spin_unlock_bh(&bp->ntp_fltr_lock); | 5351 | spin_unlock_bh(&bp->ntp_fltr_lock); |
5339 | rc = -ENOMEM; | 5352 | rc = -ENOMEM; |
5340 | goto err_free; | 5353 | goto err_free; |
5341 | } | 5354 | } |
5342 | 5355 | ||
5356 | new_fltr->sw_id = (u16)bit_id; | ||
5343 | new_fltr->flow_id = flow_id; | 5357 | new_fltr->flow_id = flow_id; |
5344 | new_fltr->rxq = rxq_index; | 5358 | new_fltr->rxq = rxq_index; |
5345 | hlist_add_head_rcu(&new_fltr->hash, head); | 5359 | hlist_add_head_rcu(&new_fltr->hash, head); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 4f2267ca482d..674bc5159b91 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
@@ -166,9 +166,11 @@ struct rx_cmp { | |||
166 | #define RX_CMP_HASH_VALID(rxcmp) \ | 166 | #define RX_CMP_HASH_VALID(rxcmp) \ |
167 | ((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID)) | 167 | ((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID)) |
168 | 168 | ||
169 | #define RSS_PROFILE_ID_MASK 0x1f | ||
170 | |||
169 | #define RX_CMP_HASH_TYPE(rxcmp) \ | 171 | #define RX_CMP_HASH_TYPE(rxcmp) \ |
170 | ((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\ | 172 | (((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\ |
171 | RX_CMP_RSS_HASH_TYPE_SHIFT) | 173 | RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK) |
172 | 174 | ||
173 | struct rx_cmp_ext { | 175 | struct rx_cmp_ext { |
174 | __le32 rx_cmp_flags2; | 176 | __le32 rx_cmp_flags2; |
@@ -282,9 +284,9 @@ struct rx_tpa_start_cmp { | |||
282 | cpu_to_le32(RX_TPA_START_CMP_FLAGS_RSS_VALID)) | 284 | cpu_to_le32(RX_TPA_START_CMP_FLAGS_RSS_VALID)) |
283 | 285 | ||
284 | #define TPA_START_HASH_TYPE(rx_tpa_start) \ | 286 | #define TPA_START_HASH_TYPE(rx_tpa_start) \ |
285 | ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ | 287 | (((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ |
286 | RX_TPA_START_CMP_RSS_HASH_TYPE) >> \ | 288 | RX_TPA_START_CMP_RSS_HASH_TYPE) >> \ |
287 | RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) | 289 | RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK) |
288 | 290 | ||
289 | #define TPA_START_AGG_ID(rx_tpa_start) \ | 291 | #define TPA_START_AGG_ID(rx_tpa_start) \ |
290 | ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ | 292 | ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ |
@@ -839,6 +841,10 @@ struct bnxt_queue_info { | |||
839 | u8 queue_profile; | 841 | u8 queue_profile; |
840 | }; | 842 | }; |
841 | 843 | ||
844 | #define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400 | ||
845 | #define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014 | ||
846 | #define BNXT_CAG_REG_BASE 0x300000 | ||
847 | |||
842 | struct bnxt { | 848 | struct bnxt { |
843 | void __iomem *bar0; | 849 | void __iomem *bar0; |
844 | void __iomem *bar1; | 850 | void __iomem *bar1; |
@@ -959,11 +965,11 @@ struct bnxt { | |||
959 | #define BNXT_RX_MASK_SP_EVENT 0 | 965 | #define BNXT_RX_MASK_SP_EVENT 0 |
960 | #define BNXT_RX_NTP_FLTR_SP_EVENT 1 | 966 | #define BNXT_RX_NTP_FLTR_SP_EVENT 1 |
961 | #define BNXT_LINK_CHNG_SP_EVENT 2 | 967 | #define BNXT_LINK_CHNG_SP_EVENT 2 |
962 | #define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 4 | 968 | #define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 3 |
963 | #define BNXT_VXLAN_ADD_PORT_SP_EVENT 8 | 969 | #define BNXT_VXLAN_ADD_PORT_SP_EVENT 4 |
964 | #define BNXT_VXLAN_DEL_PORT_SP_EVENT 16 | 970 | #define BNXT_VXLAN_DEL_PORT_SP_EVENT 5 |
965 | #define BNXT_RESET_TASK_SP_EVENT 32 | 971 | #define BNXT_RESET_TASK_SP_EVENT 6 |
966 | #define BNXT_RST_RING_SP_EVENT 64 | 972 | #define BNXT_RST_RING_SP_EVENT 7 |
967 | 973 | ||
968 | struct bnxt_pf_info pf; | 974 | struct bnxt_pf_info pf; |
969 | #ifdef CONFIG_BNXT_SRIOV | 975 | #ifdef CONFIG_BNXT_SRIOV |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 60989e7e266a..f4cf68861069 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | |||
@@ -258,7 +258,7 @@ static int bnxt_set_vf_attr(struct bnxt *bp, int num_vfs) | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp) | 261 | static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp, int num_vfs) |
262 | { | 262 | { |
263 | int i, rc = 0; | 263 | int i, rc = 0; |
264 | struct bnxt_pf_info *pf = &bp->pf; | 264 | struct bnxt_pf_info *pf = &bp->pf; |
@@ -267,7 +267,7 @@ static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp) | |||
267 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1); | 267 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1); |
268 | 268 | ||
269 | mutex_lock(&bp->hwrm_cmd_lock); | 269 | mutex_lock(&bp->hwrm_cmd_lock); |
270 | for (i = pf->first_vf_id; i < pf->first_vf_id + pf->active_vfs; i++) { | 270 | for (i = pf->first_vf_id; i < pf->first_vf_id + num_vfs; i++) { |
271 | req.vf_id = cpu_to_le16(i); | 271 | req.vf_id = cpu_to_le16(i); |
272 | rc = _hwrm_send_message(bp, &req, sizeof(req), | 272 | rc = _hwrm_send_message(bp, &req, sizeof(req), |
273 | HWRM_CMD_TIMEOUT); | 273 | HWRM_CMD_TIMEOUT); |
@@ -509,7 +509,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs) | |||
509 | 509 | ||
510 | err_out2: | 510 | err_out2: |
511 | /* Free the resources reserved for various VF's */ | 511 | /* Free the resources reserved for various VF's */ |
512 | bnxt_hwrm_func_vf_resource_free(bp); | 512 | bnxt_hwrm_func_vf_resource_free(bp, *num_vfs); |
513 | 513 | ||
514 | err_out1: | 514 | err_out1: |
515 | bnxt_free_vf_resources(bp); | 515 | bnxt_free_vf_resources(bp); |
@@ -519,13 +519,19 @@ err_out1: | |||
519 | 519 | ||
520 | void bnxt_sriov_disable(struct bnxt *bp) | 520 | void bnxt_sriov_disable(struct bnxt *bp) |
521 | { | 521 | { |
522 | if (!bp->pf.active_vfs) | 522 | u16 num_vfs = pci_num_vf(bp->pdev); |
523 | return; | ||
524 | 523 | ||
525 | pci_disable_sriov(bp->pdev); | 524 | if (!num_vfs) |
525 | return; | ||
526 | 526 | ||
527 | /* Free the resources reserved for various VF's */ | 527 | if (pci_vfs_assigned(bp->pdev)) { |
528 | bnxt_hwrm_func_vf_resource_free(bp); | 528 | netdev_warn(bp->dev, "Unable to free %d VFs because some are assigned to VMs.\n", |
529 | num_vfs); | ||
530 | } else { | ||
531 | pci_disable_sriov(bp->pdev); | ||
532 | /* Free the HW resources reserved for various VF's */ | ||
533 | bnxt_hwrm_func_vf_resource_free(bp, num_vfs); | ||
534 | } | ||
529 | 535 | ||
530 | bnxt_free_vf_resources(bp); | 536 | bnxt_free_vf_resources(bp); |
531 | 537 | ||
@@ -552,17 +558,25 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs) | |||
552 | } | 558 | } |
553 | bp->sriov_cfg = true; | 559 | bp->sriov_cfg = true; |
554 | rtnl_unlock(); | 560 | rtnl_unlock(); |
555 | if (!num_vfs) { | 561 | |
556 | bnxt_sriov_disable(bp); | 562 | if (pci_vfs_assigned(bp->pdev)) { |
557 | return 0; | 563 | netdev_warn(dev, "Unable to configure SRIOV since some VFs are assigned to VMs.\n"); |
564 | num_vfs = 0; | ||
565 | goto sriov_cfg_exit; | ||
558 | } | 566 | } |
559 | 567 | ||
560 | /* Check if enabled VFs is same as requested */ | 568 | /* Check if enabled VFs is same as requested */ |
561 | if (num_vfs == bp->pf.active_vfs) | 569 | if (num_vfs && num_vfs == bp->pf.active_vfs) |
562 | return 0; | 570 | goto sriov_cfg_exit; |
571 | |||
572 | /* if there are previous existing VFs, clean them up */ | ||
573 | bnxt_sriov_disable(bp); | ||
574 | if (!num_vfs) | ||
575 | goto sriov_cfg_exit; | ||
563 | 576 | ||
564 | bnxt_sriov_enable(bp, &num_vfs); | 577 | bnxt_sriov_enable(bp, &num_vfs); |
565 | 578 | ||
579 | sriov_cfg_exit: | ||
566 | bp->sriov_cfg = false; | 580 | bp->sriov_cfg = false; |
567 | wake_up(&bp->sriov_cfg_wait); | 581 | wake_up(&bp->sriov_cfg_wait); |
568 | 582 | ||