diff options
author | Ariel Elior <ariele@broadcom.com> | 2013-01-01 00:22:30 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-02 04:45:06 -0500 |
commit | dc1ba591463ca0f7ba2ac9af6ee4a5305f27ca1f (patch) | |
tree | cd2d17baa1de216259f12242ca28babdc7469960 /drivers/net/ethernet | |
parent | 381ac16b10ae9369ebbbd74bb52b970818f68022 (diff) |
bnx2x: VF fastpath
When VF driver is transmitting it must supply the correct mac
address in the parsing BD. This is used for firmware validation
and enforcement and also for tx-switching.
Refactor interrupt ack flow to allow for different BAR addresses of
the hardware in the PF BAR vs the VF BAR.
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')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 68 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 13 |
3 files changed, 50 insertions, 51 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 362451d6033a..18baf7531f05 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -3472,8 +3472,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3472 | cpu_to_le16(vlan_tx_tag_get(skb)); | 3472 | cpu_to_le16(vlan_tx_tag_get(skb)); |
3473 | tx_start_bd->bd_flags.as_bitfield |= | 3473 | tx_start_bd->bd_flags.as_bitfield |= |
3474 | (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); | 3474 | (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); |
3475 | } else | 3475 | } else { |
3476 | tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); | 3476 | /* when transmitting in a vf, start bd must hold the ethertype |
3477 | * for fw to enforce it | ||
3478 | */ | ||
3479 | if (IS_VF(bp)) { | ||
3480 | tx_start_bd->vlan_or_ethertype = | ||
3481 | cpu_to_le16(ntohs(eth->h_proto)); | ||
3482 | } else { | ||
3483 | /* used by FW for packet accounting */ | ||
3484 | tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); | ||
3485 | } | ||
3486 | } | ||
3477 | 3487 | ||
3478 | /* turn on parsing and get a BD */ | 3488 | /* turn on parsing and get a BD */ |
3479 | bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); | 3489 | bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); |
@@ -3489,9 +3499,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3489 | hlen = bnx2x_set_pbd_csum_e2(bp, skb, | 3499 | hlen = bnx2x_set_pbd_csum_e2(bp, skb, |
3490 | &pbd_e2_parsing_data, | 3500 | &pbd_e2_parsing_data, |
3491 | xmit_type); | 3501 | xmit_type); |
3492 | if (IS_MF_SI(bp)) { | 3502 | |
3493 | /* | 3503 | if (IS_MF_SI(bp) || IS_VF(bp)) { |
3494 | * fill in the MAC addresses in the PBD - for local | 3504 | /* fill in the MAC addresses in the PBD - for local |
3495 | * switching | 3505 | * switching |
3496 | */ | 3506 | */ |
3497 | bnx2x_set_fw_mac_addr(&pbd_e2->src_mac_addr_hi, | 3507 | bnx2x_set_fw_mac_addr(&pbd_e2->src_mac_addr_hi, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 91e432dda3de..6b0add22641d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -499,6 +499,39 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc); | |||
499 | /* select_queue callback */ | 499 | /* select_queue callback */ |
500 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); | 500 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); |
501 | 501 | ||
502 | static inline void bnx2x_update_rx_prod(struct bnx2x *bp, | ||
503 | struct bnx2x_fastpath *fp, | ||
504 | u16 bd_prod, u16 rx_comp_prod, | ||
505 | u16 rx_sge_prod) | ||
506 | { | ||
507 | struct ustorm_eth_rx_producers rx_prods = {0}; | ||
508 | u32 i; | ||
509 | |||
510 | /* Update producers */ | ||
511 | rx_prods.bd_prod = bd_prod; | ||
512 | rx_prods.cqe_prod = rx_comp_prod; | ||
513 | rx_prods.sge_prod = rx_sge_prod; | ||
514 | |||
515 | /* Make sure that the BD and SGE data is updated before updating the | ||
516 | * producers since FW might read the BD/SGE right after the producer | ||
517 | * is updated. | ||
518 | * This is only applicable for weak-ordered memory model archs such | ||
519 | * as IA-64. The following barrier is also mandatory since FW will | ||
520 | * assumes BDs must have buffers. | ||
521 | */ | ||
522 | wmb(); | ||
523 | |||
524 | for (i = 0; i < sizeof(rx_prods)/4; i++) | ||
525 | REG_WR(bp, fp->ustorm_rx_prods_offset + i*4, | ||
526 | ((u32 *)&rx_prods)[i]); | ||
527 | |||
528 | mmiowb(); /* keep prod updates ordered */ | ||
529 | |||
530 | DP(NETIF_MSG_RX_STATUS, | ||
531 | "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n", | ||
532 | fp->index, bd_prod, rx_comp_prod, rx_sge_prod); | ||
533 | } | ||
534 | |||
502 | /* reload helper */ | 535 | /* reload helper */ |
503 | int bnx2x_reload_if_running(struct net_device *dev); | 536 | int bnx2x_reload_if_running(struct net_device *dev); |
504 | 537 | ||
@@ -507,9 +540,6 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p); | |||
507 | /* NAPI poll Rx part */ | 540 | /* NAPI poll Rx part */ |
508 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); | 541 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); |
509 | 542 | ||
510 | void bnx2x_update_rx_prod(struct bnx2x *bp, struct bnx2x_fastpath *fp, | ||
511 | u16 bd_prod, u16 rx_comp_prod, u16 rx_sge_prod); | ||
512 | |||
513 | /* NAPI poll Tx part */ | 543 | /* NAPI poll Tx part */ |
514 | int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata); | 544 | int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata); |
515 | 545 | ||
@@ -612,38 +642,6 @@ static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) | |||
612 | fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID]; | 642 | fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID]; |
613 | } | 643 | } |
614 | 644 | ||
615 | static inline void bnx2x_update_rx_prod_gen(struct bnx2x *bp, | ||
616 | struct bnx2x_fastpath *fp, u16 bd_prod, | ||
617 | u16 rx_comp_prod, u16 rx_sge_prod, u32 start) | ||
618 | { | ||
619 | struct ustorm_eth_rx_producers rx_prods = {0}; | ||
620 | u32 i; | ||
621 | |||
622 | /* Update producers */ | ||
623 | rx_prods.bd_prod = bd_prod; | ||
624 | rx_prods.cqe_prod = rx_comp_prod; | ||
625 | rx_prods.sge_prod = rx_sge_prod; | ||
626 | |||
627 | /* | ||
628 | * Make sure that the BD and SGE data is updated before updating the | ||
629 | * producers since FW might read the BD/SGE right after the producer | ||
630 | * is updated. | ||
631 | * This is only applicable for weak-ordered memory model archs such | ||
632 | * as IA-64. The following barrier is also mandatory since FW will | ||
633 | * assumes BDs must have buffers. | ||
634 | */ | ||
635 | wmb(); | ||
636 | |||
637 | for (i = 0; i < sizeof(rx_prods)/4; i++) | ||
638 | REG_WR(bp, start + i*4, ((u32 *)&rx_prods)[i]); | ||
639 | |||
640 | mmiowb(); /* keep prod updates ordered */ | ||
641 | |||
642 | DP(NETIF_MSG_RX_STATUS, | ||
643 | "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n", | ||
644 | fp->index, bd_prod, rx_comp_prod, rx_sge_prod); | ||
645 | } | ||
646 | |||
647 | static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, | 645 | static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, |
648 | u8 segment, u16 index, u8 op, | 646 | u8 segment, u16 index, u8 op, |
649 | u8 update, u32 igu_addr) | 647 | u8 update, u32 igu_addr) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index d27820542c3e..aafcaf610c15 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -1697,15 +1697,6 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) | |||
1697 | return; | 1697 | return; |
1698 | } | 1698 | } |
1699 | 1699 | ||
1700 | void bnx2x_update_rx_prod(struct bnx2x *bp, struct bnx2x_fastpath *fp, | ||
1701 | u16 bd_prod, u16 rx_comp_prod, u16 rx_sge_prod) | ||
1702 | { | ||
1703 | u32 start = BAR_USTRORM_INTMEM + fp->ustorm_rx_prods_offset; | ||
1704 | |||
1705 | bnx2x_update_rx_prod_gen(bp, fp, bd_prod, rx_comp_prod, rx_sge_prod, | ||
1706 | start); | ||
1707 | } | ||
1708 | |||
1709 | irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) | 1700 | irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) |
1710 | { | 1701 | { |
1711 | struct bnx2x *bp = netdev_priv(dev_instance); | 1702 | struct bnx2x *bp = netdev_priv(dev_instance); |
@@ -4620,8 +4611,8 @@ static void bnx2x_attn_int(struct bnx2x *bp) | |||
4620 | void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, | 4611 | void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, |
4621 | u16 index, u8 op, u8 update) | 4612 | u16 index, u8 op, u8 update) |
4622 | { | 4613 | { |
4623 | u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8; | 4614 | u32 igu_addr = bp->igu_base_addr; |
4624 | 4615 | igu_addr += (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8; | |
4625 | bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update, | 4616 | bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update, |
4626 | igu_addr); | 4617 | igu_addr); |
4627 | } | 4618 | } |