aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x_main.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index c0abfc4fb34b..713d66939383 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2638,11 +2638,40 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
2638 bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); 2638 bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK);
2639} 2639}
2640 2640
2641/* must be called under the spq lock */
2642static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp)
2643{
2644 struct eth_spe *next_spe = bp->spq_prod_bd;
2645
2646 if (bp->spq_prod_bd == bp->spq_last_bd) {
2647 bp->spq_prod_bd = bp->spq;
2648 bp->spq_prod_idx = 0;
2649 DP(NETIF_MSG_TIMER, "end of spq\n");
2650 } else {
2651 bp->spq_prod_bd++;
2652 bp->spq_prod_idx++;
2653 }
2654 return next_spe;
2655}
2656
2657/* must be called under the spq lock */
2658static inline void bnx2x_sp_prod_update(struct bnx2x *bp)
2659{
2660 int func = BP_FUNC(bp);
2661
2662 /* Make sure that BD data is updated before writing the producer */
2663 wmb();
2664
2665 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
2666 bp->spq_prod_idx);
2667 mmiowb();
2668}
2669
2641/* the slow path queue is odd since completions arrive on the fastpath ring */ 2670/* the slow path queue is odd since completions arrive on the fastpath ring */
2642static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, 2671static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
2643 u32 data_hi, u32 data_lo, int common) 2672 u32 data_hi, u32 data_lo, int common)
2644{ 2673{
2645 int func = BP_FUNC(bp); 2674 struct eth_spe *spe;
2646 2675
2647 DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, 2676 DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
2648 "SPQE (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", 2677 "SPQE (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
@@ -2664,38 +2693,23 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
2664 return -EBUSY; 2693 return -EBUSY;
2665 } 2694 }
2666 2695
2696 spe = bnx2x_sp_get_next(bp);
2697
2667 /* CID needs port number to be encoded int it */ 2698 /* CID needs port number to be encoded int it */
2668 bp->spq_prod_bd->hdr.conn_and_cmd_data = 2699 spe->hdr.conn_and_cmd_data =
2669 cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) | 2700 cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
2670 HW_CID(bp, cid))); 2701 HW_CID(bp, cid)));
2671 bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE); 2702 spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
2672 if (common) 2703 if (common)
2673 bp->spq_prod_bd->hdr.type |= 2704 spe->hdr.type |=
2674 cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT)); 2705 cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
2675 2706
2676 bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi); 2707 spe->data.mac_config_addr.hi = cpu_to_le32(data_hi);
2677 bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo); 2708 spe->data.mac_config_addr.lo = cpu_to_le32(data_lo);
2678 2709
2679 bp->spq_left--; 2710 bp->spq_left--;
2680 2711
2681 if (bp->spq_prod_bd == bp->spq_last_bd) { 2712 bnx2x_sp_prod_update(bp);
2682 bp->spq_prod_bd = bp->spq;
2683 bp->spq_prod_idx = 0;
2684 DP(NETIF_MSG_TIMER, "end of spq\n");
2685
2686 } else {
2687 bp->spq_prod_bd++;
2688 bp->spq_prod_idx++;
2689 }
2690
2691 /* Make sure that BD data is updated before writing the producer */
2692 wmb();
2693
2694 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
2695 bp->spq_prod_idx);
2696
2697 mmiowb();
2698
2699 spin_unlock_bh(&bp->spq_lock); 2713 spin_unlock_bh(&bp->spq_lock);
2700 return 0; 2714 return 0;
2701} 2715}