aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:30 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:06 -0500
commitdc1ba591463ca0f7ba2ac9af6ee4a5305f27ca1f (patch)
treecd2d17baa1de216259f12242ca28babdc7469960 /drivers/net
parent381ac16b10ae9369ebbbd74bb52b970818f68022 (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')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c20
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h68
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c13
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 */
500u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); 500u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb);
501 501
502static 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 */
503int bnx2x_reload_if_running(struct net_device *dev); 536int 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 */
508int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); 541int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget);
509 542
510void 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 */
514int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata); 544int 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
615static 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
647static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, 645static 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
1700void 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
1709irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) 1700irqreturn_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)
4620void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, 4611void 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}