From 6891dd25d3f82e50979b27fde1980aa96320b975 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 3 Aug 2010 21:49:40 +0000 Subject: bnx2x: Load firmware in open() instead of probe() Loading firmware when actually bringing eth device up. This also will allow driver to be insmoded when filesystem with firmware files is not available yet. Suggested by Stephen Hemminger Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 02bf710629a3..da96d1a18c20 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "bnx2x_cmn.h" #ifdef BCM_VLAN @@ -1206,12 +1207,27 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) return rc; } +static void bnx2x_release_firmware(struct bnx2x *bp) +{ + kfree(bp->init_ops_offsets); + kfree(bp->init_ops); + kfree(bp->init_data); + release_firmware(bp->firmware); +} + /* must be called with rtnl_lock */ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { u32 load_code; int i, rc; + /* Set init arrays */ + rc = bnx2x_init_firmware(bp); + if (rc) { + BNX2X_ERR("Error loading firmware\n"); + return rc; + } + #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) return -EPERM; @@ -1427,6 +1443,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif bnx2x_inc_load_cnt(bp); + bnx2x_release_firmware(bp); + return 0; #ifdef BCM_CNIC @@ -1454,6 +1472,8 @@ load_error1: netif_napi_del(&bnx2x_fp(bp, i, napi)); bnx2x_free_mem(bp); + bnx2x_release_firmware(bp); + return rc; } -- cgit v1.2.3 From bc8acf2c8c3e43fcc192762a9f964b3e9a17748b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 2 Sep 2010 13:07:41 -0700 Subject: drivers/net: avoid some skb->ip_summed initializations fresh skbs have ip_summed set to CHECKSUM_NONE (0) We can avoid setting again skb->ip_summed to CHECKSUM_NONE in drivers. Introduce skb_checksum_none_assert() helper so that we keep this assertion documented in driver sources. Change most occurrences of : skb->ip_summed = CHECKSUM_NONE; by : skb_checksum_none_assert(skb); Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/8139cp.c | 2 +- drivers/net/acenic.c | 2 +- drivers/net/atl1c/atl1c_main.c | 2 +- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/atlx/atl1.c | 2 +- drivers/net/b44.c | 2 +- drivers/net/benet/be_main.c | 2 +- drivers/net/bna/bnad.c | 2 +- drivers/net/bnx2.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/cassini.c | 2 +- drivers/net/chelsio/sge.c | 2 +- drivers/net/cpmac.c | 2 +- drivers/net/cxgb3/sge.c | 2 +- drivers/net/cxgb4/sge.c | 2 +- drivers/net/cxgb4vf/sge.c | 2 +- drivers/net/dm9000.c | 2 +- drivers/net/e1000/e1000_main.c | 3 ++- drivers/net/e1000e/netdev.c | 3 ++- drivers/net/gianfar.c | 2 +- drivers/net/greth.c | 2 +- drivers/net/ibmlana.c | 2 +- drivers/net/igb/igb_main.c | 2 +- drivers/net/igbvf/netdev.c | 2 +- drivers/net/ipg.c | 6 +++--- drivers/net/iseries_veth.c | 2 +- drivers/net/ixgb/ixgb_main.c | 4 ++-- drivers/net/ixgbe/ixgbe_fcoe.c | 5 +++-- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/jme.c | 2 +- drivers/net/ll_temac_main.c | 2 +- drivers/net/macb.c | 2 +- drivers/net/niu.c | 2 +- drivers/net/ns83820.c | 2 +- drivers/net/pasemi_mac.c | 2 +- drivers/net/ps3_gelic_net.c | 4 ++-- drivers/net/qla3xxx.c | 4 ++-- drivers/net/qlcnic/qlcnic_init.c | 2 +- drivers/net/qlge/qlge_main.c | 6 +++--- drivers/net/r8169.c | 2 +- drivers/net/s2io.c | 4 ++-- drivers/net/sb1250-mac.c | 2 +- drivers/net/sfc/rx.c | 2 +- drivers/net/sh_eth.c | 2 +- drivers/net/smsc911x.c | 2 +- drivers/net/spider_net.c | 4 ++-- drivers/net/stmmac/stmmac_main.c | 2 +- drivers/net/tehuti.c | 5 +++-- drivers/net/tg3.c | 2 +- drivers/net/typhoon.c | 2 +- drivers/net/via-velocity.c | 2 +- drivers/net/vmxnet3/vmxnet3_drv.c | 4 ++-- drivers/net/vxge/vxge-main.c | 2 +- drivers/net/xilinx_emaclite.c | 2 +- include/linux/skbuff.h | 15 +++++++++++++++ 56 files changed, 86 insertions(+), 67 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 4a4f6b81e32d..237d4ea5a416 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -561,7 +561,7 @@ rx_status_loop: if (cp_rx_csum_ok(status)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_put(skb, len); diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index b9a591604e5b..41d9911202d0 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -2033,7 +2033,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) skb->csum = htons(csum); skb->ip_summed = CHECKSUM_COMPLETE; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } /* send it up */ diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 61f1634ab3f8..553230eb365c 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1719,7 +1719,7 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, * cannot figure out if the packet is fragmented or not, * so we tell the KERNEL CHECKSUM_NONE */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid) diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 1ae44bb26317..56ace3fbe40d 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1331,7 +1331,7 @@ static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter, u16 pkt_flags; u16 err_flags; - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); pkt_flags = prrs->pkt_flag; err_flags = prrs->err_flag; if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) && diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 5837b0184d4b..e1e0171d6e62 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -1805,7 +1805,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, * the higher layers and let it be sorted out there. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 37617abc1647..7342308718a0 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -818,7 +818,7 @@ static int b44_rx(struct b44 *bp, int budget) copy_skb->data, len); skb = copy_skb; } - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, bp->dev); netif_receive_skb(skb); received++; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 9db10fec8235..dcee7a20c0b9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1016,7 +1016,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb_fill_rx_data(adapter, skb, rxcp, num_rcvd); if (do_pkt_csum(rxcp, adapter->rx_csum)) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); else skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 79c4c2441449..44adc7aefddc 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -510,7 +510,7 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) (flags & BNA_CQ_EF_L4_CKSUM_OK))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); rcb->rxq->rx_packets++; rcb->rxq->rx_bytes += skb->len; diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a0e02aa42214..4ff76e38e788 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -3218,7 +3218,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) } - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (bp->rx_csum && (status & (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_UDP_DATAGRAM))) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index da96d1a18c20..0e4caf411905 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -623,7 +623,7 @@ reuse_rx: /* Set Toeplitz hash for a none-LRO skb */ bnx2x_set_skb_rxhash(bp, cqe, skb); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (bp->rx_csum) { if (likely(BNX2X_RX_CSUM_OK(cqe))) skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 28c88eeec757..32aaadc4734f 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -2149,7 +2149,7 @@ end_copy_pkt: skb->csum = csum_unfold(~csum); skb->ip_summed = CHECKSUM_COMPLETE; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); return len; } diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index f01cfdb995de..1950b9a20ecd 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1388,7 +1388,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) ++st->rx_cso_good; skb->ip_summed = CHECKSUM_UNNECESSARY; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(adapter->vlan_grp && p->vlan_valid)) { st->vlan_xtract++; diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 5a5af1ca7541..fec939f8f65f 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -391,7 +391,7 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv, if (likely(skb)) { skb_put(desc->skb, desc->datalen); desc->skb->protocol = eth_type_trans(desc->skb, priv->dev); - desc->skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(desc->skb); priv->dev->stats.rx_packets++; priv->dev->stats.rx_bytes += desc->datalen; result = desc->skb; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 8ff96c6f6de5..c5a142bea5e9 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2022,7 +2022,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_record_rx_queue(skb, qs - &adap->sge.qs[0]); if (unlikely(p->vlan_valid)) { diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index 6ddb3bb0ce67..9967f3debce7 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -1605,7 +1605,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, rxq->stats.rx_cso++; } } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index e00fd9c36e8b..f10864ddafbe 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1534,7 +1534,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } rxq->stats.rx_cso++; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 4fd6b2b4554b..9f6aeefa06bf 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1056,7 +1056,7 @@ dm9000_rx(struct net_device *dev) if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } netif_rx(skb); dev->stats.rx_packets++; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 3e8ac4baae1b..17f5867b5d9b 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3552,7 +3552,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, struct e1000_hw *hw = &adapter->hw; u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); - skb->ip_summed = CHECKSUM_NONE; + + skb_checksum_none_assert(skb); /* 82543 or newer only */ if (unlikely(hw->mac_type < e1000_82543)) return; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5f3eac6432cb..c9b66f4727e4 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -475,7 +475,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); - skb->ip_summed = CHECKSUM_NONE; + + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set */ if (status & E1000_RXD_STAT_IXSM) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index e6048d6ab0ea..f30adbf86bb2 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2654,7 +2654,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } diff --git a/drivers/net/greth.c b/drivers/net/greth.c index fbeaf70d1727..27d6960ce09e 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -893,7 +893,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit) if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, dev); dev->stats.rx_packets++; diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 294ccfb427cf..0037a696cd0a 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -602,7 +602,7 @@ static void irqrx_handler(struct net_device *dev) /* set up skb fields */ skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* bookkeeping */ dev->stats.rx_packets++; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index d35cc38bf8b2..c4d861b557ca 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -5455,7 +5455,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector, static inline void igb_rx_checksum_adv(struct igb_ring *ring, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set or checksum is disabled through ethtool */ if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) || diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index c539f7c9c3e0..c7fab80d2490 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -103,7 +103,7 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set or checksum is disabled through ethtool */ if ((status_err & E1000_RXD_STAT_IXSM) || diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 72e3d2da9e9f..dc0198092343 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -1213,7 +1213,7 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev, skb_put(skb, framelen); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_rx(skb); sp->rx_buff[entry] = NULL; } @@ -1278,7 +1278,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev, jumbo->skb->protocol = eth_type_trans(jumbo->skb, dev); - jumbo->skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(jumbo->skb); netif_rx(jumbo->skb); } } @@ -1476,7 +1476,7 @@ static int ipg_nic_rx(struct net_device *dev) * IP/TCP/UDP frame was received. Let the * upper layer decide. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Hand off frame for higher layer processing. * The function netif_rx() releases the sk_buff diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index ba1de5973fb2..8df645e78f2e 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1524,7 +1524,7 @@ static void veth_receive(struct veth_lpar_connection *cnx, skb_put(skb, length); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_rx(skb); /* send it up */ dev->stats.rx_packets++; dev->stats.rx_bytes += length; diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 33c4ffe6e103..c2f6e71e1181 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1905,7 +1905,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter, */ if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) || (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); return; } @@ -1913,7 +1913,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter, /* now look at the TCP checksum error bit */ if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) { /* let the stack verify checksum errors */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); adapter->hw_csum_rx_error++; } else { /* TCP checksum is good */ diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 86fa07cb061d..2f1de8b90f9e 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -304,12 +304,13 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, if (!ixgbe_rx_is_fcoe(rx_desc)) goto ddp_out; - skb->ip_summed = CHECKSUM_UNNECESSARY; sterr = le32_to_cpu(rx_desc->wb.upper.status_error); fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR); fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE); if (fcerr == IXGBE_FCERR_BADCRC) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); + else + skb->ip_summed = CHECKSUM_UNNECESSARY; if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q)) fh = (struct fc_frame_header *)(skb->data + diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5e4dc1b0a1bd..3aafe94741ba 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -980,7 +980,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, { u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 5d3c869283a5..bdbd26c60ae6 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -356,7 +356,7 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 99f24f5cac53..1fcd533b1a61 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -936,7 +936,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { if (jme->vlgrp) { diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index bdf2149e5296..874ee01e8d9d 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -760,7 +760,7 @@ static void ll_temac_recv(struct net_device *ndev) skb_put(skb, length); skb->dev = ndev; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* if we're doing rx csum offload, set it up */ if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && diff --git a/drivers/net/macb.c b/drivers/net/macb.c index ff2f158ab0b9..4297f6e8c4bc 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -407,7 +407,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, } skb_reserve(skb, RX_OFFSET); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_put(skb, len); for (frag = first_frag; ; frag = NEXT_RX(frag)) { diff --git a/drivers/net/niu.c b/drivers/net/niu.c index b4cc61f1fc59..1f89f472cbfb 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -3484,7 +3484,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, RCR_ENTRY_ERROR))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else if (!(val & RCR_ENTRY_MULTI)) append_size = len - skb->len; diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 447c2c43769a..4475ca97f031 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -923,7 +923,7 @@ static void rx_irq(struct net_device *ndev) if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) { skb->ip_summed = CHECKSUM_UNNECESSARY; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } skb->protocol = eth_type_trans(skb, ndev); #ifdef NS83820_VLAN_ACCEL_SUPPORT diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 8ab6ae0a6107..828e97cacdbf 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -808,7 +808,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx, skb->csum = (macrx & XCT_MACRX_CSUM_M) >> XCT_MACRX_CSUM_S; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); packets++; tot_bytes += len; diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 87d6b8f36304..5526ab4895e6 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -956,9 +956,9 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* update netdevice statistics */ netdev->stats.rx_packets++; diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 6168a130f33f..7496ed2c34ab 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2029,7 +2029,7 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, dma_unmap_len(lrg_buf_cb2, maplen), PCI_DMA_FROMDEVICE); prefetch(skb->data); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, qdev->ndev); netif_receive_skb(skb); @@ -2076,7 +2076,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, PCI_DMA_FROMDEVICE); prefetch(skb2->data); - skb2->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb2); if (qdev->device_id == QL3022_DEVICE_ID) { /* * Copy the ethhdr from first buffer to second. This diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 8e47d7aea562..26a7d6bca5c7 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1369,7 +1369,7 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } skb->dev = adapter->netdev; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 5a245211fc53..e2d0e108b9aa 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1566,7 +1566,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (qdev->rx_csum && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { @@ -1676,7 +1676,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. @@ -1996,7 +1996,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, } skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 078bbf4e6f19..07b3fb5175e5 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4460,7 +4460,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) ((status == RxProtoIP) && !(opts1 & IPFail))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 7061fc8e99c7..c70ad515383a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -7603,10 +7603,10 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) * Packet with erroneous checksum, let the * upper layers deal with it. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); swstats->mem_freed += skb->truesize; send_up: diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 8e6bd45b9f31..d8249d7653c6 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -1170,7 +1170,7 @@ again: sb->ip_summed = CHECKSUM_UNNECESSARY; /* don't need to set sb->csum */ } else { - sb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(sb); } } prefetch(sb->data); diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 799c461ce7b8..acb372e841b2 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -615,7 +615,7 @@ void __efx_rx_packet(struct efx_channel *channel, EFX_BUG_ON_PARANOID(!skb); /* Set the SKB flags */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Pass the packet up */ netif_receive_skb(skb); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index a812efc3632e..50259dfec583 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -798,7 +798,7 @@ static int sh_eth_rx(struct net_device *ndev) skb->dev = ndev; sh_eth_set_receive_align(skb); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); } if (entry >= RX_RING_SIZE - 1) diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 0909ae934ad0..13ddcd487200 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1048,7 +1048,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_receive_skb(skb); /* Update counters */ diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 1636a34d95dd..cb6bcca9d541 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1000,9 +1000,9 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (data_status & SPIDER_NET_VLAN_PACKET) { /* further enhancements: HW-accel VLAN diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index e3f002eba89a..1ccea76d89ae 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1256,7 +1256,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) if (unlikely(status == csum_none)) { /* always for the old mac 10/100 */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_receive_skb(skb); } else { skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 3128d6a8e9ce..8b3dc1eb4015 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -1297,12 +1297,13 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) ndev->stats.rx_bytes += len; skb_put(skb, len); - skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = eth_type_trans(skb, ndev); /* Non-IP packets aren't checksum-offloaded */ if (GET_RXD_PKT_ID(rxd_val1) == 0) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); + else + skb->ip_summed = CHECKSUM_UNNECESSARY; NETIF_RX_MUX(priv, rxd_val1, rxd_vlan, skb); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bc3af78a869f..9f6ffffc8376 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4719,7 +4719,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) >> RXD_TCPCSUM_SHIFT) == 0xffff)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, tp->dev); diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 3f4681f78262..5dfb39539b3e 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1760,7 +1760,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) { new_skb->ip_summed = CHECKSUM_UNNECESSARY; } else - new_skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(new_skb); spin_lock(&tp->state_lock); if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index fd69095ef6e3..ed7f4f5c4062 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1954,7 +1954,7 @@ static int velocity_tx_srv(struct velocity_info *vptr) */ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (rd->rdesc1.CSM & CSM_IPKT) { if (rd->rdesc1.CSM & CSM_IPOK) { diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index abe0ff53daf3..198ce92af0c3 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1042,11 +1042,11 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter, skb->csum = htons(gdesc->rcd.csum); skb->ip_summed = CHECKSUM_PARTIAL; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 01cdec712b64..5378b849f54f 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -501,7 +501,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); vxge_rx_complete(ring, skb, ext_info.vlan, pkt_length, &ext_info); diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 71122ee4e830..f3f8be5a35fa 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -641,7 +641,7 @@ static void xemaclite_rx_handler(struct net_device *dev) skb_put(skb, len); /* Tell the skb how much data we got */ skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f900ffcd847e..9e8085a89589 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2206,6 +2206,21 @@ static inline void skb_forward_csum(struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; } +/** + * skb_checksum_none_assert - make sure skb ip_summed is CHECKSUM_NONE + * @skb: skb to check + * + * fresh skbs have their ip_summed set to CHECKSUM_NONE. + * Instead of forcing ip_summed to CHECKSUM_NONE, we can + * use this helper, to document places where we make this assertion. + */ +static inline void skb_checksum_none_assert(struct sk_buff *skb) +{ +#ifdef DEBUG + BUG_ON(skb->ip_summed != CHECKSUM_NONE); +#endif +} + bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off); #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ -- cgit v1.2.3 From a22f078867ef362e35c54055878168e6613ff743 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:20 +0000 Subject: bnx2x: Add dual-media changes Add required changes in order to support dual-media boards. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 10 +- drivers/net/bnx2x/bnx2x_cmn.c | 14 +- drivers/net/bnx2x/bnx2x_cmn.h | 3 +- drivers/net/bnx2x/bnx2x_ethtool.c | 176 +++++++--- drivers/net/bnx2x/bnx2x_hsi.h | 111 +++++- drivers/net/bnx2x/bnx2x_link.c | 695 +++++++++++++++++++++++++++++--------- drivers/net/bnx2x/bnx2x_link.h | 62 ++-- drivers/net/bnx2x/bnx2x_main.c | 354 ++++++++++++------- drivers/net/bnx2x/bnx2x_reg.h | 25 ++ 9 files changed, 1074 insertions(+), 376 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index a019c67d2995..137187684f27 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -566,13 +566,13 @@ struct bnx2x_common { struct bnx2x_port { u32 pmf; - u32 link_config; + u32 link_config[LINK_CONFIG_SIZE]; - u32 supported; + u32 supported[LINK_CONFIG_SIZE]; /* link settings - missing defines */ #define SUPPORTED_2500baseX_Full (1 << 15) - u32 advertising; + u32 advertising[LINK_CONFIG_SIZE]; /* link settings - missing defines */ #define ADVERTISED_2500baseX_Full (1 << 15) @@ -931,7 +931,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command); +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, u32 addr, u32 len); @@ -939,7 +939,7 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp); int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); void bnx2x_update_coalesce(struct bnx2x *bp); - +int bnx2x_get_link_cfg_idx(struct bnx2x *bp); static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int wait) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 0e4caf411905..7f1d291eaaa5 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1283,7 +1283,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) common blocks should be initialized, otherwise - not */ if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; @@ -1322,9 +1322,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_init_hw(bp, load_code); if (rc) { BNX2X_ERR("HW init failed, aborting\n"); - bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); goto load_error2; } @@ -1339,7 +1339,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Send LOAD_DONE command to MCP */ if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; @@ -1455,8 +1455,8 @@ load_error4: load_error3: bnx2x_int_disable_sync(bp, 1); if (!BP_NOMCP(bp)) { - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); } bp->port.pmf = 0; /* Free SKBs, SGEs, TPA pool and driver internals */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 32543c32805c..d1e6a8c977d1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -49,10 +49,11 @@ void bnx2x_link_set(struct bnx2x *bp); * Query link status * * @param bp + * @param is_serdes * * @return 0 - link is UP */ -u8 bnx2x_link_test(struct bnx2x *bp); +u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes); /** * Handles link status change diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index dbcfa7a5618f..d058f9716785 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -29,9 +29,12 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); - - cmd->supported = bp->port.supported; - cmd->advertising = bp->port.advertising; + int cfg_idx = bnx2x_get_link_cfg_idx(bp); + /* Dual Media boards present all available port types */ + cmd->supported = bp->port.supported[cfg_idx] | + (bp->port.supported[cfg_idx ^ 1] & + (SUPPORTED_TP | SUPPORTED_FIBRE)); + cmd->advertising = bp->port.advertising[cfg_idx]; if ((bp->state == BNX2X_STATE_OPEN) && !(bp->flags & MF_FUNC_DIS) && @@ -48,22 +51,21 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->speed = vn_max_rate; } } else { - cmd->speed = -1; - cmd->duplex = -1; + cmd->speed = bp->link_params.req_line_speed[cfg_idx]; + cmd->duplex = bp->link_params.req_duplex[cfg_idx]; } - if (bp->link_params.num_phys > 0) { - if (bp->link_params.phy[bp->link_params.num_phys - 1]. - supported & SUPPORTED_FIBRE) - cmd->port = PORT_FIBRE; - else - cmd->port = PORT_TP; - } else - DP(NETIF_MSG_LINK, "No media found\n"); + if (bp->port.supported[cfg_idx] & SUPPORTED_TP) + cmd->port = PORT_TP; + else if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE) + cmd->port = PORT_FIBRE; + else + BNX2X_ERR("XGXS PHY Failure detected\n"); + cmd->phy_address = bp->mdio.prtad; cmd->transceiver = XCVR_INTERNAL; - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) + if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) cmd->autoneg = AUTONEG_ENABLE; else cmd->autoneg = AUTONEG_DISABLE; @@ -85,7 +87,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); - u32 advertising; + u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; if (IS_E1HMF(bp)) return 0; @@ -98,26 +100,81 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + cfg_idx = bnx2x_get_link_cfg_idx(bp); + old_multi_phy_config = bp->link_params.multi_phy_config; + switch (cmd->port) { + case PORT_TP: + if (bp->port.supported[cfg_idx] & SUPPORTED_TP) + break; /* no port change */ + + if (!(bp->port.supported[0] & SUPPORTED_TP || + bp->port.supported[1] & SUPPORTED_TP)) { + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + bp->link_params.multi_phy_config &= + ~PORT_HW_CFG_PHY_SELECTION_MASK; + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + else + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + break; + case PORT_FIBRE: + if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE) + break; /* no port change */ + + if (!(bp->port.supported[0] & SUPPORTED_FIBRE || + bp->port.supported[1] & SUPPORTED_FIBRE)) { + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + bp->link_params.multi_phy_config &= + ~PORT_HW_CFG_PHY_SELECTION_MASK; + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + else + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + break; + default: + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + /* Save new config in case command complete successuly */ + new_multi_phy_config = bp->link_params.multi_phy_config; + /* Get the new cfg_idx */ + cfg_idx = bnx2x_get_link_cfg_idx(bp); + /* Restore old config in case command failed */ + bp->link_params.multi_phy_config = old_multi_phy_config; + DP(NETIF_MSG_LINK, "cfg_idx = %x\n", cfg_idx); + if (cmd->autoneg == AUTONEG_ENABLE) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { + if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) { DP(NETIF_MSG_LINK, "Autoneg not supported\n"); return -EINVAL; } /* advertise the requested speed and duplex if supported */ - cmd->advertising &= bp->port.supported; + cmd->advertising &= bp->port.supported[cfg_idx]; - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->link_params.req_duplex = DUPLEX_FULL; - bp->port.advertising |= (ADVERTISED_Autoneg | + bp->link_params.req_line_speed[cfg_idx] = SPEED_AUTO_NEG; + bp->link_params.req_duplex[cfg_idx] = DUPLEX_FULL; + bp->port.advertising[cfg_idx] |= (ADVERTISED_Autoneg | cmd->advertising); } else { /* forced speed */ /* advertise the requested speed and duplex if supported */ - switch (cmd->speed) { + u32 speed = cmd->speed; + speed |= (cmd->speed_hi << 16); + switch (speed) { case SPEED_10: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_10baseT_Full)) { DP(NETIF_MSG_LINK, "10M full not supported\n"); @@ -127,7 +184,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising = (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_10baseT_Half)) { DP(NETIF_MSG_LINK, "10M half not supported\n"); @@ -141,7 +198,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) case SPEED_100: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_100baseT_Full)) { DP(NETIF_MSG_LINK, "100M full not supported\n"); @@ -151,7 +208,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising = (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_100baseT_Half)) { DP(NETIF_MSG_LINK, "100M half not supported\n"); @@ -169,7 +226,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) { + if (!(bp->port.supported[cfg_idx] & + SUPPORTED_1000baseT_Full)) { DP(NETIF_MSG_LINK, "1G full not supported\n"); return -EINVAL; } @@ -185,7 +243,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) { + if (!(bp->port.supported[cfg_idx] + & SUPPORTED_2500baseX_Full)) { DP(NETIF_MSG_LINK, "2.5G full not supported\n"); return -EINVAL; @@ -201,7 +260,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) { + if (!(bp->port.supported[cfg_idx] + & SUPPORTED_10000baseT_Full)) { DP(NETIF_MSG_LINK, "10G full not supported\n"); return -EINVAL; } @@ -211,20 +271,23 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; default: - DP(NETIF_MSG_LINK, "Unsupported speed\n"); + DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed); return -EINVAL; } - bp->link_params.req_line_speed = cmd->speed; - bp->link_params.req_duplex = cmd->duplex; - bp->port.advertising = advertising; + bp->link_params.req_line_speed[cfg_idx] = speed; + bp->link_params.req_duplex[cfg_idx] = cmd->duplex; + bp->port.advertising[cfg_idx] = advertising; } DP(NETIF_MSG_LINK, "req_line_speed %d\n" DP_LEVEL " req_duplex %d advertising 0x%x\n", - bp->link_params.req_line_speed, bp->link_params.req_duplex, - bp->port.advertising); + bp->link_params.req_line_speed[cfg_idx], + bp->link_params.req_duplex[cfg_idx], + bp->port.advertising[cfg_idx]); + /* Set new config */ + bp->link_params.multi_phy_config = new_multi_phy_config; if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); bnx2x_link_set(bp); @@ -937,10 +1000,9 @@ static void bnx2x_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct bnx2x *bp = netdev_priv(dev); - - epause->autoneg = (bp->link_params.req_flow_ctrl == - BNX2X_FLOW_CTRL_AUTO) && - (bp->link_params.req_line_speed == SPEED_AUTO_NEG); + int cfg_idx = bnx2x_get_link_cfg_idx(bp); + epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] == + BNX2X_FLOW_CTRL_AUTO); epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) == BNX2X_FLOW_CTRL_RX); @@ -956,7 +1018,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct bnx2x *bp = netdev_priv(dev); - + u32 cfg_idx = bnx2x_get_link_cfg_idx(bp); if (IS_E1HMF(bp)) return 0; @@ -964,29 +1026,31 @@ static int bnx2x_set_pauseparam(struct net_device *dev, DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO; if (epause->rx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX; + bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_RX; if (epause->tx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX; + bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_TX; - if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + if (bp->link_params.req_flow_ctrl[cfg_idx] == BNX2X_FLOW_CTRL_AUTO) + bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_NONE; if (epause->autoneg) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { + if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) { DP(NETIF_MSG_LINK, "autoneg not supported\n"); return -EINVAL; } - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) { + bp->link_params.req_flow_ctrl[cfg_idx] = + BNX2X_FLOW_CTRL_AUTO; + } } DP(NETIF_MSG_LINK, - "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl); + "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl[cfg_idx]); if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -1250,12 +1314,12 @@ test_mem_exit: return rc; } -static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up) +static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) { int cnt = 1000; if (link_up) - while (bnx2x_link_test(bp) && cnt--) + while (bnx2x_link_test(bp, is_serdes) && cnt--) msleep(10); } @@ -1527,7 +1591,7 @@ static void bnx2x_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) { struct bnx2x *bp = netdev_priv(dev); - + u8 is_serdes; if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); etest->flags |= ETH_TEST_FL_FAILED; @@ -1542,6 +1606,7 @@ static void bnx2x_self_test(struct net_device *dev, /* offline tests are not supported in MF mode */ if (IS_E1HMF(bp)) etest->flags &= ~ETH_TEST_FL_OFFLINE; + is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; if (etest->flags & ETH_TEST_FL_OFFLINE) { int port = BP_PORT(bp); @@ -1553,11 +1618,12 @@ static void bnx2x_self_test(struct net_device *dev, /* disable input for TX port IF */ REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0); - link_up = (bnx2x_link_test(bp) == 0); + link_up = bp->link_vars.link_up; + bnx2x_nic_unload(bp, UNLOAD_NORMAL); bnx2x_nic_load(bp, LOAD_DIAG); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); + bnx2x_wait_for_link(bp, link_up, is_serdes); if (bnx2x_test_registers(bp) != 0) { buf[0] = 1; @@ -1578,7 +1644,7 @@ static void bnx2x_self_test(struct net_device *dev, bnx2x_nic_load(bp, LOAD_NORMAL); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); + bnx2x_wait_for_link(bp, link_up, is_serdes); } if (bnx2x_test_nvram(bp) != 0) { buf[3] = 1; @@ -1589,7 +1655,7 @@ static void bnx2x_self_test(struct net_device *dev, etest->flags |= ETH_TEST_FL_FAILED; } if (bp->port.pmf) - if (bnx2x_link_test(bp) != 0) { + if (bnx2x_link_test(bp, is_serdes) != 0) { buf[5] = 1; etest->flags |= ETH_TEST_FL_FAILED; } diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index f494bc333f52..bab3b2d8cc7a 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -238,7 +238,88 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u16 xgxs_config_tx[4]; /* 0x1A0 */ - u32 Reserved1[64]; /* 0x1A8 */ + u32 Reserved1[57]; /* 0x1A8 */ + u32 speed_capability_mask2; /* 0x28C */ +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10M_FULL 0x00000001 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3__ 0x00000002 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3___ 0x00000004 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_100M_FULL 0x00000008 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_1G 0x00000010 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_2_DOT_5G 0x00000020 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10G 0x00000040 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12G 0x00000080 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12_DOT_5G 0x00000100 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_13G 0x00000200 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_15G 0x00000400 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_16G 0x00000800 + +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_MASK 0xFFFF0000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_SHIFT 16 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10M_FULL 0x00010000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0__ 0x00020000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0___ 0x00040000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_100M_FULL 0x00080000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_1G 0x00100000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_2_DOT_5G 0x00200000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10G 0x00400000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12G 0x00800000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12_DOT_5G 0x01000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_13G 0x02000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_15G 0x04000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_16G 0x08000000 + + /* In the case where two media types (e.g. copper and fiber) are + present and electrically active at the same time, PHY Selection + will determine which of the two PHYs will be designated as the + Active PHY and used for a connection to the network. */ + u32 multi_phy_config; /* 0x290 */ +#define PORT_HW_CFG_PHY_SELECTION_MASK 0x00000007 +#define PORT_HW_CFG_PHY_SELECTION_SHIFT 0 +#define PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT 0x00000000 +#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY 0x00000001 +#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY 0x00000002 +#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY 0x00000003 +#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY 0x00000004 + + /* When enabled, all second phy nvram parameters will be swapped + with the first phy parameters */ +#define PORT_HW_CFG_PHY_SWAPPED_MASK 0x00000008 +#define PORT_HW_CFG_PHY_SWAPPED_SHIFT 3 +#define PORT_HW_CFG_PHY_SWAPPED_DISABLED 0x00000000 +#define PORT_HW_CFG_PHY_SWAPPED_ENABLED 0x00000008 + + + /* Address of the second external phy */ + u32 external_phy_config2; /* 0x294 */ +#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_MASK 0x000000FF +#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_SHIFT 0 + + /* The second XGXS external PHY type */ +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_MASK 0x0000FF00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SHIFT 8 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_DIRECT 0x00000000 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8071 0x00000100 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8072 0x00000200 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8073 0x00000300 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8705 0x00000400 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8706 0x00000500 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8726 0x00000600 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8481 0x00000700 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SFX7101 0x00000800 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727 0x00000900 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727_NOC 0x00000a00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00 + + /* 4 times 16 bits for all 4 lanes. For some external PHYs (such as + 8706, 8726 and 8727) not all 4 values are needed. */ + u16 xgxs_config2_rx[4]; /* 0x296 */ + u16 xgxs_config2_tx[4]; /* 0x2A0 */ u32 lane_config; #define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff @@ -532,10 +613,17 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ #define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400 /* The default for MCP link configuration, - uses the same defines as link_config */ + uses the same defines as link_config */ u32 mfw_wol_link_cfg; + /* The default for the driver of the second external phy, + uses the same defines as link_config */ + u32 link_config2; /* 0x47C */ - u32 reserved[19]; + /* The default for MCP of the second external phy, + uses the same defines as link_config */ + u32 mfw_wol_link_cfg2; /* 0x480 */ + + u32 Reserved2[17]; /* 0x484 */ }; @@ -703,8 +791,14 @@ struct drv_func_mb { * The optic module verification commands require bootcode * v5.0.6 or later */ -#define DRV_MSG_CODE_VRFY_OPT_MDL 0xa0000000 -#define REQ_BC_VER_4_VRFY_OPT_MDL 0x00050006 +#define DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL 0xa0000000 +#define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006 + /* + * The specific optic module verification command requires bootcode + * v5.2.12 or later + */ +#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 +#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 @@ -939,7 +1033,12 @@ struct shmem2_region { #define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV 0x00000040 #define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV 0x00000080 #define SHMEM_DCC_SUPPORT_DEFAULT SHMEM_DCC_SUPPORT_NONE - + u32 ext_phy_fw_version2[PORT_MAX]; + /* + * For backwards compatibility, if the mf_cfg_addr does not exist + * (the size filed is smaller than 0xc) the mf_cfg resides at the + * end of struct shmem_region + */ }; diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index e2509aab9f0d..571785898970 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -899,6 +899,7 @@ static void bnx2x_xgxs_deassert(struct link_params *params) params->phy[INT_PHY].def_md_devad); } + void bnx2x_link_status_update(struct link_params *params, struct link_vars *vars) { @@ -906,10 +907,6 @@ void bnx2x_link_status_update(struct link_params *params, u8 link_10g; u8 port = params->port; - if (params->switch_cfg == SWITCH_CFG_1G) - vars->phy_flags = PHY_SERDES_FLAG; - else - vars->phy_flags = PHY_XGXS_FLAG; vars->link_status = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, port_mb[port].link_status)); @@ -1880,12 +1877,8 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n", gp_status, vars->phy_link_up, vars->line_speed); - DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x" - " autoneg 0x%x\n", - vars->duplex, - vars->flow_ctrl, vars->autoneg); - DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status); - + DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", + vars->duplex, vars->flow_ctrl, vars->link_status); return rc; } @@ -2164,45 +2157,43 @@ static void bnx2x_link_int_enable(struct link_params *params) REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); } -static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, - u8 is_mi_int) +static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, + u8 exp_mi_int) { - u32 latch_status = 0, is_mi_int_status; - /* Disable the MI INT ( external phy int ) - * by writing 1 to the status register. Link down indication - * is high-active-signal, so in this case we need to write the - * status to clear the XOR + u32 latch_status = 0; + + /** + * Disable the MI INT ( external phy int ) by writing 1 to the + * status register. Link down indication is high-active-signal, + * so in this case we need to write the status to clear the XOR */ /* Read Latched signals */ latch_status = REG_RD(bp, - NIG_REG_LATCH_STATUS_0 + port*8); - is_mi_int_status = REG_RD(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4); - DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x," - "latch_status = 0x%x\n", - is_mi_int, is_mi_int_status, latch_status); + NIG_REG_LATCH_STATUS_0 + port*8); + DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status); /* Handle only those with latched-signal=up.*/ + if (exp_mi_int) + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + else + bnx2x_bits_dis(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + if (latch_status & 1) { - /* For all latched-signal=up,Write original_signal to status */ - if (is_mi_int) - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); - else - bnx2x_bits_dis(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); + /* For all latched-signal=up : Re-Arm Latch signals */ REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, (latch_status & 0xfffe) | (latch_status & 1)); } + /* For all latched-signal=up,Write original_signal to status */ } static void bnx2x_link_int_ack(struct link_params *params, - struct link_vars *vars, u8 is_10g, - u8 is_mi_int) + struct link_vars *vars, u8 is_10g) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -2213,12 +2204,6 @@ static void bnx2x_link_int_ack(struct link_params *params, (NIG_STATUS_XGXS0_LINK10G | NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS)); - if ((params->phy[EXT_PHY1].type - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) || - (params->phy[EXT_PHY1].type - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) { - bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); - } if (vars->phy_link_up) { if (is_10g) { /* Disable the 10G link interrupt @@ -2264,30 +2249,39 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) u32 mask = 0xf0000000; u8 shift = 8*4; u8 digit; + u8 remove_leading_zeros = 1; if (*len < 10) { /* Need more than 10chars for this format */ *str_ptr = '\0'; + (*len)--; return -EINVAL; } while (shift > 0) { shift -= 4; digit = ((num & mask) >> shift); - if (digit < 0xa) + if (digit == 0 && remove_leading_zeros) { + mask = mask >> 4; + continue; + } else if (digit < 0xa) *str_ptr = digit + '0'; else *str_ptr = digit - 0xa + 'a'; + remove_leading_zeros = 0; str_ptr++; + (*len)--; mask = mask >> 4; if (shift == 4*4) { - *str_ptr = ':'; + *str_ptr = '.'; str_ptr++; + (*len)--; + remove_leading_zeros = 1; } } - *str_ptr = '\0'; return 0; } + static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) { str[0] = '\0'; @@ -2302,6 +2296,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, u32 spirom_ver = 0; u8 status = 0; u8 *ver_p = version; + u16 remain_len = len; if (version == NULL || params == NULL) return -EINVAL; bp = params->bp; @@ -2310,10 +2305,28 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, version[0] = '\0'; spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr); - if (params->phy[EXT_PHY1].format_fw_ver) + if (params->phy[EXT_PHY1].format_fw_ver) { status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver, ver_p, - &len); + &remain_len); + ver_p += (len - remain_len); + } + if ((params->num_phys == MAX_PHYS) && + (params->phy[EXT_PHY2].ver_addr != 0)) { + spirom_ver = REG_RD(bp, + params->phy[EXT_PHY2].ver_addr); + if (params->phy[EXT_PHY2].format_fw_ver) { + *ver_p = '/'; + ver_p++; + remain_len--; + status |= params->phy[EXT_PHY2].format_fw_ver( + spirom_ver, + ver_p, + &remain_len); + ver_p = version + (len - remain_len); + } + } + *ver_p = '\0'; return status; } @@ -2550,30 +2563,56 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) } -u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) +/** + * This function comes to reflect the actual link state read DIRECTLY from the + * HW + */ +u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, + u8 is_serdes) { struct bnx2x *bp = params->bp; u16 gp_status = 0, phy_index = 0; + u8 ext_phy_link_up = 0, serdes_phy_type; + struct link_vars temp_vars; CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); /* link is up only if both local phy and external phy are up */ - if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { - u8 ext_phy_link_up = 1; - struct link_vars temp_vars; + if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) + return -ESRCH; + + switch (params->num_phys) { + case 1: + /* No external PHY */ + return 0; + case 2: + ext_phy_link_up = params->phy[EXT_PHY1].read_status( + ¶ms->phy[EXT_PHY1], + params, &temp_vars); + break; + case 3: /* Dual Media */ for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { - if (params->phy[phy_index].read_status) - ext_phy_link_up &= + serdes_phy_type = ((params->phy[phy_index].media_type == + ETH_PHY_SFP_FIBER) || + (params->phy[phy_index].media_type == + ETH_PHY_XFP_FIBER)); + + if (is_serdes != serdes_phy_type) + continue; + if (params->phy[phy_index].read_status) { + ext_phy_link_up |= params->phy[phy_index].read_status( ¶ms->phy[phy_index], params, &temp_vars); + } } - if (ext_phy_link_up) - return 0; + break; } + if (ext_phy_link_up) + return 0; return -ESRCH; } @@ -2619,6 +2658,19 @@ static u8 bnx2x_link_initialize(struct link_params *params, if (!non_ext_phy) for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { + /** + * No need to initialize second phy in case of first + * phy only selection. In case of second phy, we do + * need to initialize the first phy, since they are + * connected. + **/ + if (phy_index == EXT_PHY2 && + (bnx2x_phy_selection(params) == + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { + DP(NETIF_MSG_LINK, "Not initializing" + "second phy\n"); + continue; + } params->phy[phy_index].config_init( ¶ms->phy[phy_index], params, vars); @@ -2816,6 +2868,40 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) if (!ext_phy_link_up) { ext_phy_link_up = 1; active_external_phy = phy_index; + } else { + switch (bnx2x_phy_selection(params)) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + /** + * In this option, the first PHY makes sure to pass the + * traffic through itself only. + * Its not clear how to reset the link on the second phy + **/ + active_external_phy = EXT_PHY1; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + /** + * In this option, the first PHY makes sure to pass the + * traffic through the second PHY. + **/ + active_external_phy = EXT_PHY2; + break; + default: + /** + * Link indication on both PHYs with the following cases + * is invalid: + * - FIRST_PHY means that second phy wasn't initialized, + * hence its link is expected to be down + * - SECOND_PHY means that first phy should not be able + * to link up by itself (using configuration) + * - DEFAULT should be overriden during initialiazation + **/ + DP(NETIF_MSG_LINK, "Invalid link indication" + "mpc=0x%x. DISABLING LINK !!!\n", + params->multi_phy_config); + ext_phy_link_up = 0; + break; + } } } prev_line_speed = vars->line_speed; @@ -2845,6 +2931,21 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) * the external phy. */ vars->link_status |= phy_vars[active_external_phy].link_status; + + /** + * if active_external_phy is first PHY and link is up - disable + * disable TX on second external PHY + */ + if (active_external_phy == EXT_PHY1) { + if (params->phy[EXT_PHY2].phy_specific_func) { + DP(NETIF_MSG_LINK, "Disabling TX on" + " EXT_PHY2\n"); + params->phy[EXT_PHY2].phy_specific_func( + ¶ms->phy[EXT_PHY2], + params, DISABLE_TX); + } + } + ext_phy_line_speed = phy_vars[active_external_phy].line_speed; vars->duplex = phy_vars[active_external_phy].duplex; if (params->phy[active_external_phy].supported & @@ -2853,6 +2954,17 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", active_external_phy); } + + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].flags & + FLAGS_REARM_LATCH_SIGNAL) { + bnx2x_rearm_latch_signal(bp, port, + phy_index == + active_external_phy); + break; + } + } DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," " ext_phy_line_speed = %d\n", vars->flow_ctrl, vars->link_status, ext_phy_line_speed); @@ -2885,7 +2997,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) (vars->line_speed == SPEED_15000) || (vars->line_speed == SPEED_16000)); - bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); + bnx2x_link_int_ack(params, vars, link_10g); /** * In case external phy link is up, and internal link is down @@ -3898,11 +4010,11 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u32 val; - u32 fw_resp; + u32 val, cmd; + u32 fw_resp, fw_cmd_param; char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; - + phy->flags &= ~FLAGS_SFP_NOT_APPROVED; val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port].config)); @@ -3912,15 +4024,27 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, return 0; } - /* Ask the FW to validate the module */ - if (!(params->feature_config_flags & - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) { + if (params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) { + /* Use specific phy request */ + cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL; + } else if (params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) { + /* Use first phy request only in case of non-dual media*/ + if (DUAL_MEDIA(params)) { + DP(NETIF_MSG_LINK, "FW does not support OPT MDL " + "verification\n"); + return -EINVAL; + } + cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL; + } else { + /* No support in OPT MDL detection */ DP(NETIF_MSG_LINK, "FW does not support OPT MDL " - "verification\n"); + "verification\n"); return -EINVAL; } - - fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL); + fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl); + fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param); if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { DP(NETIF_MSG_LINK, "Approved module\n"); return 0; @@ -3947,6 +4071,7 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected," " Port %d from %s part number %s\n", params->port, vendor_name, vendor_pn); + phy->flags |= FLAGS_SFP_NOT_APPROVED; return -EINVAL; } @@ -4092,6 +4217,27 @@ static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, return 0; } +static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, + struct link_params *params, + u32 action) +{ + struct bnx2x *bp = params->bp; + + switch (action) { + case DISABLE_TX: + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + break; + case ENABLE_TX: + if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) + bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); + break; + default: + DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n", + action); + return; + } +} + static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, struct link_params *params) { @@ -4625,6 +4771,19 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); + /** + * Power down the XAUI until link is up in case of dual-media + * and 1G + */ + if (DUAL_MEDIA(params)) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, &val); + val |= (3<<10); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, val); + } } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && ((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && @@ -4766,7 +4925,15 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u8 link_up = 0; u16 link_status = 0; - u16 rx_alarm_status, val1; + u16 rx_alarm_status, lasi_ctrl, val1; + + /* If PHY is not initialized, do not check link status */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + &lasi_ctrl); + if (!lasi_ctrl) + return 0; + /* Check the LASI */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, @@ -4837,7 +5004,8 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, ((1<<5) | (1<<2))); } - + DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n"); + bnx2x_8727_specific_func(phy, params, ENABLE_TX); /* If transmitter is disabled, ignore false link up indication */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); @@ -4867,6 +5035,24 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, } if (link_up) bnx2x_ext_phy_resolve_fc(phy, params, vars); + + if ((DUAL_MEDIA(params)) && + (phy->req_line_speed == SPEED_1000)) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, &val1); + /** + * In case of dual-media board and 1G, power up the XAUI side, + * otherwise power it down. For 10G it is done automatically + */ + if (link_up) + val1 &= ~(3<<10); + else + val1 |= (3<<10); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, val1); + } return link_up; } @@ -4876,6 +5062,9 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; /* Disable Transmitter */ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + /* Clear LASI */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0); + } /******************************************************************/ @@ -4973,16 +5162,11 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp, } static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; - /** - * This phy uses the NIG latch mechanism since link indication - * arrives through its LED4 and not via its LASI signal, so we - * get steady signal instead of clear on read - */ bnx2x_wait_reset_complete(bp, phy); bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); @@ -5122,7 +5306,11 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; + u8 initialize = 1; + u16 val; u16 temp; + u32 actual_phy_selection; + u8 rc = 0; msleep(1); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_HIGH, @@ -5135,10 +5323,55 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, */ temp = vars->line_speed; vars->line_speed = SPEED_10000; - bnx2x_set_autoneg(phy, params, vars, 0); - bnx2x_program_serdes(phy, params, vars); + bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0); + bnx2x_program_serdes(¶ms->phy[INT_PHY], params, vars); vars->line_speed = temp; - return bnx2x_848xx_cmn_config_init(phy, params, vars); + + /* Set dual-media configuration according to configuration */ + + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_MEDIA, &val); + val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | + MDIO_CTL_REG_84823_MEDIA_LINE_MASK | + MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN | + MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK | + MDIO_CTL_REG_84823_MEDIA_FIBER_1G); + val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI | + MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L; + + actual_phy_selection = bnx2x_phy_selection(params); + + switch (actual_phy_selection) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + /* Do nothing. Essentialy this is like the priority copper */ + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER; + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + /* Do nothing here. The first PHY won't be initialized at all */ + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN; + initialize = 0; + break; + } + if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000) + val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G; + + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_MEDIA, val); + DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", + params->multi_phy_config, val); + + if (initialize) + rc = bnx2x_848xx_cmn_config_init(phy, params, vars); + else + bnx2x_save_848xx_spirom_version(phy, params); + return rc; } static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, @@ -5426,7 +5659,8 @@ static struct bnx2x_phy phy_null = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_serdes = { @@ -5461,7 +5695,8 @@ static struct bnx2x_phy phy_serdes = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_xgxs = { @@ -5497,7 +5732,8 @@ static struct bnx2x_phy phy_xgxs = { .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback, .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_7101 = { @@ -5527,7 +5763,8 @@ static struct bnx2x_phy phy_7101 = { .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback, .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver, .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8073 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, @@ -5558,7 +5795,8 @@ static struct bnx2x_phy phy_8073 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8705 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705, @@ -5586,7 +5824,8 @@ static struct bnx2x_phy phy_8705 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8706 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, @@ -5615,7 +5854,8 @@ static struct bnx2x_phy phy_8706 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8726 = { @@ -5647,7 +5887,8 @@ static struct bnx2x_phy phy_8726 = { .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8727 = { @@ -5677,12 +5918,14 @@ static struct bnx2x_phy phy_8727 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func }; static struct bnx2x_phy phy_8481 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, .addr = 0xff, - .flags = FLAGS_FAN_FAILURE_DET_REQ, + .flags = FLAGS_FAN_FAILURE_DET_REQ | + FLAGS_REARM_LATCH_SIGNAL, .def_md_devad = 0, .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, @@ -5711,13 +5954,15 @@ static struct bnx2x_phy phy_8481 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_84823 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, .addr = 0xff, - .flags = FLAGS_FAN_FAILURE_DET_REQ, + .flags = FLAGS_FAN_FAILURE_DET_REQ | + FLAGS_REARM_LATCH_SIGNAL, .def_md_devad = 0, .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, @@ -5746,7 +5991,8 @@ static struct bnx2x_phy phy_84823 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; /*****************************************************************/ @@ -5767,14 +6013,23 @@ static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, * shmem. When num_phys is greater than 1, than this value * applies only to EXT_PHY1 */ + if (phy_index == INT_PHY || phy_index == EXT_PHY1) { + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); + + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + } else { + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); - rx = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); - - tx = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); + } phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff); @@ -5794,6 +6049,11 @@ static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, offsetof(struct shmem_region, dev_info.port_hw_config[port].external_phy_config)); break; + case EXT_PHY2: + ext_phy_config = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].external_phy_config2)); + break; default: DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index); return -EINVAL; @@ -5844,6 +6104,7 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, + u32 shmem2_base, u8 port, struct bnx2x_phy *phy) { @@ -5905,15 +6166,30 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, */ config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, dev_info.shared_hw_config.config2)); - - phy->ver_addr = shmem_base + offsetof(struct shmem_region, - port_mb[port].ext_phy_fw_version); + if (phy_index == EXT_PHY1) { + phy->ver_addr = shmem_base + offsetof(struct shmem_region, + port_mb[port].ext_phy_fw_version); /* Check specific mdc mdio settings */ if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) mdc_mdio_access = config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; + } else { + u32 size = REG_RD(bp, shmem2_base); + if (size > + offsetof(struct shmem2_region, ext_phy_fw_version2)) { + phy->ver_addr = shmem2_base + + offsetof(struct shmem2_region, + ext_phy_fw_version2[port]); + } + /* Check specific mdc mdio settings */ + if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) + mdc_mdio_access = (config2 & + SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >> + (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT - + SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT); + } phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); /** @@ -5931,30 +6207,41 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, } static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, - u8 port, struct bnx2x_phy *phy) + u32 shmem2_base, u8 port, struct bnx2x_phy *phy) { u8 status = 0; phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; if (phy_index == INT_PHY) return bnx2x_populate_int_phy(bp, shmem_base, port, phy); - status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, + status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base, port, phy); return status; } static void bnx2x_phy_def_cfg(struct link_params *params, struct bnx2x_phy *phy, - u8 actual_phy_idx) + u8 phy_index) { struct bnx2x *bp = params->bp; u32 link_config; /* Populate the default phy configuration for MF mode */ - link_config = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port].link_config)); - phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + if (phy_index == EXT_PHY2) { + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config2)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].speed_capability_mask2)); + } else { + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. - port_hw_config[params->port].speed_capability_mask)); + port_hw_config[params->port].speed_capability_mask)); + } + DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask" + " 0x%x\n", phy_index, link_config, phy->speed_cap_mask); phy->req_duplex = DUPLEX_FULL; switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { @@ -6001,23 +6288,66 @@ static void bnx2x_phy_def_cfg(struct link_params *params, } } +u32 bnx2x_phy_selection(struct link_params *params) +{ + u32 phy_config_swapped, prio_cfg; + u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT; + + phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; + + prio_cfg = params->multi_phy_config & + PORT_HW_CFG_PHY_SELECTION_MASK; + + if (phy_config_swapped) { + switch (prio_cfg) { + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + break; + } + } else + return_cfg = prio_cfg; + + return return_cfg; +} + + u8 bnx2x_phy_probe(struct link_params *params) { u8 phy_index, actual_phy_idx, link_cfg_idx; - + u32 phy_config_swapped; struct bnx2x *bp = params->bp; struct bnx2x_phy *phy; params->num_phys = 0; DP(NETIF_MSG_LINK, "Begin phy probe\n"); + phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; for (phy_index = INT_PHY; phy_index < MAX_PHYS; phy_index++) { link_cfg_idx = LINK_CONFIG_IDX(phy_index); actual_phy_idx = phy_index; - + if (phy_config_swapped) { + if (phy_index == EXT_PHY1) + actual_phy_idx = EXT_PHY2; + else if (phy_index == EXT_PHY2) + actual_phy_idx = EXT_PHY1; + } + DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x," + " actual_phy_idx %x\n", phy_config_swapped, + phy_index, actual_phy_idx); phy = ¶ms->phy[actual_phy_idx]; if (bnx2x_populate_phy(bp, phy_index, params->shmem_base, - params->port, + params->shmem2_base, params->port, phy) != 0) { params->num_phys = 0; DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n", @@ -6031,7 +6361,7 @@ u8 bnx2x_phy_probe(struct link_params *params) if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) break; - bnx2x_phy_def_cfg(params, phy, actual_phy_idx); + bnx2x_phy_def_cfg(params, phy, phy_index); params->num_phys++; } @@ -6049,23 +6379,30 @@ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) static void set_phy_vars(struct link_params *params) { struct bnx2x *bp = params->bp; - u8 actual_phy_idx, phy_index; - + u8 actual_phy_idx, phy_index, link_cfg_idx; + u8 phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; for (phy_index = INT_PHY; phy_index < params->num_phys; phy_index++) { - + link_cfg_idx = LINK_CONFIG_IDX(phy_index); actual_phy_idx = phy_index; + if (phy_config_swapped) { + if (phy_index == EXT_PHY1) + actual_phy_idx = EXT_PHY2; + else if (phy_index == EXT_PHY2) + actual_phy_idx = EXT_PHY1; + } params->phy[actual_phy_idx].req_flow_ctrl = - params->req_flow_ctrl; + params->req_flow_ctrl[link_cfg_idx]; params->phy[actual_phy_idx].req_line_speed = - params->req_line_speed; + params->req_line_speed[link_cfg_idx]; params->phy[actual_phy_idx].speed_cap_mask = - params->speed_cap_mask; + params->speed_cap_mask[link_cfg_idx]; params->phy[actual_phy_idx].req_duplex = - params->req_duplex; + params->req_duplex[link_cfg_idx]; DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," " speed_cap_mask %x\n", @@ -6078,11 +6415,11 @@ static void set_phy_vars(struct link_params *params) u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 val; - DP(NETIF_MSG_LINK, "Phy Initialization started\n"); - DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n", - params->req_line_speed, params->req_flow_ctrl); + DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[0], params->req_flow_ctrl[0]); + DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[1], params->req_flow_ctrl[1]); vars->link_status = 0; vars->phy_link_up = 0; vars->link_up = 0; @@ -6196,21 +6533,23 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) (params->loopback_mode == LOOPBACK_EXT_PHY)) { vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - vars->phy_flags = PHY_XGXS_FLAG; - - val = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR+ - params->port*0x18); + vars->duplex = DUPLEX_FULL; + if (params->req_line_speed[0] == SPEED_1000) { + vars->line_speed = SPEED_1000; + vars->mac_type = MAC_TYPE_EMAC; + } else { + vars->line_speed = SPEED_10000; + vars->mac_type = MAC_TYPE_BMAC; + } bnx2x_xgxs_deassert(params); bnx2x_link_initialize(params, vars); - vars->mac_type = MAC_TYPE_BMAC; - + if (params->req_line_speed[0] == SPEED_1000) { + bnx2x_emac_program(params, vars); + bnx2x_emac_enable(params, vars, 0); + } else bnx2x_bmac_enable(params, vars, 0); if (params->loopback_mode == LOOPBACK_XGXS) { @@ -6311,7 +6650,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /****************************************************************************/ /* Common function */ /****************************************************************************/ -static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index) { struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; @@ -6321,7 +6660,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { /* Extract the ext phy address for the port */ - if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate_phy failed\n"); @@ -6419,7 +6758,8 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } -static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 phy_index) { u32 val; s8 port; @@ -6435,7 +6775,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) msleep(5); for (port = 0; port < PORT_MAX; port++) { /* Extract the ext phy address for the port */ - if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); @@ -6455,10 +6795,10 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } - -static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 phy_index) { - s8 port, first_port, i; + s8 port; u32 swap_val, swap_override; struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; @@ -6466,18 +6806,19 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override)); - msleep(5); + port = 1; - if (swap_val && swap_override) - first_port = PORT_0; - else - first_port = PORT_1; + bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override)); + + /* Calculate the port based on port swap */ + port ^= (swap_val && swap_override); + + msleep(5); /* PART1 - Reset both phys */ - for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) { + for (port = PORT_MAX - 1; port >= PORT_0; port--) { /* Extract the ext phy address for the port */ - if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); @@ -6528,35 +6869,32 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 phy_index, + u32 ext_phy_type) { u8 rc = 0; - u32 ext_phy_type; - - DP(NETIF_MSG_LINK, "Begin common phy init\n"); - - /* Read the ext_phy_type for arbitrary port(0) */ - ext_phy_type = XGXS_EXT_PHY_TYPE( - REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[0].external_phy_config))); switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - { - rc = bnx2x_8073_common_init_phy(bp, shmem_base); + rc = bnx2x_8073_common_init_phy(bp, shmem_base, + shmem2_base, phy_index); break; - } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: - rc = bnx2x_8727_common_init_phy(bp, shmem_base); + rc = bnx2x_8727_common_init_phy(bp, shmem_base, + shmem2_base, phy_index); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: /* GPIO1 affects both ports, so there's need to pull it for single port alone */ - rc = bnx2x_8726_common_init_phy(bp, shmem_base); + rc = bnx2x_8726_common_init_phy(bp, shmem_base, + shmem2_base, phy_index); + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: + rc = -EINVAL; break; default: DP(NETIF_MSG_LINK, @@ -6568,14 +6906,38 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) return rc; } +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base) +{ + u8 rc = 0; + u8 phy_index; + u32 ext_phy_type, ext_phy_config; + DP(NETIF_MSG_LINK, "Begin common phy init\n"); + + if (CHIP_REV_IS_EMUL(bp)) + return 0; + + /* Read the ext_phy_type for arbitrary port(0) */ + for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; + phy_index++) { + ext_phy_config = bnx2x_get_ext_phy_config(bp, + shmem_base, + phy_index, 0); + ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); + rc |= bnx2x_ext_phy_common_init(bp, shmem_base, + shmem2_base, + phy_index, ext_phy_type); + } + return rc; +} -u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base) +u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base) { u8 phy_index; struct bnx2x_phy phy; for (phy_index = INT_PHY; phy_index < MAX_PHYS; phy_index++) { - if (bnx2x_populate_phy(bp, phy_index, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 0, &phy) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); return 0; @@ -6589,13 +6951,14 @@ u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base) u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 port) { u8 phy_index, fan_failure_det_req = 0; struct bnx2x_phy phy; for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; phy_index++) { - if (bnx2x_populate_phy(bp, phy_index, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 35f665f97be6..9115c125aeaf 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -59,13 +59,18 @@ #define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1) /* Single Media board contains single external phy */ #define SINGLE_MEDIA(params) (params->num_phys == 2) +/* Dual Media board contains two external phy with different media */ +#define DUAL_MEDIA(params) (params->num_phys == 3) +#define FW_PARAM_MDIO_CTRL_OFFSET 16 +#define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ + (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) /***********************************************************/ /* Structs */ /***********************************************************/ #define INT_PHY 0 #define EXT_PHY1 1 - -#define MAX_PHYS 2 +#define EXT_PHY2 2 +#define MAX_PHYS 3 /* Same configuration is shared between the XGXS and the first external phy */ #define LINK_CONFIG_SIZE (MAX_PHYS - 1) @@ -91,6 +96,8 @@ typedef u8 (*format_fw_ver_t)(u32 raw, u8 *str, u16 *len); typedef void (*hw_reset_t)(struct bnx2x_phy *phy, struct link_params *params); typedef void (*set_link_led_t)(struct bnx2x_phy *phy, struct link_params *params, u8 mode); +typedef void (*phy_specific_func_t)(struct bnx2x_phy *phy, + struct link_params *params, u32 action); struct bnx2x_phy { u32 type; @@ -106,7 +113,9 @@ struct bnx2x_phy { /* Fan failure detection required */ #define FLAGS_FAN_FAILURE_DET_REQ (1<<2) /* Initialize first the XGXS and only then the phy itself */ -#define FLAGS_INIT_XGXS_FIRST (1<<3) +#define FLAGS_INIT_XGXS_FIRST (1<<3) +#define FLAGS_REARM_LATCH_SIGNAL (1<<6) +#define FLAGS_SFP_NOT_APPROVED (1<<7) u8 def_md_devad; u8 reserved; @@ -161,6 +170,11 @@ struct bnx2x_phy { /* Set link led mode (on/off/oper)*/ set_link_led_t set_link_led; + + /* PHY Specific tasks */ + phy_specific_func_t phy_specific_func; +#define DISABLE_TX 1 +#define ENABLE_TX 2 }; /* Inputs parameters to the CLC */ @@ -177,18 +191,18 @@ struct link_params { #define LOOPBACK_EXT_PHY 4 #define LOOPBACK_EXT 5 - u16 req_duplex; - u16 req_flow_ctrl; - u16 req_fc_auto_adv; /* Should be set to TX / BOTH when - req_flow_ctrl is set to AUTO */ - u16 req_line_speed; /* Also determine AutoNeg */ - /* Device parameters */ u8 mac_addr[6]; + u16 req_duplex[LINK_CONFIG_SIZE]; + u16 req_flow_ctrl[LINK_CONFIG_SIZE]; + + u16 req_line_speed[LINK_CONFIG_SIZE]; /* Also determine AutoNeg */ + /* shmem parameters */ u32 shmem_base; - u32 speed_cap_mask; + u32 shmem2_base; + u32 speed_cap_mask[LINK_CONFIG_SIZE]; u32 switch_cfg; #define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH #define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH @@ -202,6 +216,7 @@ struct link_params { u32 feature_config_flags; #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) +#define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) /* Will be populated during common init */ struct bnx2x_phy phy[MAX_PHYS]; @@ -210,9 +225,12 @@ struct link_params { u8 rsrv; u16 hw_led_mode; /* part of the hw_config read from the shmem */ + u32 multi_phy_config; /* Device pointer passed to all callback functions */ struct bnx2x *bp; + u16 req_fc_auto_adv; /* Should be set to TX / BOTH when + req_flow_ctrl is set to AUTO */ }; /* Output parameters */ @@ -233,12 +251,6 @@ struct link_vars { u16 flow_ctrl; u16 ieee_fc; - u32 autoneg; -#define AUTO_NEG_DISABLED 0x0 -#define AUTO_NEG_ENABLED 0x1 -#define AUTO_NEG_COMPLETE 0x2 -#define AUTO_NEG_PARALLEL_DETECTION_USED 0x3 - /* The same definitions as the shmem parameter */ u32 link_status; }; @@ -246,8 +258,6 @@ struct link_vars { /***********************************************************/ /* Functions */ /***********************************************************/ - -/* Initialize the phy */ u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output); /* Reset the link. Should be called when driver or interface goes down @@ -298,10 +308,11 @@ void bnx2x_handle_module_detect_int(struct link_params *params); /* Get the actual link status. In case it returns 0, link is up, otherwise link is down*/ -u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); +u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars, + u8 is_serdes); /* One-time initialization for external phy after power up */ -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base); +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base); /* Reset the external PHY using GPIO */ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); @@ -316,12 +327,19 @@ u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, void bnx2x_hw_reset_phy(struct link_params *params); /* Checks if HW lock is required for this phy/board type */ -u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base); +u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base); + /* Returns the aggregative supported attributes of the phys on board */ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx); + +/* Check swap bit and adjust PHY order */ +u32 bnx2x_phy_selection(struct link_params *params); + /* Probe the phys on board, and populate them in "params" */ u8 bnx2x_phy_probe(struct link_params *params); /* Checks if fan failure detection is required on one of the phys on board */ -u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u8 port); +u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 port); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 30618c7ed4ed..f0a788467fb1 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1227,26 +1227,66 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) return 0; } +int bnx2x_get_link_cfg_idx(struct bnx2x *bp) +{ + u32 sel_phy_idx = 0; + if (bp->link_vars.link_up) { + sel_phy_idx = EXT_PHY1; + /* In case link is SERDES, check if the EXT_PHY2 is the one */ + if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) && + (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE)) + sel_phy_idx = EXT_PHY2; + } else { + + switch (bnx2x_phy_selection(&bp->link_params)) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + sel_phy_idx = EXT_PHY1; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + sel_phy_idx = EXT_PHY2; + break; + } + } + /* + * The selected actived PHY is always after swapping (in case PHY + * swapping is enabled). So when swapping is enabled, we need to reverse + * the configuration + */ + + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) { + if (sel_phy_idx == EXT_PHY1) + sel_phy_idx = EXT_PHY2; + else if (sel_phy_idx == EXT_PHY2) + sel_phy_idx = EXT_PHY1; + } + return LINK_CONFIG_IDX(sel_phy_idx); +} + void bnx2x_calc_fc_adv(struct bnx2x *bp) { + u8 cfg_idx = bnx2x_get_link_cfg_idx(bp); switch (bp->link_vars.ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | + bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: - bp->port.advertising |= (ADVERTISED_Asym_Pause | + bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause | ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: - bp->port.advertising |= ADVERTISED_Asym_Pause; + bp->port.advertising[cfg_idx] |= ADVERTISED_Asym_Pause; break; default: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | + bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause); break; } @@ -1257,7 +1297,8 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) { if (!BP_NOMCP(bp)) { u8 rc; - + int cfx_idx = bnx2x_get_link_cfg_idx(bp); + u16 req_line_speed = bp->link_params.req_line_speed[cfx_idx]; /* Initialize link parameters structure variables */ /* It is recommended to turn off RX FC for jumbo frames for better performance */ @@ -1268,8 +1309,10 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) bnx2x_acquire_phy_lock(bp); - if (load_mode == LOAD_DIAG) + if (load_mode == LOAD_DIAG) { bp->link_params.loopback_mode = LOOPBACK_XGXS; + bp->link_params.req_line_speed[cfx_idx] = SPEED_10000; + } rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); @@ -1281,7 +1324,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); bnx2x_link_report(bp); } - + bp->link_params.req_line_speed[cfx_idx] = req_line_speed; return rc; } BNX2X_ERR("Bootcode is missing - can not initialize link\n"); @@ -1311,13 +1354,14 @@ static void bnx2x__link_reset(struct bnx2x *bp) BNX2X_ERR("Bootcode is missing - can not reset link\n"); } -u8 bnx2x_link_test(struct bnx2x *bp) +u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes) { u8 rc = 0; if (!BP_NOMCP(bp)) { bnx2x_acquire_phy_lock(bp); - rc = bnx2x_test_link(&bp->link_params, &bp->link_vars); + rc = bnx2x_test_link(&bp->link_params, &bp->link_vars, + is_serdes); bnx2x_release_phy_lock(bp); } else BNX2X_ERR("Bootcode is missing - can not test link\n"); @@ -1586,7 +1630,7 @@ static void bnx2x_pmf_update(struct bnx2x *bp) */ /* send the MCP a request, block until there is a reply */ -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) { int func = BP_FUNC(bp); u32 seq = ++bp->fw_seq; @@ -1595,6 +1639,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; mutex_lock(&bp->fw_mb_mutex); + SHMEM_WR(bp, func_mb[func].drv_mb_param, param); SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); @@ -1716,9 +1761,9 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) /* Report results to MCP */ if (dcc_event) - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE); + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0); else - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0); } /* must be called under the spq lock */ @@ -3848,6 +3893,7 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) bnx2x_fan_failure_det_req( bp, bp->common.shmem_base, + bp->common.shmem2_base, port); } @@ -4116,7 +4162,8 @@ static int bnx2x_init_common(struct bnx2x *bp) } bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, - bp->common.shmem_base); + bp->common.shmem_base, + bp->common.shmem2_base); bnx2x_setup_fan_failure_detection(bp); @@ -4129,7 +4176,8 @@ static int bnx2x_init_common(struct bnx2x *bp) if (!BP_NOMCP(bp)) { bnx2x_acquire_phy_lock(bp); - bnx2x_common_init_phy(bp, bp->common.shmem_base); + bnx2x_common_init_phy(bp, bp->common.shmem_base, + bp->common.shmem2_base); bnx2x_release_phy_lock(bp); } else BNX2X_ERR("Bootcode is missing - can not initialize link\n"); @@ -4265,10 +4313,10 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, MCP_BLOCK, init_stage); bnx2x_init_block(bp, DMAE_BLOCK, init_stage); bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, - bp->common.shmem_base); - + bp->common.shmem_base, + bp->common.shmem2_base); if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, - port)) { + bp->common.shmem2_base, port)) { u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); val = REG_RD(bp, reg_addr); @@ -5226,7 +5274,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) unload_error: if (!BP_NOMCP(bp)) - reset_code = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code, 0); else { DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", load_count[0], load_count[1], load_count[2]); @@ -5251,7 +5299,7 @@ unload_error: /* Report UNLOAD_DONE to MCP */ if (!BP_NOMCP(bp)) - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); } @@ -5816,13 +5864,14 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bp->fw_seq = (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - reset_code = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code, 0); /* if UNDI is loaded on the other port */ if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { /* send "DONE" for previous unload */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, + DRV_MSG_CODE_UNLOAD_DONE, 0); /* unload UNDI on port 1 */ bp->func = 1; @@ -5831,7 +5880,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) DRV_MSG_SEQ_NUMBER_MASK); reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - bnx2x_fw_command(bp, reset_code); + bnx2x_fw_command(bp, reset_code, 0); } /* now it's safe to release the lock */ @@ -5873,7 +5922,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en); /* send unload done to the MCP */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); /* restore our func and fw_seq */ bp->func = func; @@ -5921,6 +5970,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); bp->link_params.shmem_base = bp->common.shmem_base; + bp->link_params.shmem2_base = bp->common.shmem2_base; BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", bp->common.shmem_base, bp->common.shmem2_base); @@ -5963,8 +6013,11 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) "please upgrade BC\n", BNX2X_BC_VER, val); } bp->link_params.feature_config_flags |= - (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ? + (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + bp->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ? + FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0; if (BP_E1HVN(bp) == 0) { pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc); @@ -5988,22 +6041,44 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) { - int port = BP_PORT(bp); - bp->port.supported = 0; + int cfg_size = 0, idx, port = BP_PORT(bp); + + /* Aggregation of supported attributes of all external phys */ + bp->port.supported[0] = 0; + bp->port.supported[1] = 0; switch (bp->link_params.num_phys) { case 1: - bp->port.supported = bp->link_params.phy[INT_PHY].supported; - break; + bp->port.supported[0] = bp->link_params.phy[INT_PHY].supported; + cfg_size = 1; + break; case 2: - bp->port.supported = bp->link_params.phy[EXT_PHY1].supported; - break; + bp->port.supported[0] = bp->link_params.phy[EXT_PHY1].supported; + cfg_size = 1; + break; + case 3: + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) { + bp->port.supported[1] = + bp->link_params.phy[EXT_PHY1].supported; + bp->port.supported[0] = + bp->link_params.phy[EXT_PHY2].supported; + } else { + bp->port.supported[0] = + bp->link_params.phy[EXT_PHY1].supported; + bp->port.supported[1] = + bp->link_params.phy[EXT_PHY2].supported; + } + cfg_size = 2; + break; } - if (!(bp->port.supported)) { + if (!(bp->port.supported[0] || bp->port.supported[1])) { BNX2X_ERR("NVRAM config error. BAD phy config." - "PHY1 config 0x%x\n", + "PHY1 config 0x%x, PHY2 config 0x%x\n", SHMEM_RD(bp, - dev_info.port_hw_config[port].external_phy_config)); + dev_info.port_hw_config[port].external_phy_config), + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config2)); return; } @@ -6023,147 +6098,183 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, default: BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", - bp->port.link_config); + bp->port.link_config[0]); return; } - /* mask what we support according to speed_cap_mask */ - if (!(bp->link_params.speed_cap_mask & + /* mask what we support according to speed_cap_mask per configuration */ + for (idx = 0; idx < cfg_size; idx++) { + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) - bp->port.supported &= ~SUPPORTED_10baseT_Half; + bp->port.supported[idx] &= ~SUPPORTED_10baseT_Half; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL)) - bp->port.supported &= ~SUPPORTED_10baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_10baseT_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) - bp->port.supported &= ~SUPPORTED_100baseT_Half; + bp->port.supported[idx] &= ~SUPPORTED_100baseT_Half; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL)) - bp->port.supported &= ~SUPPORTED_100baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_100baseT_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) - bp->port.supported &= ~(SUPPORTED_1000baseT_Half | + bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - bp->port.supported &= ~SUPPORTED_2500baseX_Full; + bp->port.supported[idx] &= ~SUPPORTED_2500baseX_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) - bp->port.supported &= ~SUPPORTED_10000baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full; + + } - BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported); + BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0], + bp->port.supported[1]); } static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) { - bp->link_params.req_duplex = DUPLEX_FULL; - - switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) { + u32 link_config, idx, cfg_size = 0; + bp->port.advertising[0] = 0; + bp->port.advertising[1] = 0; + switch (bp->link_params.num_phys) { + case 1: + case 2: + cfg_size = 1; + break; + case 3: + cfg_size = 2; + break; + } + for (idx = 0; idx < cfg_size; idx++) { + bp->link_params.req_duplex[idx] = DUPLEX_FULL; + link_config = bp->port.link_config[idx]; + switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { case PORT_FEATURE_LINK_SPEED_AUTO: - if (bp->port.supported & SUPPORTED_Autoneg) { - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; + if (bp->port.supported[idx] & SUPPORTED_Autoneg) { + bp->link_params.req_line_speed[idx] = + SPEED_AUTO_NEG; + bp->port.advertising[idx] |= + bp->port.supported[idx]; } else { - /* force 10G, no AN */ - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = (ADVERTISED_10000baseT_Full | + /* force 10G, no AN */ + bp->link_params.req_line_speed[idx] = + SPEED_10000; + bp->port.advertising[idx] |= + (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); + continue; } break; case PORT_FEATURE_LINK_SPEED_10M_FULL: - if (bp->port.supported & SUPPORTED_10baseT_Full) { - bp->link_params.req_line_speed = SPEED_10; - bp->port.advertising = (ADVERTISED_10baseT_Full | + if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_10; + bp->port.advertising[idx] |= + (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_10M_HALF: - if (bp->port.supported & SUPPORTED_10baseT_Half) { - bp->link_params.req_line_speed = SPEED_10; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_10baseT_Half | + if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) { + bp->link_params.req_line_speed[idx] = + SPEED_10; + bp->link_params.req_duplex[idx] = + DUPLEX_HALF; + bp->port.advertising[idx] |= + (ADVERTISED_10baseT_Half | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->port.supported & SUPPORTED_100baseT_Full) { - bp->link_params.req_line_speed = SPEED_100; - bp->port.advertising = (ADVERTISED_100baseT_Full | + if (bp->port.supported[idx] & SUPPORTED_100baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_100; + bp->port.advertising[idx] |= + (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->port.supported & SUPPORTED_100baseT_Half) { - bp->link_params.req_line_speed = SPEED_100; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_100baseT_Half | + if (bp->port.supported[idx] & SUPPORTED_100baseT_Half) { + bp->link_params.req_line_speed[idx] = SPEED_100; + bp->link_params.req_duplex[idx] = DUPLEX_HALF; + bp->port.advertising[idx] |= + (ADVERTISED_100baseT_Half | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_1G: - if (bp->port.supported & SUPPORTED_1000baseT_Full) { - bp->link_params.req_line_speed = SPEED_1000; - bp->port.advertising = (ADVERTISED_1000baseT_Full | + if (bp->port.supported[idx] & + SUPPORTED_1000baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_1000; + bp->port.advertising[idx] |= + (ADVERTISED_1000baseT_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_2_5G: - if (bp->port.supported & SUPPORTED_2500baseX_Full) { - bp->link_params.req_line_speed = SPEED_2500; - bp->port.advertising = (ADVERTISED_2500baseX_Full | + if (bp->port.supported[idx] & + SUPPORTED_2500baseX_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_2500; + bp->port.advertising[idx] |= + (ADVERTISED_2500baseX_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; @@ -6171,16 +6282,19 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) case PORT_FEATURE_LINK_SPEED_10G_CX4: case PORT_FEATURE_LINK_SPEED_10G_KX4: case PORT_FEATURE_LINK_SPEED_10G_KR: - if (bp->port.supported & SUPPORTED_10000baseT_Full) { - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = (ADVERTISED_10000baseT_Full | + if (bp->port.supported[idx] & + SUPPORTED_10000baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_10000; + bp->port.advertising[idx] |= + (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; @@ -6188,23 +6302,28 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) default: BNX2X_ERROR("NVRAM config error. " "BAD link speed link_config 0x%x\n", - bp->port.link_config); - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; + link_config); + bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG; + bp->port.advertising[idx] = bp->port.supported[idx]; break; } - bp->link_params.req_flow_ctrl = (bp->port.link_config & + bp->link_params.req_flow_ctrl[idx] = (link_config & PORT_FEATURE_FLOW_CONTROL_MASK); - if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - !(bp->port.supported & SUPPORTED_Autoneg)) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + if ((bp->link_params.req_flow_ctrl[idx] == + BNX2X_FLOW_CTRL_AUTO) && + !(bp->port.supported[idx] & SUPPORTED_Autoneg)) { + bp->link_params.req_flow_ctrl[idx] = + BNX2X_FLOW_CTRL_NONE; + } - BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x" - " advertising 0x%x\n", - bp->link_params.req_line_speed, - bp->link_params.req_duplex, - bp->link_params.req_flow_ctrl, bp->port.advertising); + BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl" + " 0x%x advertising 0x%x\n", + bp->link_params.req_line_speed[idx], + bp->link_params.req_duplex[idx], + bp->link_params.req_flow_ctrl[idx], + bp->port.advertising[idx]); + } } static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) @@ -6228,14 +6347,20 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->link_params.lane_config = SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); - bp->link_params.speed_cap_mask = + bp->link_params.speed_cap_mask[0] = SHMEM_RD(bp, dev_info.port_hw_config[port].speed_capability_mask); - - bp->port.link_config = + bp->link_params.speed_cap_mask[1] = + SHMEM_RD(bp, + dev_info.port_hw_config[port].speed_capability_mask2); + bp->port.link_config[0] = SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); + bp->port.link_config[1] = + SHMEM_RD(bp, dev_info.port_feature_config[port].link_config2); + bp->link_params.multi_phy_config = + SHMEM_RD(bp, dev_info.port_hw_config[port].multi_phy_config); /* If the device is capable of WoL, set the default state according * to the HW */ @@ -6244,11 +6369,12 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) (config & PORT_FEATURE_WOL_ENABLED)); BNX2X_DEV_INFO("lane_config 0x%08x" - " speed_cap_mask 0x%08x link_config 0x%08x\n", + "speed_cap_mask0 0x%08x link_config0 0x%08x\n", bp->link_params.lane_config, - bp->link_params.speed_cap_mask, bp->port.link_config); + bp->link_params.speed_cap_mask[0], + bp->port.link_config[0]); - bp->link_params.switch_cfg |= (bp->port.link_config & + bp->link_params.switch_cfg = (bp->port.link_config[0] & PORT_FEATURE_CONNECTED_SWITCH_MASK); bnx2x_phy_probe(&bp->link_params); bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 398cf55b8e10..f0a69563b66a 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -4964,6 +4964,8 @@ #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1 0x14 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII 0x0001 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK 0x0002 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX 0x0004 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3 @@ -5192,6 +5194,8 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_XS_8706_REG_BANK_RX3 0x80ec #define MDIO_XS_8706_REG_BANK_RXA 0x80fc +#define MDIO_XS_REG_8073_RX_CTRL_PCIE 0x80FA + #define MDIO_AN_DEVAD 0x7 /*ieee*/ #define MDIO_AN_REG_CTRL 0x0000 @@ -5227,6 +5231,27 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_AN_REG_8481_AUX_CTRL 0xfff8 #define MDIO_AN_REG_8481_LEGACY_SHADOW 0xfffc +/* BCM84823 only */ +#define MDIO_CTL_DEVAD 0x1e +#define MDIO_CTL_REG_84823_MEDIA 0x401a +#define MDIO_CTL_REG_84823_MEDIA_MAC_MASK 0x0018 + /* These pins configure the BCM84823 interface to MAC after reset. */ +#define MDIO_CTL_REG_84823_CTRL_MAC_XFI 0x0008 +#define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M 0x0010 + /* These pins configure the BCM84823 interface to Line after reset. */ +#define MDIO_CTL_REG_84823_MEDIA_LINE_MASK 0x0060 +#define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L 0x0020 +#define MDIO_CTL_REG_84823_MEDIA_LINE_XFI 0x0040 + /* When this pin is active high during reset, 10GBASE-T core is power + * down, When it is active low the 10GBASE-T is power up + */ +#define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN 0x0080 +#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK 0x0100 +#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER 0x0000 +#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER 0x0100 +#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G 0x1000 + + #define IGU_FUNC_BASE 0x0400 #define IGU_ADDR_MSIX 0x0000 -- cgit v1.2.3 From 251415808306a19be93ec93268e2985f10d3db8b Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 12 Sep 2010 05:48:28 +0000 Subject: bnx2x: Spread rx buffers between allocated queues Default number of rx buffers will be divided equally between allocated queues. This will decrease amount of pre-allocated buffers on systems with multiple CPUs. User can override this behavior with ethtool -G. Minimum amount of rx buffers per queue set to 128. Reported-by: Eric Dumazet Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 5 +++-- drivers/net/bnx2x/bnx2x_cmn.c | 6 +++++- drivers/net/bnx2x/bnx2x_ethtool.c | 10 +++++++++- drivers/net/bnx2x/bnx2x_main.c | 1 - 4 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index b6aaf22a1b84..64329c5fbdea 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.52.53-6" -#define DRV_MODULE_RELDATE "2010/09/07" +#define DRV_MODULE_VERSION "1.52.53-7" +#define DRV_MODULE_RELDATE "2010/09/12" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) @@ -369,6 +369,7 @@ struct bnx2x_fastpath { #define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS) #define MAX_RX_BD (NUM_RX_BD - 1) #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) +#define MIN_RX_AVAIL 128 #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1) #define RX_BD(x) ((x) & MAX_RX_BD) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 7f1d291eaaa5..efc7be4aefb5 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -781,6 +781,10 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) ETH_MAX_AGGREGATION_QUEUES_E1H; u16 ring_prod, cqe_ring_prod; int i, j; + int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : + MAX_RX_AVAIL/bp->num_queues; + + rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; DP(NETIF_MSG_IFUP, @@ -883,7 +887,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) /* Allocate BDs and initialize BD ring */ fp->rx_comp_cons = 0; cqe_ring_prod = ring_prod = 0; - for (i = 0; i < bp->rx_ring_size; i++) { + for (i = 0; i < rx_ring_size; i++) { if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { BNX2X_ERR("was only able to allocate " "%d rx skbs on queue[%d]\n", i, j); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 6f939c5a0089..d9748e97fad3 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -961,7 +961,14 @@ static void bnx2x_get_ringparam(struct net_device *dev, ering->rx_mini_max_pending = 0; ering->rx_jumbo_max_pending = 0; - ering->rx_pending = bp->rx_ring_size; + if (bp->rx_ring_size) + ering->rx_pending = bp->rx_ring_size; + else + if (bp->state == BNX2X_STATE_OPEN && bp->num_queues) + ering->rx_pending = MAX_RX_AVAIL/bp->num_queues; + else + ering->rx_pending = MAX_RX_AVAIL; + ering->rx_mini_pending = 0; ering->rx_jumbo_pending = 0; @@ -981,6 +988,7 @@ static int bnx2x_set_ringparam(struct net_device *dev, } if ((ering->rx_pending > MAX_RX_AVAIL) || + (ering->rx_pending < MIN_RX_AVAIL) || (ering->tx_pending > MAX_TX_AVAIL) || (ering->tx_pending <= MAX_SKB_FRAGS + 4)) return -EINVAL; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 7ba3a6d96fd5..67587fe9e358 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -6619,7 +6619,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->mrrs = mrrs; bp->tx_ring_size = MAX_TX_AVAIL; - bp->rx_ring_size = MAX_RX_AVAIL; bp->rx_csum = 1; -- cgit v1.2.3 From 31b600b5fcd101acffb261f87f60f27085ca6509 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:25:27 +0000 Subject: bnx2x: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index efc7be4aefb5..05c05a496b15 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1207,8 +1207,8 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) bp->num_queues = 1; break; } - bp->dev->real_num_tx_queues = bp->num_queues; - return rc; + netif_set_real_num_tx_queues(bp->dev, bp->num_queues); + return netif_set_real_num_rx_queues(bp->dev, bp->num_queues); } static void bnx2x_release_firmware(struct bnx2x *bp) @@ -1240,6 +1240,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; rc = bnx2x_set_num_queues(bp); + if (rc) + return rc; if (bnx2x_alloc_mem(bp)) { bnx2x_free_irq(bp, true); -- cgit v1.2.3 From 8681dc3abd54e845a2effab441921b4c4457c241 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 29 Sep 2010 01:05:37 +0000 Subject: bnx2x: Moved enabling of MSI to the bnx2x_set_num_queues() Moved enabling of MSI to the bnx2x_set_num_queues() - the same functions that handles the initialization of the MSI-X. From: Vladislav Zolotarov Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 05c05a496b15..8d42067a6989 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1185,8 +1185,10 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) int rc = 0; switch (bp->int_mode) { - case INT_MODE_INTx: case INT_MODE_MSI: + bnx2x_enable_msi(bp); + /* falling through... */ + case INT_MODE_INTx: bp->num_queues = 1; DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; @@ -1202,9 +1204,16 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) * and fallback to MSI or legacy INTx with one fp */ rc = bnx2x_enable_msix(bp); - if (rc) + if (rc) { /* failed to enable MSI-X */ bp->num_queues = 1; + + /* Fall to INTx if failed to enable MSI-X due to lack of + * memory (in bnx2x_set_num_queues()) */ + if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) + bnx2x_enable_msi(bp); + } + break; } netif_set_real_num_tx_queues(bp->dev, bp->num_queues); @@ -1265,10 +1274,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) goto load_error1; } } else { - /* Fall to INTx if failed to enable MSI-X due to lack of - memory (in bnx2x_set_num_queues()) */ - if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) - bnx2x_enable_msi(bp); bnx2x_ack_int(bp); rc = bnx2x_req_irq(bp); if (rc) { -- cgit v1.2.3 From 523224a3b3cd407ce4e6731a087194e13a90db18 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:23:26 +0000 Subject: bnx2x, cnic, bnx2i: use new FW/HSI This is the new FW HSI blob and the relevant definitions without logic changes. It also included code adaptation for new HSI. New features are not enabled. New FW/HSI includes: - Support for 57712 HW - Future support for VF (not used) - Improvements in FW interrupts scheme - FW FCoE hooks (stubs for future usage) Signed-off-by: Dmitry Kravkov Signed-off-by: Michael Chan Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 532 +++++- drivers/net/bnx2x/bnx2x_cmn.c | 488 ++--- drivers/net/bnx2x/bnx2x_cmn.h | 256 ++- drivers/net/bnx2x/bnx2x_ethtool.c | 20 +- drivers/net/bnx2x/bnx2x_fw_defs.h | 819 ++++---- drivers/net/bnx2x/bnx2x_fw_file_hdr.h | 1 + drivers/net/bnx2x/bnx2x_hsi.h | 1467 +++++++-------- drivers/net/bnx2x/bnx2x_init.h | 41 + drivers/net/bnx2x/bnx2x_init_ops.h | 338 ++++ drivers/net/bnx2x/bnx2x_link.c | 3 +- drivers/net/bnx2x/bnx2x_main.c | 3302 ++++++++++++++++++++------------- drivers/net/bnx2x/bnx2x_stats.c | 12 +- drivers/net/cnic.c | 285 ++- drivers/net/cnic.h | 51 +- drivers/net/cnic_defs.h | 456 +++-- drivers/net/cnic_if.h | 2 + drivers/scsi/bnx2i/bnx2i.h | 2 + drivers/scsi/bnx2i/bnx2i_hwi.c | 3 +- firmware/Makefile | 4 +- 19 files changed, 4812 insertions(+), 3270 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 64329c5fbdea..8b053e0c00ab 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -33,13 +33,11 @@ #define BNX2X_NEW_NAPI - #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 #include "../cnic_if.h" #endif - #ifdef BCM_CNIC #define BNX2X_MIN_MSIX_VEC_CNT 3 #define BNX2X_MSIX_VEC_FP_START 2 @@ -129,16 +127,18 @@ void bnx2x_panic_dump(struct bnx2x *bp); } while (0) #endif +#define bnx2x_mc_addr(ha) ((ha)->addr) #define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) #define U64_HI(x) (u32)(((u64)(x)) >> 32) #define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) -#define REG_ADDR(bp, offset) (bp->regview + offset) +#define REG_ADDR(bp, offset) ((bp->regview) + (offset)) #define REG_RD(bp, offset) readl(REG_ADDR(bp, offset)) #define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset)) +#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset)) #define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset)) #define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset)) @@ -160,6 +160,9 @@ void bnx2x_panic_dump(struct bnx2x *bp); offset, len32); \ } while (0) +#define REG_WR_DMAE_LEN(bp, offset, valp, len32) \ + REG_WR_DMAE(bp, offset, valp, len32) + #define VIRT_WR_DMAE_LEN(bp, data, addr, len32, le32_swap) \ do { \ memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \ @@ -175,16 +178,52 @@ void bnx2x_panic_dump(struct bnx2x *bp); offsetof(struct shmem2_region, field)) #define SHMEM2_RD(bp, field) REG_RD(bp, SHMEM2_ADDR(bp, field)) #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) +#define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ + offsetof(struct mf_cfg, field)) -#define MF_CFG_RD(bp, field) SHMEM_RD(bp, mf_cfg.field) -#define MF_CFG_WR(bp, field, val) SHMEM_WR(bp, mf_cfg.field, val) +#define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) +#define MF_CFG_WR(bp, field, val) REG_WR(bp,\ + MF_CFG_ADDR(bp, field), (val)) #define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg) #define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val) +/* SP SB indices */ + +/* General SP events - stats query, cfc delete, etc */ +#define HC_SP_INDEX_ETH_DEF_CONS 3 + +/* EQ completions */ +#define HC_SP_INDEX_EQ_CONS 7 + +/* iSCSI L2 */ +#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 + +/** + * CIDs and CLIDs: + * CLIDs below is a CLID for func 0, then the CLID for other + * functions will be calculated by the formula: + * + * FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X + * + */ +/* iSCSI L2 */ +#define BNX2X_ISCSI_ETH_CL_ID 17 +#define BNX2X_ISCSI_ETH_CID 17 + +/** Additional rings budgeting */ +#ifdef BCM_CNIC +#define CNIC_CONTEXT_USE 1 +#else +#define CNIC_CONTEXT_USE 0 +#endif /* BCM_CNIC */ + #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR +#define SM_RX_ID 0 +#define SM_TX_ID 1 /* fast path */ @@ -254,11 +293,21 @@ union db_prod { #define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1) #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) +union host_hc_status_block { + /* pointer to fp status block e1x */ + struct host_hc_status_block_e1x *e1x_sb; +}; struct bnx2x_fastpath { struct napi_struct napi; - struct host_status_block *status_blk; + union host_hc_status_block status_blk; + /* chip independed shortcuts into sb structure */ + __le16 *sb_index_values; + __le16 *sb_running_index; + /* chip independed shortcut into rx_prods_offset memory */ + u32 ustorm_rx_prods_offset; + dma_addr_t status_blk_mapping; struct sw_tx_bd *tx_buf_ring; @@ -288,10 +337,15 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_OPEN 0xa0000 #define BNX2X_FP_STATE_HALTING 0xb0000 #define BNX2X_FP_STATE_HALTED 0xc0000 +#define BNX2X_FP_STATE_TERMINATING 0xd0000 +#define BNX2X_FP_STATE_TERMINATED 0xe0000 u8 index; /* number in fp array */ u8 cl_id; /* eth client id */ - u8 sb_id; /* status block number in HW */ + u8 cl_qzone_id; + u8 fw_sb_id; /* status block number in FW */ + u8 igu_sb_id; /* status block number in HW */ + u32 cid; union db_prod tx_db; @@ -301,8 +355,7 @@ struct bnx2x_fastpath { u16 tx_bd_cons; __le16 *tx_cons_sb; - __le16 fp_c_idx; - __le16 fp_u_idx; + __le16 fp_hc_idx; u16 rx_bd_prod; u16 rx_bd_cons; @@ -312,7 +365,7 @@ struct bnx2x_fastpath { /* The last maximal completed SGE */ u16 last_max_sge; __le16 *rx_cons_sb; - __le16 *rx_bd_cons_sb; + unsigned long tx_pkt, @@ -356,6 +409,8 @@ struct bnx2x_fastpath { #define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS) #define MAX_TX_BD (NUM_TX_BD - 1) #define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2) +#define INIT_JUMBO_TX_RING_SIZE MAX_TX_AVAIL +#define INIT_TX_RING_SIZE MAX_TX_AVAIL #define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \ (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1) #define TX_BD(x) ((x) & MAX_TX_BD) @@ -370,6 +425,8 @@ struct bnx2x_fastpath { #define MAX_RX_BD (NUM_RX_BD - 1) #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) #define MIN_RX_AVAIL 128 +#define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL +#define INIT_RX_RING_SIZE MAX_RX_AVAIL #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1) #define RX_BD(x) ((x) & MAX_RX_BD) @@ -420,11 +477,12 @@ struct bnx2x_fastpath { le32_to_cpu((bd)->addr_lo)) #define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes)) - +#define BNX2X_DB_MIN_SHIFT 3 /* 8 bytes */ +#define BNX2X_DB_SHIFT 7 /* 128 bytes*/ #define DPM_TRIGER_TYPE 0x40 #define DOORBELL(bp, cid, val) \ do { \ - writel((u32)(val), bp->doorbells + (BCM_PAGE_SIZE * (cid)) + \ + writel((u32)(val), bp->doorbells + (bp->db_size * (cid)) + \ DPM_TRIGER_TYPE); \ } while (0) @@ -482,31 +540,15 @@ struct bnx2x_fastpath { #define BNX2X_RX_SUM_FIX(cqe) \ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags) - -#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES) -#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES) - -#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS -#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS -#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS +#define U_SB_ETH_RX_CQ_INDEX 1 +#define U_SB_ETH_RX_BD_INDEX 2 +#define C_SB_ETH_TX_CQ_INDEX 5 #define BNX2X_RX_SB_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX]) - -#define BNX2X_RX_SB_BD_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_BD_INDEX]) - -#define BNX2X_RX_SB_INDEX_NUM \ - (((U_SB_ETH_RX_CQ_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) | \ - ((U_SB_ETH_RX_BD_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER)) + (&fp->sb_index_values[U_SB_ETH_RX_CQ_INDEX]) #define BNX2X_TX_SB_INDEX \ - (&fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX]) - + (&fp->sb_index_values[C_SB_ETH_TX_CQ_INDEX]) /* end of fast path */ @@ -553,10 +595,16 @@ struct bnx2x_common { u32 shmem_base; u32 shmem2_base; + u32 mf_cfg_base; u32 hw_config; u32 bc_ver; + + u8 int_block; +#define INT_BLOCK_HC 0 + u8 chip_port_mode; +#define CHIP_PORT_MODE_NONE 0x2 }; @@ -590,27 +638,98 @@ struct bnx2x_port { /* end of port */ +/* e1h Classification CAM line allocations */ +enum { + CAM_ETH_LINE = 0, + CAM_ISCSI_ETH_LINE, + CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE +}; +#define BNX2X_VF_ID_INVALID 0xFF -#ifdef BCM_CNIC -#define MAX_CONTEXT 15 -#else -#define MAX_CONTEXT 16 -#endif +/* + * The total number of L2 queues, MSIX vectors and HW contexts (CIDs) is + * control by the number of fast-path status blocks supported by the + * device (HW/FW). Each fast-path status block (FP-SB) aka non-default + * status block represents an independent interrupts context that can + * serve a regular L2 networking queue. However special L2 queues such + * as the FCoE queue do not require a FP-SB and other components like + * the CNIC may consume FP-SB reducing the number of possible L2 queues + * + * If the maximum number of FP-SB available is X then: + * a. If CNIC is supported it consumes 1 FP-SB thus the max number of + * regular L2 queues is Y=X-1 + * b. in MF mode the actual number of L2 queues is Y= (X-1/MF_factor) + * c. If the FCoE L2 queue is supported the actual number of L2 queues + * is Y+1 + * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for + * slow-path interrupts) or Y+2 if CNIC is supported (one additional + * FP interrupt context for the CNIC). + * e. The number of HW context (CID count) is always X or X+1 if FCoE + * L2 queue is supported. the cid for the FCoE L2 queue is always X. + */ + +#define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */ +#define MAX_CONTEXT FP_SB_MAX_E1x + +/* + * cid_cnt paramter below refers to the value returned by + * 'bnx2x_get_l2_cid_count()' routine + */ + +/* + * The number of FP context allocated by the driver == max number of regular + * L2 queues + 1 for the FCoE L2 queue + */ +#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) union cdu_context { struct eth_context eth; char pad[1024]; }; +/* CDU host DB constants */ +#define CDU_ILT_PAGE_SZ_HW 3 +#define CDU_ILT_PAGE_SZ (4096 << CDU_ILT_PAGE_SZ_HW) /* 32K */ +#define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) + +#ifdef BCM_CNIC +#define CNIC_ISCSI_CID_MAX 256 +#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX) +#define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) +#endif + +#define QM_ILT_PAGE_SZ_HW 3 +#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 32K */ +#define QM_CID_ROUND 1024 + +#ifdef BCM_CNIC +/* TM (timers) host DB constants */ +#define TM_ILT_PAGE_SZ_HW 2 +#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 16K */ +/* #define TM_CONN_NUM (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */ +#define TM_CONN_NUM 1024 +#define TM_ILT_SZ (8 * TM_CONN_NUM) +#define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ) + +/* SRC (Searcher) host DB constants */ +#define SRC_ILT_PAGE_SZ_HW 3 +#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 32K */ +#define SRC_HASH_BITS 10 +#define SRC_CONN_NUM (1 << SRC_HASH_BITS) /* 1024 */ +#define SRC_ILT_SZ (sizeof(struct src_ent) * SRC_CONN_NUM) +#define SRC_T2_SZ SRC_ILT_SZ +#define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ) +#endif + #define MAX_DMAE_C 8 /* DMA memory not used in fastpath */ struct bnx2x_slowpath { - union cdu_context context[MAX_CONTEXT]; struct eth_stats_query fw_stats; struct mac_configuration_cmd mac_config; struct mac_configuration_cmd mcast_config; + struct client_init_ramrod_data client_init_data; /* used by dmae command executer */ struct dmae_command dmae[MAX_DMAE_C]; @@ -638,37 +757,71 @@ struct attn_route { u32 sig[4]; }; +struct iro { + u32 base; + u16 m1; + u16 m2; + u16 m3; + u16 size; +}; + +struct hw_context { + union cdu_context *vcxt; + dma_addr_t cxt_mapping; + size_t size; +}; + +/* forward */ +struct bnx2x_ilt; + typedef enum { BNX2X_RECOVERY_DONE, BNX2X_RECOVERY_INIT, BNX2X_RECOVERY_WAIT, } bnx2x_recovery_state_t; +/** + * Event queue (EQ or event ring) MC hsi + * NUM_EQ_PAGES and EQ_DESC_CNT_PAGE must be power of 2 + */ +#define NUM_EQ_PAGES 1 +#define EQ_DESC_CNT_PAGE (BCM_PAGE_SIZE / sizeof(union event_ring_elem)) +#define EQ_DESC_MAX_PAGE (EQ_DESC_CNT_PAGE - 1) +#define NUM_EQ_DESC (EQ_DESC_CNT_PAGE * NUM_EQ_PAGES) +#define EQ_DESC_MASK (NUM_EQ_DESC - 1) +#define MAX_EQ_AVAIL (EQ_DESC_MAX_PAGE * NUM_EQ_PAGES - 2) + +/* depends on EQ_DESC_CNT_PAGE being a power of 2 */ +#define NEXT_EQ_IDX(x) ((((x) & EQ_DESC_MAX_PAGE) == \ + (EQ_DESC_MAX_PAGE - 1)) ? (x) + 2 : (x) + 1) + +/* depends on the above and on NUM_EQ_PAGES being a power of 2 */ +#define EQ_DESC(x) ((x) & EQ_DESC_MASK) + +#define BNX2X_EQ_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_EQ_CONS]) + struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure */ - struct bnx2x_fastpath fp[MAX_CONTEXT]; + struct bnx2x_fastpath *fp; void __iomem *regview; void __iomem *doorbells; -#ifdef BCM_CNIC -#define BNX2X_DB_SIZE (18*BCM_PAGE_SIZE) -#else -#define BNX2X_DB_SIZE (16*BCM_PAGE_SIZE) -#endif + u16 db_size; struct net_device *dev; struct pci_dev *pdev; + struct iro *iro_arr; +#define IRO (bp->iro_arr) + atomic_t intr_sem; bnx2x_recovery_state_t recovery_state; int is_leader; -#ifdef BCM_CNIC - struct msix_entry msix_table[MAX_CONTEXT+2]; -#else - struct msix_entry msix_table[MAX_CONTEXT+1]; -#endif + struct msix_entry *msix_table; #define INT_MODE_INTx 1 #define INT_MODE_MSI 2 @@ -680,7 +833,8 @@ struct bnx2x { u32 rx_csum; u32 rx_buf_size; -#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */ +/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8) #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 @@ -689,13 +843,12 @@ struct bnx2x { #define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \ L1_CACHE_SHIFT : 8) #define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT) +#define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) - struct host_def_status_block *def_status_blk; -#define DEF_SB_ID 16 - __le16 def_c_idx; - __le16 def_u_idx; - __le16 def_x_idx; - __le16 def_t_idx; + struct host_sp_status_block *def_status_blk; +#define DEF_SB_IGU_ID 16 +#define DEF_SB_ID HC_SP_SB_ID + __le16 def_idx; __le16 def_att_idx; u32 attn_state; struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS]; @@ -711,6 +864,13 @@ struct bnx2x { /* used to synchronize spq accesses */ spinlock_t spq_lock; + /* event queue */ + union event_ring_elem *eq_ring; + dma_addr_t eq_mapping; + u16 eq_prod; + u16 eq_cons; + __le16 *eq_cons_sb; + /* Flags for marking that there is a STAT_QUERY or SET_MAC ramrod pending */ int stats_pending; @@ -737,6 +897,8 @@ struct bnx2x { #define MF_FUNC_DIS 0x1000 int func; + int base_fw_ndsb; + #define BP_PORT(bp) (bp->func % PORT_MAX) #define BP_FUNC(bp) (bp->func) #define BP_E1HVN(bp) (bp->func >> 1) @@ -801,6 +963,7 @@ struct bnx2x { #define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000 #define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000 #define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000 +#define BNX2X_STATE_FUNC_STARTED 0x7000 #define BNX2X_STATE_DIAG 0xe000 #define BNX2X_STATE_ERROR 0xf000 @@ -809,6 +972,15 @@ struct bnx2x { int disable_tpa; int int_mode; + struct tstorm_eth_mac_filter_config mac_filters; +#define BNX2X_ACCEPT_NONE 0x0000 +#define BNX2X_ACCEPT_UNICAST 0x0001 +#define BNX2X_ACCEPT_MULTICAST 0x0002 +#define BNX2X_ACCEPT_ALL_UNICAST 0x0004 +#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 +#define BNX2X_ACCEPT_BROADCAST 0x0010 +#define BNX2X_PROMISCUOUS_MODE 0x10000 + u32 rx_mode; #define BNX2X_RX_MODE_NONE 0 #define BNX2X_RX_MODE_NORMAL 1 @@ -817,12 +989,25 @@ struct bnx2x { #define BNX2X_MAX_MULTICAST 64 #define BNX2X_MAX_EMUL_MULTI 16 - u32 rx_mode_cl_mask; - + u8 igu_dsb_id; + u8 igu_base_sb; + u8 igu_sb_cnt; dma_addr_t def_status_blk_mapping; struct bnx2x_slowpath *slowpath; dma_addr_t slowpath_mapping; + struct hw_context context; + + struct bnx2x_ilt *ilt; +#define BP_ILT(bp) ((bp)->ilt) +#define ILT_MAX_LINES 128 + + int l2_cid_count; +#define L2_ILT_LINES(bp) (DIV_ROUND_UP((bp)->l2_cid_count, \ + ILT_PAGE_CIDS)) +#define BNX2X_DB_SIZE(bp) ((bp)->l2_cid_count * (1 << BNX2X_DB_SHIFT)) + + int qm_cid_count; int dropless_fc; @@ -842,9 +1027,10 @@ struct bnx2x { void *cnic_data; u32 cnic_tag; struct cnic_eth_dev cnic_eth_dev; - struct host_status_block *cnic_sb; + union host_hc_status_block cnic_sb; dma_addr_t cnic_sb_mapping; -#define CNIC_SB_ID(bp) BP_L_ID(bp) +#define CNIC_SB_ID(bp) ((bp)->base_fw_ndsb + BP_L_ID(bp)) +#define CNIC_IGU_SB_ID(bp) ((bp)->igu_base_sb) struct eth_spe *cnic_kwq; struct eth_spe *cnic_kwq_prod; struct eth_spe *cnic_kwq_cons; @@ -914,12 +1100,167 @@ struct bnx2x { const struct firmware *firmware; }; +/** + * Init queue/func interface + */ +/* queue init flags */ +#define QUEUE_FLG_TPA 0x0001 +#define QUEUE_FLG_CACHE_ALIGN 0x0002 +#define QUEUE_FLG_STATS 0x0004 +#define QUEUE_FLG_OV 0x0008 +#define QUEUE_FLG_VLAN 0x0010 +#define QUEUE_FLG_COS 0x0020 +#define QUEUE_FLG_HC 0x0040 +#define QUEUE_FLG_DHC 0x0080 +#define QUEUE_FLG_OOO 0x0100 + +#define QUEUE_DROP_IP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR +#define QUEUE_DROP_TCP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR +#define QUEUE_DROP_TTL0 TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 +#define QUEUE_DROP_UDP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR + + + +/* rss capabilities */ +#define RSS_IPV4_CAP 0x0001 +#define RSS_IPV4_TCP_CAP 0x0002 +#define RSS_IPV6_CAP 0x0004 +#define RSS_IPV6_TCP_CAP 0x0008 #define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) + +#define RSS_IPV4_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY + +#define RSS_IPV4_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY + +#define RSS_IPV6_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY + +#define RSS_IPV6_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY + +/* func init flags */ +#define FUNC_FLG_RSS 0x0001 +#define FUNC_FLG_STATS 0x0002 +/* removed FUNC_FLG_UNMATCHED 0x0004 */ +#define FUNC_FLG_TPA 0x0008 +#define FUNC_FLG_SPQ 0x0010 +#define FUNC_FLG_LEADING 0x0020 /* PF only */ + +#define FUNC_CONFIG(flgs) ((flgs) & (FUNC_FLG_RSS | FUNC_FLG_TPA | \ + FUNC_FLG_LEADING)) + +struct rxq_pause_params { + u16 bd_th_lo; + u16 bd_th_hi; + u16 rcq_th_lo; + u16 rcq_th_hi; + u16 sge_th_lo; /* valid iff QUEUE_FLG_TPA */ + u16 sge_th_hi; /* valid iff QUEUE_FLG_TPA */ + u16 pri_map; +}; + +struct bnx2x_rxq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + dma_addr_t sge_map; + dma_addr_t rcq_map; + dma_addr_t rcq_np_map; + + u16 flags; + u16 drop_flags; + u16 mtu; + u16 buf_sz; + u16 fw_sb_id; + u16 cl_id; + u16 spcl_id; + u16 cl_qzone_id; + + /* valid iff QUEUE_FLG_STATS */ + u16 stat_id; + + /* valid iff QUEUE_FLG_TPA */ + u16 tpa_agg_sz; + u16 sge_buf_sz; + u16 max_sges_pkt; + + /* valid iff QUEUE_FLG_CACHE_ALIGN */ + u8 cache_line_log; + + u8 sb_cq_index; + u32 cid; + + /* desired interrupts per sec. valid iff QUEUE_FLG_HC */ + u32 hc_rate; +}; + +struct bnx2x_txq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + + u16 flags; + u16 fw_sb_id; + u8 sb_cq_index; + u8 cos; /* valid iff QUEUE_FLG_COS */ + u16 stat_id; /* valid iff QUEUE_FLG_STATS */ + u16 traffic_type; + u32 cid; + u16 hc_rate; /* desired interrupts per sec.*/ + /* valid iff QUEUE_FLG_HC */ + +}; + +struct bnx2x_client_ramrod_params { + int *pstate; + int state; + u16 index; + u16 cl_id; + u32 cid; + u8 poll; +#define CLIENT_IS_LEADING_RSS 0x02 + u8 flags; +}; + +struct bnx2x_client_init_params { + struct rxq_pause_params pause; + struct bnx2x_rxq_init_params rxq_params; + struct bnx2x_txq_init_params txq_params; + struct bnx2x_client_ramrod_params ramrod_params; +}; + +struct bnx2x_rss_params { + int mode; + u16 cap; + u16 result_mask; +}; + +struct bnx2x_func_init_params { + + /* rss */ + struct bnx2x_rss_params *rss; /* valid iff FUNC_FLG_RSS */ + + /* dma */ + dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */ + dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */ + + u16 func_flgs; + u16 func_id; /* abs fid */ + u16 pf_id; + u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ +}; + #define for_each_queue(bp, var) \ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) #define for_each_nondefault_queue(bp, var) \ @@ -957,6 +1298,38 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, return val; } +#define BNX2X_ILT_ZALLOC(x, y, size) \ + do { \ + x = pci_alloc_consistent(bp->pdev, size, y); \ + if (x) \ + memset(x, 0, size); \ + } while (0) + +#define BNX2X_ILT_FREE(x, y, size) \ + do { \ + if (x) { \ + pci_free_consistent(bp->pdev, size, x, y); \ + x = NULL; \ + y = 0; \ + } \ + } while (0) + +#define ILOG2(x) (ilog2((x))) + +#define ILT_NUM_PAGE_ENTRIES (3072) +/* In 57710/11 we use whole table since we have 8 func + */ +#define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8) + +#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) +/* + * the phys address is shifted right 12 bits and has an added + * 1=valid bit added to the 53rd bit + * then since this is a wide register(TM) + * we split it into two 32 bit writes + */ +#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) /* load/unload mode */ @@ -1032,7 +1405,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define MAX_SP_DESC_CNT (SP_DESC_CNT - 1) -#define BNX2X_BTR 1 +#define BNX2X_BTR 4 #define MAX_SPQ_PENDING 8 @@ -1149,20 +1522,22 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT)) #define MULTI_MASK 0x7f - -#define DEF_USB_FUNC_OFF (2 + 2*HC_USTORM_DEF_SB_NUM_INDICES) -#define DEF_CSB_FUNC_OFF (2 + 2*HC_CSTORM_DEF_SB_NUM_INDICES) -#define DEF_XSB_FUNC_OFF (2 + 2*HC_XSTORM_DEF_SB_NUM_INDICES) -#define DEF_TSB_FUNC_OFF (2 + 2*HC_TSTORM_DEF_SB_NUM_INDICES) - -#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH - #define BNX2X_SP_DSB_INDEX \ -(&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX]) + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_DEF_CONS]) +#define SET_FLAG(value, mask, flag) \ + do {\ + (value) &= ~(mask);\ + (value) |= ((flag) << (mask##_SHIFT));\ + } while (0) +#define GET_FLAG(value, mask) \ + (((value) &= (mask)) >> (mask##_SHIFT)) #define CAM_IS_INVALID(x) \ -(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) + (GET_FLAG(x.flags, \ + MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \ + (T_ETH_MAC_COMMAND_INVALIDATE)) #define CAM_INVALIDATE(x) \ (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) @@ -1181,6 +1556,14 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 +/* Congestion management fairness mode */ +#define CMNG_FNS_NONE 0 +#define CMNG_FNS_MINMAX 1 + +#define HC_SEG_ACCESS_DEF 0 /*Driver decision 0-3*/ +#define HC_SEG_ACCESS_ATTN 4 +#define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/ + #ifdef BNX2X_MAIN #define BNX2X_EXTERN #else @@ -1195,4 +1578,9 @@ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +#define WAIT_RAMROD_POLL 0x01 +#define WAIT_RAMROD_COMMON 0x02 + +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 8d42067a6989..bcc4a8f4677b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -27,6 +27,8 @@ #include #endif +#include "bnx2x_init.h" + static int bnx2x_poll(struct napi_struct *napi, int budget); /* free skb in the packet ring at pos idx @@ -190,14 +192,16 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, /* First mark all used pages */ for (i = 0; i < sge_len; i++) - SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i]))); + SGE_MASK_CLEAR_BIT(fp, + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[i]))); DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n", - sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + sge_len - 1, le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); /* Here we assume that the last SGE index is the biggest */ prefetch((void *)(fp->sge_mask)); - bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + bnx2x_update_last_max_sge(fp, + le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); last_max = RX_SGE(fp->last_max_sge); last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT; @@ -298,7 +302,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Run through the SGL and compose the fragmented skb */ for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) { - u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j])); + u16 sge_idx = + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[j])); /* FW gives the indices of the SGE as if the ring is an array (meaning that "next" element will consume 2 indices) */ @@ -394,8 +399,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && is_vlan_cqe && - (!is_not_hwaccel_vlan_cqe)) + if ((bp->vlgrp != NULL) && + (le16_to_cpu(cqe->fast_path_cqe. + pars_flags.flags) & PARSING_FLAGS_VLAN)) vlan_gro_receive(&fp->napi, bp->vlgrp, le16_to_cpu(cqe->fast_path_cqe. vlan_tag), skb); @@ -686,9 +692,10 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) return IRQ_HANDLED; } - DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n", - fp->index, fp->sb_id); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); + DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB " + "[fp %d fw_sd %d igusb %d]\n", + fp->index, fp->fw_sb_id, fp->igu_sb_id); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -698,8 +705,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) /* Handle Rx and Tx according to MSI-X vector */ prefetch(fp->rx_cons_sb); prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->u_status_block.status_block_index); - prefetch(&fp->status_blk->c_status_block.status_block_index); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); return IRQ_HANDLED; @@ -774,27 +780,73 @@ void bnx2x_link_report(struct bnx2x *bp) } } +/* Returns the number of actually allocated BDs */ +static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, + int rx_ring_size) +{ + struct bnx2x *bp = fp->bp; + u16 ring_prod, cqe_ring_prod; + int i; + + fp->rx_comp_cons = 0; + cqe_ring_prod = ring_prod = 0; + for (i = 0; i < rx_ring_size; i++) { + if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx skbs on queue[%d]\n", i, fp->index); + fp->eth_q_stats.rx_skb_alloc_failed++; + break; + } + ring_prod = NEXT_RX_IDX(ring_prod); + cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); + WARN_ON(ring_prod <= i); + } + + fp->rx_bd_prod = ring_prod; + /* Limit the CQE producer by the CQE ring size */ + fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, + cqe_ring_prod); + fp->rx_pkt = fp->rx_calls = 0; + + return i; +} + +static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp) +{ + struct bnx2x *bp = fp->bp; + int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : + MAX_RX_AVAIL/bp->num_queues; + + rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); + + bnx2x_alloc_rx_bds(fp, rx_ring_size); + + /* Warning! + * this will generate an interrupt (to the TSTORM) + * must only be done after chip is initialized + */ + bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, + fp->rx_sge_prod); +} + void bnx2x_init_rx_rings(struct bnx2x *bp) { int func = BP_FUNC(bp); int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : ETH_MAX_AGGREGATION_QUEUES_E1H; - u16 ring_prod, cqe_ring_prod; + u16 ring_prod; int i, j; - int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : - MAX_RX_AVAIL/bp->num_queues; - rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); + bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + + BNX2X_FW_IP_HDR_ALIGN_PAD; - bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - if (bp->flags & TPA_ENABLE_FLAG) { - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + if (!fp->disable_tpa) { for (i = 0; i < max_agg_queues; i++) { fp->tpa_pool[i].skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); @@ -812,6 +864,35 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) mapping, 0); fp->tpa_state[i] = BNX2X_TPA_STOP; } + + /* "next page" elements initialization */ + bnx2x_set_next_page_sgl(fp); + + /* set SGEs bit mask */ + bnx2x_init_sge_ring_bit_mask(fp); + + /* Allocate SGEs and initialize the ring elements */ + for (i = 0, ring_prod = 0; + i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { + + if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx sges\n", i); + BNX2X_ERR("disabling TPA for" + " queue[%d]\n", j); + /* Cleanup already allocated elements */ + bnx2x_free_rx_sge_range(bp, + fp, ring_prod); + bnx2x_free_tpa_pool(bp, + fp, max_agg_queues); + fp->disable_tpa = 1; + ring_prod = 0; + break; + } + ring_prod = NEXT_SGE_IDX(ring_prod); + } + + fp->rx_sge_prod = ring_prod; } } @@ -819,98 +900,15 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) struct bnx2x_fastpath *fp = &bp->fp[j]; fp->rx_bd_cons = 0; - fp->rx_cons_sb = BNX2X_RX_SB_INDEX; - fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX; - - /* "next page" elements initialization */ - /* SGE ring */ - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - struct eth_rx_sge *sge; - - sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; - sge->addr_hi = - cpu_to_le32(U64_HI(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - sge->addr_lo = - cpu_to_le32(U64_LO(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - } - bnx2x_init_sge_ring_bit_mask(fp); - - /* RX BD ring */ - for (i = 1; i <= NUM_RX_RINGS; i++) { - struct eth_rx_bd *rx_bd; - - rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; - rx_bd->addr_hi = - cpu_to_le32(U64_HI(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - rx_bd->addr_lo = - cpu_to_le32(U64_LO(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - } + bnx2x_set_next_page_rx_bd(fp); /* CQ ring */ - for (i = 1; i <= NUM_RCQ_RINGS; i++) { - struct eth_rx_cqe_next_page *nextpg; - - nextpg = (struct eth_rx_cqe_next_page *) - &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; - nextpg->addr_hi = - cpu_to_le32(U64_HI(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - nextpg->addr_lo = - cpu_to_le32(U64_LO(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - } - - /* Allocate SGEs and initialize the ring elements */ - for (i = 0, ring_prod = 0; - i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { - - if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx sges\n", i); - BNX2X_ERR("disabling TPA for queue[%d]\n", j); - /* Cleanup already allocated elements */ - bnx2x_free_rx_sge_range(bp, fp, ring_prod); - bnx2x_free_tpa_pool(bp, fp, max_agg_queues); - fp->disable_tpa = 1; - ring_prod = 0; - break; - } - ring_prod = NEXT_SGE_IDX(ring_prod); - } - fp->rx_sge_prod = ring_prod; + bnx2x_set_next_page_rx_cq(fp); /* Allocate BDs and initialize BD ring */ - fp->rx_comp_cons = 0; - cqe_ring_prod = ring_prod = 0; - for (i = 0; i < rx_ring_size; i++) { - if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx skbs on queue[%d]\n", i, j); - fp->eth_q_stats.rx_skb_alloc_failed++; - break; - } - ring_prod = NEXT_RX_IDX(ring_prod); - cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); - WARN_ON(ring_prod <= i); - } + bnx2x_alloc_rx_bd_ring(fp); - fp->rx_bd_prod = ring_prod; - /* must not have more available CQEs than BDs */ - fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, - cqe_ring_prod); - fp->rx_pkt = fp->rx_calls = 0; - - /* Warning! - * this will generate an interrupt (to the TSTORM) - * must only be done after chip is initialized - */ - bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod, - fp->rx_sge_prod); if (j != 0) continue; @@ -921,6 +919,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, U64_HI(fp->rx_comp_mapping)); } + } static void bnx2x_free_tx_skbs(struct bnx2x *bp) { @@ -1252,6 +1251,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (rc) return rc; + /* must be called before memory allocation and HW init */ + bnx2x_ilt_set_info(bp); + if (bnx2x_alloc_mem(bp)) { bnx2x_free_irq(bp, true); return -ENOMEM; @@ -1339,6 +1341,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) goto load_error2; } + if (rc) { + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); + goto load_error2; + } + /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp, load_code); @@ -1360,7 +1367,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - rc = bnx2x_setup_leading(bp); + rc = bnx2x_func_start(bp); + if (rc) { + BNX2X_ERR("Function start failed!\n"); +#ifndef BNX2X_STOP_ON_ERROR + goto load_error3; +#else + bp->panic = 1; + return -EBUSY; +#endif + } + + rc = bnx2x_setup_client(bp, &bp->fp[0], 1 /* Leading */); if (rc) { BNX2X_ERR("Setup leading failed!\n"); #ifndef BNX2X_STOP_ON_ERROR @@ -1377,37 +1395,37 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->flags |= MF_FUNC_DIS; } - if (bp->state == BNX2X_STATE_OPEN) { #ifdef BCM_CNIC - /* Enable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); + /* Enable Timer scan */ + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); #endif - for_each_nondefault_queue(bp, i) { - rc = bnx2x_setup_multi(bp, i); - if (rc) + for_each_nondefault_queue(bp, i) { + rc = bnx2x_setup_client(bp, &bp->fp[i], 0); + if (rc) #ifdef BCM_CNIC - goto load_error4; + goto load_error4; #else - goto load_error3; + goto load_error3; #endif - } + } + + /* Now when Clients are configured we are ready to work */ + bp->state = BNX2X_STATE_OPEN; + + bnx2x_set_eth_mac(bp, 1); - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); #ifdef BCM_CNIC - /* Set iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, - CNIC_SB_ID(bp)); - } - mutex_unlock(&bp->cnic_mutex); -#endif + /* Set iSCSI L2 MAC */ + mutex_lock(&bp->cnic_mutex); + if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { + bnx2x_set_iscsi_eth_mac_addr(bp, 1); + bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; + bnx2x_init_sb(bp, bp->cnic_sb_mapping, + BNX2X_VF_ID_INVALID, false, + CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); } + mutex_unlock(&bp->cnic_mutex); +#endif if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); @@ -1415,18 +1433,15 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Start fast path */ switch (load_mode) { case LOAD_NORMAL: - if (bp->state == BNX2X_STATE_OPEN) { - /* Tx queue should be only reenabled */ - netif_tx_wake_all_queues(bp->dev); - } + /* Tx queue should be only reenabled */ + netif_tx_wake_all_queues(bp->dev); /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); break; case LOAD_OPEN: netif_tx_start_all_queues(bp->dev); - if (bp->state != BNX2X_STATE_OPEN) - netif_tx_disable(bp->dev); + smp_mb__after_clear_bit(); /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); break; @@ -1512,21 +1527,22 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->rx_mode = BNX2X_RX_MODE_NONE; bnx2x_set_storm_rx_mode(bp); - /* Disable HW interrupts, NAPI and Tx */ - bnx2x_netif_stop(bp, 1); - netif_carrier_off(bp->dev); - del_timer_sync(&bp->timer); SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); bnx2x_stats_handle(bp, STATS_EVENT_STOP); - /* Release IRQs */ - bnx2x_free_irq(bp, false); /* Cleanup the chip if needed */ if (unload_mode != UNLOAD_RECOVERY) bnx2x_chip_cleanup(bp, unload_mode); + else { + /* Disable HW interrupts, NAPI and Tx */ + bnx2x_netif_stop(bp, 1); + + /* Release IRQs */ + bnx2x_free_irq(bp, false); + } bp->port.pmf = 0; @@ -1634,27 +1650,28 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) /* Fall out from the NAPI loop if needed */ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { bnx2x_update_fpsb_idx(fp); - /* bnx2x_has_rx_work() reads the status block, thus we need - * to ensure that status block indices have been actually read - * (bnx2x_update_fpsb_idx) prior to this check - * (bnx2x_has_rx_work) so that we won't write the "newer" - * value of the status block to IGU (if there was a DMA right - * after bnx2x_has_rx_work and if there is no rmb, the memory - * reading (bnx2x_update_fpsb_idx) may be postponed to right - * before bnx2x_ack_sb). In this case there will never be - * another interrupt until there is another update of the - * status block, while there is still unhandled work. + /* bnx2x_has_rx_work() reads the status block, + * thus we need to ensure that status block indices + * have been actually read (bnx2x_update_fpsb_idx) + * prior to this check (bnx2x_has_rx_work) so that + * we won't write the "newer" value of the status block + * to IGU (if there was a DMA right after + * bnx2x_has_rx_work and if there is no rmb, the memory + * reading (bnx2x_update_fpsb_idx) may be postponed + * to right before bnx2x_ack_sb). In this case there + * will never be another interrupt until there is + * another update of the status block, while there + * is still unhandled work. */ rmb(); if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { napi_complete(napi); /* Re-enable interrupts */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, - le16_to_cpu(fp->fp_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, - le16_to_cpu(fp->fp_u_idx), + DP(NETIF_MSG_HW, + "Update index to %d\n", fp->fp_hc_idx); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, + le16_to_cpu(fp->fp_hc_idx), IGU_INT_ENABLE, 1); break; } @@ -1850,7 +1867,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; - struct eth_tx_parse_bd *pbd = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -1926,10 +1943,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = (mac_type << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_ETH_ADDR_TYPE, + mac_type); /* header nbd */ - tx_start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_HDR_NBDS, + 1); /* remember the first BD of the packet */ tx_buf->first_bd = fp->tx_bd_prod; @@ -1943,62 +1963,68 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) #ifdef BCM_VLAN if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && (bp->flags & HW_VLAN_TX_FLAG)) { - tx_start_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; + tx_start_bd->vlan_or_ethertype = + cpu_to_le16(vlan_tx_tag_get(skb)); + tx_start_bd->bd_flags.as_bitfield |= + (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); } else #endif - tx_start_bd->vlan = cpu_to_le16(pkt_prod); + tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp->tx_desc_ring[bd_prod].parse_bd; - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); + if (xmit_type & XMIT_CSUM) { + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; + + if (xmit_type & XMIT_CSUM_V4) + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IP_CSUM; + else + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IPV6; + if (!(xmit_type & XMIT_CSUM_TCP)) + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IS_UDP; + } + pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); + /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) { hlen = (skb_network_header(skb) - skb->data) / 2; /* for now NS flag is not used in Linux */ - pbd->global_data = + pbd_e1x->global_data = (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << - ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); + ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); - pbd->ip_hlen = (skb_transport_header(skb) - + pbd_e1x->ip_hlen_w = (skb_transport_header(skb) - skb_network_header(skb)) / 2; - hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2; + hlen += pbd_e1x->ip_hlen_w + tcp_hdrlen(skb) / 2; - pbd->total_hlen = cpu_to_le16(hlen); + pbd_e1x->total_hlen_w = cpu_to_le16(hlen); hlen = hlen*2; - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; - - if (xmit_type & XMIT_CSUM_V4) - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IP_CSUM; - else - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IPV6; - if (xmit_type & XMIT_CSUM_TCP) { - pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); + pbd_e1x->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); } else { s8 fix = SKB_CS_OFF(skb); /* signed! */ - pbd->global_data |= ETH_TX_PARSE_BD_UDP_CS_FLG; - DP(NETIF_MSG_TX_QUEUED, "hlen %d fix %d csum before fix %x\n", - le16_to_cpu(pbd->total_hlen), fix, SKB_CS(skb)); + le16_to_cpu(pbd_e1x->total_hlen_w), + fix, SKB_CS(skb)); /* HW bug: fixup the CSUM */ - pbd->tcp_pseudo_csum = + pbd_e1x->tcp_pseudo_csum = bnx2x_csum_fix(skb_transport_header(skb), SKB_CS(skb), fix); DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", - pbd->tcp_pseudo_csum); + pbd_e1x->tcp_pseudo_csum); } } @@ -2016,7 +2042,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) " nbytes %d flags %x vlan %x\n", tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo, le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes), - tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan)); + tx_start_bd->bd_flags.as_bitfield, + le16_to_cpu(tx_start_bd->vlan_or_ethertype)); if (xmit_type & XMIT_GSO) { @@ -2031,24 +2058,25 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); - pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); - pbd->tcp_flags = pbd_tcp_flags(skb); + pbd_e1x->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbd_e1x->tcp_send_seq = swab32(tcp_hdr(skb)->seq); + pbd_e1x->tcp_flags = pbd_tcp_flags(skb); if (xmit_type & XMIT_GSO_V4) { - pbd->ip_id = swab16(ip_hdr(skb)->id); - pbd->tcp_pseudo_csum = + pbd_e1x->ip_id = swab16(ip_hdr(skb)->id); + pbd_e1x->tcp_pseudo_csum = swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0)); } else - pbd->tcp_pseudo_csum = + pbd_e1x->tcp_pseudo_csum = swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0)); - pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN; + pbd_e1x->global_data |= + ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; } tx_data_bd = (struct eth_tx_bd *)tx_start_bd; @@ -2088,13 +2116,14 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (total_pkt_bd != NULL) total_pkt_bd->total_pkt_bytes = pkt_size; - if (pbd) + if (pbd_e1x) DP(NETIF_MSG_TX_QUEUED, - "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" + "PBD (E1X) @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" " tcp_flags %x xsum %x seq %u hlen %u\n", - pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id, - pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum, - pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen)); + pbd_e1x, pbd_e1x->global_data, pbd_e1x->ip_hlen_w, + pbd_e1x->ip_id, pbd_e1x->lso_mss, pbd_e1x->tcp_flags, + pbd_e1x->tcp_pseudo_csum, pbd_e1x->tcp_send_seq, + le16_to_cpu(pbd_e1x->total_hlen_w)); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); @@ -2109,7 +2138,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) fp->tx_db.data.prod += nbd; barrier(); - DOORBELL(bp, fp->index, fp->tx_db.raw); + DOORBELL(bp, fp->cid, fp->tx_db.raw); mmiowb(); @@ -2141,16 +2170,51 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) return -EINVAL; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - if (netif_running(dev)) { - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); - } + if (netif_running(dev)) + bnx2x_set_eth_mac(bp, 1); return 0; } +void bnx2x_free_mem_bp(struct bnx2x *bp) +{ + kfree(bp->fp); + kfree(bp->msix_table); + kfree(bp->ilt); +} + +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) +{ + struct bnx2x_fastpath *fp; + struct msix_entry *tbl; + struct bnx2x_ilt *ilt; + + /* fp array */ + fp = kzalloc(L2_FP_COUNT(bp->l2_cid_count)*sizeof(*fp), GFP_KERNEL); + if (!fp) + goto alloc_err; + bp->fp = fp; + + /* msix table */ + tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl), + GFP_KERNEL); + if (!tbl) + goto alloc_err; + bp->msix_table = tbl; + + /* ilt */ + ilt = kzalloc(sizeof(*ilt), GFP_KERNEL); + if (!ilt) + goto alloc_err; + bp->ilt = ilt; + + return 0; +alloc_err: + bnx2x_free_mem_bp(bp); + return -ENOMEM; + +} + /* called with rtnl_lock */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { @@ -2200,18 +2264,6 @@ void bnx2x_vlan_rx_register(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); bp->vlgrp = vlgrp; - - /* Set flags according to the required capabilities */ - bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); - - if (dev->features & NETIF_F_HW_VLAN_TX) - bp->flags |= HW_VLAN_TX_FLAG; - - if (dev->features & NETIF_F_HW_VLAN_RX) - bp->flags |= HW_VLAN_RX_FLAG; - - if (netif_running(dev)) - bnx2x_set_client_config(bp); } #endif diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 1ad08e4e88f4..2fb9045833e1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -106,6 +106,13 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); */ void bnx2x_int_enable(struct bnx2x *bp); +/** + * Disable HW interrupts. + * + * @param bp + */ +void bnx2x_int_disable(struct bnx2x *bp); + /** * Disable interrupts. This function ensures that there are no * ISRs or SP DPCs (sp_task) are running after it returns. @@ -163,27 +170,30 @@ int bnx2x_alloc_mem(struct bnx2x *bp); void bnx2x_free_mem(struct bnx2x *bp); /** - * Bring up a leading (the first) eth Client. + * Setup eth Client. * * @param bp + * @param fp + * @param is_leading * * @return int */ -int bnx2x_setup_leading(struct bnx2x *bp); +int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, + int is_leading); /** - * Setup non-leading eth Client. + * Bring down an eth client. * * @param bp - * @param fp + * @param p * * @return int */ -int bnx2x_setup_multi(struct bnx2x *bp, int index); +int bnx2x_stop_fw_client(struct bnx2x *bp, + struct bnx2x_client_ramrod_params *p); /** - * Set number of quueus according to mode and number of available - * msi-x vectors + * Set number of quueus according to mode * * @param bp * @@ -228,16 +238,7 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); * @param bp driver handle * @param set */ -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set); - -/** - * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57710 - * - * @param bp driver handle - * @param set - */ -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set); +void bnx2x_set_eth_mac(struct bnx2x *bp, int set); #ifdef BCM_CNIC /** @@ -257,12 +258,15 @@ int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set); * Initialize status block in FW and HW * * @param bp driver handle - * @param sb host_status_block * @param dma_addr_t mapping * @param int sb_id + * @param int vfid + * @param u8 vf_valid + * @param int fw_sb_id + * @param int igu_sb_id */ -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id); +void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, + u8 vf_valid, int fw_sb_id, int igu_sb_id); /** * Reconfigure FW/HW according to dev->flags rx mode @@ -294,14 +298,6 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp); */ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); -/** - * Configures FW with client paramteres (like HW VLAN removal) - * for each active client. - * - * @param bp - */ -void bnx2x_set_client_config(struct bnx2x *bp); - /** * Handle sp events * @@ -310,14 +306,29 @@ void bnx2x_set_client_config(struct bnx2x *bp); */ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); +/** + * Init/halt function before/after sending + * CLIENT_SETUP/CFC_DEL for the first/last client. + * + * @param bp + * + * @return int + */ +int bnx2x_func_start(struct bnx2x *bp); +int bnx2x_func_stop(struct bnx2x *bp); + +/** + * Prepare ILT configurations according to current driver + * parameters. + * + * @param bp + */ +void bnx2x_ilt_set_info(struct bnx2x *bp); static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { - struct host_status_block *fpsb = fp->status_blk; - barrier(); /* status block is written to by the chip */ - fp->fp_c_idx = fpsb->c_status_block.status_block_index; - fp->fp_u_idx = fpsb->u_status_block.status_block_index; + fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID]; } static inline void bnx2x_update_rx_prod(struct bnx2x *bp, @@ -344,8 +355,8 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, wmb(); for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4, + REG_WR(bp, + BAR_USTRORM_INTMEM + fp->ustorm_rx_prods_offset + i*4, ((u32 *)&rx_prods)[i]); mmiowb(); /* keep prod updates ordered */ @@ -434,6 +445,17 @@ static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) return hw_cons != fp->tx_pkt_cons; } +static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) +{ + u16 rx_cons_sb; + + /* Tell compiler that status block fields can change */ + barrier(); + rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); + if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) + rx_cons_sb++; + return (fp->rx_comp_cons != rx_cons_sb); +} static inline void bnx2x_free_rx_sge(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { @@ -454,13 +476,35 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, sge->addr_lo = 0; } -static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, - struct bnx2x_fastpath *fp, int last) + + + + +static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) { - int i; + int i, j; - for (i = 0; i < last; i++) - bnx2x_free_rx_sge(bp, fp, i); + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + int idx = RX_SGE_CNT * i - 1; + + for (j = 0; j < 2; j++) { + SGE_MASK_CLEAR_BIT(fp, idx); + idx--; + } + } +} + +static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) +{ + /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ + memset(fp->sge_mask, 0xff, + (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); + + /* Clear the two last indices in the page to 1: + these are the indices that correspond to the "next" element, + hence will never be indicated and should be removed from + the calculations. */ + bnx2x_clear_sge_mask_next_elems(fp); } static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, @@ -540,33 +584,15 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, dma_unmap_addr(cons_rx_buf, mapping)); *prod_bd = *cons_bd; } - -static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) +static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, + struct bnx2x_fastpath *fp, int last) { - int i, j; - - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - int idx = RX_SGE_CNT * i - 1; + int i; - for (j = 0; j < 2; j++) { - SGE_MASK_CLEAR_BIT(fp, idx); - idx--; - } - } + for (i = 0; i < last; i++) + bnx2x_free_rx_sge(bp, fp, i); } -static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) -{ - /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ - memset(fp->sge_mask, 0xff, - (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); - - /* Clear the two last indices in the page to 1: - these are the indices that correspond to the "next" element, - hence will never be indicated and should be removed from - the calculations. */ - bnx2x_clear_sge_mask_next_elems(fp); -} static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, struct bnx2x_fastpath *fp, int last) { @@ -592,7 +618,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, } -static inline void bnx2x_init_tx_ring(struct bnx2x *bp) +static inline void bnx2x_init_tx_rings(struct bnx2x *bp) { int i, j; @@ -611,7 +637,7 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp) BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); } - fp->tx_db.data.header.header = DOORBELL_HDR_DB_TYPE; + SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1); fp->tx_db.data.zero_fill1 = 0; fp->tx_db.data.prod = 0; @@ -619,22 +645,94 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp) fp->tx_pkt_cons = 0; fp->tx_bd_prod = 0; fp->tx_bd_cons = 0; - fp->tx_cons_sb = BNX2X_TX_SB_INDEX; fp->tx_pkt = 0; } } -static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) +static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) { - u16 rx_cons_sb; + int i; - /* Tell compiler that status block fields can change */ - barrier(); - rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); - if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) - rx_cons_sb++; - return fp->rx_comp_cons != rx_cons_sb; + for (i = 1; i <= NUM_RX_RINGS; i++) { + struct eth_rx_bd *rx_bd; + + rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; + rx_bd->addr_hi = + cpu_to_le32(U64_HI(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + rx_bd->addr_lo = + cpu_to_le32(U64_LO(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + } } +static inline void bnx2x_set_next_page_sgl(struct bnx2x_fastpath *fp) +{ + int i; + + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + struct eth_rx_sge *sge; + + sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; + sge->addr_hi = + cpu_to_le32(U64_HI(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + + sge->addr_lo = + cpu_to_le32(U64_LO(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + } +} + +static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp) +{ + int i; + for (i = 1; i <= NUM_RCQ_RINGS; i++) { + struct eth_rx_cqe_next_page *nextpg; + + nextpg = (struct eth_rx_cqe_next_page *) + &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; + nextpg->addr_hi = + cpu_to_le32(U64_HI(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + nextpg->addr_lo = + cpu_to_le32(U64_LO(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + } +} + + + +static inline void __storm_memset_struct(struct bnx2x *bp, + u32 addr, size_t size, u32 *data) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), data[i]); +} + +static inline void storm_memset_mac_filters(struct bnx2x *bp, + struct tstorm_eth_mac_filter_config *mac_filters, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_mac_filter_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_MAC_FILTER_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)mac_filters); +} + +static inline void storm_memset_cmng(struct bnx2x *bp, + struct cmng_struct_per_port *cmng, + u8 port) +{ + size_t size = sizeof(struct cmng_struct_per_port); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port); + + __storm_memset_struct(bp, addr, size, (u32 *)cmng); +} /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); @@ -659,4 +757,16 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); int bnx2x_nic_load(struct bnx2x *bp, int load_mode); int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); +/** + * Allocate/release memories outsize main driver structure + * + * @param bp + * + * @return int + */ +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp); +void bnx2x_free_mem_bp(struct bnx2x *bp); + +#define BNX2X_FW_IP_HDR_ALIGN_PAD 2 /* FW places hdr with this padding */ + #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index d9748e97fad3..56a0cb579c21 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1343,7 +1343,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) u16 pkt_prod, bd_prod; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_parse_bd *pbd = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; dma_addr_t mapping; union eth_rx_cqe *cqe; u8 cqe_fp_flags; @@ -1399,16 +1399,20 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */ tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); - tx_start_bd->vlan = cpu_to_le16(pkt_prod); + tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = ((UNICAST_ADDRESS << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_ETH_ADDR_TYPE, + UNICAST_ADDRESS); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_HDR_NBDS, + 1); /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd; + pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); wmb(); @@ -1578,9 +1582,9 @@ static int bnx2x_test_intr(struct bnx2x *bp) bp->set_mac_pending++; smp_wmb(); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); if (rc == 0) { for (i = 0; i < 10; i++) { if (!bp->set_mac_pending) diff --git a/drivers/net/bnx2x/bnx2x_fw_defs.h b/drivers/net/bnx2x/bnx2x_fw_defs.h index 08d71bf438d6..f4e5b1ce8149 100644 --- a/drivers/net/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/bnx2x/bnx2x_fw_defs.h @@ -7,369 +7,272 @@ * the Free Software Foundation. */ - -#define CSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x7000 : 0x1000) -#define CSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0x8622 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100) + (index * 0x4)) : (0x3562 + (function * \ - 0x40) + (index * 0x4))) -#define CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0x8822 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200) + (index * 0x4)) : (0x35e2 + (function * \ - 0x80) + (index * 0x4))) -#define CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8600 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100)) : (0x3540 + (function * 0x40))) -#define CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8800 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200)) : (0x35c0 + (function * 0x80))) -#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8608 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100)) : (0x3548 + (function * 0x40))) -#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8808 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200)) : (0x35c8 + (function * 0x80))) -#define CSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x11e8 : 0xffffffff) -#define CSTORM_HC_BTR_C_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x8c04 + (port * 0xf0)) : (0x36c4 + (port * 0xc0))) -#define CSTORM_HC_BTR_U_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x8de4 + (port * 0xf0)) : (0x3844 + (port * 0xc0))) -#define CSTORM_ISCSI_CQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6680 + (function * 0x8)) : (0x25a0 + \ - (function * 0x8))) -#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x66c0 + (function * 0x8)) : (0x25b0 + \ - (function * 0x8))) -#define CSTORM_ISCSI_EQ_CONS_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6040 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2410 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6044 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2414 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x604c + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x241c + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6057 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2427 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_PROD_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6042 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2412 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6056 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2426 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6054 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2424 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_HQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6640 + (function * 0x8)) : (0x2590 + \ - (function * 0x8))) -#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x2404 + \ - (function * 0x8))) -#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x2402 + \ - (function * 0x8))) -#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x2400 + \ - (function * 0x8))) -#define CSTORM_SB_HC_DISABLE_C_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0x811a + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4)) : (0x305a + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4))) -#define CSTORM_SB_HC_DISABLE_U_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0xb01a + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4)) : (0x401a + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4))) -#define CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0x8118 + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4)) : (0x3058 + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4))) -#define CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0xb018 + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4)) : (0x4018 + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4))) -#define CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0x8100 + (port * 0x280) + (cpu_id * 0x28)) : \ - (0x3040 + (port * 0x280) + (cpu_id * 0x28))) -#define CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0xb000 + (port * 0x800) + (cpu_id * 0x80)) : \ - (0x4000 + (port * 0x800) + (cpu_id * 0x80))) -#define CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0x8108 + (port * 0x280) + (cpu_id * 0x28)) : \ - (0x3048 + (port * 0x280) + (cpu_id * 0x28))) -#define CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0xb008 + (port * 0x800) + (cpu_id * 0x80)) : \ - (0x4008 + (port * 0x800) + (cpu_id * 0x80))) -#define CSTORM_SB_STATUS_BLOCK_C_SIZE 0x10 -#define CSTORM_SB_STATUS_BLOCK_U_SIZE 0x60 -#define CSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x1108 + (function * 0x8)) : (0x5108 + \ - (function * 0x8))) -#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3200 + (function * 0x20)) : 0xffffffff) -#define TSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0xa000 : 0x1000) -#define TSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \ - (IS_E1H_OFFSET ? (0x33a0 + (port * 0x1a0) + (client_id * 0x10)) \ - : (0x9c0 + (port * 0x120) + (client_id * 0x10))) -#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \ - (IS_E1H_OFFSET ? 0x1ed8 : 0xffffffff) +#ifndef BNX2X_FW_DEFS_H +#define BNX2X_FW_DEFS_H + +#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[142].base) +#define CSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[141].base + ((assertListEntry) * IRO[141].m1)) +#define CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[144].base + ((pfId) * IRO[144].m1)) +#define CSTORM_EVENT_RING_DATA_OFFSET(pfId) \ + (IRO[149].base + (((pfId)>>1) * IRO[149].m1) + (((pfId)&1) * \ + IRO[149].m2)) +#define CSTORM_EVENT_RING_PROD_OFFSET(pfId) \ + (IRO[150].base + (((pfId)>>1) * IRO[150].m1) + (((pfId)&1) * \ + IRO[150].m2)) +#define CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(funcId) \ + (IRO[156].base + ((funcId) * IRO[156].m1)) +#define CSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[146].base + ((funcId) * IRO[146].m1)) +#define CSTORM_FUNCTION_MODE_OFFSET (IRO[153].base) +#define CSTORM_IGU_MODE_OFFSET (IRO[154].base) +#define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ + (IRO[311].base + ((pfId) * IRO[311].m1)) +#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[312].base + ((pfId) * IRO[312].m1)) + #define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \ + (IRO[304].base + ((pfId) * IRO[304].m1) + ((iscsiEqId) * \ + IRO[304].m2)) + #define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[306].base + ((pfId) * IRO[306].m1) + ((iscsiEqId) * \ + IRO[306].m2)) + #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[305].base + ((pfId) * IRO[305].m1) + ((iscsiEqId) * \ + IRO[305].m2)) + #define \ + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \ + (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * \ + IRO[307].m2)) + #define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \ + (IRO[303].base + ((pfId) * IRO[303].m1) + ((iscsiEqId) * \ + IRO[303].m2)) + #define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \ + (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * \ + IRO[309].m2)) + #define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ + (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * \ + IRO[308].m2)) +#define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ + (IRO[310].base + ((pfId) * IRO[310].m1)) +#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[302].base + ((pfId) * IRO[302].m1)) +#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[301].base + ((pfId) * IRO[301].m1)) +#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[300].base + ((pfId) * IRO[300].m1)) +#define CSTORM_PATH_ID_OFFSET (IRO[159].base) +#define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \ + (IRO[137].base + ((pfId) * IRO[137].m1)) +#define CSTORM_SP_STATUS_BLOCK_OFFSET(pfId) \ + (IRO[136].base + ((pfId) * IRO[136].m1)) +#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[136].size) +#define CSTORM_SP_SYNC_BLOCK_OFFSET(pfId) \ + (IRO[138].base + ((pfId) * IRO[138].m1)) +#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[138].size) +#define CSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[143].base + ((pfId) * IRO[143].m1)) +#define CSTORM_STATUS_BLOCK_DATA_OFFSET(sbId) \ + (IRO[129].base + ((sbId) * IRO[129].m1)) +#define CSTORM_STATUS_BLOCK_OFFSET(sbId) \ + (IRO[128].base + ((sbId) * IRO[128].m1)) +#define CSTORM_STATUS_BLOCK_SIZE (IRO[128].size) +#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \ + (IRO[132].base + ((sbId) * IRO[132].m1)) +#define CSTORM_SYNC_BLOCK_SIZE (IRO[132].size) +#define CSTORM_VF_PF_CHANNEL_STATE_OFFSET(vfId) \ + (IRO[151].base + ((vfId) * IRO[151].m1)) +#define CSTORM_VF_PF_CHANNEL_VALID_OFFSET(vfId) \ + (IRO[152].base + ((vfId) * IRO[152].m1)) +#define CSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[147].base + ((funcId) * IRO[147].m1)) +#define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[199].base) +#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \ + (IRO[198].base + ((pfId) * IRO[198].m1)) +#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[99].base) +#define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[98].base + ((assertListEntry) * IRO[98].m1)) + #define TSTORM_CLIENT_CONFIG_OFFSET(portId, clientId) \ + (IRO[197].base + ((portId) * IRO[197].m1) + ((clientId) * \ + IRO[197].m2)) +#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET (IRO[104].base) #define TSTORM_COMMON_SAFC_WORKAROUND_TIMEOUT_10USEC_OFFSET \ - (IS_E1H_OFFSET ? 0x1eda : 0xffffffff) -#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \ - 0x28) + (index * 0x4))) -#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xb000 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1400 + (function * 0x28))) -#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xb008 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1408 + (function * 0x28))) -#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2940 + (function * 0x8)) : (0x4928 + \ - (function * 0x8))) -#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3000 + (function * 0x40)) : (0x1500 + \ - (function * 0x40))) -#define TSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x1ed0 : 0xffffffff) -#define TSTORM_HC_BTR_OFFSET(port) \ - (IS_E1H_OFFSET ? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18))) -#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x12c8 + (function * 0x80)) : (0x22c8 + \ - (function * 0x80))) -#define TSTORM_INDIRECTION_TABLE_SIZE 0x80 -#define TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(function, pblEntry) \ - (IS_E1H_OFFSET ? (0x60c0 + (function * 0x40) + (pblEntry * 0x8)) \ - : (0x4c30 + (function * 0x40) + (pblEntry * 0x8))) -#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6340 + (function * 0x8)) : (0x4cd0 + \ - (function * 0x8))) -#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x4c04 + \ - (function * 0x8))) -#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x4c02 + \ - (function * 0x8))) -#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x4c00 + \ - (function * 0x8))) -#define TSTORM_ISCSI_RQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6080 + (function * 0x8)) : (0x4c20 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6040 + (function * 0x8)) : (0x4c10 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6042 + (function * 0x8)) : (0x4c12 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6044 + (function * 0x8)) : (0x4c14 + \ - (function * 0x8))) -#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3008 + (function * 0x40)) : (0x1508 + \ - (function * 0x40))) -#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0x2010 + (port * 0x490) + (stats_counter_id * \ - 0x40)) : (0x4010 + (port * 0x490) + (stats_counter_id * 0x40))) -#define TSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x29c0 + (function * 0x8)) : (0x4948 + \ - (function * 0x8))) -#define TSTORM_TCP_MAX_CWND_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x4004 + (function * 0x8)) : (0x1fb4 + \ - (function * 0x8))) -#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa000 : 0x3000) -#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2000 : 0x1000) -#define USTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x8000 : 0x1000) -#define USTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1010 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4010 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_CQE_PAGE_NEXT_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1028 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4028 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_ETH_PAUSE_ENABLED_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff) -#define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1030 + (port * 0x680) + (clientId * 0x40)) : \ - 0xffffffff) -#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1dd0 + \ - (function * 0x8))) -#define USTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x2448 : 0xffffffff) -#define USTORM_ISCSI_CQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7044 + (function * 0x8)) : (0x2414 + \ - (function * 0x8))) -#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7046 + (function * 0x8)) : (0x2416 + \ - (function * 0x8))) -#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7688 + (function * 0x8)) : (0x29c8 + \ - (function * 0x8))) -#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7648 + (function * 0x8)) : (0x29b8 + \ - (function * 0x8))) -#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7004 + (function * 0x8)) : (0x2404 + \ - (function * 0x8))) -#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7002 + (function * 0x8)) : (0x2402 + \ - (function * 0x8))) -#define USTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7000 + (function * 0x8)) : (0x2400 + \ - (function * 0x8))) -#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7040 + (function * 0x8)) : (0x2410 + \ - (function * 0x8))) -#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7080 + (function * 0x8)) : (0x2420 + \ - (function * 0x8))) -#define USTORM_ISCSI_RQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7084 + (function * 0x8)) : (0x2424 + \ - (function * 0x8))) -#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1018 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4018 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x1da8 + \ - (function * 0x8))) -#define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \ - 0x28)) : (0x1500 + (port * 0x2d0) + (stats_counter_id * 0x28))) -#define USTORM_RX_PRODS_OFFSET(port, client_id) \ - (IS_E1H_OFFSET ? (0x1000 + (port * 0x680) + (client_id * 0x40)) \ - : (0x4000 + (port * 0x360) + (client_id * 0x30))) -#define USTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1db8 + \ - (function * 0x8))) -#define USTORM_TPA_BTR_OFFSET (IS_E1H_OFFSET ? 0x3da5 : 0x5095) -#define USTORM_TPA_BTR_SIZE 0x1 -#define XSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x9000 : 0x1000) -#define XSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3a80 + (port * 0x50))) -#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \ - 0x28) + (index * 0x4))) -#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xa000 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1400 + (function * 0x28))) -#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1408 + (function * 0x28))) -#define XSTORM_E1HOV_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2c10 + (function * 0x8)) : 0xffffffff) -#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3a50 + \ - (function * 0x8))) -#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3b60 + \ - (function * 0x90))) -#define XSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x2c50 : 0xffffffff) -#define XSTORM_HC_BTR_OFFSET(port) \ - (IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18))) -#define XSTORM_ISCSI_HQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c0 + (function * 0x8)) : (0x1c30 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8080 + (function * 0x8)) : (0x1c20 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8081 + (function * 0x8)) : (0x1c21 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8082 + (function * 0x8)) : (0x1c22 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8083 + (function * 0x8)) : (0x1c23 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8084 + (function * 0x8)) : (0x1c24 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8085 + (function * 0x8)) : (0x1c25 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8086 + (function * 0x8)) : (0x1c26 + \ - (function * 0x8))) -#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8004 + (function * 0x8)) : (0x1c04 + \ - (function * 0x8))) -#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8002 + (function * 0x8)) : (0x1c02 + \ - (function * 0x8))) -#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8000 + (function * 0x8)) : (0x1c00 + \ - (function * 0x8))) -#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c4 + (function * 0x8)) : (0x1c34 + \ - (function * 0x8))) -#define XSTORM_ISCSI_SQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c2 + (function * 0x8)) : (0x1c32 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8043 + (function * 0x8)) : (0x1c13 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8042 + (function * 0x8)) : (0x1c12 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8041 + (function * 0x8)) : (0x1c11 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8040 + (function * 0x8)) : (0x1c10 + \ - (function * 0x8))) -#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0xc000 + (port * 0x360) + (stats_counter_id * \ - 0x30)) : (0x3378 + (port * 0x360) + (stats_counter_id * 0x30))) -#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3b20 + \ - (function * 0x90))) -#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \ - (function * 0x10))) -#define XSTORM_SPQ_PROD_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2008 + (function * 0x10)) : (0x3330 + \ - (function * 0x10))) -#define XSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3a40 + \ - (function * 0x8))) -#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x4000 + (port * 0x8)) : (0x1960 + (port * 0x8))) -#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x4001 + (port * 0x8)) : (0x1961 + (port * 0x8))) -#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x4060 + ((function>>1) * 0x8) + ((function&1) \ - * 0x4)) : (0x1978 + (function * 0x4))) + (IRO[105].base) +#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[96].base + ((pfId) * IRO[96].m1)) +#define TSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[101].base + ((funcId) * IRO[101].m1)) +#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \ + (IRO[195].base + ((pfId) * IRO[195].m1)) +#define TSTORM_FUNCTION_MODE_OFFSET (IRO[103].base) +#define TSTORM_INDIRECTION_TABLE_OFFSET(pfId) \ + (IRO[91].base + ((pfId) * IRO[91].m1)) +#define TSTORM_INDIRECTION_TABLE_SIZE (IRO[91].size) + #define \ + TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfId, iscsiConBufPblEntry) \ + (IRO[260].base + ((pfId) * IRO[260].m1) + ((iscsiConBufPblEntry) \ + * IRO[260].m2)) +#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ + (IRO[264].base + ((pfId) * IRO[264].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \ + (IRO[265].base + ((pfId) * IRO[265].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \ + (IRO[266].base + ((pfId) * IRO[266].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \ + (IRO[267].base + ((pfId) * IRO[267].m1)) +#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[263].base + ((pfId) * IRO[263].m1)) +#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[262].base + ((pfId) * IRO[262].m1)) +#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[261].base + ((pfId) * IRO[261].m1)) +#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[259].base + ((pfId) * IRO[259].m1)) +#define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \ + (IRO[269].base + ((pfId) * IRO[269].m1)) +#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ + (IRO[256].base + ((pfId) * IRO[256].m1)) +#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ + (IRO[257].base + ((pfId) * IRO[257].m1)) +#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ + (IRO[258].base + ((pfId) * IRO[258].m1)) +#define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \ + (IRO[196].base + ((pfId) * IRO[196].m1)) + #define TSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, tStatCntId) \ + (IRO[100].base + ((portId) * IRO[100].m1) + ((tStatCntId) * \ + IRO[100].m2)) +#define TSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[95].base + ((pfId) * IRO[95].m1)) +#define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \ + (IRO[211].base + ((pfId) * IRO[211].m1)) +#define TSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[102].base + ((funcId) * IRO[102].m1)) +#define USTORM_AGG_DATA_OFFSET (IRO[201].base) +#define USTORM_AGG_DATA_SIZE (IRO[201].size) +#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[170].base) +#define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[169].base + ((assertListEntry) * IRO[169].m1)) +#define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \ + (IRO[178].base + ((portId) * IRO[178].m1)) +#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[172].base + ((pfId) * IRO[172].m1)) +#define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \ + (IRO[313].base + ((pfId) * IRO[313].m1)) +#define USTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[174].base + ((funcId) * IRO[174].m1)) +#define USTORM_FUNCTION_MODE_OFFSET (IRO[177].base) +#define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ + (IRO[277].base + ((pfId) * IRO[277].m1)) +#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[278].base + ((pfId) * IRO[278].m1)) +#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ + (IRO[282].base + ((pfId) * IRO[282].m1)) +#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \ + (IRO[279].base + ((pfId) * IRO[279].m1)) +#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[275].base + ((pfId) * IRO[275].m1)) +#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[274].base + ((pfId) * IRO[274].m1)) +#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[273].base + ((pfId) * IRO[273].m1)) +#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ + (IRO[276].base + ((pfId) * IRO[276].m1)) +#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \ + (IRO[280].base + ((pfId) * IRO[280].m1)) +#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[281].base + ((pfId) * IRO[281].m1)) +#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \ + (IRO[176].base + ((pfId) * IRO[176].m1)) + #define USTORM_PER_COUNTER_ID_STATS_OFFSET(portId, uStatCntId) \ + (IRO[173].base + ((portId) * IRO[173].m1) + ((uStatCntId) * \ + IRO[173].m2)) + #define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \ + (IRO[204].base + ((portId) * IRO[204].m1) + ((clientId) * \ + IRO[204].m2)) +#define USTORM_RX_PRODS_E2_OFFSET(qzoneId) \ + (IRO[205].base + ((qzoneId) * IRO[205].m1)) +#define USTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[171].base + ((pfId) * IRO[171].m1)) +#define USTORM_TPA_BTR_OFFSET (IRO[202].base) +#define USTORM_TPA_BTR_SIZE (IRO[202].size) +#define USTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[175].base + ((funcId) * IRO[175].m1)) +#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[59].base) +#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[58].base) +#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[54].base) +#define XSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[53].base + ((assertListEntry) * IRO[53].m1)) +#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(portId) \ + (IRO[47].base + ((portId) * IRO[47].m1)) +#define XSTORM_E1HOV_OFFSET(pfId) \ + (IRO[55].base + ((pfId) * IRO[55].m1)) +#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[45].base + ((pfId) * IRO[45].m1)) +#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(pfId) \ + (IRO[49].base + ((pfId) * IRO[49].m1)) +#define XSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[51].base + ((funcId) * IRO[51].m1)) +#define XSTORM_FUNCTION_MODE_OFFSET (IRO[56].base) +#define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ + (IRO[290].base + ((pfId) * IRO[290].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \ + (IRO[293].base + ((pfId) * IRO[293].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \ + (IRO[294].base + ((pfId) * IRO[294].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \ + (IRO[295].base + ((pfId) * IRO[295].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \ + (IRO[296].base + ((pfId) * IRO[296].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \ + (IRO[297].base + ((pfId) * IRO[297].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \ + (IRO[298].base + ((pfId) * IRO[298].m1)) +#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \ + (IRO[299].base + ((pfId) * IRO[299].m1)) +#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[289].base + ((pfId) * IRO[289].m1)) +#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[288].base + ((pfId) * IRO[288].m1)) +#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[287].base + ((pfId) * IRO[287].m1)) +#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ + (IRO[292].base + ((pfId) * IRO[292].m1)) +#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \ + (IRO[291].base + ((pfId) * IRO[291].m1)) +#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \ + (IRO[286].base + ((pfId) * IRO[286].m1)) +#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ + (IRO[285].base + ((pfId) * IRO[285].m1)) +#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \ + (IRO[284].base + ((pfId) * IRO[284].m1)) +#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \ + (IRO[283].base + ((pfId) * IRO[283].m1)) +#define XSTORM_PATH_ID_OFFSET (IRO[65].base) + #define XSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, xStatCntId) \ + (IRO[50].base + ((portId) * IRO[50].m1) + ((xStatCntId) * \ + IRO[50].m2)) +#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \ + (IRO[48].base + ((pfId) * IRO[48].m1)) +#define XSTORM_SPQ_DATA_OFFSET(funcId) \ + (IRO[32].base + ((funcId) * IRO[32].m1)) +#define XSTORM_SPQ_DATA_SIZE (IRO[32].size) +#define XSTORM_SPQ_PAGE_BASE_OFFSET(funcId) \ + (IRO[30].base + ((funcId) * IRO[30].m1)) +#define XSTORM_SPQ_PROD_OFFSET(funcId) \ + (IRO[31].base + ((funcId) * IRO[31].m1)) +#define XSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[43].base + ((pfId) * IRO[43].m1)) +#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(portId) \ + (IRO[206].base + ((portId) * IRO[206].m1)) +#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(portId) \ + (IRO[207].base + ((portId) * IRO[207].m1)) +#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfId) \ + (IRO[209].base + (((pfId)>>1) * IRO[209].m1) + (((pfId)&1) * \ + IRO[209].m2)) +#define XSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[52].base + ((funcId) * IRO[52].m1)) #define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0 -/** -* This file defines HSI constants for the ETH flow -*/ -#ifdef _EVEREST_MICROCODE -#include "microcode_constants.h" -#include "eth_rx_bd.h" -#include "eth_tx_bd.h" -#include "eth_rx_cqe.h" -#include "eth_rx_sge.h" -#include "eth_rx_cqe_next_page.h" -#endif - /* RSS hash types */ #define DEFAULT_HASH_TYPE 0 #define IPV4_HASH_TYPE 1 @@ -389,11 +292,17 @@ #define U_ETH_NUM_OF_SGES_TO_FETCH 8 #define U_ETH_MAX_SGES_FOR_PACKET 3 +/*Tx params*/ +#define X_ETH_NO_VLAN 0 +#define X_ETH_OUTBAND_VLAN 1 +#define X_ETH_INBAND_VLAN 2 /* Rx ring params */ #define U_ETH_LOCAL_BD_RING_SIZE 8 #define U_ETH_LOCAL_SGE_RING_SIZE 10 #define U_ETH_SGL_SIZE 8 - + /* The fw will padd the buffer with this value, so the IP header \ + will be align to 4 Byte */ +#define IP_HEADER_ALIGNMENT_PADDING 2 #define U_ETH_SGES_PER_PAGE_INVERSE_MASK \ (0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1)) @@ -409,16 +318,15 @@ #define U_ETH_UNDEFINED_Q 0xFF /* values of command IDs in the ramrod message */ -#define RAMROD_CMD_ID_ETH_PORT_SETUP 80 -#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 85 -#define RAMROD_CMD_ID_ETH_STAT_QUERY 90 -#define RAMROD_CMD_ID_ETH_UPDATE 100 -#define RAMROD_CMD_ID_ETH_HALT 105 -#define RAMROD_CMD_ID_ETH_SET_MAC 110 -#define RAMROD_CMD_ID_ETH_CFC_DEL 115 -#define RAMROD_CMD_ID_ETH_PORT_DEL 120 -#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 125 - +#define RAMROD_CMD_ID_ETH_UNUSED 0 +#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 1 +#define RAMROD_CMD_ID_ETH_UPDATE 2 +#define RAMROD_CMD_ID_ETH_HALT 3 +#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 4 +#define RAMROD_CMD_ID_ETH_ACTIVATE 5 +#define RAMROD_CMD_ID_ETH_DEACTIVATE 6 +#define RAMROD_CMD_ID_ETH_EMPTY 7 +#define RAMROD_CMD_ID_ETH_TERMINATE 8 /* command values for set mac command */ #define T_ETH_MAC_COMMAND_SET 0 @@ -431,7 +339,9 @@ /* Maximal L2 clients supported */ #define ETH_MAX_RX_CLIENTS_E1 18 -#define ETH_MAX_RX_CLIENTS_E1H 26 +#define ETH_MAX_RX_CLIENTS_E1H 28 + +#define MAX_STAT_COUNTER_ID ETH_MAX_RX_CLIENTS_E1H /* Maximal aggregation queues supported */ #define ETH_MAX_AGGREGATION_QUEUES_E1 32 @@ -443,6 +353,20 @@ #define ETH_RSS_MODE_VLAN_PRI 2 #define ETH_RSS_MODE_E1HOV_PRI 3 #define ETH_RSS_MODE_IP_DSCP 4 +#define ETH_RSS_MODE_E2_INTEG 5 + + +/* ETH vlan filtering modes */ +#define ETH_VLAN_FILTER_ANY_VLAN 0 /* Don't filter by vlan */ +#define ETH_VLAN_FILTER_SPECIFIC_VLAN \ + 1 /* Only the vlan_id is allowed */ +#define ETH_VLAN_FILTER_CLASSIFY \ + 2 /* vlan will be added to CAM for classification */ + +/* Fast path CQE selection */ +#define ETH_FP_CQE_REGULAR 0 +#define ETH_FP_CQE_SGL 1 +#define ETH_FP_CQE_RAW 2 /** @@ -458,6 +382,7 @@ #define RESERVED_CONNECTION_TYPE_0 5 #define RESERVED_CONNECTION_TYPE_1 6 #define RESERVED_CONNECTION_TYPE_2 7 +#define NONE_CONNECTION_TYPE 8 #define PROTOCOL_STATE_BIT_OFFSET 6 @@ -466,6 +391,16 @@ #define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET) #define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET) +/* values of command IDs in the ramrod message */ +#define RAMROD_CMD_ID_COMMON_FUNCTION_START 1 +#define RAMROD_CMD_ID_COMMON_FUNCTION_STOP 2 +#define RAMROD_CMD_ID_COMMON_CFC_DEL 3 +#define RAMROD_CMD_ID_COMMON_CFC_DEL_WB 4 +#define RAMROD_CMD_ID_COMMON_SET_MAC 5 +#define RAMROD_CMD_ID_COMMON_STAT_QUERY 6 +#define RAMROD_CMD_ID_COMMON_STOP_TRAFFIC 7 +#define RAMROD_CMD_ID_COMMON_START_TRAFFIC 8 + /* microcode fixed page page size 4K (chains and ring segments) */ #define MC_PAGE_SIZE 4096 @@ -473,46 +408,26 @@ /* Host coalescing constants */ #define HC_IGU_BC_MODE 0 #define HC_IGU_NBC_MODE 1 +/* Host coalescing constants. E1 includes E1H as well */ + +/* Number of indices per slow-path SB */ +#define HC_SP_SB_MAX_INDICES 16 + +/* Number of indices per SB */ +#define HC_SB_MAX_INDICES_E1X 8 +#define HC_SB_MAX_INDICES_E2 8 + +#define HC_SB_MAX_SB_E1X 32 +#define HC_SB_MAX_SB_E2 136 + +#define HC_SP_SB_ID 0xde #define HC_REGULAR_SEGMENT 0 #define HC_DEFAULT_SEGMENT 1 +#define HC_SB_MAX_SM 2 -/* index numbers */ -#define HC_USTORM_DEF_SB_NUM_INDICES 8 -#define HC_CSTORM_DEF_SB_NUM_INDICES 8 -#define HC_XSTORM_DEF_SB_NUM_INDICES 4 -#define HC_TSTORM_DEF_SB_NUM_INDICES 4 -#define HC_USTORM_SB_NUM_INDICES 4 -#define HC_CSTORM_SB_NUM_INDICES 4 - -/* index values - which counter to update */ - -#define HC_INDEX_U_TOE_RX_CQ_CONS 0 -#define HC_INDEX_U_ETH_RX_CQ_CONS 1 -#define HC_INDEX_U_ETH_RX_BD_CONS 2 -#define HC_INDEX_U_FCOE_EQ_CONS 3 - -#define HC_INDEX_C_TOE_TX_CQ_CONS 0 -#define HC_INDEX_C_ETH_TX_CQ_CONS 1 -#define HC_INDEX_C_ISCSI_EQ_CONS 2 - -#define HC_INDEX_DEF_X_SPQ_CONS 0 - -#define HC_INDEX_DEF_C_RDMA_EQ_CONS 0 -#define HC_INDEX_DEF_C_RDMA_NAL_PROD 1 -#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2 -#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3 -#define HC_INDEX_DEF_C_ETH_RDMA_CQ_CONS 4 -#define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5 -#define HC_INDEX_DEF_C_ETH_FCOE_CQ_CONS 6 - -#define HC_INDEX_DEF_U_ETH_RDMA_RX_CQ_CONS 0 -#define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1 -#define HC_INDEX_DEF_U_ETH_RDMA_RX_BD_CONS 2 -#define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3 -#define HC_INDEX_DEF_U_ETH_FCOE_RX_CQ_CONS 4 -#define HC_INDEX_DEF_U_ETH_FCOE_RX_BD_CONS 5 - +#define HC_SB_MAX_DYNAMIC_INDICES 4 +#define HC_FUNCTION_DISABLED 0xff /* used by the driver to get the SB offset */ #define USTORM_ID 0 #define CSTORM_ID 1 @@ -529,45 +444,17 @@ /**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/ -#define EMULATION_FREQUENCY_FACTOR 1600 -#define FPGA_FREQUENCY_FACTOR 100 #define TIMERS_TICK_SIZE_CHIP (1e-3) -#define TIMERS_TICK_SIZE_EMUL \ - ((TIMERS_TICK_SIZE_CHIP)/((EMULATION_FREQUENCY_FACTOR))) -#define TIMERS_TICK_SIZE_FPGA \ - ((TIMERS_TICK_SIZE_CHIP)/((FPGA_FREQUENCY_FACTOR))) #define TSEMI_CLK1_RESUL_CHIP (1e-3) -#define TSEMI_CLK1_RESUL_EMUL \ - ((TSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define TSEMI_CLK1_RESUL_FPGA \ - ((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - -#define USEMI_CLK1_RESUL_CHIP (TIMERS_TICK_SIZE_CHIP) -#define USEMI_CLK1_RESUL_EMUL (TIMERS_TICK_SIZE_EMUL) -#define USEMI_CLK1_RESUL_FPGA (TIMERS_TICK_SIZE_FPGA) #define XSEMI_CLK1_RESUL_CHIP (1e-3) -#define XSEMI_CLK1_RESUL_EMUL \ - ((XSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define XSEMI_CLK1_RESUL_FPGA \ - ((XSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - -#define XSEMI_CLK2_RESUL_CHIP (1e-6) -#define XSEMI_CLK2_RESUL_EMUL \ - ((XSEMI_CLK2_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define XSEMI_CLK2_RESUL_FPGA \ - ((XSEMI_CLK2_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) #define SDM_TIMER_TICK_RESUL_CHIP (4*(1e-6)) -#define SDM_TIMER_TICK_RESUL_EMUL \ - ((SDM_TIMER_TICK_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define SDM_TIMER_TICK_RESUL_FPGA \ - ((SDM_TIMER_TICK_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - /**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/ + #define XSTORM_IP_ID_ROLL_HALF 0x8000 #define XSTORM_IP_ID_ROLL_ALL 0 @@ -576,10 +463,36 @@ #define NUM_OF_PROTOCOLS 4 #define NUM_OF_SAFC_BITS 16 #define MAX_COS_NUMBER 4 -#define MAX_T_STAT_COUNTER_ID 18 -#define MAX_X_STAT_COUNTER_ID 18 -#define MAX_U_STAT_COUNTER_ID 18 +#define FAIRNESS_COS_WRR_MODE 0 +#define FAIRNESS_COS_ETS_MODE 1 + + +/* Priority Flow Control (PFC) */ +#define MAX_PFC_PRIORITIES 8 +#define MAX_PFC_TRAFFIC_TYPES 8 + +/* Available Traffic Types for Link Layer Flow Control */ +#define LLFC_TRAFFIC_TYPE_NW 0 +#define LLFC_TRAFFIC_TYPE_FCOE 1 +#define LLFC_TRAFFIC_TYPE_ISCSI 2 + /***************** START OF E2 INTEGRATION \ + CODE***************************************/ +#define LLFC_TRAFFIC_TYPE_NW_COS1_E2INTEG 3 + /***************** END OF E2 INTEGRATION \ + CODE***************************************/ +#define LLFC_TRAFFIC_TYPE_MAX 4 + + /* used by array traffic_type_to_priority[] to mark traffic type \ + that is not mapped to priority*/ +#define LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED 0xFF + +#define LLFC_MODE_NONE 0 +#define LLFC_MODE_PFC 1 +#define LLFC_MODE_SAFC 2 + +#define DCB_DISABLED 0 +#define DCB_ENABLED 1 #define UNKNOWN_ADDRESS 0 #define UNICAST_ADDRESS 1 @@ -587,8 +500,32 @@ #define BROADCAST_ADDRESS 3 #define SINGLE_FUNCTION 0 -#define MULTI_FUNCTION 1 +#define MULTI_FUNCTION_SD 1 +#define MULTI_FUNCTION_SI 2 #define IP_V4 0 #define IP_V6 1 + +#define C_ERES_PER_PAGE \ + (PAGE_SIZE / BITS_TO_BYTES(STRUCT_SIZE(event_ring_elem))) +#define C_ERE_PER_PAGE_MASK (C_ERES_PER_PAGE - 1) + +#define EVENT_RING_OPCODE_VF_PF_CHANNEL 0 +#define EVENT_RING_OPCODE_FUNCTION_START 1 +#define EVENT_RING_OPCODE_FUNCTION_STOP 2 +#define EVENT_RING_OPCODE_CFC_DEL 3 +#define EVENT_RING_OPCODE_CFC_DEL_WB 4 +#define EVENT_RING_OPCODE_SET_MAC 5 +#define EVENT_RING_OPCODE_STAT_QUERY 6 +#define EVENT_RING_OPCODE_STOP_TRAFFIC 7 +#define EVENT_RING_OPCODE_START_TRAFFIC 8 +#define EVENT_RING_OPCODE_FORWARD_SETUP 9 + +#define VF_PF_CHANNEL_STATE_READY 0 +#define VF_PF_CHANNEL_STATE_WAITING_FOR_ACK 1 + +#define VF_PF_CHANNEL_STATE_MAX_NUMBER 2 + + +#endif /* BNX2X_FW_DEFS_H */ diff --git a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h index 3f5ee5d7cc2a..f807262911e5 100644 --- a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h +++ b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h @@ -31,6 +31,7 @@ struct bnx2x_fw_file_hdr { struct bnx2x_fw_file_section csem_pram_data; struct bnx2x_fw_file_section xsem_int_table_data; struct bnx2x_fw_file_section xsem_pram_data; + struct bnx2x_fw_file_section iro_arr; struct bnx2x_fw_file_section fw_version; }; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 60d141cd9950..596041cbd977 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -6,6 +6,10 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. */ +#ifndef BNX2X_HSI_H +#define BNX2X_HSI_H + +#include "bnx2x_fw_defs.h" struct license_key { u32 reserved[6]; @@ -326,6 +330,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u32 lane_config; #define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff #define PORT_HW_CFG_LANE_SWAP_CFG_SHIFT 0 + #define PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK 0x000000ff #define PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT 0 #define PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK 0x0000ff00 @@ -1016,11 +1021,12 @@ struct shmem_region { /* SharedMem Offset (size) */ struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */ struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */ - struct drv_func_mb func_mb[E1H_FUNC_MAX]; + struct drv_func_mb func_mb[]; /* 0x684 + (44*2/4/8=0x58/0xb0/0x160) */ + +}; /* 57710 = 0x6dc | 57711 = 0x7E4 | 57712 = 0x734 */ - struct mf_cfg mf_cfg; -}; /* 0x6dc */ struct shmem2_region { @@ -1096,7 +1102,7 @@ struct emac_stats { }; -struct bmac_stats { +struct bmac1_stats { u32 tx_stat_gtpkt_lo; u32 tx_stat_gtpkt_hi; u32 tx_stat_gtxpf_lo; @@ -1202,8 +1208,8 @@ struct bmac_stats { union mac_stats { - struct emac_stats emac_stats; - struct bmac_stats bmac_stats; + struct emac_stats emac_stats; + struct bmac1_stats bmac1_stats; }; @@ -1377,17 +1383,17 @@ struct host_func_stats { }; -#define BCM_5710_FW_MAJOR_VERSION 5 -#define BCM_5710_FW_MINOR_VERSION 2 -#define BCM_5710_FW_REVISION_VERSION 13 -#define BCM_5710_FW_ENGINEERING_VERSION 0 +#define BCM_5710_FW_MAJOR_VERSION 6 +#define BCM_5710_FW_MINOR_VERSION 0 +#define BCM_5710_FW_REVISION_VERSION 34 +#define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 /* * attention bits */ -struct atten_def_status_block { +struct atten_sp_status_block { __le32 attn_bits; __le32 attn_bits_ack; u8 status_block_id; @@ -1445,7 +1451,60 @@ struct doorbell_set_prod { /* - * IGU driver acknowledgement register + * 3 lines. status block + */ +struct hc_status_block_e1x { + __le16 index_values[HC_SB_MAX_INDICES_E1X]; + __le16 running_index[HC_SB_MAX_SM]; + u32 rsrv; +}; + +/* + * host status block + */ +struct host_hc_status_block_e1x { + struct hc_status_block_e1x sb; +}; + + +/* + * 3 lines. status block + */ +struct hc_status_block_e2 { + __le16 index_values[HC_SB_MAX_INDICES_E2]; + __le16 running_index[HC_SB_MAX_SM]; + u32 reserved; +}; + +/* + * host status block + */ +struct host_hc_status_block_e2 { + struct hc_status_block_e2 sb; +}; + + +/* + * 5 lines. slow-path status block + */ +struct hc_sp_status_block { + __le16 index_values[HC_SP_SB_MAX_INDICES]; + __le16 running_index; + __le16 rsrv; + u32 rsrv1; +}; + +/* + * host status block + */ +struct host_sp_status_block { + struct atten_sp_status_block atten_status_block; + struct hc_sp_status_block sp_sb; +}; + + +/* + * IGU driver acknowledgment register */ struct igu_ack_register { #if defined(__BIG_ENDIAN) @@ -1603,8 +1662,14 @@ struct dmae_command { #define DMAE_COMMAND_DST_RESET_SHIFT 14 #define DMAE_COMMAND_E1HVN (0x3<<15) #define DMAE_COMMAND_E1HVN_SHIFT 15 -#define DMAE_COMMAND_RESERVED0 (0x7FFF<<17) -#define DMAE_COMMAND_RESERVED0_SHIFT 17 +#define DMAE_COMMAND_DST_VN (0x3<<17) +#define DMAE_COMMAND_DST_VN_SHIFT 17 +#define DMAE_COMMAND_C_FUNC (0x1<<19) +#define DMAE_COMMAND_C_FUNC_SHIFT 19 +#define DMAE_COMMAND_ERR_POLICY (0x3<<20) +#define DMAE_COMMAND_ERR_POLICY_SHIFT 20 +#define DMAE_COMMAND_RESERVED0 (0x3FF<<22) +#define DMAE_COMMAND_RESERVED0_SHIFT 22 u32 src_addr_lo; u32 src_addr_hi; u32 dst_addr_lo; @@ -1629,11 +1694,11 @@ struct dmae_command { u16 crc16_c; #endif #if defined(__BIG_ENDIAN) - u16 reserved2; + u16 reserved3; u16 crc_t10; #elif defined(__LITTLE_ENDIAN) u16 crc_t10; - u16 reserved2; + u16 reserved3; #endif #if defined(__BIG_ENDIAN) u16 xsum8; @@ -1654,96 +1719,20 @@ struct double_regpair { /* - * The eth storm context of Ustorm (configuration part) + * SDM operation gen command (generate aggregative interrupt) */ -struct ustorm_eth_st_context_config { -#if defined(__BIG_ENDIAN) - u8 flags; -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3 -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4) -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4 - u8 status_block_id; - u8 clientId; - u8 sb_index_numbers; -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4) -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4 -#elif defined(__LITTLE_ENDIAN) - u8 sb_index_numbers; -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4) -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4 - u8 clientId; - u8 status_block_id; - u8 flags; -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3 -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4) -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4 -#endif -#if defined(__BIG_ENDIAN) - u16 bd_buff_size; - u8 statistics_counter_id; - u8 mc_alignment_log_size; -#elif defined(__LITTLE_ENDIAN) - u8 mc_alignment_log_size; - u8 statistics_counter_id; - u16 bd_buff_size; -#endif -#if defined(__BIG_ENDIAN) - u8 __local_sge_prod; - u8 __local_bd_prod; - u16 sge_buff_size; -#elif defined(__LITTLE_ENDIAN) - u16 sge_buff_size; - u8 __local_bd_prod; - u8 __local_sge_prod; -#endif -#if defined(__BIG_ENDIAN) - u16 __sdm_bd_expected_counter; - u8 cstorm_agg_int; - u8 __expected_bds_on_ram; -#elif defined(__LITTLE_ENDIAN) - u8 __expected_bds_on_ram; - u8 cstorm_agg_int; - u16 __sdm_bd_expected_counter; -#endif -#if defined(__BIG_ENDIAN) - u16 __ring_data_ram_addr; - u16 __hc_cstorm_ram_addr; -#elif defined(__LITTLE_ENDIAN) - u16 __hc_cstorm_ram_addr; - u16 __ring_data_ram_addr; -#endif -#if defined(__BIG_ENDIAN) - u8 reserved1; - u8 max_sges_for_packet; - u16 __bd_ring_ram_addr; -#elif defined(__LITTLE_ENDIAN) - u16 __bd_ring_ram_addr; - u8 max_sges_for_packet; - u8 reserved1; -#endif - u32 bd_page_base_lo; - u32 bd_page_base_hi; - u32 sge_page_base_lo; - u32 sge_page_base_hi; - struct regpair reserved2; +struct sdm_op_gen { + __le32 command; +#define SDM_OP_GEN_COMP_PARAM (0x1F<<0) +#define SDM_OP_GEN_COMP_PARAM_SHIFT 0 +#define SDM_OP_GEN_COMP_TYPE (0x7<<5) +#define SDM_OP_GEN_COMP_TYPE_SHIFT 5 +#define SDM_OP_GEN_AGG_VECT_IDX (0xFF<<8) +#define SDM_OP_GEN_AGG_VECT_IDX_SHIFT 8 +#define SDM_OP_GEN_AGG_VECT_IDX_VALID (0x1<<16) +#define SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT 16 +#define SDM_OP_GEN_RESERVED (0x7FFF<<17) +#define SDM_OP_GEN_RESERVED_SHIFT 17 }; /* @@ -1762,20 +1751,13 @@ struct eth_rx_sge { __le32 addr_hi; }; -/* - * Local BDs and SGEs rings (in ETH) - */ -struct eth_local_rx_rings { - struct eth_rx_bd __local_bd_ring[8]; - struct eth_rx_sge __local_sge_ring[10]; -}; + /* * The eth storm context of Ustorm */ struct ustorm_eth_st_context { - struct ustorm_eth_st_context_config common; - struct eth_local_rx_rings __rings; + u32 reserved0[48]; }; /* @@ -1785,338 +1767,54 @@ struct tstorm_eth_st_context { u32 __reserved0[28]; }; -/* - * The eth aggregative context section of Xstorm - */ -struct xstorm_eth_extra_ag_context_section { -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars1; - u8 __reserved50; - u16 __mss; -#elif defined(__LITTLE_ENDIAN) - u16 __mss; - u8 __reserved50; - u8 __tcp_agg_vars1; -#endif - u32 __snd_nxt; - u32 __tx_wnd; - u32 __snd_una; - u32 __reserved53; -#if defined(__BIG_ENDIAN) - u8 __agg_val8_th; - u8 __agg_val8; - u16 __tcp_agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __tcp_agg_vars2; - u8 __agg_val8; - u8 __agg_val8_th; -#endif - u32 __reserved58; - u32 __reserved59; - u32 __reserved60; - u32 __reserved61; -#if defined(__BIG_ENDIAN) - u16 __agg_val7_th; - u16 __agg_val7; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val7; - u16 __agg_val7_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars5; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars3; - u8 __reserved62; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved62; - u8 __tcp_agg_vars3; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars5; -#endif - u32 __tcp_agg_vars6; -#if defined(__BIG_ENDIAN) - u16 __agg_misc6; - u16 __tcp_agg_vars7; -#elif defined(__LITTLE_ENDIAN) - u16 __tcp_agg_vars7; - u16 __agg_misc6; -#endif - u32 __agg_val10; - u32 __agg_val10_th; -#if defined(__BIG_ENDIAN) - u16 __reserved3; - u8 __reserved2; - u8 __da_only_cnt; -#elif defined(__LITTLE_ENDIAN) - u8 __da_only_cnt; - u8 __reserved2; - u16 __reserved3; -#endif -}; - /* * The eth aggregative context of Xstorm */ struct xstorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u16 agg_val1; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u16 agg_val1; -#endif + u32 reserved0; #if defined(__BIG_ENDIAN) u8 cdu_reserved; - u8 __agg_vars4; - u8 __agg_vars3; - u8 __agg_vars2; + u8 reserved2; + u16 reserved1; #elif defined(__LITTLE_ENDIAN) - u8 __agg_vars2; - u8 __agg_vars3; - u8 __agg_vars4; + u16 reserved1; + u8 reserved2; u8 cdu_reserved; #endif - u32 __bd_prod; -#if defined(__BIG_ENDIAN) - u16 __agg_vars5; - u16 __agg_val4_th; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val4_th; - u16 __agg_vars5; -#endif - struct xstorm_eth_extra_ag_context_section __extra_section; -#if defined(__BIG_ENDIAN) - u16 __agg_vars7; - u8 __agg_val3_th; - u8 __agg_vars6; -#elif defined(__LITTLE_ENDIAN) - u8 __agg_vars6; - u8 __agg_val3_th; - u16 __agg_vars7; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val11_th; - u16 __agg_val11; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val11; - u16 __agg_val11_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved1; - u8 __agg_val6_th; - u16 __agg_val9; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val9; - u8 __agg_val6_th; - u8 __reserved1; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val2_th; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u16 __agg_val2_th; -#endif - u32 __agg_vars8; -#if defined(__BIG_ENDIAN) - u16 __agg_misc0; - u16 __agg_val4; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val4; - u16 __agg_misc0; -#endif -#if defined(__BIG_ENDIAN) - u8 __agg_val3; - u8 __agg_val6; - u8 __agg_val5_th; - u8 __agg_val5; -#elif defined(__LITTLE_ENDIAN) - u8 __agg_val5; - u8 __agg_val5_th; - u8 __agg_val6; - u8 __agg_val3; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_misc1; - u16 __bd_ind_max_val; -#elif defined(__LITTLE_ENDIAN) - u16 __bd_ind_max_val; - u16 __agg_misc1; -#endif - u32 __reserved57; - u32 __agg_misc4; - u32 __agg_misc5; -}; - -/* - * The eth extra aggregative context section of Tstorm - */ -struct tstorm_eth_extra_ag_context_section { - u32 __agg_val1; -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars2; - u8 __agg_val3; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u8 __agg_val3; - u8 __tcp_agg_vars2; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val5; - u8 __agg_val6; - u8 __tcp_agg_vars3; -#elif defined(__LITTLE_ENDIAN) - u8 __tcp_agg_vars3; - u8 __agg_val6; - u16 __agg_val5; -#endif - u32 __reserved63; - u32 __reserved64; - u32 __reserved65; - u32 __reserved66; - u32 __reserved67; - u32 __tcp_agg_vars1; - u32 __reserved61; - u32 __reserved62; - u32 __reserved2; + u32 reserved3[30]; }; /* * The eth aggregative context of Tstorm */ struct tstorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u16 __reserved54; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u16 __reserved54; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val4; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u16 __agg_val4; -#endif - struct tstorm_eth_extra_ag_context_section __extra_section; + u32 __reserved0[14]; }; + /* * The eth aggregative context of Cstorm */ struct cstorm_eth_ag_context { - u32 __agg_vars1; -#if defined(__BIG_ENDIAN) - u8 __aux1_th; - u8 __aux1_val; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u8 __aux1_val; - u8 __aux1_th; -#endif - u32 __num_of_treated_packet; - u32 __last_packet_treated; -#if defined(__BIG_ENDIAN) - u16 __reserved58; - u16 __reserved57; -#elif defined(__LITTLE_ENDIAN) - u16 __reserved57; - u16 __reserved58; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved62; - u8 __reserved61; - u8 __reserved60; - u8 __reserved59; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved59; - u8 __reserved60; - u8 __reserved61; - u8 __reserved62; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved64; - u16 __reserved63; -#elif defined(__LITTLE_ENDIAN) - u16 __reserved63; - u16 __reserved64; -#endif - u32 __reserved65; -#if defined(__BIG_ENDIAN) - u16 __agg_vars3; - u16 __rq_inv_cnt; -#elif defined(__LITTLE_ENDIAN) - u16 __rq_inv_cnt; - u16 __agg_vars3; -#endif -#if defined(__BIG_ENDIAN) - u16 __packet_index_th; - u16 __packet_index; -#elif defined(__LITTLE_ENDIAN) - u16 __packet_index; - u16 __packet_index_th; -#endif + u32 __reserved0[10]; }; + /* * The eth aggregative context of Ustorm */ struct ustorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u8 __aux_counter_flags; - u8 __agg_vars2; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u8 __agg_vars2; - u8 __aux_counter_flags; -#endif + u32 __reserved0; #if defined(__BIG_ENDIAN) u8 cdu_usage; - u8 __agg_misc2; - u16 __agg_misc1; + u8 __reserved2; + u16 __reserved1; #elif defined(__LITTLE_ENDIAN) - u16 __agg_misc1; - u8 __agg_misc2; + u16 __reserved1; + u8 __reserved2; u8 cdu_usage; #endif - u32 __agg_misc4; -#if defined(__BIG_ENDIAN) - u8 __agg_val3_th; - u8 __agg_val3; - u16 __agg_misc3; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_misc3; - u8 __agg_val3; - u8 __agg_val3_th; -#endif - u32 __agg_val1; - u32 __agg_misc4_th; -#if defined(__BIG_ENDIAN) - u16 __agg_val2_th; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u16 __agg_val2_th; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved2; - u8 __decision_rules; - u8 __decision_rule_enable_bits; -#elif defined(__LITTLE_ENDIAN) - u8 __decision_rule_enable_bits; - u8 __decision_rules; - u16 __reserved2; -#endif + u32 __reserved3[6]; }; /* @@ -2140,18 +1838,16 @@ struct timers_block_context { */ struct eth_tx_bd_flags { u8 as_bitfield; -#define ETH_TX_BD_FLAGS_VLAN_TAG (0x1<<0) -#define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT 0 -#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<1) -#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 1 -#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<2) -#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 2 -#define ETH_TX_BD_FLAGS_END_BD (0x1<<3) -#define ETH_TX_BD_FLAGS_END_BD_SHIFT 3 +#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<0) +#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 0 +#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<1) +#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 1 +#define ETH_TX_BD_FLAGS_VLAN_MODE (0x3<<2) +#define ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT 2 #define ETH_TX_BD_FLAGS_START_BD (0x1<<4) #define ETH_TX_BD_FLAGS_START_BD_SHIFT 4 -#define ETH_TX_BD_FLAGS_HDR_POOL (0x1<<5) -#define ETH_TX_BD_FLAGS_HDR_POOL_SHIFT 5 +#define ETH_TX_BD_FLAGS_IS_UDP (0x1<<5) +#define ETH_TX_BD_FLAGS_IS_UDP_SHIFT 5 #define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6) #define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6 #define ETH_TX_BD_FLAGS_IPV6 (0x1<<7) @@ -2166,7 +1862,7 @@ struct eth_tx_start_bd { __le32 addr_hi; __le16 nbd; __le16 nbytes; - __le16 vlan; + __le16 vlan_or_ethertype; struct eth_tx_bd_flags bd_flags; u8 general_data; #define ETH_TX_START_BD_HDR_NBDS (0x3F<<0) @@ -2179,48 +1875,48 @@ struct eth_tx_start_bd { * Tx regular BD structure */ struct eth_tx_bd { - u32 addr_lo; - u32 addr_hi; - u16 total_pkt_bytes; - u16 nbytes; + __le32 addr_lo; + __le32 addr_hi; + __le16 total_pkt_bytes; + __le16 nbytes; u8 reserved[4]; }; /* - * Tx parsing BD structure for ETH,Relevant in START + * Tx parsing BD structure for ETH E1/E1h */ -struct eth_tx_parse_bd { +struct eth_tx_parse_bd_e1x { u8 global_data; -#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET (0xF<<0) -#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET_SHIFT 0 -#define ETH_TX_PARSE_BD_UDP_CS_FLG (0x1<<4) -#define ETH_TX_PARSE_BD_UDP_CS_FLG_SHIFT 4 -#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN (0x1<<5) -#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 -#define ETH_TX_PARSE_BD_LLC_SNAP_EN (0x1<<6) -#define ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT 6 -#define ETH_TX_PARSE_BD_NS_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_NS_FLG_SHIFT 7 +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W (0xF<<0) +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 7 u8 tcp_flags; -#define ETH_TX_PARSE_BD_FIN_FLG (0x1<<0) -#define ETH_TX_PARSE_BD_FIN_FLG_SHIFT 0 -#define ETH_TX_PARSE_BD_SYN_FLG (0x1<<1) -#define ETH_TX_PARSE_BD_SYN_FLG_SHIFT 1 -#define ETH_TX_PARSE_BD_RST_FLG (0x1<<2) -#define ETH_TX_PARSE_BD_RST_FLG_SHIFT 2 -#define ETH_TX_PARSE_BD_PSH_FLG (0x1<<3) -#define ETH_TX_PARSE_BD_PSH_FLG_SHIFT 3 -#define ETH_TX_PARSE_BD_ACK_FLG (0x1<<4) -#define ETH_TX_PARSE_BD_ACK_FLG_SHIFT 4 -#define ETH_TX_PARSE_BD_URG_FLG (0x1<<5) -#define ETH_TX_PARSE_BD_URG_FLG_SHIFT 5 -#define ETH_TX_PARSE_BD_ECE_FLG (0x1<<6) -#define ETH_TX_PARSE_BD_ECE_FLG_SHIFT 6 -#define ETH_TX_PARSE_BD_CWR_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7 - u8 ip_hlen; +#define ETH_TX_PARSE_BD_E1X_FIN_FLG (0x1<<0) +#define ETH_TX_PARSE_BD_E1X_FIN_FLG_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_SYN_FLG (0x1<<1) +#define ETH_TX_PARSE_BD_E1X_SYN_FLG_SHIFT 1 +#define ETH_TX_PARSE_BD_E1X_RST_FLG (0x1<<2) +#define ETH_TX_PARSE_BD_E1X_RST_FLG_SHIFT 2 +#define ETH_TX_PARSE_BD_E1X_PSH_FLG (0x1<<3) +#define ETH_TX_PARSE_BD_E1X_PSH_FLG_SHIFT 3 +#define ETH_TX_PARSE_BD_E1X_ACK_FLG (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_ACK_FLG_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_URG_FLG (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_URG_FLG_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_ECE_FLG (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_ECE_FLG_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_CWR_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_CWR_FLG_SHIFT 7 + u8 ip_hlen_w; s8 reserved; - __le16 total_hlen; + __le16 total_hlen_w; __le16 tcp_pseudo_csum; __le16 lso_mss; __le16 ip_id; @@ -2242,79 +1938,23 @@ struct eth_tx_next_bd { union eth_tx_bd_types { struct eth_tx_start_bd start_bd; struct eth_tx_bd reg_bd; - struct eth_tx_parse_bd parse_bd; + struct eth_tx_parse_bd_e1x parse_bd_e1x; struct eth_tx_next_bd next_bd; }; + /* * The eth storm context of Xstorm */ struct xstorm_eth_st_context { - u32 tx_bd_page_base_lo; - u32 tx_bd_page_base_hi; -#if defined(__BIG_ENDIAN) - u16 tx_bd_cons; - u8 statistics_data; -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0 -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7 - u8 __local_tx_bd_prod; -#elif defined(__LITTLE_ENDIAN) - u8 __local_tx_bd_prod; - u8 statistics_data; -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0 -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7 - u16 tx_bd_cons; -#endif - u32 __reserved1; - u32 __reserved2; -#if defined(__BIG_ENDIAN) - u8 __ram_cache_index; - u8 __double_buffer_client; - u16 __pkt_cons; -#elif defined(__LITTLE_ENDIAN) - u16 __pkt_cons; - u8 __double_buffer_client; - u8 __ram_cache_index; -#endif -#if defined(__BIG_ENDIAN) - u16 __statistics_address; - u16 __gso_next; -#elif defined(__LITTLE_ENDIAN) - u16 __gso_next; - u16 __statistics_address; -#endif -#if defined(__BIG_ENDIAN) - u8 __local_tx_bd_cons; - u8 safc_group_num; - u8 safc_group_en; - u8 __is_eth_conn; -#elif defined(__LITTLE_ENDIAN) - u8 __is_eth_conn; - u8 safc_group_en; - u8 safc_group_num; - u8 __local_tx_bd_cons; -#endif - union eth_tx_bd_types __bds[13]; + u32 reserved0[60]; }; /* * The eth storm context of Cstorm */ struct cstorm_eth_st_context { -#if defined(__BIG_ENDIAN) - u16 __reserved0; - u8 sb_index_number; - u8 status_block_id; -#elif defined(__LITTLE_ENDIAN) - u8 status_block_id; - u8 sb_index_number; - u16 __reserved0; -#endif - u32 __reserved1[3]; + u32 __reserved0[4]; }; /* @@ -2362,103 +2002,114 @@ struct eth_tx_doorbell { /* - * cstorm default status block, generated by ustorm - */ -struct cstorm_def_status_block_u { - __le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; - -/* - * cstorm default status block, generated by cstorm - */ -struct cstorm_def_status_block_c { - __le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; - -/* - * xstorm status block + * client init fc data */ -struct xstorm_def_status_block { - __le16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; +struct client_init_fc_data { + __le16 cqe_pause_thr_low; + __le16 cqe_pause_thr_high; + __le16 bd_pause_thr_low; + __le16 bd_pause_thr_high; + __le16 sge_pause_thr_low; + __le16 sge_pause_thr_high; + __le16 rx_cos_mask; + u8 safc_group_num; + u8 safc_group_en_flg; + u8 traffic_type; + u8 reserved0; + __le16 reserved1; + __le32 reserved2; }; -/* - * tstorm status block - */ -struct tstorm_def_status_block { - __le16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; /* - * host status block + * client init ramrod data */ -struct host_def_status_block { - struct atten_def_status_block atten_status_block; - struct cstorm_def_status_block_u u_def_status_block; - struct cstorm_def_status_block_c c_def_status_block; - struct xstorm_def_status_block x_def_status_block; - struct tstorm_def_status_block t_def_status_block; +struct client_init_general_data { + u8 client_id; + u8 statistics_counter_id; + u8 statistics_en_flg; + u8 is_fcoe_flg; + u8 activate_flg; + u8 sp_client_id; + __le16 reserved0; + __le32 reserved1[2]; }; /* - * cstorm status block, generated by ustorm + * client init rx data */ -struct cstorm_status_block_u { - __le16 index_values[HC_USTORM_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; +struct client_init_rx_data { + u8 tpa_en_flg; + u8 vmqueue_mode_en_flg; + u8 extra_data_over_sgl_en_flg; + u8 cache_line_alignment_log_size; + u8 enable_dynamic_hc; + u8 max_sges_for_packet; + u8 client_qzone_id; + u8 drop_ip_cs_err_flg; + u8 drop_tcp_cs_err_flg; + u8 drop_ttl0_flg; + u8 drop_udp_cs_err_flg; + u8 inner_vlan_removal_enable_flg; + u8 outer_vlan_removal_enable_flg; u8 status_block_id; - __le32 __flags; + u8 rx_sb_index_number; + u8 reserved0[3]; + __le16 bd_buff_size; + __le16 sge_buff_size; + __le16 mtu; + struct regpair bd_page_base; + struct regpair sge_page_base; + struct regpair cqe_page_base; + u8 is_leading_rss; + u8 is_approx_mcast; + __le16 max_agg_size; + __le32 reserved2[3]; +}; + +/* + * client init tx data + */ +struct client_init_tx_data { + u8 enforce_security_flg; + u8 tx_status_block_id; + u8 tx_sb_index_number; + u8 reserved0; + __le16 mtu; + __le16 reserved1; + struct regpair tx_bd_page_base; + __le32 reserved2[2]; }; /* - * cstorm status block, generated by cstorm + * client init ramrod data */ -struct cstorm_status_block_c { - __le16 index_values[HC_CSTORM_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; +struct client_init_ramrod_data { + struct client_init_general_data general; + struct client_init_rx_data rx; + struct client_init_tx_data tx; + struct client_init_fc_data fc; }; + /* - * host status block + * The data contain client ID need to the ramrod */ -struct host_status_block { - struct cstorm_status_block_u u_status_block; - struct cstorm_status_block_c c_status_block; +struct eth_common_ramrod_data { + u32 client_id; + u32 reserved1; }; /* - * The data for RSS setup ramrod + * union for sgl and raw data. */ -struct eth_client_setup_ramrod_data { - u32 client_id; - u8 is_rdma; - u8 is_fcoe; - u16 reserved1; +union eth_sgl_or_raw_data { + __le16 sgl[8]; + u32 raw_data[4]; }; - /* * regular eth FP CQE parameters struct */ @@ -2476,8 +2127,8 @@ struct eth_fast_path_rx_cqe { #define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4 #define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5) #define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5 -#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6) -#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6 +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL (0x3<<6) +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL_SHIFT 6 u8 status_flags; #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 @@ -2498,7 +2149,7 @@ struct eth_fast_path_rx_cqe { __le16 pkt_len; __le16 len_on_bd; struct parsing_flags pars_flags; - __le16 sgl[8]; + union eth_sgl_or_raw_data sgl_or_raw_data; }; @@ -2510,11 +2161,10 @@ struct eth_halt_ramrod_data { u32 reserved0; }; - /* * The data for statistics query ramrod */ -struct eth_query_ramrod_data { +struct common_query_ramrod_data { #if defined(__BIG_ENDIAN) u8 reserved0; u8 collect_port; @@ -2597,9 +2247,9 @@ struct spe_hdr { __le16 type; #define SPE_HDR_CONN_TYPE (0xFF<<0) #define SPE_HDR_CONN_TYPE_SHIFT 0 -#define SPE_HDR_COMMON_RAMROD (0xFF<<8) -#define SPE_HDR_COMMON_RAMROD_SHIFT 8 - __le16 reserved; +#define SPE_HDR_FUNCTION_ID (0xFF<<8) +#define SPE_HDR_FUNCTION_ID_SHIFT 8 + __le16 reserved1; }; /* @@ -2607,12 +2257,10 @@ struct spe_hdr { */ union eth_specific_data { u8 protocol_data[8]; - struct regpair mac_config_addr; - struct eth_client_setup_ramrod_data client_setup_ramrod_data; + struct regpair client_init_ramrod_init_data; struct eth_halt_ramrod_data halt_ramrod_data; - struct regpair leading_cqe_addr; struct regpair update_data_addr; - struct eth_query_ramrod_data query_ramrod_data; + struct eth_common_ramrod_data common_ramrod_data; }; /* @@ -2637,7 +2285,7 @@ struct eth_tx_bds_array { */ struct tstorm_eth_function_common_config { #if defined(__BIG_ENDIAN) - u8 leading_client_id; + u8 reserved1; u8 rss_result_mask; u16 config_flags; #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) @@ -2650,16 +2298,12 @@ struct tstorm_eth_function_common_config { #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 #elif defined(__LITTLE_ENDIAN) u16 config_flags; #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) @@ -2672,18 +2316,14 @@ struct tstorm_eth_function_common_config { #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 u8 rss_result_mask; - u8 leading_client_id; + u8 reserved1; #endif u16 vlan_id[2]; }; @@ -2731,55 +2371,38 @@ struct mac_configuration_hdr { u8 length; u8 offset; u16 client_id; - u32 reserved1; + u16 echo; + u16 reserved1; }; /* * MAC address in list for ramrod */ -struct tstorm_cam_entry { +struct mac_configuration_entry { __le16 lsb_mac_addr; __le16 middle_mac_addr; __le16 msb_mac_addr; - __le16 flags; -#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0) -#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0 -#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1) -#define TSTORM_CAM_ENTRY_RSRVVAL0_SHIFT 1 -#define TSTORM_CAM_ENTRY_RESERVED0 (0xFFF<<4) -#define TSTORM_CAM_ENTRY_RESERVED0_SHIFT 4 -}; - -/* - * MAC filtering: CAM target table entry - */ -struct tstorm_cam_target_table_entry { + __le16 vlan_id; + u8 pf_id; u8 flags; -#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST (0x1<<0) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST_SHIFT 0 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<1) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 1 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE (0x1<<2) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE_SHIFT 2 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC (0x1<<3) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC_SHIFT 3 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0 (0xF<<4) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0_SHIFT 4 - u8 reserved1; - u16 vlan_id; +#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE (0x1<<0) +#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE_SHIFT 0 +#define MAC_CONFIGURATION_ENTRY_RDMA_MAC (0x1<<1) +#define MAC_CONFIGURATION_ENTRY_RDMA_MAC_SHIFT 1 +#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE (0x3<<2) +#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE_SHIFT 2 +#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<4) +#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 4 +#define MAC_CONFIGURATION_ENTRY_BROADCAST (0x1<<5) +#define MAC_CONFIGURATION_ENTRY_BROADCAST_SHIFT 5 +#define MAC_CONFIGURATION_ENTRY_RESERVED1 (0x3<<6) +#define MAC_CONFIGURATION_ENTRY_RESERVED1_SHIFT 6 + u16 reserved0; u32 clients_bit_vector; }; /* - * MAC address in list for ramrod - */ -struct mac_configuration_entry { - struct tstorm_cam_entry cam_entry; - struct tstorm_cam_target_table_entry target_table_entry; -}; - -/* - * MAC filtering configuration command + * MAC filtering configuration command */ struct mac_configuration_cmd { struct mac_configuration_hdr hdr; @@ -2787,37 +2410,6 @@ struct mac_configuration_cmd { }; -/* - * MAC address in list for ramrod - */ -struct mac_configuration_entry_e1h { - __le16 lsb_mac_addr; - __le16 middle_mac_addr; - __le16 msb_mac_addr; - __le16 vlan_id; - __le16 e1hov_id; - u8 reserved0; - u8 flags; -#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0) -#define MAC_CONFIGURATION_ENTRY_E1H_PORT_SHIFT 0 -#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE (0x1<<1) -#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE_SHIFT 1 -#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC (0x1<<2) -#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC_SHIFT 2 -#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1 (0x1F<<3) -#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1_SHIFT 3 - u32 clients_bit_vector; -}; - -/* - * MAC filtering configuration command - */ -struct mac_configuration_cmd_e1h { - struct mac_configuration_hdr hdr; - struct mac_configuration_entry_e1h config_table[32]; -}; - - /* * approximate-match multicast filtering for E1H per function in Tstorm */ @@ -2826,65 +2418,6 @@ struct tstorm_eth_approximate_match_multicast_filtering { }; -/* - * Configuration parameters per client in Tstorm - */ -struct tstorm_eth_client_config { -#if defined(__BIG_ENDIAN) - u8 reserved0; - u8 statistics_counter_id; - u16 mtu; -#elif defined(__LITTLE_ENDIAN) - u16 mtu; - u8 statistics_counter_id; - u8 reserved0; -#endif -#if defined(__BIG_ENDIAN) - u16 drop_flags; -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4 - u16 config_flags; -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3 -#elif defined(__LITTLE_ENDIAN) - u16 config_flags; -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3 - u16 drop_flags; -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4 -#endif -}; - - /* * MAC filtering configuration parameters per port in Tstorm */ @@ -2895,8 +2428,8 @@ struct tstorm_eth_mac_filter_config { u32 mcast_accept_all; u32 bcast_drop_all; u32 bcast_accept_all; - u32 strict_vlan; u32 vlan_filter[2]; + u32 unmatched_unicast; u32 reserved; }; @@ -2918,41 +2451,6 @@ struct tstorm_eth_tpa_exist { }; -/* - * rx rings pause data for E1h only - */ -struct ustorm_eth_rx_pause_data_e1h { -#if defined(__BIG_ENDIAN) - u16 bd_thr_low; - u16 cqe_thr_low; -#elif defined(__LITTLE_ENDIAN) - u16 cqe_thr_low; - u16 bd_thr_low; -#endif -#if defined(__BIG_ENDIAN) - u16 cos; - u16 sge_thr_low; -#elif defined(__LITTLE_ENDIAN) - u16 sge_thr_low; - u16 cos; -#endif -#if defined(__BIG_ENDIAN) - u16 bd_thr_high; - u16 cqe_thr_high; -#elif defined(__LITTLE_ENDIAN) - u16 cqe_thr_high; - u16 bd_thr_high; -#endif -#if defined(__BIG_ENDIAN) - u16 reserved0; - u16 sge_thr_high; -#elif defined(__LITTLE_ENDIAN) - u16 sge_thr_high; - u16 reserved0; -#endif -}; - - /* * Three RX producers for ETH */ @@ -2974,6 +2472,18 @@ struct ustorm_eth_rx_producers { }; +/* + * cfc delete event data + */ +struct cfc_del_event_data { + u32 cid; + u8 error; + u8 reserved0; + u16 reserved1; + u32 reserved2; +}; + + /* * per-port SAFC demo variables */ @@ -2990,8 +2500,10 @@ struct cmng_flags_per_port { #define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3 #define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4) #define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4 -#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5) -#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5 +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE (0x1<<5) +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE_SHIFT 5 +#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x3FFFFFF<<6) +#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 6 }; @@ -3025,9 +2537,43 @@ struct safc_struct_per_port { u8 __reserved0; u16 __reserved1; #endif + u8 cos_to_traffic_types[MAX_COS_NUMBER]; + u32 __reserved2; u16 cos_to_pause_mask[NUM_OF_SAFC_BITS]; }; +/* + * per-port PFC variables + */ +struct pfc_struct_per_port { + u8 priority_to_traffic_types[MAX_PFC_PRIORITIES]; +#if defined(__BIG_ENDIAN) + u16 pfc_pause_quanta_in_nanosec; + u8 __reserved0; + u8 priority_non_pausable_mask; +#elif defined(__LITTLE_ENDIAN) + u8 priority_non_pausable_mask; + u8 __reserved0; + u16 pfc_pause_quanta_in_nanosec; +#endif +}; + +/* + * Priority and cos + */ +struct priority_cos { +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 cos; + u8 priority; +#elif defined(__LITTLE_ENDIAN) + u8 priority; + u8 cos; + u16 reserved1; +#endif + u32 reserved2; +}; + /* * Per-port congestion management variables */ @@ -3035,20 +2581,48 @@ struct cmng_struct_per_port { struct rate_shaping_vars_per_port rs_vars; struct fairness_vars_per_port fair_vars; struct safc_struct_per_port safc_vars; + struct pfc_struct_per_port pfc_vars; +#if defined(__BIG_ENDIAN) + u16 __reserved1; + u8 dcb_enabled; + u8 llfc_mode; +#elif defined(__LITTLE_ENDIAN) + u8 llfc_mode; + u8 dcb_enabled; + u16 __reserved1; +#endif + struct priority_cos + traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES]; struct cmng_flags_per_port flags; }; + +/* + * Dynamic HC counters set by the driver + */ +struct hc_dynamic_drv_counter { + u32 val[HC_SB_MAX_DYNAMIC_INDICES]; +}; + +/* + * zone A per-queue data + */ +struct cstorm_queue_zone_data { + struct hc_dynamic_drv_counter hc_dyn_drv_cnt; + struct regpair reserved[2]; +}; + /* * Dynamic host coalescing init parameters */ struct dynamic_hc_config { u32 threshold[3]; - u8 shift_per_protocol[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout0[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout1[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout2[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout3[HC_USTORM_SB_NUM_INDICES]; + u8 shift_per_protocol[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout0[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout1[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout2[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout3[HC_SB_MAX_DYNAMIC_INDICES]; }; @@ -3072,7 +2646,7 @@ struct xstorm_per_client_stats { * Common statistics collected by the Xstorm (per port) */ struct xstorm_common_stats { - struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID]; + struct xstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3109,7 +2683,7 @@ struct tstorm_per_client_stats { */ struct tstorm_common_stats { struct tstorm_per_port_stats port_statistics; - struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID]; + struct tstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3130,7 +2704,7 @@ struct ustorm_per_client_stats { * Protocol-common statistics collected by the Ustorm */ struct ustorm_common_stats { - struct ustorm_per_client_stats client_statistics[MAX_U_STAT_COUNTER_ID]; + struct ustorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3143,6 +2717,70 @@ struct eth_stats_query { }; +/* + * set mac event data + */ +struct set_mac_event_data { + u16 echo; + u16 reserved0; + u32 reserved1; + u32 reserved2; +}; + +/* + * union for all event ring message types + */ +union event_data { + struct set_mac_event_data set_mac_event; + struct cfc_del_event_data cfc_del_event; +}; + + +/* + * per PF event ring data + */ +struct event_ring_data { + struct regpair base_addr; +#if defined(__BIG_ENDIAN) + u8 index_id; + u8 sb_id; + u16 producer; +#elif defined(__LITTLE_ENDIAN) + u16 producer; + u8 sb_id; + u8 index_id; +#endif + u32 reserved0; +}; + + +/* + * event ring message element (each element is 128 bits) + */ +struct event_ring_msg { + u8 opcode; + u8 reserved0; + u16 reserved1; + union event_data data; +}; + +/* + * event ring next page element (128 bits) + */ +struct event_ring_next { + struct regpair addr; + u32 reserved[2]; +}; + +/* + * union for event ring element types (each element is 128 bits) + */ +union event_ring_elem { + struct event_ring_msg message; + struct event_ring_next next_page; +}; + + /* * per-vnic fairness variables */ @@ -3181,6 +2819,137 @@ struct fw_version { }; +/* + * Dynamic Host-Coalescing - Driver(host) counters + */ +struct hc_dynamic_sb_drv_counters { + u32 dynamic_hc_drv_counter[HC_SB_MAX_DYNAMIC_INDICES]; +}; + + +/* + * 2 bytes. configuration/state parameters for a single protocol index + */ +struct hc_index_data { +#if defined(__BIG_ENDIAN) + u8 flags; +#define HC_INDEX_DATA_SM_ID (0x1<<0) +#define HC_INDEX_DATA_SM_ID_SHIFT 0 +#define HC_INDEX_DATA_HC_ENABLED (0x1<<1) +#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1 +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2) +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2 +#define HC_INDEX_DATA_RESERVE (0x1F<<3) +#define HC_INDEX_DATA_RESERVE_SHIFT 3 + u8 timeout; +#elif defined(__LITTLE_ENDIAN) + u8 timeout; + u8 flags; +#define HC_INDEX_DATA_SM_ID (0x1<<0) +#define HC_INDEX_DATA_SM_ID_SHIFT 0 +#define HC_INDEX_DATA_HC_ENABLED (0x1<<1) +#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1 +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2) +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2 +#define HC_INDEX_DATA_RESERVE (0x1F<<3) +#define HC_INDEX_DATA_RESERVE_SHIFT 3 +#endif +}; + + +/* + * HC state-machine + */ +struct hc_status_block_sm { +#if defined(__BIG_ENDIAN) + u8 igu_seg_id; + u8 igu_sb_id; + u8 timer_value; + u8 __flags; +#elif defined(__LITTLE_ENDIAN) + u8 __flags; + u8 timer_value; + u8 igu_sb_id; + u8 igu_seg_id; +#endif + u32 time_to_expire; +}; + +/* + * hold PCI identification variables- used in various places in firmware + */ +struct pci_entity { +#if defined(__BIG_ENDIAN) + u8 vf_valid; + u8 vf_id; + u8 vnic_id; + u8 pf_id; +#elif defined(__LITTLE_ENDIAN) + u8 pf_id; + u8 vnic_id; + u8 vf_id; + u8 vf_valid; +#endif +}; + +/* + * The fast-path status block meta-data, common to all chips + */ +struct hc_sb_data { + struct regpair host_sb_addr; + struct hc_status_block_sm state_machine[HC_SB_MAX_SM]; + struct pci_entity p_func; +#if defined(__BIG_ENDIAN) + u8 rsrv0; + u8 dhc_qzone_id; + u8 __dynamic_hc_level; + u8 same_igu_sb_1b; +#elif defined(__LITTLE_ENDIAN) + u8 same_igu_sb_1b; + u8 __dynamic_hc_level; + u8 dhc_qzone_id; + u8 rsrv0; +#endif + struct regpair rsrv1[2]; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_sp_status_block_data { + struct regpair host_sb_addr; +#if defined(__BIG_ENDIAN) + u16 rsrv; + u8 igu_seg_id; + u8 igu_sb_id; +#elif defined(__LITTLE_ENDIAN) + u8 igu_sb_id; + u8 igu_seg_id; + u16 rsrv; +#endif + struct pci_entity p_func; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_status_block_data_e1x { + struct hc_index_data index_data[HC_SB_MAX_INDICES_E1X]; + struct hc_sb_data common; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_status_block_data_e2 { + struct hc_index_data index_data[HC_SB_MAX_INDICES_E2]; + struct hc_sb_data common; +}; + + /* * FW version stored in first line of pram */ @@ -3203,12 +2972,22 @@ struct pram_fw_version { }; +/* + * Ethernet slow path element + */ +union protocol_common_specific_data { + u8 protocol_data[8]; + struct regpair phy_address; + struct regpair mac_config_addr; + struct common_query_ramrod_data query_ramrod_data; +}; + /* * The send queue element */ struct protocol_common_spe { struct spe_hdr hdr; - struct regpair phy_address; + union protocol_common_specific_data data; }; @@ -3241,7 +3020,7 @@ struct rate_shaping_vars_per_vn { */ struct slow_path_element { struct spe_hdr hdr; - u8 protocol_data[8]; + struct regpair protocol_data; }; @@ -3254,3 +3033,97 @@ struct stats_indication_flags { }; +/* + * per-port PFC variables + */ +struct storm_pfc_struct_per_port { +#if defined(__BIG_ENDIAN) + u16 mid_mac_addr; + u16 msb_mac_addr; +#elif defined(__LITTLE_ENDIAN) + u16 msb_mac_addr; + u16 mid_mac_addr; +#endif +#if defined(__BIG_ENDIAN) + u16 pfc_pause_quanta_in_nanosec; + u16 lsb_mac_addr; +#elif defined(__LITTLE_ENDIAN) + u16 lsb_mac_addr; + u16 pfc_pause_quanta_in_nanosec; +#endif +}; + +/* + * Per-port congestion management variables + */ +struct storm_cmng_struct_per_port { + struct storm_pfc_struct_per_port pfc_vars; +}; + + +/* + * zone A per-queue data + */ +struct tstorm_queue_zone_data { + struct regpair reserved[4]; +}; + + +/* + * zone B per-VF data + */ +struct tstorm_vf_zone_data { + struct regpair reserved; +}; + + +/* + * zone A per-queue data + */ +struct ustorm_queue_zone_data { + struct ustorm_eth_rx_producers eth_rx_producers; + struct regpair reserved[3]; +}; + + +/* + * zone B per-VF data + */ +struct ustorm_vf_zone_data { + struct regpair reserved; +}; + + +/* + * data per VF-PF channel + */ +struct vf_pf_channel_data { +#if defined(__BIG_ENDIAN) + u16 reserved0; + u8 valid; + u8 state; +#elif defined(__LITTLE_ENDIAN) + u8 state; + u8 valid; + u16 reserved0; +#endif + u32 reserved1; +}; + + +/* + * zone A per-queue data + */ +struct xstorm_queue_zone_data { + struct regpair reserved[4]; +}; + + +/* + * zone B per-VF data + */ +struct xstorm_vf_zone_data { + struct regpair reserved; +}; + +#endif /* BNX2X_HSI_H */ diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 65b26cbfe3e7..5ae22e085518 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -148,5 +148,46 @@ union init_op { struct raw_op raw; }; +#define INITOP_SET 0 /* set the HW directly */ +#define INITOP_CLEAR 1 /* clear the HW directly */ +#define INITOP_INIT 2 /* set the init-value array */ + +/**************************************************************************** +* ILT management +****************************************************************************/ +struct ilt_line { + dma_addr_t page_mapping; + void *page; + u32 size; +}; + +struct ilt_client_info { + u32 page_size; + u16 start; + u16 end; + u16 client_num; + u16 flags; +#define ILT_CLIENT_SKIP_INIT 0x1 +#define ILT_CLIENT_SKIP_MEM 0x2 +}; + +struct bnx2x_ilt { + u32 start_line; + struct ilt_line *lines; + struct ilt_client_info clients[4]; +#define ILT_CLIENT_CDU 0 +#define ILT_CLIENT_QM 1 +#define ILT_CLIENT_SRC 2 +#define ILT_CLIENT_TM 3 +}; + +/**************************************************************************** +* SRC configuration +****************************************************************************/ +struct src_ent { + u8 opaque[56]; + u64 next; +}; + #endif /* BNX2X_INIT_H */ diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index 2b1363a6fe78..aae7fea00622 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -151,6 +151,15 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, bnx2x_init_ind_wr(bp, addr, data, len); } +static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, u32 val_hi) +{ + u32 wb_write[2]; + + wb_write[0] = val_lo; + wb_write[1] = val_hi; + REG_WR_DMAE_LEN(bp, reg, wb_write, 2); +} + static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off) { const u8 *data = NULL; @@ -503,4 +512,333 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) } } +/**************************************************************************** +* ILT management +****************************************************************************/ +/* + * This codes hides the low level HW interaction for ILT management and + * configuration. The API consists of a shadow ILT table which is set by the + * driver and a set of routines to use it to configure the HW. + * + */ + +/* ILT HW init operations */ + +/* ILT memory management operations */ +#define ILT_MEMOP_ALLOC 0 +#define ILT_MEMOP_FREE 1 + +/* the phys address is shifted right 12 bits and has an added + * 1=valid bit added to the 53rd bit + * then since this is a wide register(TM) + * we split it into two 32 bit writes + */ +#define ILT_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ILT_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) +#define ILT_RANGE(f, l) (((l) << 10) | f) + +static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, struct ilt_line *line, + u32 size, u8 memop) +{ + if (memop == ILT_MEMOP_FREE) { + BNX2X_ILT_FREE(line->page, line->page_mapping, line->size); + return 0; + } + BNX2X_ILT_ZALLOC(line->page, &line->page_mapping, size); + if (!line->page) + return -1; + line->size = size; + return 0; +} + + +static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, u8 memop) +{ + int i, rc; + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + if (!ilt || !ilt->lines) + return -1; + + if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM)) + return 0; + + for (rc = 0, i = ilt_cli->start; i <= ilt_cli->end && !rc; i++) { + rc = bnx2x_ilt_line_mem_op(bp, &ilt->lines[i], + ilt_cli->page_size, memop); + } + return rc; +} + +int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop) +{ + int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop); + + return rc; +} + +static void bnx2x_ilt_line_wr(struct bnx2x *bp, int abs_idx, + dma_addr_t page_mapping) +{ + u32 reg; + + if (CHIP_IS_E1(bp)) + reg = PXP2_REG_RQ_ONCHIP_AT + abs_idx*8; + else + reg = PXP2_REG_RQ_ONCHIP_AT_B0 + abs_idx*8; + + bnx2x_wr_64(bp, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping)); +} + +static void bnx2x_ilt_line_init_op(struct bnx2x *bp, struct bnx2x_ilt *ilt, + int idx, u8 initop) +{ + dma_addr_t null_mapping; + int abs_idx = ilt->start_line + idx; + + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + bnx2x_ilt_line_wr(bp, abs_idx, ilt->lines[idx].page_mapping); + break; + case INITOP_CLEAR: + null_mapping = 0; + bnx2x_ilt_line_wr(bp, abs_idx, null_mapping); + break; + } +} + +void bnx2x_ilt_boundry_init_op(struct bnx2x *bp, + struct ilt_client_info *ilt_cli, + u32 ilt_start, u8 initop) +{ + u32 start_reg = 0; + u32 end_reg = 0; + + /* The boundary is either SET or INIT, + CLEAR => SET and for now SET ~~ INIT */ + + /* find the appropriate regs */ + if (CHIP_IS_E1(bp)) { + switch (ilt_cli->client_num) { + case ILT_CLIENT_CDU: + start_reg = PXP2_REG_PSWRQ_CDU0_L2P; + break; + case ILT_CLIENT_QM: + start_reg = PXP2_REG_PSWRQ_QM0_L2P; + break; + case ILT_CLIENT_SRC: + start_reg = PXP2_REG_PSWRQ_SRC0_L2P; + break; + case ILT_CLIENT_TM: + start_reg = PXP2_REG_PSWRQ_TM0_L2P; + break; + } + REG_WR(bp, start_reg + BP_FUNC(bp)*4, + ILT_RANGE((ilt_start + ilt_cli->start), + (ilt_start + ilt_cli->end))); + } else { + switch (ilt_cli->client_num) { + case ILT_CLIENT_CDU: + start_reg = PXP2_REG_RQ_CDU_FIRST_ILT; + end_reg = PXP2_REG_RQ_CDU_LAST_ILT; + break; + case ILT_CLIENT_QM: + start_reg = PXP2_REG_RQ_QM_FIRST_ILT; + end_reg = PXP2_REG_RQ_QM_LAST_ILT; + break; + case ILT_CLIENT_SRC: + start_reg = PXP2_REG_RQ_SRC_FIRST_ILT; + end_reg = PXP2_REG_RQ_SRC_LAST_ILT; + break; + case ILT_CLIENT_TM: + start_reg = PXP2_REG_RQ_TM_FIRST_ILT; + end_reg = PXP2_REG_RQ_TM_LAST_ILT; + break; + } + REG_WR(bp, start_reg, (ilt_start + ilt_cli->start)); + REG_WR(bp, end_reg, (ilt_start + ilt_cli->end)); + } +} + +void bnx2x_ilt_client_init_op_ilt(struct bnx2x *bp, struct bnx2x_ilt *ilt, + struct ilt_client_info *ilt_cli, u8 initop) +{ + int i; + + if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT) + return; + + for (i = ilt_cli->start; i <= ilt_cli->end; i++) + bnx2x_ilt_line_init_op(bp, ilt, i, initop); + + /* init/clear the ILT boundries */ + bnx2x_ilt_boundry_init_op(bp, ilt_cli, ilt->start_line, initop); +} + +void bnx2x_ilt_client_init_op(struct bnx2x *bp, + struct ilt_client_info *ilt_cli, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + + bnx2x_ilt_client_init_op_ilt(bp, ilt, ilt_cli, initop); +} + +static void bnx2x_ilt_client_id_init_op(struct bnx2x *bp, + int cli_num, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + bnx2x_ilt_client_init_op(bp, ilt_cli, initop); +} + +void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop) +{ + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop); +} + +static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num, + u32 psz_reg, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT) + return; + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + REG_WR(bp, psz_reg, ILOG2(ilt_cli->page_size >> 12)); + break; + case INITOP_CLEAR: + break; + } +} + +/* + * called during init common stage, ilt clients should be initialized + * prioir to calling this function + */ +void bnx2x_ilt_init_page_size(struct bnx2x *bp, u8 initop) +{ + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_CDU, + PXP2_REG_RQ_CDU_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_QM, + PXP2_REG_RQ_QM_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_SRC, + PXP2_REG_RQ_SRC_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_TM, + PXP2_REG_RQ_TM_P_SIZE, initop); +} + +/**************************************************************************** +* QM initializations +****************************************************************************/ +#define QM_QUEUES_PER_FUNC 16 /* E1 has 32, but only 16 are used */ +#define QM_INIT_MIN_CID_COUNT 31 +#define QM_INIT(cid_cnt) (cid_cnt > QM_INIT_MIN_CID_COUNT) + +/* called during init port stage */ +void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count, + u8 initop) +{ + int port = BP_PORT(bp); + + if (QM_INIT(qm_cid_count)) { + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + REG_WR(bp, QM_REG_CONNNUM_0 + port*4, + qm_cid_count/16 - 1); + break; + case INITOP_CLEAR: + break; + } + } +} + +static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count) +{ + int i; + u32 wb_data[2]; + + wb_data[0] = wb_data[1] = 0; + + for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) { + REG_WR(bp, QM_REG_BASEADDR + i*4, + qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, + wb_data, 2); + + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, + qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, + wb_data, 2); + } + } +} + +/* called during init common stage */ +void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, + u8 initop) +{ + if (!QM_INIT(qm_cid_count)) + return; + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + bnx2x_qm_set_ptr_table(bp, qm_cid_count); + break; + case INITOP_CLEAR: + break; + } +} + +/**************************************************************************** +* SRC initializations +****************************************************************************/ + +/* called during init func stage */ +void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, + dma_addr_t t2_mapping, int src_cid_count) +{ + int i; + int port = BP_PORT(bp); + + /* Initialize T2 */ + for (i = 0; i < src_cid_count-1; i++) + t2[i].next = (u64)(t2_mapping + (i+1)*sizeof(struct src_ent)); + + /* tell the searcher where the T2 table is */ + REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, src_cid_count); + + bnx2x_wr_64(bp, SRC_REG_FIRSTFREE0 + port*16, + U64_LO(t2_mapping), U64_HI(t2_mapping)); + + bnx2x_wr_64(bp, SRC_REG_LASTFREE0 + port*16, + U64_LO((u64)t2_mapping + + (src_cid_count-1) * sizeof(struct src_ent)), + U64_HI((u64)t2_mapping + + (src_cid_count-1) * sizeof(struct src_ent))); +} + #endif /* BNX2X_INIT_OPS_H */ diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index a07a3a6abd40..51d468d430ee 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -28,7 +28,7 @@ /********************************************************/ #define ETH_HLEN 14 -#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */ #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 @@ -4066,6 +4066,7 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, "verification\n"); return -EINVAL; } + fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl); fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param); if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 3696a4b6547b..119ca871f016 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -149,6 +149,242 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); * General service functions ****************************************************************************/ +static inline void __storm_memset_dma_mapping(struct bnx2x *bp, + u32 addr, dma_addr_t mapping) +{ + REG_WR(bp, addr, U64_LO(mapping)); + REG_WR(bp, addr + 4, U64_HI(mapping)); +} + +static inline void __storm_memset_fill(struct bnx2x *bp, + u32 addr, size_t size, u32 val) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), val); +} + +static inline void storm_memset_ustats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct ustorm_per_client_stats); + + u32 addr = BAR_USTRORM_INTMEM + + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + +static inline void storm_memset_tstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct tstorm_per_client_stats); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + +static inline void storm_memset_xstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct xstorm_per_client_stats); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + + +static inline void storm_memset_spq_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ov(struct bnx2x *bp, u16 ov, u16 abs_fid) +{ + REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(abs_fid), ov); +} + +static inline void storm_memset_func_cfg(struct bnx2x *bp, + struct tstorm_eth_function_common_config *tcfg, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_function_common_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)tcfg); +} + +static inline void storm_memset_xstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_tstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_ustats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_cstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_xstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_tstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ustats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_USTRORM_INTMEM + + USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_cstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, + u16 pf_id) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); +} + +static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, + u8 enable) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), + enable); +} + +static inline void storm_memset_eq_data(struct bnx2x *bp, + struct event_ring_data *eq_data, + u16 pfid) +{ + size_t size = sizeof(struct event_ring_data); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_DATA_OFFSET(pfid); + + __storm_memset_struct(bp, addr, size, (u32 *)eq_data); +} + +static inline void storm_memset_eq_prod(struct bnx2x *bp, u16 eq_prod, + u16 pfid) +{ + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_PROD_OFFSET(pfid); + REG_WR16(bp, addr, eq_prod); +} + +static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port, + u16 fw_sb_id, u8 sb_index, + u8 ticks) +{ + + int index_offset = + offsetof(struct hc_status_block_data_e1x, index_data); + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + index_offset + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, timeout); + REG_WR8(bp, addr, ticks); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d ticks %d\n", + port, fw_sb_id, sb_index, ticks); +} +static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port, + u16 fw_sb_id, u8 sb_index, + u8 disable) +{ + u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); + int index_offset = + offsetof(struct hc_status_block_data_e1x, index_data); + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + index_offset + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, flags); + u16 flags = REG_RD16(bp, addr); + /* clear and set */ + flags &= ~HC_INDEX_DATA_HC_ENABLED; + flags |= enable_flag; + REG_WR16(bp, addr, flags); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d disable %d\n", + port, fw_sb_id, sb_index, disable); +} + /* used only at init * locking is done by mcp */ @@ -538,7 +774,12 @@ static void bnx2x_fw_dump(struct bnx2x *bp) void bnx2x_panic_dump(struct bnx2x *bp) { int i; - u16 j, start, end; + u16 j; + struct hc_sp_status_block_data sp_sb_data; + int func = BP_FUNC(bp); +#ifdef BNX2X_STOP_ON_ERROR + u16 start = 0, end = 0; +#endif bp->stats_state = STATS_STATE_DISABLED; DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); @@ -547,44 +788,124 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* Indices */ /* Common */ - BNX2X_ERR("def_c_idx(0x%x) def_u_idx(0x%x) def_x_idx(0x%x)" - " def_t_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)" + BNX2X_ERR("def_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)" " spq_prod_idx(0x%x)\n", - bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx, - bp->def_att_idx, bp->attn_state, bp->spq_prod_idx); + bp->def_idx, bp->def_att_idx, + bp->attn_state, bp->spq_prod_idx); + BNX2X_ERR("DSB: attn bits(0x%x) ack(0x%x) id(0x%x) idx(0x%x)\n", + bp->def_status_blk->atten_status_block.attn_bits, + bp->def_status_blk->atten_status_block.attn_bits_ack, + bp->def_status_blk->atten_status_block.status_block_id, + bp->def_status_blk->atten_status_block.attn_bits_index); + BNX2X_ERR(" def ("); + for (i = 0; i < HC_SP_SB_MAX_INDICES; i++) + pr_cont("0x%x%s", + bp->def_status_blk->sp_sb.index_values[i], + (i == HC_SP_SB_MAX_INDICES - 1) ? ") " : " "); + + for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++) + *((u32 *)&sp_sb_data + i) = REG_RD(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + i*sizeof(u32)); + + pr_cont("igu_sb_id(0x%x) igu_seg_id (0x%x) " + "pf_id(0x%x) vnic_id(0x%x) " + "vf_id(0x%x) vf_valid (0x%x)\n", + sp_sb_data.igu_sb_id, + sp_sb_data.igu_seg_id, + sp_sb_data.p_func.pf_id, + sp_sb_data.p_func.vnic_id, + sp_sb_data.p_func.vf_id, + sp_sb_data.p_func.vf_valid); + - /* Rx */ for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - + int loop; + struct hc_status_block_data_e1x sb_data_e1x; + struct hc_status_block_sm *hc_sm_p = + sb_data_e1x.common.state_machine; + struct hc_index_data *hc_index_p = + sb_data_e1x.index_data; + int data_size; + u32 *sb_data_p; + + /* Rx */ BNX2X_ERR("fp%d: rx_bd_prod(0x%x) rx_bd_cons(0x%x)" - " *rx_bd_cons_sb(0x%x) rx_comp_prod(0x%x)" + " rx_comp_prod(0x%x)" " rx_comp_cons(0x%x) *rx_cons_sb(0x%x)\n", i, fp->rx_bd_prod, fp->rx_bd_cons, - le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod, + fp->rx_comp_prod, fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb)); BNX2X_ERR(" rx_sge_prod(0x%x) last_max_sge(0x%x)" - " fp_u_idx(0x%x) *sb_u_idx(0x%x)\n", + " fp_hc_idx(0x%x)\n", fp->rx_sge_prod, fp->last_max_sge, - le16_to_cpu(fp->fp_u_idx), - fp->status_blk->u_status_block.status_block_index); - } - - /* Tx */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; + le16_to_cpu(fp->fp_hc_idx)); + /* Tx */ BNX2X_ERR("fp%d: tx_pkt_prod(0x%x) tx_pkt_cons(0x%x)" " tx_bd_prod(0x%x) tx_bd_cons(0x%x)" " *tx_cons_sb(0x%x)\n", i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); - BNX2X_ERR(" fp_c_idx(0x%x) *sb_c_idx(0x%x)" - " tx_db_prod(0x%x)\n", le16_to_cpu(fp->fp_c_idx), - fp->status_blk->c_status_block.status_block_index, - fp->tx_db.data.prod); + + loop = HC_SB_MAX_INDICES_E1X; + + /* host sb data */ + + BNX2X_ERR(" run indexes ("); + for (j = 0; j < HC_SB_MAX_SM; j++) + pr_cont("0x%x%s", + fp->sb_running_index[j], + (j == HC_SB_MAX_SM - 1) ? ")" : " "); + + BNX2X_ERR(" indexes ("); + for (j = 0; j < loop; j++) + pr_cont("0x%x%s", + fp->sb_index_values[j], + (j == loop - 1) ? ")" : " "); + /* fw sb data */ + data_size = + sizeof(struct hc_status_block_data_e1x); + data_size /= sizeof(u32); + sb_data_p = (u32 *)&sb_data_e1x; + /* copy sb data in here */ + for (j = 0; j < data_size; j++) + *(sb_data_p + j) = REG_RD(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + + j * sizeof(u32)); + + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e1x.common.p_func.pf_id, + sb_data_e1x.common.p_func.vf_id, + sb_data_e1x.common.p_func.vf_valid, + sb_data_e1x.common.p_func.vnic_id, + sb_data_e1x.common.same_igu_sb_1b); + + /* SB_SMs data */ + for (j = 0; j < HC_SB_MAX_SM; j++) { + pr_cont("SM[%d] __flags (0x%x) " + "igu_sb_id (0x%x) igu_seg_id(0x%x) " + "time_to_expire (0x%x) " + "timer_value(0x%x)\n", j, + hc_sm_p[j].__flags, + hc_sm_p[j].igu_sb_id, + hc_sm_p[j].igu_seg_id, + hc_sm_p[j].time_to_expire, + hc_sm_p[j].timer_value); + } + + /* Indecies data */ + for (j = 0; j < loop; j++) { + pr_cont("INDEX[%d] flags (0x%x) " + "timeout (0x%x)\n", j, + hc_index_p[j].flags, + hc_index_p[j].timeout); + } } +#ifdef BNX2X_STOP_ON_ERROR /* Rings */ /* Rx */ for_each_queue(bp, i) { @@ -642,7 +963,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]); } } - +#endif bnx2x_fw_dump(bp); bnx2x_mc_assert(bp); BNX2X_ERR("end crash dump -----------------\n"); @@ -708,7 +1029,7 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); } -static void bnx2x_int_disable(struct bnx2x *bp) +void bnx2x_int_disable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -817,76 +1138,35 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.ramrod_type); - bp->spq_left++; - - if (fp->index) { - switch (command | fp->state) { - case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | - BNX2X_FP_STATE_OPENING): - DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", - cid); - fp->state = BNX2X_FP_STATE_OPEN; - break; - - case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING): - DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", - cid); - fp->state = BNX2X_FP_STATE_HALTED; - break; - - default: - BNX2X_ERR("unexpected MC reply (%d) " - "fp[%d] state is %x\n", - command, fp->index, fp->state); - break; - } - mb(); /* force bnx2x_wait_ramrod() to see the change */ - return; - } - - switch (command | bp->state) { - case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT): - DP(NETIF_MSG_IFUP, "got setup ramrod\n"); - bp->state = BNX2X_STATE_OPEN; + switch (command | fp->state) { + case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | BNX2X_FP_STATE_OPENING): + DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", cid); + fp->state = BNX2X_FP_STATE_OPEN; break; - case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got halt ramrod\n"); - bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE; + case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING): + DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", cid); fp->state = BNX2X_FP_STATE_HALTED; break; - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid); - bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; + case (RAMROD_CMD_ID_ETH_TERMINATE | BNX2X_FP_STATE_TERMINATING): + DP(NETIF_MSG_IFDOWN, "got MULTI[%d] teminate ramrod\n", cid); + fp->state = BNX2X_FP_STATE_TERMINATED; break; -#ifdef BCM_CNIC - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_OPEN): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for CID %d\n", cid); - bnx2x_cnic_cfc_comp(bp, cid); + default: + BNX2X_ERR("unexpected MC reply (%d) " + "fp[%d] state is %x\n", + command, fp->index, fp->state); break; -#endif + } - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): - DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); - bp->set_mac_pending--; - smp_wmb(); - break; + bp->spq_left++; - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); - bp->set_mac_pending--; - smp_wmb(); - break; + /* push the change in fp->state and towards the memory */ + smp_wmb(); - default: - BNX2X_ERR("unexpected MC reply (%d) bp->state is %x\n", - command, bp->state); - break; - } - mb(); /* force bnx2x_wait_ramrod() to see the change */ + return; } irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) @@ -917,22 +1197,19 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) { struct bnx2x_fastpath *fp = &bp->fp[i]; - mask = 0x2 << fp->sb_id; + mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); if (status & mask) { /* Handle Rx and Tx according to SB id */ prefetch(fp->rx_cons_sb); - prefetch(&fp->status_blk->u_status_block. - status_block_index); prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->c_status_block. - status_block_index); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); status &= ~mask; } } #ifdef BCM_CNIC - mask = 0x2 << CNIC_SB_ID(bp); + mask = 0x2; if (status & (mask | 0x1)) { struct cnic_ops *c_ops = NULL; @@ -1422,7 +1699,7 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) bp->vn_weight_sum = 0; for (vn = VN_0; vn < E1HVN_MAX; vn++) { int func = 2*vn + port; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; @@ -1454,7 +1731,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) { struct rate_shaping_vars_per_vn m_rs_vn; struct fairness_vars_per_vn m_fair_vn; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); u16 vn_min_rate, vn_max_rate; int i; @@ -1511,7 +1788,83 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4, ((u32 *)(&m_fair_vn))[i]); } +static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) +{ + if (CHIP_REV_IS_SLOW(bp)) + return CMNG_FNS_NONE; + if (IS_E1HMF(bp)) + return CMNG_FNS_MINMAX; + + return CMNG_FNS_NONE; +} + +static void bnx2x_read_mf_cfg(struct bnx2x *bp) +{ + int vn; + + if (BP_NOMCP(bp)) + return; /* what should be the default bvalue in this case */ + + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + int /*abs*/func = 2*vn + BP_PORT(bp); + bp->mf_config = + MF_CFG_RD(bp, func_mf_config[func].config); + } +} + +static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) +{ + + if (cmng_type == CMNG_FNS_MINMAX) { + int vn; + + /* clear cmng_enables */ + bp->cmng.flags.cmng_enables = 0; + + /* read mf conf from shmem */ + if (read_cfg) + bnx2x_read_mf_cfg(bp); + + /* Init rate shaping and fairness contexts */ + bnx2x_init_port_minmax(bp); + + /* vn_weight_sum and enable fairness if not 0 */ + bnx2x_calc_vn_weight_sum(bp); + + /* calculate and set min-max rate for each vn */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, vn); + + /* always enable rate shaping and fairness */ + bp->cmng.flags.cmng_enables |= + CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; + if (!bp->vn_weight_sum) + DP(NETIF_MSG_IFUP, "All MIN values are zeroes" + " fairness will be disabled\n"); + return; + } + + /* rate shaping and fairness are disabled */ + DP(NETIF_MSG_IFUP, + "rate shaping and fairness are disabled\n"); +} +static inline void bnx2x_link_sync_notify(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int func; + int vn; + + /* Set the attention towards other drivers on the same port */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + if (vn == BP_E1HVN(bp)) + continue; + + func = ((vn << 1) | port); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + + (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); + } +} /* This function is called upon link interrupt */ static void bnx2x_link_attn(struct bnx2x *bp) @@ -1669,120 +2022,390 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) return rc; } -static void bnx2x_e1h_disable(struct bnx2x *bp) +/* must be called under rtnl_lock */ +void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) { - int port = BP_PORT(bp); + u32 mask = (1 << cl_id); - netif_tx_disable(bp->dev); + /* initial seeting is BNX2X_ACCEPT_NONE */ + u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; + u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; + u8 unmatched_unicast = 0; - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); + if (filters & BNX2X_PROMISCUOUS_MODE) { + /* promiscious - accept all, drop none */ + drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; + accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_UNICAST) { + /* accept matched ucast */ + drop_all_ucast = 0; + } + if (filters & BNX2X_ACCEPT_MULTICAST) { + /* accept matched mcast */ + drop_all_mcast = 0; + } + if (filters & BNX2X_ACCEPT_ALL_UNICAST) { + /* accept all mcast */ + drop_all_ucast = 0; + accp_all_ucast = 1; + } + if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { + /* accept all mcast */ + drop_all_mcast = 0; + accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_BROADCAST) { + /* accept (all) bcast */ + drop_all_bcast = 0; + accp_all_bcast = 1; + } - netif_carrier_off(bp->dev); -} + bp->mac_filters.ucast_drop_all = drop_all_ucast ? + bp->mac_filters.ucast_drop_all | mask : + bp->mac_filters.ucast_drop_all & ~mask; -static void bnx2x_e1h_enable(struct bnx2x *bp) -{ - int port = BP_PORT(bp); + bp->mac_filters.mcast_drop_all = drop_all_mcast ? + bp->mac_filters.mcast_drop_all | mask : + bp->mac_filters.mcast_drop_all & ~mask; - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); + bp->mac_filters.bcast_drop_all = drop_all_bcast ? + bp->mac_filters.bcast_drop_all | mask : + bp->mac_filters.bcast_drop_all & ~mask; - /* Tx queue should be only reenabled */ - netif_tx_wake_all_queues(bp->dev); + bp->mac_filters.ucast_accept_all = accp_all_ucast ? + bp->mac_filters.ucast_accept_all | mask : + bp->mac_filters.ucast_accept_all & ~mask; - /* - * Should not call netif_carrier_on since it will be called if the link - * is up when checking for link state - */ + bp->mac_filters.mcast_accept_all = accp_all_mcast ? + bp->mac_filters.mcast_accept_all | mask : + bp->mac_filters.mcast_accept_all & ~mask; + + bp->mac_filters.bcast_accept_all = accp_all_bcast ? + bp->mac_filters.bcast_accept_all | mask : + bp->mac_filters.bcast_accept_all & ~mask; + + bp->mac_filters.unmatched_unicast = unmatched_unicast ? + bp->mac_filters.unmatched_unicast | mask : + bp->mac_filters.unmatched_unicast & ~mask; } -static void bnx2x_update_min_max(struct bnx2x *bp) +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) { - int port = BP_PORT(bp); - int vn, i; + if (FUNC_CONFIG(p->func_flgs)) { + struct tstorm_eth_function_common_config tcfg = {0}; - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); - - bnx2x_calc_vn_weight_sum(bp); + /* tpa */ + if (p->func_flgs & FUNC_FLG_TPA) + tcfg.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); + /* set rss flags */ + if (p->func_flgs & FUNC_FLG_RSS) { + u16 rss_flgs = (p->rss->mode << + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); - if (bp->port.pmf) { - int func; + if (p->rss->cap & RSS_IPV4_CAP) + rss_flgs |= RSS_IPV4_CAP_MASK; + if (p->rss->cap & RSS_IPV4_TCP_CAP) + rss_flgs |= RSS_IPV4_TCP_CAP_MASK; + if (p->rss->cap & RSS_IPV6_CAP) + rss_flgs |= RSS_IPV6_CAP_MASK; + if (p->rss->cap & RSS_IPV6_TCP_CAP) + rss_flgs |= RSS_IPV6_TCP_CAP_MASK; - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; + tcfg.config_flags |= rss_flgs; + tcfg.rss_result_mask = p->rss->result_mask; - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); } - /* Store it to internal memory */ - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); + storm_memset_func_cfg(bp, &tcfg, p->func_id); } -} -static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) -{ - DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); + /* Enable the function in the FW */ + storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); + storm_memset_func_en(bp, p->func_id, 1); - if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) { + /* statistics */ + if (p->func_flgs & FUNC_FLG_STATS) { + struct stats_indication_flags stats_flags = {0}; + stats_flags.collect_eth = 1; - /* - * This is the only place besides the function initialization - * where the bp->flags can change so it is done without any - * locks - */ - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { - DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; + storm_memset_xstats_flags(bp, &stats_flags, p->func_id); + storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); - bnx2x_e1h_disable(bp); - } else { - DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n"); - bp->flags &= ~MF_FUNC_DIS; + storm_memset_tstats_flags(bp, &stats_flags, p->func_id); + storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); - bnx2x_e1h_enable(bp); - } - dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; - } - if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { + storm_memset_ustats_flags(bp, &stats_flags, p->func_id); + storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); - bnx2x_update_min_max(bp); - dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; + storm_memset_cstats_flags(bp, &stats_flags, p->func_id); + storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); } - /* Report results to MCP */ - if (dcc_event) - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0); - else - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0); + /* spq */ + if (p->func_flgs & FUNC_FLG_SPQ) { + storm_memset_spq_addr(bp, p->spq_map, p->func_id); + REG_WR(bp, XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); + } } -/* must be called under the spq lock */ -static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp) +static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, + struct bnx2x_fastpath *fp) { - struct eth_spe *next_spe = bp->spq_prod_bd; + u16 flags = 0; - if (bp->spq_prod_bd == bp->spq_last_bd) { - bp->spq_prod_bd = bp->spq; - bp->spq_prod_idx = 0; - DP(NETIF_MSG_TIMER, "end of spq\n"); - } else { - bp->spq_prod_bd++; - bp->spq_prod_idx++; - } - return next_spe; -} + /* calculate queue flags */ + flags |= QUEUE_FLG_CACHE_ALIGN; + flags |= QUEUE_FLG_HC; + flags |= IS_E1HMF(bp) ? QUEUE_FLG_OV : 0; -/* must be called under the spq lock */ +#ifdef BCM_VLAN + flags |= QUEUE_FLG_VLAN; + DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); +#endif + + if (!fp->disable_tpa) + flags |= QUEUE_FLG_TPA; + + flags |= QUEUE_FLG_STATS; + + return flags; +} + +static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct rxq_pause_params *pause, + struct bnx2x_rxq_init_params *rxq_init) +{ + u16 max_sge = 0; + u16 sge_sz = 0; + u16 tpa_agg_size = 0; + + /* calculate queue flags */ + u16 flags = bnx2x_get_cl_flags(bp, fp); + + if (!fp->disable_tpa) { + pause->sge_th_hi = 250; + pause->sge_th_lo = 150; + tpa_agg_size = min_t(u32, + (min_t(u32, 8, MAX_SKB_FRAGS) * + SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); + max_sge = SGE_PAGE_ALIGN(bp->dev->mtu) >> + SGE_PAGE_SHIFT; + max_sge = ((max_sge + PAGES_PER_SGE - 1) & + (~(PAGES_PER_SGE-1))) >> PAGES_PER_SGE_SHIFT; + sge_sz = (u16)min_t(u32, SGE_PAGE_SIZE * PAGES_PER_SGE, + 0xffff); + } + + /* pause - not for e1 */ + if (!CHIP_IS_E1(bp)) { + pause->bd_th_hi = 350; + pause->bd_th_lo = 250; + pause->rcq_th_hi = 350; + pause->rcq_th_lo = 250; + pause->sge_th_hi = 0; + pause->sge_th_lo = 0; + pause->pri_map = 1; + } + + /* rxq setup */ + rxq_init->flags = flags; + rxq_init->cxt = &bp->context.vcxt[fp->cid].eth; + rxq_init->dscr_map = fp->rx_desc_mapping; + rxq_init->sge_map = fp->rx_sge_mapping; + rxq_init->rcq_map = fp->rx_comp_mapping; + rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE; + rxq_init->mtu = bp->dev->mtu; + rxq_init->buf_sz = bp->rx_buf_size; + rxq_init->cl_qzone_id = fp->cl_qzone_id; + rxq_init->cl_id = fp->cl_id; + rxq_init->spcl_id = fp->cl_id; + rxq_init->stat_id = fp->cl_id; + rxq_init->tpa_agg_sz = tpa_agg_size; + rxq_init->sge_buf_sz = sge_sz; + rxq_init->max_sges_pkt = max_sge; + rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT; + rxq_init->fw_sb_id = fp->fw_sb_id; + + rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; + + rxq_init->cid = HW_CID(bp, fp->cid); + + rxq_init->hc_rate = bp->rx_ticks ? (1000000 / bp->rx_ticks) : 0; +} + +static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct bnx2x_txq_init_params *txq_init) +{ + u16 flags = bnx2x_get_cl_flags(bp, fp); + + txq_init->flags = flags; + txq_init->cxt = &bp->context.vcxt[fp->cid].eth; + txq_init->dscr_map = fp->tx_desc_mapping; + txq_init->stat_id = fp->cl_id; + txq_init->cid = HW_CID(bp, fp->cid); + txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX; + txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; + txq_init->fw_sb_id = fp->fw_sb_id; + txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0; +} + +void bnx2x_pf_init(struct bnx2x *bp) +{ + struct bnx2x_func_init_params func_init = {0}; + struct bnx2x_rss_params rss = {0}; + struct event_ring_data eq_data = { {0} }; + u16 flags; + + /* pf specific setups */ + if (!CHIP_IS_E1(bp)) + storm_memset_ov(bp, bp->e1hov, BP_FUNC(bp)); + + /* function setup flags */ + flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); + + flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; + + /** + * Although RSS is meaningless when there is a single HW queue we + * still need it enabled in order to have HW Rx hash generated. + * + * if (is_eth_multi(bp)) + * flags |= FUNC_FLG_RSS; + */ + + /* function setup */ + if (flags & FUNC_FLG_RSS) { + rss.cap = (RSS_IPV4_CAP | RSS_IPV4_TCP_CAP | + RSS_IPV6_CAP | RSS_IPV6_TCP_CAP); + rss.mode = bp->multi_mode; + rss.result_mask = MULTI_MASK; + func_init.rss = &rss; + } + + func_init.func_flgs = flags; + func_init.pf_id = BP_FUNC(bp); + func_init.func_id = BP_FUNC(bp); + func_init.fw_stat_map = bnx2x_sp_mapping(bp, fw_stats); + func_init.spq_map = bp->spq_mapping; + func_init.spq_prod = bp->spq_prod_idx; + + bnx2x_func_init(bp, &func_init); + + memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); + + /* + Congestion management values depend on the link rate + There is no active link so initial link rate is set to 10 Gbps. + When the link comes up The congestion management values are + re-calculated according to the actual link rate. + */ + bp->link_vars.line_speed = SPEED_10000; + bnx2x_cmng_fns_init(bp, true, bnx2x_get_cmng_fns_mode(bp)); + + /* Only the PMF sets the HW */ + if (bp->port.pmf) + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + + /* no rx until link is up */ + bp->rx_mode = BNX2X_RX_MODE_NONE; + bnx2x_set_storm_rx_mode(bp); + + /* init Event Queue */ + eq_data.base_addr.hi = U64_HI(bp->eq_mapping); + eq_data.base_addr.lo = U64_LO(bp->eq_mapping); + eq_data.producer = bp->eq_prod; + eq_data.index_id = HC_SP_INDEX_EQ_CONS; + eq_data.sb_id = DEF_SB_ID; + storm_memset_eq_data(bp, &eq_data, BP_FUNC(bp)); +} + + +static void bnx2x_e1h_disable(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + + netif_tx_disable(bp->dev); + + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); + + netif_carrier_off(bp->dev); +} + +static void bnx2x_e1h_enable(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); + + /* Tx queue should be only reenabled */ + netif_tx_wake_all_queues(bp->dev); + + /* + * Should not call netif_carrier_on since it will be called if the link + * is up when checking for link state + */ +} + +static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) +{ + DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); + + if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) { + + /* + * This is the only place besides the function initialization + * where the bp->flags can change so it is done without any + * locks + */ + if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { + DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); + bp->flags |= MF_FUNC_DIS; + + bnx2x_e1h_disable(bp); + } else { + DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n"); + bp->flags &= ~MF_FUNC_DIS; + + bnx2x_e1h_enable(bp); + } + dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; + } + if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { + + bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); + bnx2x_link_sync_notify(bp); + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; + } + + /* Report results to MCP */ + if (dcc_event) + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0); + else + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0); +} + +/* must be called under the spq lock */ +static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp) +{ + struct eth_spe *next_spe = bp->spq_prod_bd; + + if (bp->spq_prod_bd == bp->spq_last_bd) { + bp->spq_prod_bd = bp->spq; + bp->spq_prod_idx = 0; + DP(NETIF_MSG_TIMER, "end of spq\n"); + } else { + bp->spq_prod_bd++; + bp->spq_prod_idx++; + } + return next_spe; +} + +/* must be called under the spq lock */ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) { int func = BP_FUNC(bp); @@ -1790,7 +2413,7 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) /* Make sure that BD data is updated before writing the producer */ wmb(); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), + REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), bp->spq_prod_idx); mmiowb(); } @@ -1800,6 +2423,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common) { struct eth_spe *spe; + u16 type; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -1821,22 +2445,42 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, spe->hdr.conn_and_cmd_data = cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | HW_CID(bp, cid)); - spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE); + if (common) - spe->hdr.type |= - cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT)); + /* Common ramrods: + * FUNC_START, FUNC_STOP, CFC_DEL, STATS, SET_MAC + * TRAFFIC_STOP, TRAFFIC_START + */ + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + else + /* ETH ramrods: SETUP, HALT */ + type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; - spe->data.mac_config_addr.hi = cpu_to_le32(data_hi); - spe->data.mac_config_addr.lo = cpu_to_le32(data_lo); + type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); - bp->spq_left--; + spe->hdr.type = cpu_to_le16(type); + + spe->data.update_data_addr.hi = cpu_to_le32(data_hi); + spe->data.update_data_addr.lo = cpu_to_le32(data_lo); + + /* stats ramrod has it's own slot on the spq */ + if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) + /* It's ok if the actual decrement is issued towards the memory + * somewhere between the spin_lock and spin_unlock. Thus no + * more explict memory barrier is needed. + */ + bp->spq_left--; DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, - "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", + "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) " + "type(0x%x) left %x\n", bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) + (void *)bp->spq_prod_bd - (void *)bp->spq), command, - HW_CID(bp, cid), data_hi, data_lo, bp->spq_left); + HW_CID(bp, cid), data_hi, data_lo, type, bp->spq_left); bnx2x_sp_prod_update(bp); spin_unlock_bh(&bp->spq_lock); @@ -1873,32 +2517,27 @@ static void bnx2x_release_alr(struct bnx2x *bp) REG_WR(bp, GRCBASE_MCP + 0x9c, 0); } +#define BNX2X_DEF_SB_ATT_IDX 0x0001 +#define BNX2X_DEF_SB_IDX 0x0002 + static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) { - struct host_def_status_block *def_sb = bp->def_status_blk; + struct host_sp_status_block *def_sb = bp->def_status_blk; u16 rc = 0; barrier(); /* status block is written to by the chip */ if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) { bp->def_att_idx = def_sb->atten_status_block.attn_bits_index; - rc |= 1; - } - if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) { - bp->def_c_idx = def_sb->c_def_status_block.status_block_index; - rc |= 2; - } - if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) { - bp->def_u_idx = def_sb->u_def_status_block.status_block_index; - rc |= 4; - } - if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) { - bp->def_x_idx = def_sb->x_def_status_block.status_block_index; - rc |= 8; + rc |= BNX2X_DEF_SB_ATT_IDX; } - if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) { - bp->def_t_idx = def_sb->t_def_status_block.status_block_index; - rc |= 16; + + if (bp->def_idx != def_sb->sp_sb.running_index) { + bp->def_idx = def_sb->sp_sb.running_index; + rc |= BNX2X_DEF_SB_IDX; } + + /* Do not reorder: indecies reading should complete before handling */ + barrier(); return rc; } @@ -2144,8 +2783,8 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) int func = BP_FUNC(bp); REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - bp->mf_config = SHMEM_RD(bp, - mf_cfg.func_mf_config[func].config); + bp->mf_config = + MF_CFG_RD(bp, func_mf_config[func].config); val = SHMEM_RD(bp, func_mb[func].drv_status); if (val & DRV_STATUS_DCC_EVENT_MASK) bnx2x_dcc_event(bp, @@ -2598,6 +3237,140 @@ static void bnx2x_attn_int(struct bnx2x *bp) bnx2x_attn_int_deasserted(bp, deasserted); } +static inline void bnx2x_update_eq_prod(struct bnx2x *bp, u16 prod) +{ + /* No memory barriers */ + storm_memset_eq_prod(bp, prod, BP_FUNC(bp)); + mmiowb(); /* keep prod updates ordered */ +} + +#ifdef BCM_CNIC +static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, + union event_ring_elem *elem) +{ + if (!bp->cnic_eth_dev.starting_cid || + cid < bp->cnic_eth_dev.starting_cid) + return 1; + + DP(BNX2X_MSG_SP, "got delete ramrod for CNIC CID %d\n", cid); + + if (unlikely(elem->message.data.cfc_del_event.error)) { + BNX2X_ERR("got delete ramrod for CNIC CID %d with error!\n", + cid); + bnx2x_panic_dump(bp); + } + bnx2x_cnic_cfc_comp(bp, cid); + return 0; +} +#endif + +static void bnx2x_eq_int(struct bnx2x *bp) +{ + u16 hw_cons, sw_cons, sw_prod; + union event_ring_elem *elem; + u32 cid; + u8 opcode; + int spqe_cnt = 0; + + hw_cons = le16_to_cpu(*bp->eq_cons_sb); + + /* The hw_cos range is 1-255, 257 - the sw_cons range is 0-254, 256. + * when we get the the next-page we nned to adjust so the loop + * condition below will be met. The next element is the size of a + * regular element and hence incrementing by 1 + */ + if ((hw_cons & EQ_DESC_MAX_PAGE) == EQ_DESC_MAX_PAGE) + hw_cons++; + + /* This function may never run in parralel with itself for a + * specific bp, thus there is no need in "paired" read memory + * barrier here. + */ + sw_cons = bp->eq_cons; + sw_prod = bp->eq_prod; + + DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->spq_left %u\n", + hw_cons, sw_cons, bp->spq_left); + + for (; sw_cons != hw_cons; + sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) { + + + elem = &bp->eq_ring[EQ_DESC(sw_cons)]; + + cid = SW_CID(elem->message.data.cfc_del_event.cid); + opcode = elem->message.opcode; + + + /* handle eq element */ + switch (opcode) { + case EVENT_RING_OPCODE_STAT_QUERY: + DP(NETIF_MSG_TIMER, "got statistics comp event\n"); + /* nothing to do with stats comp */ + continue; + + case EVENT_RING_OPCODE_CFC_DEL: + /* handle according to cid range */ + /* + * we may want to verify here that the bp state is + * HALTING + */ + DP(NETIF_MSG_IFDOWN, + "got delete ramrod for MULTI[%d]\n", cid); +#ifdef BCM_CNIC + if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem)) + goto next_spqe; +#endif + bnx2x_fp(bp, cid, state) = + BNX2X_FP_STATE_CLOSED; + + goto next_spqe; + } + + switch (opcode | bp->state) { + case (EVENT_RING_OPCODE_FUNCTION_START | + BNX2X_STATE_OPENING_WAIT4_PORT): + DP(NETIF_MSG_IFUP, "got setup ramrod\n"); + bp->state = BNX2X_STATE_FUNC_STARTED; + break; + + case (EVENT_RING_OPCODE_FUNCTION_STOP | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFDOWN, "got halt ramrod\n"); + bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + break; + + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG): + DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); + bp->set_mac_pending = 0; + break; + + case (EVENT_RING_OPCODE_SET_MAC | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); + bp->set_mac_pending = 0; + break; + default: + /* unknown event log error and continue */ + BNX2X_ERR("Unknown EQ event %d\n", + elem->message.opcode); + } +next_spqe: + spqe_cnt++; + } /* for */ + + bp->spq_left++; + + bp->eq_cons = sw_cons; + bp->eq_prod = sw_prod; + /* Make sure that above mem writes were issued towards the memory */ + smp_wmb(); + + /* update producer */ + bnx2x_update_eq_prod(bp, bp->eq_prod); +} + static void bnx2x_sp_task(struct work_struct *work) { struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work); @@ -2616,31 +3389,29 @@ static void bnx2x_sp_task(struct work_struct *work) DP(NETIF_MSG_INTR, "got a slowpath interrupt (status 0x%x)\n", status); /* HW attentions */ - if (status & 0x1) { + if (status & BNX2X_DEF_SB_ATT_IDX) { bnx2x_attn_int(bp); - status &= ~0x1; + status &= ~BNX2X_DEF_SB_ATT_IDX; } - /* CStorm events: STAT_QUERY */ - if (status & 0x2) { - DP(BNX2X_MSG_SP, "CStorm events: STAT_QUERY\n"); - status &= ~0x2; + /* SP events: STAT_QUERY and others */ + if (status & BNX2X_DEF_SB_IDX) { + + /* Handle EQ completions */ + bnx2x_eq_int(bp); + + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, + le16_to_cpu(bp->def_idx), IGU_INT_NOP, 1); + + status &= ~BNX2X_DEF_SB_IDX; } if (unlikely(status)) DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n", status); - bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx), - IGU_INT_ENABLE, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, ATTENTION_ID, + le16_to_cpu(bp->def_att_idx), IGU_INT_ENABLE, 1); } irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) @@ -2654,7 +3425,8 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) return IRQ_HANDLED; } - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0); + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, + IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -2736,232 +3508,234 @@ timer_restart: * nic init service functions */ -static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id) +static inline void bnx2x_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) { - int port = BP_PORT(bp); + u32 i; + if (!(len%4) && !(addr%4)) + for (i = 0; i < len; i += 4) + REG_WR(bp, addr + i, fill); + else + for (i = 0; i < len; i++) + REG_WR8(bp, addr + i, fill); - /* "CSTORM" */ - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_U_SIZE / 4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_C_SIZE / 4); } -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id) +/* helper: writes FP SP data to FW - data_size in dwords */ +static inline void bnx2x_wr_fp_sb_data(struct bnx2x *bp, + int fw_sb_id, + u32 *sb_data_p, + u32 data_size) { - int port = BP_PORT(bp); - int func = BP_FUNC(bp); int index; - u64 section; + for (index = 0; index < data_size; index++) + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + sizeof(u32)*index, + *(sb_data_p + index)); +} - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - u_status_block); - sb->u_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_USB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), func); - - for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, index), 1); +static inline void bnx2x_zero_fp_sb(struct bnx2x *bp, int fw_sb_id) +{ + u32 *sb_data_p; + u32 data_size = 0; + struct hc_status_block_data_e1x sb_data_e1x; - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - c_status_block); - sb->c_status_block.status_block_id = sb_id; + /* disable the function first */ + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), func); + bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); - for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, index), 1); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_OFFSET(fw_sb_id), 0, + CSTORM_STATUS_BLOCK_SIZE); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SYNC_BLOCK_OFFSET(fw_sb_id), 0, + CSTORM_SYNC_BLOCK_SIZE); +} - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); +/* helper: writes SP SB data to FW */ +static inline void bnx2x_wr_sp_sb_data(struct bnx2x *bp, + struct hc_sp_status_block_data *sp_sb_data) +{ + int func = BP_FUNC(bp); + int i; + for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++) + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + i*sizeof(u32), + *((u32 *)sp_sb_data + i)); } -static void bnx2x_zero_def_sb(struct bnx2x *bp) +static inline void bnx2x_zero_sp_sb(struct bnx2x *bp) { int func = BP_FUNC(bp); + struct hc_sp_status_block_data sp_sb_data; + memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); - bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct tstorm_def_status_block)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_u)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_c)/4); - bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct xstorm_def_status_block)/4); + sp_sb_data.p_func.pf_id = HC_FUNCTION_DISABLED; + sp_sb_data.p_func.vf_id = HC_FUNCTION_DISABLED; + sp_sb_data.p_func.vf_valid = false; + + bnx2x_wr_sp_sb_data(bp, &sp_sb_data); + + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_OFFSET(func), 0, + CSTORM_SP_STATUS_BLOCK_SIZE); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_SYNC_BLOCK_OFFSET(func), 0, + CSTORM_SP_SYNC_BLOCK_SIZE); + +} + + +static inline +void bnx2x_setup_ndsb_state_machine(struct hc_status_block_sm *hc_sm, + int igu_sb_id, int igu_seg_id) +{ + hc_sm->igu_sb_id = igu_sb_id; + hc_sm->igu_seg_id = igu_seg_id; + hc_sm->timer_value = 0xFF; + hc_sm->time_to_expire = 0xFFFFFFFF; } -static void bnx2x_init_def_sb(struct bnx2x *bp, - struct host_def_status_block *def_sb, - dma_addr_t mapping, int sb_id) +void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, + u8 vf_valid, int fw_sb_id, int igu_sb_id) { + int igu_seg_id; + + struct hc_status_block_data_e1x sb_data_e1x; + struct hc_status_block_sm *hc_sm_p; + struct hc_index_data *hc_index_p; + int data_size; + u32 *sb_data_p; + + igu_seg_id = HC_SEG_ACCESS_NORM; + + bnx2x_zero_fp_sb(bp, fw_sb_id); + + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e1x.common.p_func.vf_id = 0xff; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_e1x.common.p_func.vnic_id = BP_E1HVN(bp); + sb_data_e1x.common.same_igu_sb_1b = true; + sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e1x.common.state_machine; + hc_index_p = sb_data_e1x.index_data; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + + + bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_RX_ID], + igu_sb_id, igu_seg_id); + bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_TX_ID], + igu_sb_id, igu_seg_id); + + DP(NETIF_MSG_HW, "Init FW SB %d\n", fw_sb_id); + + /* write indecies to HW */ + bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); +} + +static void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, + u8 sb_index, u8 disable, u16 usec) +{ + int port = BP_PORT(bp); + u8 ticks = usec / BNX2X_BTR; + + storm_memset_hc_timeout(bp, port, fw_sb_id, sb_index, ticks); + + disable = disable ? 1 : (usec ? 0 : 1); + storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable); +} + +static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u16 fw_sb_id, + u16 tx_usec, u16 rx_usec) +{ + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, U_SB_ETH_RX_CQ_INDEX, + false, rx_usec); + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, C_SB_ETH_TX_CQ_INDEX, + false, tx_usec); +} +static void bnx2x_init_def_sb(struct bnx2x *bp) +{ + struct host_sp_status_block *def_sb = bp->def_status_blk; + dma_addr_t mapping = bp->def_status_blk_mapping; + int igu_sp_sb_index; + int igu_seg_id; int port = BP_PORT(bp); int func = BP_FUNC(bp); - int index, val, reg_offset; + int reg_offset; u64 section; + int index; + struct hc_sp_status_block_data sp_sb_data; + memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); + + igu_sp_sb_index = DEF_SB_IGU_ID; + igu_seg_id = HC_SEG_ACCESS_DEF; /* ATTN */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, + section = ((u64)mapping) + offsetof(struct host_sp_status_block, atten_status_block); - def_sb->atten_status_block.status_block_id = sb_id; + def_sb->atten_status_block.status_block_id = igu_sp_sb_index; bp->attn_state = 0; reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); - for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { - bp->attn_group[index].sig[0] = REG_RD(bp, - reg_offset + 0x10*index); - bp->attn_group[index].sig[1] = REG_RD(bp, - reg_offset + 0x4 + 0x10*index); - bp->attn_group[index].sig[2] = REG_RD(bp, - reg_offset + 0x8 + 0x10*index); - bp->attn_group[index].sig[3] = REG_RD(bp, - reg_offset + 0xc + 0x10*index); + int sindex; + /* take care of sig[0]..sig[4] */ + for (sindex = 0; sindex < 4; sindex++) + bp->attn_group[index].sig[sindex] = + REG_RD(bp, reg_offset + sindex*0x4 + 0x10*index); } reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : HC_REG_ATTN_MSG0_ADDR_L); - REG_WR(bp, reg_offset, U64_LO(section)); REG_WR(bp, reg_offset + 4, U64_HI(section)); - reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0); + section = ((u64)mapping) + offsetof(struct host_sp_status_block, + sp_sb); - val = REG_RD(bp, reg_offset); - val |= sb_id; - REG_WR(bp, reg_offset, val); + bnx2x_zero_sp_sb(bp); - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - u_def_status_block); - def_sb->u_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_USB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), func); - - for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(func, index), 1); + sp_sb_data.host_sb_addr.lo = U64_LO(section); + sp_sb_data.host_sb_addr.hi = U64_HI(section); + sp_sb_data.igu_sb_id = igu_sp_sb_index; + sp_sb_data.igu_seg_id = igu_seg_id; + sp_sb_data.p_func.pf_id = func; + sp_sb_data.p_func.vnic_id = BP_E1HVN(bp); + sp_sb_data.p_func.vf_id = 0xff; - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - c_def_status_block); - def_sb->c_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), func); - - for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(func, index), 1); - - /* TSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - t_def_status_block); - def_sb->t_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_TSTRORM_INTMEM + - ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); - - for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); - - /* XSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - x_def_status_block); - def_sb->x_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_XSTRORM_INTMEM + - ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); - - for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + bnx2x_wr_sp_sb_data(bp, &sp_sb_data); bp->stats_pending = 0; bp->set_mac_pending = 0; - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); } void bnx2x_update_coalesce(struct bnx2x *bp) { - int port = BP_PORT(bp); int i; - for_each_queue(bp, i) { - int sb_id = bp->fp[i].sb_id; - - /* HC_INDEX_U_ETH_RX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - bp->rx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - (bp->rx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); - - /* HC_INDEX_C_ETH_TX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - bp->tx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - (bp->tx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); - } + for_each_queue(bp, i) + bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id, + bp->rx_ticks, bp->tx_ticks); } static void bnx2x_init_sp_ring(struct bnx2x *bp) { - int func = BP_FUNC(bp); - spin_lock_init(&bp->spq_lock); bp->spq_left = MAX_SPQ_PENDING; @@ -2969,91 +3743,25 @@ static void bnx2x_init_sp_ring(struct bnx2x *bp) bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; bp->spq_prod_bd = bp->spq; bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT; - - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func), - U64_LO(bp->spq_mapping)); - REG_WR(bp, - XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4, - U64_HI(bp->spq_mapping)); - - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); } -static void bnx2x_init_context(struct bnx2x *bp) +static void bnx2x_init_eq_ring(struct bnx2x *bp) { int i; + for (i = 1; i <= NUM_EQ_PAGES; i++) { + union event_ring_elem *elem = + &bp->eq_ring[EQ_DESC_CNT_PAGE * i - 1]; - /* Rx */ - for_each_queue(bp, i) { - struct eth_context *context = bnx2x_sp(bp, context[i].eth); - struct bnx2x_fastpath *fp = &bp->fp[i]; - u8 cl_id = fp->cl_id; - - context->ustorm_st_context.common.sb_index_numbers = - BNX2X_RX_SB_INDEX_NUM; - context->ustorm_st_context.common.clientId = cl_id; - context->ustorm_st_context.common.status_block_id = fp->sb_id; - context->ustorm_st_context.common.flags = - (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT | - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS); - context->ustorm_st_context.common.statistics_counter_id = - cl_id; - context->ustorm_st_context.common.mc_alignment_log_size = - BNX2X_RX_ALIGN_SHIFT; - context->ustorm_st_context.common.bd_buff_size = - bp->rx_buf_size; - context->ustorm_st_context.common.bd_page_base_hi = - U64_HI(fp->rx_desc_mapping); - context->ustorm_st_context.common.bd_page_base_lo = - U64_LO(fp->rx_desc_mapping); - if (!fp->disable_tpa) { - context->ustorm_st_context.common.flags |= - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA; - context->ustorm_st_context.common.sge_buff_size = - (u16)min_t(u32, SGE_PAGE_SIZE*PAGES_PER_SGE, - 0xffff); - context->ustorm_st_context.common.sge_page_base_hi = - U64_HI(fp->rx_sge_mapping); - context->ustorm_st_context.common.sge_page_base_lo = - U64_LO(fp->rx_sge_mapping); - - context->ustorm_st_context.common.max_sges_for_packet = - SGE_PAGE_ALIGN(bp->dev->mtu) >> SGE_PAGE_SHIFT; - context->ustorm_st_context.common.max_sges_for_packet = - ((context->ustorm_st_context.common. - max_sges_for_packet + PAGES_PER_SGE - 1) & - (~(PAGES_PER_SGE - 1))) >> PAGES_PER_SGE_SHIFT; - } - - context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); - - context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); - } - - /* Tx */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - struct eth_context *context = - bnx2x_sp(bp, context[i].eth); - - context->cstorm_st_context.sb_index_number = - C_SB_ETH_TX_CQ_INDEX; - context->cstorm_st_context.status_block_id = fp->sb_id; - - context->xstorm_st_context.tx_bd_page_base_hi = - U64_HI(fp->tx_desc_mapping); - context->xstorm_st_context.tx_bd_page_base_lo = - U64_LO(fp->tx_desc_mapping); - context->xstorm_st_context.statistics_data = (fp->cl_id | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE); + elem->next_page.addr.hi = + cpu_to_le32(U64_HI(bp->eq_mapping + + BCM_PAGE_SIZE * (i % NUM_EQ_PAGES))); + elem->next_page.addr.lo = + cpu_to_le32(U64_LO(bp->eq_mapping + + BCM_PAGE_SIZE*(i % NUM_EQ_PAGES))); } + bp->eq_cons = 0; + bp->eq_prod = NUM_EQ_DESC; + bp->eq_cons_sb = BNX2X_EQ_INDEX; } static void bnx2x_init_ind_table(struct bnx2x *bp) @@ -3072,47 +3780,11 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) bp->fp->cl_id + (i % bp->num_queues)); } -void bnx2x_set_client_config(struct bnx2x *bp) -{ - struct tstorm_eth_client_config tstorm_client = {0}; - int port = BP_PORT(bp); - int i; - - tstorm_client.mtu = bp->dev->mtu; - tstorm_client.config_flags = - (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE | - TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE); -#ifdef BCM_VLAN - if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE; - DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); - } -#endif - - for_each_queue(bp, i) { - tstorm_client.statistics_counter_id = bp->fp[i].cl_id; - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id), - ((u32 *)&tstorm_client)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4, - ((u32 *)&tstorm_client)[1]); - } - - DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n", - ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); -} - void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { - struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0}; int mode = bp->rx_mode; - int mask = bp->rx_mode_cl_mask; - int func = BP_FUNC(bp); - int port = BP_PORT(bp); - int i; + u16 cl_id; + /* All but management unicast packets should pass to the host as well */ u32 llh_mask = NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | @@ -3120,28 +3792,32 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; - DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask); - switch (mode) { case BNX2X_RX_MODE_NONE: /* no Rx */ - tstorm_mac_filter.ucast_drop_all = mask; - tstorm_mac_filter.mcast_drop_all = mask; - tstorm_mac_filter.bcast_drop_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); break; case BNX2X_RX_MODE_NORMAL: - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_MULTICAST); break; case BNX2X_RX_MODE_ALLMULTI: - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST); break; case BNX2X_RX_MODE_PROMISC: - tstorm_mac_filter.ucast_accept_all = mask; - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_PROMISCUOUS_MODE); + /* pass management unicast packets as well */ llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; break; @@ -3152,256 +3828,52 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) } REG_WR(bp, - (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK), + BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK, llh_mask); - for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) { - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4, - ((u32 *)&tstorm_mac_filter)[i]); - -/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, - ((u32 *)&tstorm_mac_filter)[i]); */ - } + DP(NETIF_MSG_IFUP, "rx mode %d\n" + "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" + "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n", mode, + bp->mac_filters.ucast_drop_all, + bp->mac_filters.mcast_drop_all, + bp->mac_filters.bcast_drop_all, + bp->mac_filters.ucast_accept_all, + bp->mac_filters.mcast_accept_all, + bp->mac_filters.bcast_accept_all + ); - if (mode != BNX2X_RX_MODE_NONE) - bnx2x_set_client_config(bp); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); } static void bnx2x_init_internal_common(struct bnx2x *bp) { int i; - /* Zero this manually as its initialization is - currently missing in the initTool */ - for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_AGG_DATA_OFFSET + i * 4, 0); -} - -static void bnx2x_init_internal_port(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_U_OFFSET(port), BNX2X_BTR); - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_C_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); -} - -static void bnx2x_init_internal_func(struct bnx2x *bp) -{ - struct tstorm_eth_function_common_config tstorm_config = {0}; - struct stats_indication_flags stats_flags = {0}; - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int i, j; - u32 offset; - u16 max_agg_size; - - tstorm_config.config_flags = RSS_FLAGS(bp); - - if (is_multi(bp)) - tstorm_config.rss_result_mask = MULTI_MASK; - - /* Enable TPA if needed */ - if (bp->flags & TPA_ENABLE_FLAG) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - - if (IS_E1HMF(bp)) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM; - - tstorm_config.leading_client_id = BP_L_ID(bp); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func), - (*(u32 *)&tstorm_config)); - - bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ - bp->rx_mode_cl_mask = (1 << BP_L_ID(bp)); - bnx2x_set_storm_rx_mode(bp); - - for_each_queue(bp, i) { - u8 cl_id = bp->fp[i].cl_id; - - /* reset xstorm per client statistics */ - offset = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct xstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - - /* reset tstorm per client statistics */ - offset = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct tstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - - /* reset ustorm per client statistics */ - offset = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct ustorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - } - - /* Init statistics related context */ - stats_flags.collect_eth = 1; - - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); - - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + if (!CHIP_IS_E1(bp)) { - if (CHIP_IS_E1H(bp)) { + /* xstorm needs to know whether to add ovlan to packets or not, + * in switch-independent we'll write 0 to here... */ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->e1hmf); REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->e1hmf); REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->e1hmf); REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); - - REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func), - bp->e1hov); + bp->e1hmf); } - /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */ - max_agg_size = min_t(u32, (min_t(u32, 8, MAX_SKB_FRAGS) * - SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping)); - - /* Next page */ - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping + BCM_PAGE_SIZE)); + /* Zero this manually as its initialization is + currently missing in the initTool */ + for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping + BCM_PAGE_SIZE)); - - REG_WR16(bp, BAR_USTRORM_INTMEM + - USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id), - max_agg_size); - } - - /* dropless flow control */ - if (CHIP_IS_E1H(bp)) { - struct ustorm_eth_rx_pause_data_e1h rx_pause = {0}; - - rx_pause.bd_thr_low = 250; - rx_pause.cqe_thr_low = 250; - rx_pause.cos = 1; - rx_pause.sge_thr_low = 0; - rx_pause.bd_thr_high = 350; - rx_pause.cqe_thr_high = 350; - rx_pause.sge_thr_high = 0; - - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - if (!fp->disable_tpa) { - rx_pause.sge_thr_low = 150; - rx_pause.sge_thr_high = 250; - } - - - offset = BAR_USTRORM_INTMEM + - USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, - fp->cl_id); - for (j = 0; - j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4; - j++) - REG_WR(bp, offset + j*4, - ((u32 *)&rx_pause)[j]); - } - } - - memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); - - /* Init rate shaping and fairness contexts */ - if (IS_E1HMF(bp)) { - int vn; - - /* During init there is no active link - Until link is up, set link rate to 10Gbps */ - bp->link_vars.line_speed = SPEED_10000; - bnx2x_init_port_minmax(bp); - - if (!BP_NOMCP(bp)) - bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); - bnx2x_calc_vn_weight_sum(bp); - - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); - - /* Enable rate shaping and fairness */ - bp->cmng.flags.cmng_enables |= - CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; - - } else { - /* rate shaping and fairness are disabled */ - DP(NETIF_MSG_IFUP, - "single function mode minmax will be disabled\n"); - } - + USTORM_AGG_DATA_OFFSET + i * 4, 0); +} - /* Store cmng structures to internal memory */ - if (bp->port.pmf) - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4, - ((u32 *)(&bp->cmng))[i]); +static void bnx2x_init_internal_port(struct bnx2x *bp) +{ + /* port */ } static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) @@ -3416,7 +3888,8 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) /* no break */ case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bnx2x_init_internal_func(bp); + /* internal memory per function is + initialized inside bnx2x_pf_init */ break; default: @@ -3425,43 +3898,61 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) } } +static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx) +{ + struct bnx2x_fastpath *fp = &bp->fp[fp_idx]; + + fp->state = BNX2X_FP_STATE_CLOSED; + + fp->index = fp->cid = fp_idx; + fp->cl_id = BP_L_ID(bp) + fp_idx; + fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE; + fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; + /* qZone id equals to FW (per path) client id */ + fp->cl_qzone_id = fp->cl_id + + BP_PORT(bp)*(ETH_MAX_RX_CLIENTS_E1H); + /* init shortcut */ + fp->ustorm_rx_prods_offset = + USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); + /* Setup SB indicies */ + fp->rx_cons_sb = BNX2X_RX_SB_INDEX; + fp->tx_cons_sb = BNX2X_TX_SB_INDEX; + + DP(NETIF_MSG_IFUP, "queue[%d]: bnx2x_init_sb(%p,%p) " + "cl_id %d fw_sb %d igu_sb %d\n", + fp_idx, bp, fp->status_blk.e1x_sb, fp->cl_id, fp->fw_sb_id, + fp->igu_sb_id); + bnx2x_init_sb(bp, fp->status_blk_mapping, BNX2X_VF_ID_INVALID, false, + fp->fw_sb_id, fp->igu_sb_id); + + bnx2x_update_fpsb_idx(fp); +} + void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) { int i; - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - fp->bp = bp; - fp->state = BNX2X_FP_STATE_CLOSED; - fp->index = i; - fp->cl_id = BP_L_ID(bp) + i; + for_each_queue(bp, i) + bnx2x_init_fp_sb(bp, i); #ifdef BCM_CNIC - fp->sb_id = fp->cl_id + 1; -#else - fp->sb_id = fp->cl_id; + + bnx2x_init_sb(bp, bp->cnic_sb_mapping, + BNX2X_VF_ID_INVALID, false, + CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); + #endif - DP(NETIF_MSG_IFUP, - "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n", - i, bp, fp->status_blk, fp->cl_id, fp->sb_id); - bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, - fp->sb_id); - bnx2x_update_fpsb_idx(fp); - } /* ensure status block indices were read */ rmb(); - - bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping, - DEF_SB_ID); + bnx2x_init_def_sb(bp); bnx2x_update_dsb_idx(bp); - bnx2x_update_coalesce(bp); bnx2x_init_rx_rings(bp); - bnx2x_init_tx_ring(bp); + bnx2x_init_tx_rings(bp); bnx2x_init_sp_ring(bp); - bnx2x_init_context(bp); + bnx2x_init_eq_ring(bp); bnx2x_init_internal(bp, load_code); + bnx2x_pf_init(bp); bnx2x_init_ind_table(bp); bnx2x_stats_init(bp); @@ -3620,8 +4111,6 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) else factor = 1; - DP(NETIF_MSG_HW, "start part1\n"); - /* Disable inputs of parser neighbor blocks */ REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); @@ -3917,12 +4406,9 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); } -static int bnx2x_init_common(struct bnx2x *bp) +static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) { u32 val, i; -#ifdef BCM_CNIC - u32 wb_write[2]; -#endif DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp)); @@ -3964,12 +4450,8 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); #endif - REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2); -#ifdef BCM_CNIC - REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5); -#endif + bnx2x_ilt_init_page_size(bp, INITOP_SET); + if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1); @@ -4009,20 +4491,9 @@ static int bnx2x_init_common(struct bnx2x *bp) bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); -#ifdef BCM_CNIC - wb_write[0] = 0; - wb_write[1] = 0; - for (i = 0; i < 64; i++) { - REG_WR(bp, QM_REG_BASEADDR + i*4, 1024 * 4 * (i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, wb_write, 2); - - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, 1024*4*(i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, - wb_write, 2); - } - } -#endif + /* QM queues pointers table */ + bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); + /* soft reset pulse */ REG_WR(bp, QM_REG_SOFT_RESET, 1); REG_WR(bp, QM_REG_SOFT_RESET, 0); @@ -4032,7 +4503,8 @@ static int bnx2x_init_common(struct bnx2x *bp) #endif bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE); - REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT); + REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT); + if (!CHIP_REV_IS_SLOW(bp)) { /* enable hw interrupt from doorbell Q */ REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); @@ -4184,7 +4656,7 @@ static int bnx2x_init_common(struct bnx2x *bp) return 0; } -static int bnx2x_init_port(struct bnx2x *bp) +static int bnx2x_init_hw_port(struct bnx2x *bp) { int port = BP_PORT(bp); int init_stage = port ? PORT1_STAGE : PORT0_STAGE; @@ -4203,9 +4675,10 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, CCM_BLOCK, init_stage); bnx2x_init_block(bp, XCM_BLOCK, init_stage); -#ifdef BCM_CNIC - REG_WR(bp, QM_REG_CONNNUM_0 + port*4, 1024/16 - 1); + /* QM cid (connection) count */ + bnx2x_qm_init_cid_count(bp, bp->qm_cid_count, INITOP_SET); +#ifdef BCM_CNIC bnx2x_init_block(bp, TIMERS_BLOCK, init_stage); REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); @@ -4327,25 +4800,6 @@ static int bnx2x_init_port(struct bnx2x *bp) return 0; } -#define ILT_PER_FUNC (768/2) -#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) -/* the phys address is shifted right 12 bits and has an added - 1=valid bit added to the 53rd bit - then since this is a wide register(TM) - we split it into two 32 bit writes - */ -#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) -#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) -#define PXP_ONE_ILT(x) (((x) << 10) | x) -#define PXP_ILT_RANGE(f, l) (((l) << 10) | f) - -#ifdef BCM_CNIC -#define CNIC_ILT_LINES 127 -#define CNIC_CTX_PER_ILT 16 -#else -#define CNIC_ILT_LINES 0 -#endif - static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) { int reg; @@ -4358,10 +4812,12 @@ static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr)); } -static int bnx2x_init_func(struct bnx2x *bp) +static int bnx2x_init_hw_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); + struct bnx2x_ilt *ilt = BP_ILT(bp); + u16 cdu_ilt_start; u32 addr, val; int i; @@ -4373,72 +4829,67 @@ static int bnx2x_init_func(struct bnx2x *bp) val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; REG_WR(bp, addr, val); - i = FUNC_ILT_BASE(func); - - bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context)); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES); - } else /* E1 */ - REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, - PXP_ILT_RANGE(i, i + CNIC_ILT_LINES)); - -#ifdef BCM_CNIC - i += 1 + CNIC_ILT_LINES; - bnx2x_ilt_wr(bp, i, bp->timers_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_TM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_TM_LAST_ILT, i); - } - - i++; - bnx2x_ilt_wr(bp, i, bp->qm_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_QM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_QM_LAST_ILT, i); - } + ilt = BP_ILT(bp); + cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; - i++; - bnx2x_ilt_wr(bp, i, bp->t1_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_SRC_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_SRC_LAST_ILT, i); + for (i = 0; i < L2_ILT_LINES(bp); i++) { + ilt->lines[cdu_ilt_start + i].page = + bp->context.vcxt + (ILT_PAGE_CIDS * i); + ilt->lines[cdu_ilt_start + i].page_mapping = + bp->context.cxt_mapping + (CDU_ILT_PAGE_SZ * i); + /* cdu ilt pages are allocated manually so there's no need to + set the size */ } + bnx2x_ilt_init_op(bp, INITOP_SET); +#ifdef BCM_CNIC + bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM); - /* tell the searcher where the T2 table is */ - REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, 16*1024/64); - - bnx2x_wb_wr(bp, SRC_REG_FIRSTFREE0 + port*16, - U64_LO(bp->t2_mapping), U64_HI(bp->t2_mapping)); + /* T1 hash bits value determines the T1 number of entries */ + REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, SRC_HASH_BITS); +#endif - bnx2x_wb_wr(bp, SRC_REG_LASTFREE0 + port*16, - U64_LO((u64)bp->t2_mapping + 16*1024 - 64), - U64_HI((u64)bp->t2_mapping + 16*1024 - 64)); +#ifndef BCM_CNIC + /* set NIC mode */ + REG_WR(bp, PRS_REG_NIC_MODE, 1); +#endif /* BCM_CNIC */ - REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, 10); -#endif + bp->dmae_ready = 1; - if (CHIP_IS_E1H(bp)) { - bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PGLUE_B_BLOCK, FUNC0_STAGE + func); + + bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + + bnx2x_init_block(bp, QM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TIMERS_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DQ_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BRB1_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PRS_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, USDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, UPB_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XPB_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PBF_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CDU_BLOCK, FUNC0_STAGE + func); + + bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); + if (IS_E1HMF(bp)) { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); } + bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); + /* HC init per function */ if (CHIP_IS_E1H(bp)) { REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); @@ -4451,13 +4902,21 @@ static int bnx2x_init_func(struct bnx2x *bp) /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); REG_WR(bp, 0x2120, 0xffffffff); + + bnx2x_init_block(bp, EMAC0_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, EMAC1_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DBU_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DBG_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, MCP_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func); + bnx2x_phy_probe(&bp->link_params); return 0; } int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) { - int i, rc = 0; + int rc = 0; DP(BNX2X_MSG_MCP, "function %d load_code %x\n", BP_FUNC(bp), load_code); @@ -4470,21 +4929,19 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: - rc = bnx2x_init_common(bp); + rc = bnx2x_init_hw_common(bp, load_code); if (rc) goto init_hw_err; /* no break */ case FW_MSG_CODE_DRV_LOAD_PORT: - bp->dmae_ready = 1; - rc = bnx2x_init_port(bp); + rc = bnx2x_init_hw_port(bp); if (rc) goto init_hw_err; /* no break */ case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bp->dmae_ready = 1; - rc = bnx2x_init_func(bp); + rc = bnx2x_init_hw_func(bp); if (rc) goto init_hw_err; break; @@ -4503,14 +4960,6 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); } - /* this needs to be done before gunzip end */ - bnx2x_zero_def_sb(bp); - for_each_queue(bp, i) - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#ifdef BCM_CNIC - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#endif - init_hw_err: bnx2x_gunzip_end(bp); @@ -4523,7 +4972,7 @@ void bnx2x_free_mem(struct bnx2x *bp) #define BNX2X_PCI_FREE(x, y, size) \ do { \ if (x) { \ - dma_free_coherent(&bp->pdev->dev, size, x, y); \ + dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \ x = NULL; \ y = 0; \ } \ @@ -4532,7 +4981,7 @@ void bnx2x_free_mem(struct bnx2x *bp) #define BNX2X_FREE(x) \ do { \ if (x) { \ - vfree(x); \ + kfree((void *)x); \ x = NULL; \ } \ } while (0) @@ -4542,11 +4991,10 @@ void bnx2x_free_mem(struct bnx2x *bp) /* fastpath */ /* Common */ for_each_queue(bp, i) { - /* status blocks */ - BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk), + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); + sizeof(struct host_hc_status_block_e1x)); } /* Rx */ for_each_queue(bp, i) { @@ -4580,21 +5028,28 @@ void bnx2x_free_mem(struct bnx2x *bp) /* end of fastpath */ BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); + sizeof(struct host_sp_status_block)); BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, sizeof(struct bnx2x_slowpath)); + BNX2X_PCI_FREE(bp->context.vcxt, bp->context.cxt_mapping, + bp->context.size); + + bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); + + BNX2X_FREE(bp->ilt->lines); #ifdef BCM_CNIC - BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024); - BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024); - BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024); - BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024); - BNX2X_PCI_FREE(bp->cnic_sb, bp->cnic_sb_mapping, - sizeof(struct host_status_block)); + + BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); + BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); #endif BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); + BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, + BCM_PAGE_SIZE * NUM_EQ_PAGES); + #undef BNX2X_PCI_FREE #undef BNX2X_KFREE } @@ -4612,13 +5067,13 @@ int bnx2x_alloc_mem(struct bnx2x *bp) #define BNX2X_ALLOC(x, size) \ do { \ - x = vmalloc(size); \ + x = kzalloc(size, GFP_KERNEL); \ if (x == NULL) \ goto alloc_mem_err; \ - memset(x, 0, size); \ } while (0) int i; + void *p; /* fastpath */ /* Common */ @@ -4626,9 +5081,17 @@ int bnx2x_alloc_mem(struct bnx2x *bp) bnx2x_fp(bp, i, bp) = bp; /* status blocks */ - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk), + BNX2X_PCI_ALLOC(p, &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); + sizeof(struct host_hc_status_block_e1x)); + + bnx2x_fp(bp, i, status_blk.e1x_sb) = + (struct host_hc_status_block_e1x *)p; + + bnx2x_fp(bp, i, sb_index_values) = (__le16 *) + (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.index_values); + bnx2x_fp(bp, i, sb_running_index) = (__le16 *) + (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.running_index); } /* Rx */ for_each_queue(bp, i) { @@ -4664,37 +5127,36 @@ int bnx2x_alloc_mem(struct bnx2x *bp) } /* end of fastpath */ - BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); +#ifdef BCM_CNIC + BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); - BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, - sizeof(struct bnx2x_slowpath)); + /* allocate searcher T2 table */ + BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); +#endif -#ifdef BCM_CNIC - BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024); - /* allocate searcher T2 table - we allocate 1/4 of alloc num for T2 - (which is not entered into the ILT) */ - BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024); + BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, + sizeof(struct host_sp_status_block)); - /* Initialize T2 (for 1024 connections) */ - for (i = 0; i < 16*1024; i += 64) - *(u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; + BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, + sizeof(struct bnx2x_slowpath)); - /* Timer block array (8*MAX_CONN) phys uncached for now 1024 conns */ - BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024); + bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count; + BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, + bp->context.size); - /* QM queues (128*MAX_CONN) */ - BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024); + BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); - BNX2X_PCI_ALLOC(bp->cnic_sb, &bp->cnic_sb_mapping, - sizeof(struct host_status_block)); -#endif + if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) + goto alloc_mem_err; /* Slow path ring */ BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE); + /* EQ */ + BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, + BCM_PAGE_SIZE * NUM_EQ_PAGES); return 0; alloc_mem_err: @@ -4705,97 +5167,52 @@ alloc_mem_err: #undef BNX2X_ALLOC } - /* * Init service functions */ - -/** - * Sets a MAC in a CAM for a few L2 Clients for E1 chip - * - * @param bp driver descriptor - * @param set set or clear an entry (1 or 0) - * @param mac pointer to a buffer containing a MAC - * @param cl_bit_vec bit vector of clients to register a MAC for - * @param cam_offset offset in a CAM to use - * @param with_bcast set broadcast MAC as well - */ -static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 with_bcast) +int bnx2x_func_start(struct bnx2x *bp) { - struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); - int port = BP_PORT(bp); - - /* CAM allocation - * unicasts 0-31:port0 32-63:port1 - * multicast 64-127:port0 128-191:port1 - */ - config->hdr.length = 1 + (with_bcast ? 1 : 0); - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 0, 0, 1); - /* primary MAC */ - config->config_table[0].cam_entry.msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].cam_entry.middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].cam_entry.lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[0].target_table_entry.flags = 0; - else - CAM_INVALIDATE(config->config_table[0]); - config->config_table[0].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].target_table_entry.vlan_id = 0; + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_STATE_FUNC_STARTED, 0, &(bp->state), + WAIT_RAMROD_COMMON); +} - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n", - (set ? "setting" : "clearing"), - config->config_table[0].cam_entry.msb_mac_addr, - config->config_table[0].cam_entry.middle_mac_addr, - config->config_table[0].cam_entry.lsb_mac_addr); - - /* broadcast */ - if (with_bcast) { - config->config_table[1].cam_entry.msb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.middle_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.lsb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[1].target_table_entry.flags = - TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST; - else - CAM_INVALIDATE(config->config_table[1]); - config->config_table[1].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[1].target_table_entry.vlan_id = 0; - } +int bnx2x_func_stop(struct bnx2x *bp) +{ + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0, 0, 1); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_STATE_CLOSING_WAIT4_UNLOAD, + 0, &(bp->state), WAIT_RAMROD_COMMON); } /** - * Sets a MAC in a CAM for a few L2 Clients for E1H chip + * Sets a MAC in a CAM for a few L2 Clients for E1x chip * * @param bp driver descriptor * @param set set or clear an entry (1 or 0) * @param mac pointer to a buffer containing a MAC * @param cl_bit_vec bit vector of clients to register a MAC for * @param cam_offset offset in a CAM to use + * @param is_bcast is the set MAC a broadcast address (for E1 only) */ -static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset) +static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast) { - struct mac_configuration_cmd_e1h *config = - (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config); + struct mac_configuration_cmd *config = + (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; + smp_wmb(); + + config->hdr.length = 1 + (is_bcast ? 1 : 0); + config->hdr.offset = cam_offset; + config->hdr.client_id = 0xff; + config->hdr.reserved1 = 0; config->hdr.length = 1; config->hdr.offset = cam_offset; @@ -4812,29 +5229,42 @@ static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, config->config_table[0].clients_bit_vector = cpu_to_le32(cl_bit_vec); config->config_table[0].vlan_id = 0; - config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov); + config->config_table[0].pf_id = BP_FUNC(bp); if (set) - config->config_table[0].flags = BP_PORT(bp); + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); else - config->config_table[0].flags = - MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE; + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID mask %d\n", + if (is_bcast) + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_BROADCAST, 1); + + DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", (set ? "setting" : "clearing"), config->config_table[0].msb_mac_addr, config->config_table[0].middle_mac_addr, - config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec); + config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); } -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int poll) + +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags) { /* can take a while if any port is running */ int cnt = 5000; + u8 poll = flags & WAIT_RAMROD_POLL; + u8 common = flags & WAIT_RAMROD_COMMON; DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", poll ? "polling" : "waiting", state, idx); @@ -4842,13 +5272,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, might_sleep(); while (cnt--) { if (poll) { - bnx2x_rx_int(bp->fp, 10); - /* if index is different from 0 - * the reply for some commands will - * be on the non default queue - */ - if (idx) - bnx2x_rx_int(&bp->fp[idx], 10); + if (common) + bnx2x_eq_int(bp); + else { + bnx2x_rx_int(bp->fp, 10); + /* if index is different from 0 + * the reply for some commands will + * be on the non default queue + */ + if (idx) + bnx2x_rx_int(&bp->fp[idx], 10); + } } mb(); /* state is changed by bnx2x_sp_event() */ @@ -4875,31 +5309,110 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, return -EBUSY; } -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set) +u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) { - bp->set_mac_pending++; - smp_wmb(); + return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); +} + +void bnx2x_set_eth_mac(struct bnx2x *bp, int set) +{ + u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : + bnx2x_e1h_cam_offset(bp, CAM_ETH_LINE)); - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), BP_FUNC(bp)); + /* networking MAC */ + bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, + (1 << bp->fp->cl_id), cam_offset , 0); - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + if (CHIP_IS_E1(bp)) { + /* broadcast MAC */ + u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1); + } } +static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset) +{ + int i = 0, old; + struct net_device *dev = bp->dev; + struct netdev_hw_addr *ha; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + + netdev_for_each_mc_addr(ha, dev) { + /* copy mac */ + config_cmd->config_table[i].msb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); + config_cmd->config_table[i].middle_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); + config_cmd->config_table[i].lsb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) + config_cmd->config_table[i].vlan_id = 0; + config_cmd->config_table[i].pf_id = BP_FUNC(bp); + config_cmd->config_table[i].clients_bit_vector = + cpu_to_le32(1 << BP_L_ID(bp)); + + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + + DP(NETIF_MSG_IFUP, + "setting MCAST[%d] (%04x:%04x:%04x)\n", i, + config_cmd->config_table[i].msb_mac_addr, + config_cmd->config_table[i].middle_mac_addr, + config_cmd->config_table[i].lsb_mac_addr); + i++; + } + old = config_cmd->hdr.length; + if (old > i) { + for (; i < old; i++) { + if (CAM_IS_INVALID(config_cmd-> + config_table[i])) { + /* already invalidated */ + break; + } + /* invalidate */ + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + } + } + + config_cmd->hdr.length = i; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + config_cmd->hdr.reserved1 = 0; + + bp->set_mac_pending = 1; + smp_wmb(); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); +} +static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp) { - bp->set_mac_pending++; + int i; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; smp_wmb(); - bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0), - 1); + for (i = 0; i < config_cmd->hdr.length; i++) + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, + ramrod_flags); + } + #ifdef BCM_CNIC /** * Set iSCSI MAC(s) at the next enties in the CAM after the ETH @@ -4913,65 +5426,181 @@ void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) */ int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) { - u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID); - - bp->set_mac_pending++; - smp_wmb(); + u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) : + bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE)); + u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID; + u32 cl_bit_vec = (1 << iscsi_l2_cl_id); /* Send a SET_MAC ramrod */ - if (CHIP_IS_E1(bp)) - bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2, - 1); - else - /* CAM allocation for E1H - * unicasts: by func number - * multicast: 20+FUNC*20, 20 each - */ - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp)); - - /* Wait for a completion when setting */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); - + bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, + cam_offset, 0); return 0; } #endif -int bnx2x_setup_leading(struct bnx2x *bp) -{ - int rc; +static void bnx2x_fill_cl_init_data(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data) +{ + /* Clear the buffer */ + memset(data, 0, sizeof(*data)); + + /* general */ + data->general.client_id = params->rxq_params.cl_id; + data->general.statistics_counter_id = params->rxq_params.stat_id; + data->general.statistics_en_flg = + (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; + data->general.activate_flg = activate; + data->general.sp_client_id = params->rxq_params.spcl_id; + + /* Rx data */ + data->rx.tpa_en_flg = + (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; + data->rx.vmqueue_mode_en_flg = 0; + data->rx.cache_line_alignment_log_size = + params->rxq_params.cache_line_log; + data->rx.enable_dynamic_hc = + (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; + data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; + data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; + data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; + + /* We don't set drop flags */ + data->rx.drop_ip_cs_err_flg = 0; + data->rx.drop_tcp_cs_err_flg = 0; + data->rx.drop_ttl0_flg = 0; + data->rx.drop_udp_cs_err_flg = 0; + + data->rx.inner_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; + data->rx.outer_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; + data->rx.status_block_id = params->rxq_params.fw_sb_id; + data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; + data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); + data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); + data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); + data->rx.bd_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); + data->rx.bd_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); + data->rx.sge_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.sge_map)); + data->rx.sge_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.sge_map)); + data->rx.cqe_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); + data->rx.cqe_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); + data->rx.is_leading_rss = + (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; + data->rx.is_approx_mcast = data->rx.is_leading_rss; + + /* Tx data */ + data->tx.enforce_security_flg = 0; /* VF specific */ + data->tx.tx_status_block_id = params->txq_params.fw_sb_id; + data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; + data->tx.mtu = 0; /* VF specific */ + data->tx.tx_bd_page_base.lo = + cpu_to_le32(U64_LO(params->txq_params.dscr_map)); + data->tx.tx_bd_page_base.hi = + cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + + /* flow control data */ + data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); + data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); + data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); + data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); + data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); + data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); + data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); + + data->fc.safc_group_num = params->txq_params.cos; + data->fc.safc_group_en_flg = + (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; + data->fc.traffic_type = LLFC_TRAFFIC_TYPE_NW; +} + +static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) +{ + /* ustorm cxt validation */ + cxt->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, + ETH_CONNECTION_TYPE); + /* xcontext validation */ + cxt->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, + ETH_CONNECTION_TYPE); +} + +int bnx2x_setup_fw_client(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data, + dma_addr_t data_mapping) +{ + u16 hc_usec; + int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; + int ramrod_flags = 0, rc; + + /* HC and context validation values */ + hc_usec = params->txq_params.hc_rate ? + 1000000 / params->txq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->txq_params.fw_sb_id, + params->txq_params.sb_cq_index, + !(params->txq_params.flags & QUEUE_FLG_HC), + hc_usec); + + *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; + + hc_usec = params->rxq_params.hc_rate ? + 1000000 / params->rxq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->rxq_params.fw_sb_id, + params->rxq_params.sb_cq_index, + !(params->rxq_params.flags & QUEUE_FLG_HC), + hc_usec); + + bnx2x_set_ctx_validation(params->rxq_params.cxt, + params->rxq_params.cid); + + /* zero stats */ + if (params->txq_params.flags & QUEUE_FLG_STATS) + storm_memset_xstats_zero(bp, BP_PORT(bp), + params->txq_params.stat_id); + + if (params->rxq_params.flags & QUEUE_FLG_STATS) { + storm_memset_ustats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + storm_memset_tstats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + } + + /* Fill the ramrod data */ + bnx2x_fill_cl_init_data(bp, params, activate, data); + + /* SETUP ramrod. + * + * bnx2x_sp_post() takes a spin_lock thus no other explict memory + * barrier except from mmiowb() is needed to impose a + * proper ordering of memory operations. + */ + mmiowb(); - /* reset IGU state */ - bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); - /* SETUP ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0); + bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, + U64_HI(data_mapping), U64_LO(data_mapping), 0); /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0); - + rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, + params->ramrod_params.index, + params->ramrod_params.pstate, + ramrod_flags); return rc; } -int bnx2x_setup_multi(struct bnx2x *bp, int index) -{ - struct bnx2x_fastpath *fp = &bp->fp[index]; - - /* reset IGU state */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); - - /* SETUP ramrod */ - fp->state = BNX2X_FP_STATE_OPENING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, - fp->cl_id, 0); - - /* Wait for completion */ - return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, - &(fp->state), 0); -} - - void bnx2x_set_num_queues_msix(struct bnx2x *bp) { @@ -4996,87 +5625,217 @@ void bnx2x_set_num_queues_msix(struct bnx2x *bp) } } +void bnx2x_ilt_set_info(struct bnx2x *bp) +{ + struct ilt_client_info *ilt_client; + struct bnx2x_ilt *ilt = BP_ILT(bp); + u16 line = 0; + + ilt->start_line = FUNC_ILT_BASE(BP_FUNC(bp)); + DP(BNX2X_MSG_SP, "ilt starts at line %d\n", ilt->start_line); + + /* CDU */ + ilt_client = &ilt->clients[ILT_CLIENT_CDU]; + ilt_client->client_num = ILT_CLIENT_CDU; + ilt_client->page_size = CDU_ILT_PAGE_SZ; + ilt_client->flags = ILT_CLIENT_SKIP_MEM; + ilt_client->start = line; + line += L2_ILT_LINES(bp); +#ifdef BCM_CNIC + line += CNIC_ILT_LINES; +#endif + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[CDU]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + + /* QM */ + if (QM_INIT(bp->qm_cid_count)) { + ilt_client = &ilt->clients[ILT_CLIENT_QM]; + ilt_client->client_num = ILT_CLIENT_QM; + ilt_client->page_size = QM_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + + /* 4 bytes for each cid */ + line += DIV_ROUND_UP(bp->qm_cid_count * QM_QUEUES_PER_FUNC * 4, + QM_ILT_PAGE_SZ); + + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[QM]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + + } + /* SRC */ + ilt_client = &ilt->clients[ILT_CLIENT_SRC]; +#ifdef BCM_CNIC + ilt_client->client_num = ILT_CLIENT_SRC; + ilt_client->page_size = SRC_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + line += SRC_ILT_LINES; + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[SRC]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + +#else + ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); +#endif + /* TM */ + ilt_client = &ilt->clients[ILT_CLIENT_TM]; +#ifdef BCM_CNIC + ilt_client->client_num = ILT_CLIENT_TM; + ilt_client->page_size = TM_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + line += TM_ILT_LINES; + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[TM]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); -static int bnx2x_stop_multi(struct bnx2x *bp, int index) +#else + ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); +#endif +} +int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, + int is_leading) { - struct bnx2x_fastpath *fp = &bp->fp[index]; + struct bnx2x_client_init_params params = { {0} }; int rc; - /* halt the connection */ - fp->state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, + IGU_INT_ENABLE, 0); - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, - &(fp->state), 1); - if (rc) /* timeout */ - return rc; + params.ramrod_params.pstate = &fp->state; + params.ramrod_params.state = BNX2X_FP_STATE_OPEN; + params.ramrod_params.index = fp->index; + params.ramrod_params.cid = fp->cid; - /* delete cfc entry */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); + if (is_leading) + params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS; - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index, - &(fp->state), 1); + bnx2x_pf_rx_cl_prep(bp, fp, ¶ms.pause, ¶ms.rxq_params); + + bnx2x_pf_tx_cl_prep(bp, fp, ¶ms.txq_params); + + rc = bnx2x_setup_fw_client(bp, ¶ms, 1, + bnx2x_sp(bp, client_init_data), + bnx2x_sp_mapping(bp, client_init_data)); return rc; } -static int bnx2x_stop_leading(struct bnx2x *bp) +int bnx2x_stop_fw_client(struct bnx2x *bp, struct bnx2x_client_ramrod_params *p) { - __le16 dsb_sp_prod_idx; - /* if the other port is handling traffic, - this can take a lot of time */ - int cnt = 500; int rc; - might_sleep(); + int poll_flag = p->poll ? WAIT_RAMROD_POLL : 0; - /* Send HALT ramrod */ - bp->fp[0].state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0); + /* halt the connection */ + *p->pstate = BNX2X_FP_STATE_HALTING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, p->cid, 0, + p->cl_id, 0); /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0, - &(bp->fp[0].state), 1); + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, p->index, + p->pstate, poll_flag); if (rc) /* timeout */ return rc; - dsb_sp_prod_idx = *bp->dsb_sp_prod; + *p->pstate = BNX2X_FP_STATE_TERMINATING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, p->cid, 0, + p->cl_id, 0); + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_TERMINATED, p->index, + p->pstate, poll_flag); + if (rc) /* timeout */ + return rc; - /* Send PORT_DELETE ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); - /* Wait for completion to arrive on default status block - we are going to reset the chip anyway - so there is not much to do if this times out - */ - while (dsb_sp_prod_idx == *bp->dsb_sp_prod) { - if (!cnt) { - DP(NETIF_MSG_IFDOWN, "timeout waiting for port del " - "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", - *bp->dsb_sp_prod, dsb_sp_prod_idx); -#ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); -#endif - rc = -EBUSY; - break; - } - cnt--; - msleep(1); - rmb(); /* Refresh the dsb_sp_prod */ - } - bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; - bp->fp[0].state = BNX2X_FP_STATE_CLOSED; + /* delete cfc entry */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, p->cid, 0, 0, 1); + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, p->index, + p->pstate, WAIT_RAMROD_COMMON); return rc; } +static int bnx2x_stop_client(struct bnx2x *bp, int index) +{ + struct bnx2x_client_ramrod_params client_stop = {0}; + struct bnx2x_fastpath *fp = &bp->fp[index]; + + client_stop.index = index; + client_stop.cid = fp->cid; + client_stop.cl_id = fp->cl_id; + client_stop.pstate = &(fp->state); + client_stop.poll = 0; + + return bnx2x_stop_fw_client(bp, &client_stop); +} + + static void bnx2x_reset_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); int base, i; + int pfunc_offset_fp = offsetof(struct hc_sb_data, p_func) + + offsetof(struct hc_status_block_data_e1x, common); + int pfunc_offset_sp = offsetof(struct hc_sp_status_block_data, p_func); + int pfid_offset = offsetof(struct pci_entity, pf_id); + + /* Disable the function in the FW */ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(func), 0); + + /* FP SBs */ + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + REG_WR8(bp, + BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + + pfunc_offset_fp + pfid_offset, + HC_FUNCTION_DISABLED); + } + + /* SP SB */ + REG_WR8(bp, + BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + pfunc_offset_sp + pfid_offset, + HC_FUNCTION_DISABLED); + + + for (i = 0; i < XSTORM_SPQ_DATA_SIZE / 4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_DATA_OFFSET(func), + 0); /* Configure IGU */ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); @@ -5099,6 +5858,8 @@ static void bnx2x_reset_func(struct bnx2x *bp) base = FUNC_ILT_BASE(func); for (i = base; i < base + ILT_PER_FUNC; i++) bnx2x_ilt_wr(bp, i, 0); + + bp->dmae_ready = 0; } static void bnx2x_reset_port(struct bnx2x *bp) @@ -5167,7 +5928,6 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) cnt = 1000; while (bnx2x_has_tx_work_unload(fp)) { - bnx2x_tx_int(fp); if (!cnt) { BNX2X_ERR("timeout waiting for queue[%d]\n", i); @@ -5186,39 +5946,21 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) msleep(1); if (CHIP_IS_E1(bp)) { - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - bnx2x_set_eth_mac_addr_e1(bp, 0); - - for (i = 0; i < config->hdr.length; i++) - CAM_INVALIDATE(config->config_table[i]); - - config->hdr.length = i; - if (CHIP_REV_IS_SLOW(bp)) - config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port); - else - config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port); - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending++; - smp_wmb(); - - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mcast_config)), - U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0); + /* invalidate mc list, + * wait and poll (interrupts are off) + */ + bnx2x_invlidate_e1_mc_list(bp); + bnx2x_set_eth_mac(bp, 0); - } else { /* E1H */ + } else { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); - bnx2x_set_eth_mac_addr_e1h(bp, 0); + bnx2x_set_eth_mac(bp, 0); for (i = 0; i < MC_HASH_SIZE; i++) REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); - - REG_WR(bp, MISC_REG_E1HMF_MODE, 0); } + #ifdef BCM_CNIC /* Clear iSCSI L2 MAC */ mutex_lock(&bp->cnic_mutex); @@ -5257,21 +5999,27 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) /* Close multi and leading connections Completions for ramrods are collected in a synchronous way */ - for_each_nondefault_queue(bp, i) - if (bnx2x_stop_multi(bp, i)) + for_each_queue(bp, i) + + if (bnx2x_stop_client(bp, i)) +#ifdef BNX2X_STOP_ON_ERROR + return; +#else goto unload_error; +#endif - rc = bnx2x_stop_leading(bp); + rc = bnx2x_func_stop(bp); if (rc) { - BNX2X_ERR("Stop leading failed!\n"); + BNX2X_ERR("Function stop failed!\n"); #ifdef BNX2X_STOP_ON_ERROR - return -EBUSY; + return; #else goto unload_error; #endif } - +#ifndef BNX2X_STOP_ON_ERROR unload_error: +#endif if (!BP_NOMCP(bp)) reset_code = bnx2x_fw_command(bp, reset_code, 0); else { @@ -5293,6 +6041,12 @@ unload_error: (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT)) bnx2x__link_reset(bp); + /* Disable HW interrupts, NAPI */ + bnx2x_netif_stop(bp, 1); + + /* Release IRQs */ + bnx2x_free_irq(bp, false); + /* Reset the chip */ bnx2x_reset_chip(bp, reset_code); @@ -5953,6 +6707,18 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->link_params.chip_id = bp->common.chip_id; BNX2X_DEV_INFO("chip ID is 0x%x\n", id); + bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */ + + /* Set doorbell size */ + bp->db_size = (1 << BNX2X_DB_SHIFT); + + /* + * set base FW non-default (fast path) status block id, this value is + * used to initialize the fw_sb_id saved on the fp/queue structure to + * determine the id used by the FW. + */ + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; + val = (REG_RD(bp, 0x2874) & 0x55); if ((bp->common.chip_id & 0x1) || (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) { @@ -6417,13 +7183,23 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bnx2x_get_common_hwinfo(bp); + bp->common.int_block = INT_BLOCK_HC; + + bp->igu_dsb_id = DEF_SB_IGU_ID; + bp->igu_base_sb = 0; + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + bp->e1hov = 0; bp->e1hmf = 0; if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { + + bp->common.mf_cfg_base = bp->common.shmem_base + + offsetof(struct shmem_region, func_mb) + + E1H_FUNC_MAX * sizeof(struct drv_func_mb); bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + MF_CFG_RD(bp, func_mf_config[func].config); - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[FUNC_0].e1hov_tag) & + val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) bp->e1hmf = 1; @@ -6431,7 +7207,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) IS_E1HMF(bp) ? "multi" : "single"); if (IS_E1HMF(bp)) { - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func]. + val = (MF_CFG_RD(bp, func_mf_config[func]. e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { @@ -6453,6 +7229,10 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } } + /* adjust igu_sb_cnt to MF */ + if (IS_E1HMF(bp)) + bp->igu_sb_cnt /= E1HVN_MAX; + if (!BP_NOMCP(bp)) { bnx2x_get_port_hwinfo(bp); @@ -6462,8 +7242,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } if (IS_E1HMF(bp)) { - val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper); - val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower); + val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); + val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); @@ -6577,6 +7357,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) rc = bnx2x_get_hwinfo(bp); + if (!rc) + rc = bnx2x_alloc_mem_bp(bp); + bnx2x_read_fwinfo(bp); /* need to reset chip if undi was active */ if (!BP_NOMCP(bp)) @@ -6623,8 +7406,8 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->rx_csum = 1; /* make sure that the numbers are in the right granularity */ - bp->tx_ticks = (50 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); - bp->rx_ticks = (25 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); + bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR; + bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR; timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ); bp->current_interval = (poll ? poll : timer_interval); @@ -6724,73 +7507,16 @@ void bnx2x_set_rx_mode(struct net_device *dev) else { /* some multicasts */ if (CHIP_IS_E1(bp)) { - int i, old, offset; - struct netdev_hw_addr *ha; - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - i = 0; - netdev_for_each_mc_addr(ha, dev) { - config->config_table[i]. - cam_entry.msb_mac_addr = - swab16(*(u16 *)&ha->addr[0]); - config->config_table[i]. - cam_entry.middle_mac_addr = - swab16(*(u16 *)&ha->addr[2]); - config->config_table[i]. - cam_entry.lsb_mac_addr = - swab16(*(u16 *)&ha->addr[4]); - config->config_table[i].cam_entry.flags = - cpu_to_le16(port); - config->config_table[i]. - target_table_entry.flags = 0; - config->config_table[i].target_table_entry. - clients_bit_vector = - cpu_to_le32(1 << BP_L_ID(bp)); - config->config_table[i]. - target_table_entry.vlan_id = 0; - - DP(NETIF_MSG_IFUP, - "setting MCAST[%d] (%04x:%04x:%04x)\n", i, - config->config_table[i]. - cam_entry.msb_mac_addr, - config->config_table[i]. - cam_entry.middle_mac_addr, - config->config_table[i]. - cam_entry.lsb_mac_addr); - i++; - } - old = config->hdr.length; - if (old > i) { - for (; i < old; i++) { - if (CAM_IS_INVALID(config-> - config_table[i])) { - /* already invalidated */ - break; - } - /* invalidate */ - CAM_INVALIDATE(config-> - config_table[i]); - } - } - - if (CHIP_REV_IS_SLOW(bp)) - offset = BNX2X_MAX_EMUL_MULTI*(1 + port); - else - offset = BNX2X_MAX_MULTICAST*(1 + port); - - config->hdr.length = i; - config->hdr.offset = offset; - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending++; - smp_wmb(); + /* + * set mc list, do not wait as wait implies sleep + * and set_rx_mode can be invoked from non-sleepable + * context + */ + u8 offset = (CHIP_REV_IS_SLOW(bp) ? + BNX2X_MAX_EMUL_MULTI*(1 + port) : + BNX2X_MAX_MULTICAST*(1 + port)); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mcast_config)), - U64_LO(bnx2x_sp_mapping(bp, mcast_config)), - 0); + bnx2x_set_e1_mc_list(bp, offset); } else { /* E1H */ /* Accept one or more multicasts */ struct netdev_hw_addr *ha; @@ -6802,9 +7528,10 @@ void bnx2x_set_rx_mode(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", - ha->addr); + bnx2x_mc_addr(ha)); - crc = crc32c_le(0, ha->addr, ETH_ALEN); + crc = crc32c_le(0, bnx2x_mc_addr(ha), + ETH_ALEN); bit = (crc >> 24) & 0xff; regidx = bit >> 5; bit &= 0x1f; @@ -6817,6 +7544,7 @@ void bnx2x_set_rx_mode(struct net_device *dev) } } + bp->rx_mode = rx_mode; bnx2x_set_storm_rx_mode(bp); } @@ -7003,7 +7731,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, } bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2), - min_t(u64, BNX2X_DB_SIZE, + min_t(u64, BNX2X_DB_SIZE(bp), pci_resource_len(pdev, 2))); if (!bp->doorbells) { dev_err(&bp->pdev->dev, @@ -7179,6 +7907,30 @@ static inline void bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n) } } +/** + * IRO array is stored in the following format: + * {base(24bit), m1(16bit), m2(16bit), m3(16bit), size(16bit) } + */ +static inline void bnx2x_prep_iro(const u8 *_source, u8 *_target, u32 n) +{ + const __be32 *source = (const __be32 *)_source; + struct iro *target = (struct iro *)_target; + u32 i, j, tmp; + + for (i = 0, j = 0; i < n/sizeof(struct iro); i++) { + target[i].base = be32_to_cpu(source[j]); + j++; + tmp = be32_to_cpu(source[j]); + target[i].m1 = (tmp >> 16) & 0xffff; + target[i].m2 = tmp & 0xffff; + j++; + tmp = be32_to_cpu(source[j]); + target[i].m3 = (tmp >> 16) & 0xffff; + target[i].size = tmp & 0xffff; + j++; + } +} + static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n) { const __be16 *source = (const __be16 *)_source; @@ -7260,9 +8012,13 @@ int bnx2x_init_firmware(struct bnx2x *bp) be32_to_cpu(fw_hdr->csem_int_table_data.offset); INIT_CSEM_PRAM_DATA(bp) = bp->firmware->data + be32_to_cpu(fw_hdr->csem_pram_data.offset); + /* IRO */ + BNX2X_ALLOC_AND_SET(iro_arr, iro_alloc_err, bnx2x_prep_iro); return 0; +iro_alloc_err: + kfree(bp->init_ops_offsets); init_offsets_alloc_err: kfree(bp->init_ops); init_ops_alloc_err: @@ -7273,17 +8029,27 @@ request_firmware_exit: return rc; } +static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) +{ + int cid_count = L2_FP_COUNT(l2_cid_count); +#ifdef BCM_CNIC + cid_count += CNIC_CID_MAX; +#endif + return roundup(cid_count, QM_CID_ROUND); +} static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev = NULL; struct bnx2x *bp; int pcie_width, pcie_speed; - int rc; + int rc, cid_count; + + cid_count = FP_SB_MAX_E1x + CNIC_CONTEXT_USE; /* dev zeroed in init_etherdev */ - dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT); + dev = alloc_etherdev_mq(sizeof(*bp), cid_count); if (!dev) { dev_err(&pdev->dev, "Cannot allocate net device\n"); return -ENOMEM; @@ -7294,6 +8060,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); + bp->l2_cid_count = cid_count; + rc = bnx2x_init_dev(pdev, dev); if (rc < 0) { free_netdev(dev); @@ -7304,6 +8072,9 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, if (rc) goto init_one_exit; + /* calc qm_cid_count */ + bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); + rc = register_netdev(dev); if (rc) { dev_err(&pdev->dev, "Cannot register net device\n"); @@ -7360,6 +8131,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) if (bp->doorbells) iounmap(bp->doorbells); + bnx2x_free_mem_bp(bp); + free_netdev(dev); if (atomic_read(&pdev->enable_cnt) == 1) @@ -7387,16 +8160,9 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) /* Release IRQs */ bnx2x_free_irq(bp, false); - if (CHIP_IS_E1(bp)) { - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - for (i = 0; i < config->hdr.length; i++) - CAM_INVALIDATE(config->config_table[i]); - } - /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); + for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); for_each_queue(bp, i) @@ -7641,8 +8407,8 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev, DP(NETIF_MSG_TIMER, "L5 SPQE %x %x %x:%x pos %d\n", spe->hdr.conn_and_cmd_data, spe->hdr.type, - spe->data.mac_config_addr.hi, - spe->data.mac_config_addr.lo, + spe->data.update_data_addr.hi, + spe->data.update_data_addr.lo, bp->cnic_kwq_pending); if (bp->cnic_kwq_prod == bp->cnic_kwq_last) @@ -7736,8 +8502,24 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_START_L2_CMD: { u32 cli = ctl->data.ring.client_id; - bp->rx_mode_cl_mask |= (1 << cli); - bnx2x_set_storm_rx_mode(bp); + /* Set iSCSI MAC address */ + bnx2x_set_iscsi_eth_mac_addr(bp, 1); + + mmiowb(); + barrier(); + + /* Start accepting on iSCSI L2 ring. Accept all multicasts + * because it's the only way for UIO Client to accept + * multicasts (in non-promiscuous mode only one Client per + * function will receive multicast packets (leading in our + * case). + */ + bnx2x_rxq_set_mac_filters(bp, cli, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + break; } @@ -7745,8 +8527,15 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_STOP_L2_CMD: { u32 cli = ctl->data.ring.client_id; - bp->rx_mode_cl_mask &= ~(1 << cli); - bnx2x_set_storm_rx_mode(bp); + /* Stop accepting on iSCSI L2 ring */ + bnx2x_rxq_set_mac_filters(bp, cli, BNX2X_ACCEPT_NONE); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + + mmiowb(); + barrier(); + + /* Unset iSCSI L2 MAC */ + bnx2x_set_iscsi_eth_mac_addr(bp, 0); break; } @@ -7770,10 +8559,12 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX; cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX; } - cp->irq_arr[0].status_blk = bp->cnic_sb; + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp); + cp->irq_arr[0].status_blk_num2 = CNIC_IGU_SB_ID(bp); cp->irq_arr[1].status_blk = bp->def_status_blk; cp->irq_arr[1].status_blk_num = DEF_SB_ID; + cp->irq_arr[1].status_blk_num2 = DEF_SB_IGU_ID; cp->num_irq = 2; } @@ -7805,8 +8596,11 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, cp->num_irq = 0; cp->drv_state = CNIC_DRV_STATE_REGD; + cp->iro_arr = bp->iro_arr; - bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, CNIC_SB_ID(bp)); + bnx2x_init_sb(bp, bp->cnic_sb_mapping, + BNX2X_VF_ID_INVALID, false, + CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); bnx2x_setup_cnic_irq_info(bp); bnx2x_set_iscsi_eth_mac_addr(bp, 1); @@ -7847,7 +8641,7 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->io_base = bp->regview; cp->io_base2 = bp->doorbells; cp->max_kwqe_pending = 8; - cp->ctx_blk_size = CNIC_CTX_PER_ILT * sizeof(union cdu_context); + cp->ctx_blk_size = CDU_ILT_PAGE_SZ; cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1; cp->ctx_tbl_len = CNIC_ILT_LINES; cp->starting_cid = BCM_CNIC_CID_START; diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index efa1403ebf82..1256f62f7bff 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -153,7 +153,7 @@ static inline long bnx2x_hilo(u32 *hiref) static void bnx2x_storm_stats_post(struct bnx2x *bp) { if (!bp->stats_pending) { - struct eth_query_ramrod_data ramrod_data = {0}; + struct common_query_ramrod_data ramrod_data = {0}; int i, rc; spin_lock_bh(&bp->stats_lock); @@ -163,9 +163,9 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) for_each_queue(bp, i) ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, ((u32 *)&ramrod_data)[1], - ((u32 *)&ramrod_data)[0], 0); + ((u32 *)&ramrod_data)[0], 1); if (rc == 0) { /* stats ramrod has it's own slot on the spq */ bp->spq_left++; @@ -398,9 +398,9 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_RX_STAT_GR64) >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; @@ -571,7 +571,7 @@ static void bnx2x_stats_restart(struct bnx2x *bp) static void bnx2x_bmac_stats_update(struct bnx2x *bp) { - struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats); + struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats); struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); struct bnx2x_eth_stats *estats = &bp->eth_stats; struct { diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 4e9d4ae1f303..80259815af06 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -942,7 +942,7 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & PAGE_MASK; - uinfo->mem[1].size = sizeof(struct host_def_status_block); + uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); uinfo->name = "bnx2x_cnic"; } @@ -1063,6 +1063,8 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) int i, j, n, ret, pages; struct cnic_dma *kwq_16_dma = &cp->kwq_16_data_info; + cp->iro_arr = ethdev->iro_arr; + cp->max_cid_space = MAX_ISCSI_TBL_SZ; cp->iscsi_start_cid = start_cid; if (start_cid < BNX2X_ISCSI_START_CID) { @@ -1127,8 +1129,6 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->bnx2x_def_status_blk = cp->ethdev->irq_arr[1].status_blk; - memset(cp->status_blk.bnx2x, 0, sizeof(*cp->status_blk.bnx2x)); - cp->l2_rx_ring_size = 15; ret = cnic_alloc_l2_rings(dev, 4); @@ -1211,7 +1211,7 @@ static int cnic_submit_kwqe_16(struct cnic_dev *dev, u32 cmd, u32 cid, cpu_to_le32(((cmd << SPE_HDR_CMD_ID_SHIFT) | BNX2X_HW_CID(cp, cid))); kwqe.hdr.type = cpu_to_le16(type); - kwqe.hdr.reserved = 0; + kwqe.hdr.reserved1 = 0; kwqe.data.phy_address.lo = cpu_to_le32(l5_data->phy_address.lo); kwqe.data.phy_address.hi = cpu_to_le32(l5_data->phy_address.hi); @@ -1527,8 +1527,10 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], ictx->tstorm_st_context.tcp.cwnd = 0x5A8; ictx->tstorm_st_context.tcp.flags2 |= TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN; + ictx->tstorm_st_context.tcp.ooo_support_mode = + TCP_TSTORM_OOO_DROP_AND_PROC_ACK; - ictx->timers_context.flags |= ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG; + ictx->timers_context.flags |= TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG; ictx->ustorm_st_context.ring.rq.pbl_base.lo = req2->rq_page_table_addr_lo; @@ -1717,6 +1719,7 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) int ret = 0; struct iscsi_kcqe kcqe; struct kcqe *cqes[1]; + u32 hw_cid, type; if (!(ctx->ctx_flags & CTX_FL_OFFLD_START)) goto skip_cfc_delete; @@ -1727,11 +1730,15 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) init_waitqueue_head(&ctx->waitq); ctx->wait_cond = 0; memset(&l5_data, 0, sizeof(l5_data)); - ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL, - req->context_id, - ETH_CONNECTION_TYPE | - (1 << SPE_HDR_COMMON_RAMROD_SHIFT), - &l5_data); + hw_cid = BNX2X_HW_CID(cp, ctx->cid); + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); + + ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, + hw_cid, type, &l5_data); + if (ret == 0) wait_event(ctx->waitq, ctx->wait_cond); @@ -2322,7 +2329,7 @@ static void cnic_ack_bnx2x_msix(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, 0, + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, CSTORM_ID, 0, IGU_INT_DISABLE, 0); } @@ -2357,7 +2364,7 @@ static void cnic_service_bnx2x_bh(unsigned long data) status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, status_idx, IGU_INT_ENABLE, 1); } @@ -3285,6 +3292,7 @@ static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; u32 pfid = cp->pfid; + u32 port = CNIC_PORT(cp); cnic_init_bnx2x_mac(dev); cnic_bnx2x_set_tcp_timestamp(dev, 1); @@ -3293,9 +3301,9 @@ static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfid), 0); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(pfid), 1); + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port), 1); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(pfid), + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port), DEF_MAX_DA_COUNT); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + @@ -3859,32 +3867,48 @@ static int cnic_init_bnx2x_irq(struct cnic_dev *dev) return err; } +static inline void cnic_storm_memset_hc_disable(struct cnic_dev *dev, + u16 sb_id, u8 sb_index, + u8 disable) +{ + + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) + + offsetof(struct hc_status_block_data_e1x, index_data) + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, flags); + u16 flags = CNIC_RD16(dev, addr); + /* clear and set */ + flags &= ~HC_INDEX_DATA_HC_ENABLED; + flags |= (((~disable) << HC_INDEX_DATA_HC_ENABLED_SHIFT) & + HC_INDEX_DATA_HC_ENABLED); + CNIC_WR16(dev, addr, flags); +} + static void cnic_enable_bnx2x_int(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; u8 sb_id = cp->status_blk_num; - int port = CNIC_PORT(cp); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, - HC_INDEX_C_ISCSI_EQ_CONS), - 64 / 12); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, - HC_INDEX_C_ISCSI_EQ_CONS), 0); + CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) + + offsetof(struct hc_status_block_data_e1x, index_data) + + sizeof(struct hc_index_data)*HC_INDEX_ISCSI_EQ_CONS + + offsetof(struct hc_index_data, timeout), 64 / 12); + cnic_storm_memset_hc_disable(dev, sb_id, HC_INDEX_ISCSI_EQ_CONS, 0); } static void cnic_disable_bnx2x_int_sync(struct cnic_dev *dev) { } -static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) +static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, + struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) cp->l2_ring; - struct eth_context *context; - struct regpair context_addr; - dma_addr_t buf_map; + dma_addr_t buf_map, ring_map = cp->l2_ring_map; + struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int port = CNIC_PORT(cp); int i; int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); @@ -3909,33 +3933,23 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); } - context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 1, &context_addr); - val = (u64) cp->l2_ring_map >> 32; + val = (u64) ring_map >> 32; txbd->next_bd.addr_hi = cpu_to_le32(val); - context->xstorm_st_context.tx_bd_page_base_hi = val; + data->tx.tx_bd_page_base.hi = cpu_to_le32(val); - val = (u64) cp->l2_ring_map & 0xffffffff; + val = (u64) ring_map & 0xffffffff; txbd->next_bd.addr_lo = cpu_to_le32(val); - context->xstorm_st_context.tx_bd_page_base_lo = val; - - context->cstorm_st_context.sb_index_number = - HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS; - context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID; - - if (cli < MAX_X_STAT_COUNTER_ID) - context->xstorm_st_context.statistics_data = cli | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE; + data->tx.tx_bd_page_base.lo = cpu_to_le32(val); - context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(cp, BNX2X_ISCSI_L2_CID), - CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); + /* Other ramrod params */ + data->tx.tx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_CQ_CONS; + data->tx.tx_status_block_id = BNX2X_DEF_SB_ID; /* reset xstorm per client statistics */ - if (cli < MAX_X_STAT_COUNTER_ID) { + if (cli < MAX_STAT_COUNTER_ID) { val = BAR_XSTRORM_INTMEM + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) @@ -3943,24 +3957,31 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) } cp->tx_cons_ptr = - &cp->bnx2x_def_status_blk->c_def_status_block.index_values[ - HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS]; + &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_CQ_CONS]; } -static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) +static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, + struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE); struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *) (cp->l2_ring + (2 * BCM_PAGE_SIZE)); - struct eth_context *context; - struct regpair context_addr; + struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int i; int port = CNIC_PORT(cp); int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); u32 val; - struct tstorm_eth_client_config tstorm_client = {0}; + dma_addr_t ring_map = cp->l2_ring_map; + + /* General data */ + data->general.client_id = cli; + data->general.statistics_en_flg = 1; + data->general.statistics_counter_id = cli; + data->general.activate_flg = 1; + data->general.sp_client_id = cli; for (i = 0; i < BNX2X_MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; @@ -3970,83 +3991,42 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) rxbd->addr_hi = cpu_to_le32((u64) buf_map >> 32); rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff); } - context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 0, &context_addr); - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32; + val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32; rxbd->addr_hi = cpu_to_le32(val); + data->rx.bd_page_base.hi = cpu_to_le32(val); - context->ustorm_st_context.common.bd_page_base_hi = val; - - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff; + val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff; rxbd->addr_lo = cpu_to_le32(val); - - context->ustorm_st_context.common.bd_page_base_lo = val; - - context->ustorm_st_context.common.sb_index_numbers = - BNX2X_ISCSI_RX_SB_INDEX_NUM; - context->ustorm_st_context.common.clientId = cli; - context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID; - if (cli < MAX_U_STAT_COUNTER_ID) { - context->ustorm_st_context.common.flags = - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS; - context->ustorm_st_context.common.statistics_counter_id = cli; - } - context->ustorm_st_context.common.mc_alignment_log_size = 0; - context->ustorm_st_context.common.bd_buff_size = - cp->l2_single_buf_size; - - context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(cp, BNX2X_ISCSI_L2_CID), - CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); + data->rx.bd_page_base.lo = cpu_to_le32(val); rxcqe += BNX2X_MAX_RCQ_DESC_CNT; - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) >> 32; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) >> 32; rxcqe->addr_hi = cpu_to_le32(val); + data->rx.cqe_page_base.hi = cpu_to_le32(val); - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, cli) + 4, val); - - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, cli) + 4, val); - - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; rxcqe->addr_lo = cpu_to_le32(val); + data->rx.cqe_page_base.lo = cpu_to_le32(val); - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, cli), val); - - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, cli), val); - - /* client tstorm info */ - tstorm_client.mtu = cp->l2_single_buf_size - 14; - tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE; - - if (cli < MAX_T_STAT_COUNTER_ID) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; - tstorm_client.statistics_counter_id = cli; - } + /* Other ramrod params */ + data->rx.client_qzone_id = cl_qzone_id; + data->rx.rx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS; + data->rx.status_block_id = BNX2X_DEF_SB_ID; - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, cli), - ((u32 *)&tstorm_client)[0]); - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, cli) + 4, - ((u32 *)&tstorm_client)[1]); + data->rx.cache_line_alignment_log_size = L1_CACHE_SHIFT; + data->rx.bd_buff_size = cpu_to_le16(cp->l2_single_buf_size); - /* reset tstorm per client statistics */ - if (cli < MAX_T_STAT_COUNTER_ID) { + data->rx.mtu = cpu_to_le16(cp->l2_single_buf_size - 14); + data->rx.outer_vlan_removal_enable_flg = 1; + /* reset tstorm and ustorm per client statistics */ + if (cli < MAX_STAT_COUNTER_ID) { val = BAR_TSTRORM_INTMEM + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) CNIC_WR(dev, val + i * 4, 0); - } - /* reset ustorm per client statistics */ - if (cli < MAX_U_STAT_COUNTER_ID) { val = BAR_USTRORM_INTMEM + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) @@ -4054,8 +4034,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) } cp->rx_cons_ptr = - &cp->bnx2x_def_status_blk->u_def_status_block.index_values[ - HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS]; + &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS]; } static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) @@ -4066,7 +4045,7 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) dev->max_iscsi_conn = 0; base = CNIC_RD(dev, MISC_REG_SHARED_MEM_ADDR); - if (base < 0xa0000 || base >= 0xc0000) + if (base == 0) return; addr = BNX2X_SHMEM_ADDR(base, @@ -4103,14 +4082,19 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) } if (BNX2X_CHIP_IS_E1H(cp->chip_id)) { int func = CNIC_FUNC(cp); + u32 mf_cfg_addr; + + mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; + + addr = mf_cfg_addr + + offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag); - addr = BNX2X_SHMEM_ADDR(base, - mf_cfg.func_mf_config[func].e1hov_tag); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - addr = BNX2X_SHMEM_ADDR(base, - mf_cfg.func_mf_config[func].config); + addr = mf_cfg_addr + + offsetof(struct mf_cfg, + func_mf_config[func].config); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_PROTOCOL_MASK; if (val != FUNC_MF_CFG_PROTOCOL_ISCSI) @@ -4122,11 +4106,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) static int cnic_start_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_eth_dev *ethdev = cp->ethdev; int func = CNIC_FUNC(cp), ret, i; - int port = CNIC_PORT(cp); u32 pfid; - u16 eq_idx; - u8 sb_id = cp->status_blk_num; + struct host_hc_status_block_e1x *sb = cp->status_blk.gen; cp->pfid = func; pfid = cp->pfid; @@ -4137,15 +4120,16 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (ret) return -ENOMEM; + cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2; + cp->kcq1.io_addr = BAR_CSTRORM_INTMEM + CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); cp->kcq1.sw_prod_idx = 0; cp->kcq1.hw_prod_idx_ptr = - &cp->status_blk.bnx2x->c_status_block.index_values[ - HC_INDEX_C_ISCSI_EQ_CONS]; + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; cp->kcq1.status_idx_ptr = - &cp->status_blk.bnx2x->c_status_block.status_block_index; + &sb->sb.running_index[SM_RX_ID]; cnic_get_bnx2x_iscsi_info(dev); @@ -4171,7 +4155,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfid, 0), cp->status_blk_num); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfid, 0), - HC_INDEX_C_ISCSI_EQ_CONS); + HC_INDEX_ISCSI_EQ_CONS); for (i = 0; i < cp->conn_buf_info.num_pages; i++) { CNIC_WR(dev, BAR_TSTRORM_INTMEM + @@ -4189,16 +4173,11 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid) + 4, (u64) cp->gbl_buf_info.pg_map_arr[0] >> 32); + CNIC_WR(dev, BAR_TSTRORM_INTMEM + + TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfid), DEF_RCV_BUF); + cnic_setup_bnx2x_context(dev); - eq_idx = CNIC_RD16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) + - offsetof(struct cstorm_status_block_c, - index_values[HC_INDEX_C_ISCSI_EQ_CONS])); - if (eq_idx != 0) { - netdev_err(dev->netdev, "EQ cons index %x != 0\n", eq_idx); - return -EBUSY; - } ret = cnic_init_bnx2x_irq(dev); if (ret) return ret; @@ -4218,8 +4197,9 @@ static void cnic_init_rings(struct cnic_dev *dev) cnic_init_bnx2_rx_ring(dev); set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { - struct cnic_local *cp = dev->cnic_priv; u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + u32 cl_qzone_id, type; + struct client_init_ramrod_data *data; union l5cm_specific_data l5_data; struct ustorm_eth_rx_producers rx_prods = {0}; u32 off, i; @@ -4228,23 +4208,36 @@ static void cnic_init_rings(struct cnic_dev *dev) rx_prods.cqe_prod = BNX2X_MAX_RCQ_DESC_CNT; barrier(); + cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); + off = BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_OFFSET(CNIC_PORT(cp), cli); + USTORM_RX_PRODS_E1X_OFFSET(CNIC_PORT(cp), cli); for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++) CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]); set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); - cnic_init_bnx2x_tx_ring(dev); - cnic_init_bnx2x_rx_ring(dev); + data = cp->l2_buf; + + memset(data, 0, sizeof(*data)); + + cnic_init_bnx2x_tx_ring(dev, data); + cnic_init_bnx2x_rx_ring(dev, data); + + l5_data.phy_address.lo = cp->l2_buf_map & 0xffffffff; + l5_data.phy_address.hi = (u64) cp->l2_buf_map >> 32; + + type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); - l5_data.phy_address.lo = cli; - l5_data.phy_address.hi = 0; cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP, - BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data); + BNX2X_ISCSI_L2_CID, type, &l5_data); + i = 0; while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) && ++i < 10) @@ -4272,6 +4265,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); union l5cm_specific_data l5_data; int i; + u32 type; cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0); @@ -4292,9 +4286,12 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) cnic_kwq_completion(dev, 1); memset(&l5_data, 0, sizeof(l5_data)); - cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL, - BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE | - (1 << SPE_HDR_COMMON_RAMROD_SHIFT), &l5_data); + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); + cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, + BNX2X_ISCSI_L2_CID, type, &l5_data); msleep(10); } clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); @@ -4392,15 +4389,9 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev) static void cnic_stop_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u8 sb_id = cp->status_blk_num; - int port = CNIC_PORT(cp); cnic_free_irq(dev); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) + - offsetof(struct cstorm_status_block_c, - index_values[HC_INDEX_C_ISCSI_EQ_CONS]), - 0); + *cp->kcq1.hw_prod_idx_ptr = 0; CNIC_WR(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_EQ_CONS_OFFSET(cp->pfid, 0), 0); CNIC_WR16(dev, cp->kcq1.io_addr, 0); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 481618399b1f..676d008509c6 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -12,6 +12,13 @@ #ifndef CNIC_H #define CNIC_H +#define HC_INDEX_ISCSI_EQ_CONS 6 + +#define HC_INDEX_FCOE_EQ_CONS 3 + +#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 + #define KWQ_PAGE_CNT 4 #define KCQ_PAGE_CNT 16 @@ -179,6 +186,14 @@ struct kcq_info { u32 io_addr; }; +struct iro { + u32 base; + u16 m1; + u16 m2; + u16 m3; + u16 size; +}; + struct cnic_local { spinlock_t cnic_ulp_lock; @@ -213,6 +228,9 @@ struct cnic_local { u16 rx_cons; u16 tx_cons; + struct iro *iro_arr; +#define IRO (((struct cnic_local *) dev->cnic_priv)->iro_arr) + struct cnic_dma kwq_info; struct kwqe **kwq; @@ -231,12 +249,16 @@ struct cnic_local { union { void *gen; struct status_block_msix *bnx2; - struct host_status_block *bnx2x; + struct host_hc_status_block_e1x *bnx2x_e1x; + /* index values - which counter to update */ + #define SM_RX_ID 0 + #define SM_TX_ID 1 } status_blk; - struct host_def_status_block *bnx2x_def_status_blk; + struct host_sp_status_block *bnx2x_def_status_blk; u32 status_blk_num; + u32 bnx2x_igu_sb_id; u32 int_num; u32 last_status_idx; struct tasklet_struct cnic_irq_task; @@ -358,24 +380,33 @@ struct bnx2x_bd_chain_next { (BNX2X_MAX_RCQ_DESC_CNT - 1)) ? \ ((x) + 2) : ((x) + 1) -#define BNX2X_DEF_SB_ID 16 +#define BNX2X_DEF_SB_ID HC_SP_SB_ID -#define BNX2X_ISCSI_RX_SB_INDEX_NUM \ - ((HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS << \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) +#define BNX2X_SHMEM_MF_BLK_OFFSET 0x7e4 #define BNX2X_SHMEM_ADDR(base, field) (base + \ offsetof(struct shmem_region, field)) -#define CNIC_PORT(cp) ((cp)->func % PORT_MAX) +#define BNX2X_SHMEM2_ADDR(base, field) (base + \ + offsetof(struct shmem2_region, field)) + +#define BNX2X_SHMEM2_HAS(base, field) \ + ((base) && \ + (CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \ + offsetof(struct shmem2_region, field))) + +#define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_FUNC(cp) ((cp)->func) -#define CNIC_E1HVN(cp) ((cp)->func >> 1) +#define CNIC_E1HVN(cp) ((cp)->pfid >> 1) -#define BNX2X_HW_CID(cp, x) (((CNIC_FUNC(cp) % PORT_MAX) << 23) | \ +#define BNX2X_HW_CID(cp, x) ((CNIC_PORT(cp) << 23) | \ (CNIC_E1HVN(cp) << 17) | (x)) #define BNX2X_SW_CID(x) (x & 0x1ffff) +#define BNX2X_CL_QZONE_ID(cp, cli) \ + (cli + (CNIC_PORT(cp) * ETH_MAX_RX_CLIENTS_E1H)) + +#define TCP_TSTORM_OOO_DROP_AND_PROC_ACK (0<<4) #endif diff --git a/drivers/net/cnic_defs.h b/drivers/net/cnic_defs.h index 7ce694d41b6b..328e8b2765a3 100644 --- a/drivers/net/cnic_defs.h +++ b/drivers/net/cnic_defs.h @@ -14,6 +14,7 @@ /* KWQ (kernel work queue) request op codes */ #define L2_KWQE_OPCODE_VALUE_FLUSH (4) +#define L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE (8) #define L4_KWQE_OPCODE_VALUE_CONNECT1 (50) #define L4_KWQE_OPCODE_VALUE_CONNECT2 (51) @@ -48,11 +49,14 @@ #define L4_KCQE_OPCODE_VALUE_UPLOAD_PG (14) /* KCQ (kernel completion queue) completion status */ -#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0) -#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93) +#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0) +#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93) -#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83) -#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89) +#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83) +#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89) + +#define L4_KCQE_OPCODE_VALUE_OOO_EVENT_NOTIFICATION (0xa0) +#define L4_KCQE_OPCODE_VALUE_OOO_FLUSH (0xa1) #define L4_LAYER_CODE (4) #define L2_LAYER_CODE (2) @@ -584,6 +588,100 @@ struct l4_kwq_upload { * bnx2x structures */ +/* + * The iscsi aggregative context of Cstorm + */ +struct cstorm_iscsi_ag_context { + u32 agg_vars1; +#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0) +#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16 +#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18) +#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22 +#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23) +#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23 +#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26) +#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30 +#if defined(__BIG_ENDIAN) + u8 __aux1_th; + u8 __aux1_val; + u16 __agg_vars2; +#elif defined(__LITTLE_ENDIAN) + u16 __agg_vars2; + u8 __aux1_val; + u8 __aux1_th; +#endif + u32 rel_seq; + u32 rel_seq_th; +#if defined(__BIG_ENDIAN) + u16 hq_cons; + u16 hq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 hq_prod; + u16 hq_cons; +#endif +#if defined(__BIG_ENDIAN) + u8 __reserved62; + u8 __reserved61; + u8 __reserved60; + u8 __reserved59; +#elif defined(__LITTLE_ENDIAN) + u8 __reserved59; + u8 __reserved60; + u8 __reserved61; + u8 __reserved62; +#endif +#if defined(__BIG_ENDIAN) + u16 __reserved64; + u16 __cq_u_prod0; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod0; + u16 __reserved64; +#endif + u32 __cq_u_prod1; +#if defined(__BIG_ENDIAN) + u16 __agg_vars3; + u16 __cq_u_prod2; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod2; + u16 __agg_vars3; +#endif +#if defined(__BIG_ENDIAN) + u16 __aux2_th; + u16 __cq_u_prod3; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod3; + u16 __aux2_th; +#endif +}; + /* * iSCSI context region, used only in iSCSI */ @@ -696,7 +794,7 @@ struct ustorm_iscsi_st_context { struct regpair task_pbl_base; struct regpair tce_phy_addr; struct ustorm_iscsi_placement_db place_db; - u32 data_rcv_seq; + u32 reserved8; u32 rem_rcv_len; #if defined(__BIG_ENDIAN) u16 hdr_itt; @@ -713,8 +811,10 @@ struct ustorm_iscsi_st_context { #define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 u8 task_pdu_cache_index; u8 task_pbe_cache_index; #elif defined(__LITTLE_ENDIAN) @@ -725,8 +825,10 @@ struct ustorm_iscsi_st_context { #define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 u8 hdr_second_byte_union; #endif #if defined(__BIG_ENDIAN) @@ -777,14 +879,14 @@ struct ustorm_iscsi_st_context { */ struct tstorm_tcp_st_context_section { u32 flags1; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_SHIFT 0 #define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID (0x1<<24) #define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID_SHIFT 24 #define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS (0x1<<25) #define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS_SHIFT 25 -#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS (0x1<<26) -#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS_SHIFT 26 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0 (0x1<<26) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0_SHIFT 26 #define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD (0x1<<27) #define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD_SHIFT 27 #define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED (0x1<<28) @@ -793,11 +895,11 @@ struct tstorm_tcp_st_context_section { #define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE_SHIFT 29 #define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN (0x1<<30) #define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN_SHIFT 30 -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3 (0x1<<31) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3_SHIFT 31 +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN (0x1<<31) +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN_SHIFT 31 u32 flags2; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_SHIFT 0 #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN (0x1<<24) #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN_SHIFT 24 #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN (0x1<<25) @@ -810,18 +912,18 @@ struct tstorm_tcp_st_context_section { #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 28 #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<29) #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 29 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED (0x1<<30) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED_SHIFT 30 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO (0x1<<31) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO_SHIFT 31 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK (0x1<<30) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK_SHIFT 30 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK (0x1<<31) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK_SHIFT 31 #if defined(__BIG_ENDIAN) - u16 reserved_slowpath; - u8 tcp_sm_state_3b; - u8 rto_exp_3b; + u16 mss; + u8 tcp_sm_state; + u8 rto_exp; #elif defined(__LITTLE_ENDIAN) - u8 rto_exp_3b; - u8 tcp_sm_state_3b; - u16 reserved_slowpath; + u8 rto_exp; + u8 tcp_sm_state; + u16 mss; #endif u32 rcv_nxt; u32 timestamp_recent; @@ -846,11 +948,11 @@ struct tstorm_tcp_st_context_section { #if defined(__BIG_ENDIAN) u8 statistics_counter_id; u8 ooo_support_mode; - u8 snd_wnd_scale_4b; + u8 snd_wnd_scale; u8 dup_ack_count; #elif defined(__LITTLE_ENDIAN) u8 dup_ack_count; - u8 snd_wnd_scale_4b; + u8 snd_wnd_scale; u8 ooo_support_mode; u8 statistics_counter_id; #endif @@ -860,13 +962,21 @@ struct tstorm_tcp_st_context_section { u32 isle_start_seq; u32 isle_end_seq; #if defined(__BIG_ENDIAN) - u16 mss; + u16 second_isle_address; u16 recent_seg_wnd; #elif defined(__LITTLE_ENDIAN) u16 recent_seg_wnd; - u16 mss; + u16 second_isle_address; +#endif +#if defined(__BIG_ENDIAN) + u8 max_isles_ever_happened; + u8 isles_number; + u16 last_isle_address; +#elif defined(__LITTLE_ENDIAN) + u16 last_isle_address; + u8 isles_number; + u8 max_isles_ever_happened; #endif - u32 reserved4; u32 max_rt_time; #if defined(__BIG_ENDIAN) u16 lsb_mac_address; @@ -876,7 +986,7 @@ struct tstorm_tcp_st_context_section { u16 lsb_mac_address; #endif u32 msb_mac_address; - u32 reserved2; + u32 rightmost_received_seq; }; /* @@ -951,7 +1061,7 @@ struct tstorm_iscsi_st_context_section { u8 scratchpad_idx; struct iscsi_term_vars term_vars; #endif - u32 reserved2; + u32 process_nxt; }; /* @@ -1174,24 +1284,12 @@ struct xstorm_iscsi_ag_context { #endif #if defined(__BIG_ENDIAN) u8 cdu_reserved; - u8 agg_vars4; -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7 + u8 __agg_vars4; u8 agg_vars3; #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 u8 agg_vars2; #define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0) #define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0 @@ -1222,21 +1320,9 @@ struct xstorm_iscsi_ag_context { u8 agg_vars3; #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6 - u8 agg_vars4; -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 + u8 __agg_vars4; u8 cdu_reserved; #endif u32 more_to_send; @@ -1270,8 +1356,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4) -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 #define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) @@ -1286,8 +1372,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 u8 agg_val3_th; u8 agg_vars6; #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0) @@ -1310,8 +1396,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4) -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 #define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) @@ -1326,14 +1412,14 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 #endif #if defined(__BIG_ENDIAN) u16 __agg_val11_th; - u16 __agg_val11; + u16 __gen_data; #elif defined(__LITTLE_ENDIAN) - u16 __agg_val11; + u16 __gen_data; u16 __agg_val11_th; #endif #if defined(__BIG_ENDIAN) @@ -1384,7 +1470,7 @@ struct xstorm_iscsi_ag_context { #endif u32 hq_cons_tcp_seq; u32 exp_stat_sn; - u32 agg_misc5; + u32 rst_seq_num; }; /* @@ -1478,12 +1564,12 @@ struct tstorm_iscsi_ag_context { #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 u8 state; #elif defined(__LITTLE_ENDIAN) u8 state; @@ -1496,63 +1582,63 @@ struct tstorm_iscsi_ag_context { #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 u16 ulp_credit; #endif #if defined(__BIG_ENDIAN) u16 __agg_val4; u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11) -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11 -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 #elif defined(__LITTLE_ENDIAN) u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11) -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11 -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) @@ -1562,100 +1648,6 @@ struct tstorm_iscsi_ag_context { struct tstorm_tcp_tcp_ag_context_section tcp; }; -/* - * The iscsi aggregative context of Cstorm - */ -struct cstorm_iscsi_ag_context { - u32 agg_vars1; -#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0) -#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16 -#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18) -#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22 -#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23) -#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23 -#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26) -#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30 -#if defined(__BIG_ENDIAN) - u8 __aux1_th; - u8 __aux1_val; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u8 __aux1_val; - u8 __aux1_th; -#endif - u32 rel_seq; - u32 rel_seq_th; -#if defined(__BIG_ENDIAN) - u16 hq_cons; - u16 hq_prod; -#elif defined(__LITTLE_ENDIAN) - u16 hq_prod; - u16 hq_cons; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved62; - u8 __reserved61; - u8 __reserved60; - u8 __reserved59; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved59; - u8 __reserved60; - u8 __reserved61; - u8 __reserved62; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved64; - u16 __cq_u_prod0; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod0; - u16 __reserved64; -#endif - u32 __cq_u_prod1; -#if defined(__BIG_ENDIAN) - u16 __agg_vars3; - u16 __cq_u_prod2; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod2; - u16 __agg_vars3; -#endif -#if defined(__BIG_ENDIAN) - u16 __aux2_th; - u16 __cq_u_prod3; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod3; - u16 __aux2_th; -#endif -}; - /* * The iscsi aggregative context of Ustorm */ @@ -1746,8 +1738,8 @@ struct ustorm_iscsi_ag_context { #define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 u8 decision_rule_enable_bits; @@ -1790,30 +1782,14 @@ struct ustorm_iscsi_ag_context { #define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 u16 __reserved2; #endif }; -/* - * Timers connection context - */ -struct iscsi_timers_block_context { - u32 __reserved_0; - u32 __reserved_1; - u32 __reserved_2; - u32 flags; -#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0) -#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0 -#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2) -#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2 -#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3) -#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3 -}; - /* * Ethernet context section, shared in TOE, RDMA and ISCSI */ @@ -1963,7 +1939,7 @@ struct xstorm_tcp_context_section { #endif #if defined(__BIG_ENDIAN) u8 original_nagle_1b; - u8 ts_enabled_1b; + u8 ts_enabled; u16 tcp_params; #define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0) #define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0 @@ -1973,8 +1949,8 @@ struct xstorm_tcp_context_section { #define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) @@ -1991,15 +1967,15 @@ struct xstorm_tcp_context_section { #define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13 #define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14) #define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14 - u8 ts_enabled_1b; + u8 ts_enabled; u8 original_nagle_1b; #endif #if defined(__BIG_ENDIAN) @@ -2030,8 +2006,8 @@ struct xstorm_common_context_section { #define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7 +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 u8 ip_version_1b; #elif defined(__LITTLE_ENDIAN) u8 ip_version_1b; @@ -2042,8 +2018,8 @@ struct xstorm_common_context_section { #define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7 +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 u16 reserved; #endif }; @@ -2284,7 +2260,7 @@ struct iscsi_context { struct tstorm_iscsi_ag_context tstorm_ag_context; struct cstorm_iscsi_ag_context cstorm_ag_context; struct ustorm_iscsi_ag_context ustorm_ag_context; - struct iscsi_timers_block_context timers_context; + struct timers_block_context timers_context; struct regpair upb_context; struct xstorm_iscsi_st_context xstorm_st_context; struct regpair xpb_context; @@ -2434,16 +2410,16 @@ struct l5cm_packet_size { * l5cm connection parameters */ union l5cm_reduce_param_union { - u32 passive_side_scramble_key; - u32 pcs_id; + u32 opaque1; + u32 opaque2; }; /* * l5cm connection parameters */ struct l5cm_reduce_conn { - union l5cm_reduce_param_union param; - u32 isn; + union l5cm_reduce_param_union opaque1; + u32 opaque2; }; /* diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 344c842d55ab..4018de12f819 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -138,6 +138,7 @@ struct cnic_irq { unsigned int vector; void *status_blk; u32 status_blk_num; + u32 status_blk_num2; u32 irq_flags; #define CNIC_IRQ_FL_MSIX 0x00000001 }; @@ -152,6 +153,7 @@ struct cnic_eth_dev { struct pci_dev *pdev; void __iomem *io_base; void __iomem *io_base2; + void *iro_arr; u32 ctx_tbl_offset; u32 ctx_tbl_len; diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 00c033511cbf..99568cb9ad1c 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -58,6 +58,8 @@ #define MAX_PAGES_PER_CTRL_STRUCT_POOL 8 #define BNX2I_RESERVED_SLOW_PATH_CMD_SLOTS 4 +#define BNX2I_5771X_DBELL_PAGE_SIZE 128 + /* 5706/08 hardware has limit on maximum buffer size per BD it can handle */ #define MAX_BD_LENGTH 65535 #define BD_SPLIT_SIZE 32768 diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index d23fc256d585..99c71e6d4c14 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2405,7 +2405,8 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) { reg_base = pci_resource_start(ep->hba->pcidev, BNX2X_DOORBELL_PCI_BAR); - reg_off = PAGE_SIZE * (cid_num & 0x1FFFF) + DPM_TRIGER_TYPE; + reg_off = BNX2I_5771X_DBELL_PAGE_SIZE * (cid_num & 0x1FFFF) + + DPM_TRIGER_TYPE; ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, 4); goto arm_cq; } diff --git a/firmware/Makefile b/firmware/Makefile index 44b3aae66b84..e0a3439ab312 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -32,8 +32,8 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw -fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-5.2.13.0.fw \ - bnx2x/bnx2x-e1h-5.2.13.0.fw +fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \ + bnx2x/bnx2x-e1h-6.0.34.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \ bnx2/bnx2-rv2p-09-5.0.0.j10.fw \ bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \ -- cgit v1.2.3 From fb3bff178e722fe88b5ab02319c9636da0980e25 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:26:40 +0000 Subject: bnx2x: rename MF related fields MF (multi-function) mode supported not only by 57711E (E1H) devices, but also by coming 57712E, then we use more generic names. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 8 +++--- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_ethtool.c | 24 ++++++++--------- drivers/net/bnx2x/bnx2x_main.c | 56 +++++++++++++++++++-------------------- drivers/net/bnx2x/bnx2x_stats.c | 4 +-- 5 files changed, 47 insertions(+), 47 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 8b053e0c00ab..d7b24f9e7939 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -933,9 +933,9 @@ struct bnx2x { u32 vn_weight_sum; u32 mf_config; - u16 e1hov; - u8 e1hmf; -#define IS_E1HMF(bp) (bp->e1hmf != 0) + u16 mf_ov; + u8 mf_mode; +#define IS_MF(bp) (bp->mf_mode != 0) u8 wol; @@ -1127,7 +1127,7 @@ struct bnx2x { #define RSS_IPV6_CAP 0x0004 #define RSS_IPV6_TCP_CAP 0x0008 -#define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ +#define BNX2X_MAX_QUEUES(bp) (IS_MF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index bcc4a8f4677b..ae05987e647e 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -745,7 +745,7 @@ void bnx2x_link_report(struct bnx2x *bp) netdev_info(bp->dev, "NIC Link is Up, "); line_speed = bp->link_vars.line_speed; - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { u16 vn_max_rate; vn_max_rate = diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 56a0cb579c21..fa8f9526f93c 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -41,7 +41,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) (bp->link_vars.link_up)) { cmd->speed = bp->link_vars.line_speed; cmd->duplex = bp->link_vars.duplex; - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { u16 vn_max_rate; vn_max_rate = @@ -89,7 +89,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) struct bnx2x *bp = netdev_priv(dev); u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; - if (IS_E1HMF(bp)) + if (IS_MF(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" @@ -1027,7 +1027,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev, { struct bnx2x *bp = netdev_priv(dev); u32 cfg_idx = bnx2x_get_link_cfg_idx(bp); - if (IS_E1HMF(bp)) + if (IS_MF(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n" @@ -1616,7 +1616,7 @@ static void bnx2x_self_test(struct net_device *dev, return; /* offline tests are not supported in MF mode */ - if (IS_E1HMF(bp)) + if (IS_MF(bp)) etest->flags &= ~ETH_TEST_FL_OFFLINE; is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; @@ -1808,8 +1808,8 @@ static const struct { #define IS_PORT_STAT(i) \ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) #define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) -#define IS_E1HMF_MODE_STAT(bp) \ - (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) +#define IS_MF_MODE_STAT(bp) \ + (IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) static int bnx2x_get_sset_count(struct net_device *dev, int stringset) { @@ -1820,10 +1820,10 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) case ETH_SS_STATS: if (is_multi(bp)) { num_stats = BNX2X_NUM_Q_STATS * bp->num_queues; - if (!IS_E1HMF_MODE_STAT(bp)) + if (!IS_MF_MODE_STAT(bp)) num_stats += BNX2X_NUM_STATS; } else { - if (IS_E1HMF_MODE_STAT(bp)) { + if (IS_MF_MODE_STAT(bp)) { num_stats = 0; for (i = 0; i < BNX2X_NUM_STATS; i++) if (IS_FUNC_STAT(i)) @@ -1856,14 +1856,14 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) bnx2x_q_stats_arr[j].string, i); k += BNX2X_NUM_Q_STATS; } - if (IS_E1HMF_MODE_STAT(bp)) + if (IS_MF_MODE_STAT(bp)) break; for (j = 0; j < BNX2X_NUM_STATS; j++) strcpy(buf + (k + j)*ETH_GSTRING_LEN, bnx2x_stats_arr[j].string); } else { for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) continue; strcpy(buf + j*ETH_GSTRING_LEN, bnx2x_stats_arr[i].string); @@ -1907,7 +1907,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } k += BNX2X_NUM_Q_STATS; } - if (IS_E1HMF_MODE_STAT(bp)) + if (IS_MF_MODE_STAT(bp)) return; hw_stats = (u32 *)&bp->eth_stats; for (j = 0; j < BNX2X_NUM_STATS; j++) { @@ -1928,7 +1928,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } else { hw_stats = (u32 *)&bp->eth_stats; for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) continue; if (bnx2x_stats_arr[i].size == 0) { /* skip this counter */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 119ca871f016..238e38f051fb 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1013,7 +1013,7 @@ void bnx2x_int_enable(struct bnx2x *bp) if (CHIP_IS_E1H(bp)) { /* init leading/trailing edge */ - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); if (bp->port.pmf) /* enable nig and gpio3 attention */ @@ -1792,7 +1792,7 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) { if (CHIP_REV_IS_SLOW(bp)) return CMNG_FNS_NONE; - if (IS_E1HMF(bp)) + if (IS_MF(bp)) return CMNG_FNS_MINMAX; return CMNG_FNS_NONE; @@ -1906,7 +1906,7 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (prev_link_status != bp->link_vars.link_status) bnx2x_link_report(bp); - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { int port = BP_PORT(bp); int func; int vn; @@ -2160,7 +2160,7 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, /* calculate queue flags */ flags |= QUEUE_FLG_CACHE_ALIGN; flags |= QUEUE_FLG_HC; - flags |= IS_E1HMF(bp) ? QUEUE_FLG_OV : 0; + flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; #ifdef BCM_VLAN flags |= QUEUE_FLG_VLAN; @@ -2262,7 +2262,7 @@ void bnx2x_pf_init(struct bnx2x *bp) /* pf specific setups */ if (!CHIP_IS_E1(bp)) - storm_memset_ov(bp, bp->e1hov, BP_FUNC(bp)); + storm_memset_ov(bp, bp->mf_ov, BP_FUNC(bp)); /* function setup flags */ flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); @@ -3855,13 +3855,13 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) /* xstorm needs to know whether to add ovlan to packets or not, * in switch-independent we'll write 0 to here... */ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); } /* Zero this manually as its initialization is @@ -4418,7 +4418,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); if (CHIP_IS_E1H(bp)) - REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp)); + REG_WR(bp, MISC_REG_E1HMF_MODE, IS_MF(bp)); REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); msleep(30); @@ -4518,7 +4518,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif if (CHIP_IS_E1H(bp)) - REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); + REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); @@ -4596,8 +4596,8 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); if (CHIP_IS_E1H(bp)) { - REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp)); - REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp)); + REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); + REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); } if (CHIP_REV_IS_SLOW(bp)) @@ -4692,7 +4692,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) low = 0; high = 513; } else { - if (IS_E1HMF(bp)) + if (IS_MF(bp)) low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); else if (bp->dev->mtu > 4096) { if (bp->flags & ONE_PORT_FLAG) @@ -4758,7 +4758,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF * bits 4-7 are used for "per vn group attention" */ REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, - (IS_E1HMF(bp) ? 0xF7 : 0x7)); + (IS_MF(bp) ? 0xF7 : 0x7)); bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); @@ -4771,9 +4771,9 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); if (CHIP_IS_E1H(bp)) { - /* 0x2 disable e1hov, 0x1 enable */ + /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, - (IS_E1HMF(bp) ? 0x1 : 0x2)); + (IS_MF(bp) ? 0x1 : 0x2)); { REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); @@ -4883,9 +4883,9 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); - REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); + REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov); } bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); @@ -7189,8 +7189,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->igu_base_sb = 0; bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); - bp->e1hov = 0; - bp->e1hmf = 0; + bp->mf_ov = 0; + bp->mf_mode = 0; if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { bp->common.mf_cfg_base = bp->common.shmem_base + @@ -7202,19 +7202,19 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) - bp->e1hmf = 1; + bp->mf_mode = 1; BNX2X_DEV_INFO("%s function mode\n", - IS_E1HMF(bp) ? "multi" : "single"); + IS_MF(bp) ? "multi" : "single"); - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { val = (MF_CFG_RD(bp, func_mf_config[func]. e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - bp->e1hov = val; + bp->mf_ov = val; BNX2X_DEV_INFO("E1HOV for func %d is %d " "(0x%04x)\n", - func, bp->e1hov, bp->e1hov); + func, bp->mf_ov, bp->mf_ov); } else { BNX2X_ERROR("No valid E1HOV for func %d," " aborting\n", func); @@ -7230,7 +7230,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } /* adjust igu_sb_cnt to MF */ - if (IS_E1HMF(bp)) + if (IS_MF(bp)) bp->igu_sb_cnt /= E1HVN_MAX; if (!BP_NOMCP(bp)) { @@ -7241,7 +7241,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 1256f62f7bff..c271fc52613d 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -253,7 +253,7 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) u32 *stats_comp = bnx2x_sp(bp, stats_comp); /* sanity */ - if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) { + if (!IS_MF(bp) || !bp->port.pmf || !bp->port.port_stx) { BNX2X_ERR("BUG!\n"); return; } @@ -1284,7 +1284,7 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) static void bnx2x_func_stats_base_init(struct bnx2x *bp) { - int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; + int vn, vn_max = IS_MF(bp) ? E1HVN_MAX : E1VN_MAX; int port = BP_PORT(bp); int func; u32 func_stx; -- cgit v1.2.3 From f2e0899f0f275cc3f5e9c9726178d7d0ac19b2db Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:28:26 +0000 Subject: bnx2x: Add 57712 support 57712 HW supported with same set of features as for 57710/57711 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 124 ++- drivers/net/bnx2x/bnx2x_cmn.c | 275 ++++-- drivers/net/bnx2x/bnx2x_cmn.h | 137 ++- drivers/net/bnx2x/bnx2x_dump.h | 35 +- drivers/net/bnx2x/bnx2x_ethtool.c | 123 ++- drivers/net/bnx2x/bnx2x_hsi.h | 187 +++- drivers/net/bnx2x/bnx2x_init.h | 3 + drivers/net/bnx2x/bnx2x_init_ops.h | 28 +- drivers/net/bnx2x/bnx2x_link.c | 379 ++++++-- drivers/net/bnx2x/bnx2x_link.h | 6 +- drivers/net/bnx2x/bnx2x_main.c | 1777 +++++++++++++++++++++++++++--------- drivers/net/bnx2x/bnx2x_reg.h | 879 +++++++++++++++++- drivers/net/bnx2x/bnx2x_stats.c | 262 +++--- firmware/Makefile | 3 +- 14 files changed, 3428 insertions(+), 790 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 09fb7ff811d8..6f8e2666f05f 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -180,10 +180,16 @@ void bnx2x_panic_dump(struct bnx2x *bp); #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) #define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ offsetof(struct mf_cfg, field)) +#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \ + offsetof(struct mf2_cfg, field)) #define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) #define MF_CFG_WR(bp, field, val) REG_WR(bp,\ MF_CFG_ADDR(bp, field), (val)) +#define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field)) +#define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \ + (SHMEM2_RD((bp), size) > \ + offsetof(struct shmem2_region, field))) #define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg) #define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val) @@ -296,6 +302,8 @@ union db_prod { union host_hc_status_block { /* pointer to fp status block e1x */ struct host_hc_status_block_e1x *e1x_sb; + /* pointer to fp status block e2 */ + struct host_hc_status_block_e2 *e2_sb; }; struct bnx2x_fastpath { @@ -564,12 +572,19 @@ struct bnx2x_common { #define CHIP_NUM_57710 0x164e #define CHIP_NUM_57711 0x164f #define CHIP_NUM_57711E 0x1650 +#define CHIP_NUM_57712 0x1662 +#define CHIP_NUM_57712E 0x1663 #define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710) #define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711) #define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E) +#define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712) +#define CHIP_IS_57712E(bp) (CHIP_NUM(bp) == CHIP_NUM_57712E) #define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ CHIP_IS_57711E(bp)) -#define IS_E1H_OFFSET CHIP_IS_E1H(bp) +#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ + CHIP_IS_57712E(bp)) +#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp))) +#define IS_E1H_OFFSET (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) #define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000) #define CHIP_REV_Ax 0x00000000 @@ -596,6 +611,7 @@ struct bnx2x_common { u32 shmem_base; u32 shmem2_base; u32 mf_cfg_base; + u32 mf2_cfg_base; u32 hw_config; @@ -603,10 +619,25 @@ struct bnx2x_common { u8 int_block; #define INT_BLOCK_HC 0 +#define INT_BLOCK_IGU 1 +#define INT_BLOCK_MODE_NORMAL 0 +#define INT_BLOCK_MODE_BW_COMP 2 +#define CHIP_INT_MODE_IS_NBC(bp) \ + (CHIP_IS_E2(bp) && \ + !((bp)->common.int_block & INT_BLOCK_MODE_BW_COMP)) +#define CHIP_INT_MODE_IS_BC(bp) (!CHIP_INT_MODE_IS_NBC(bp)) + u8 chip_port_mode; +#define CHIP_4_PORT_MODE 0x0 +#define CHIP_2_PORT_MODE 0x1 #define CHIP_PORT_MODE_NONE 0x2 +#define CHIP_MODE(bp) (bp->common.chip_port_mode) +#define CHIP_MODE_IS_4_PORT(bp) (CHIP_MODE(bp) == CHIP_4_PORT_MODE) }; +/* IGU MSIX STATISTICS on 57712: 64 for VFs; 4 for PFs; 4 for Attentions */ +#define BNX2X_IGU_STAS_MSG_VF_CNT 64 +#define BNX2X_IGU_STAS_MSG_PF_CNT 4 /* end of common */ @@ -670,7 +701,7 @@ enum { */ #define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */ -#define MAX_CONTEXT FP_SB_MAX_E1x +#define FP_SB_MAX_E2 16 /* fast-path interrupt contexts E2 */ /* * cid_cnt paramter below refers to the value returned by @@ -754,7 +785,7 @@ struct bnx2x_slowpath { #define MAX_DYNAMIC_ATTN_GRPS 8 struct attn_route { - u32 sig[4]; + u32 sig[5]; }; struct iro { @@ -896,13 +927,20 @@ struct bnx2x { #define HW_VLAN_RX_FLAG 0x800 #define MF_FUNC_DIS 0x1000 - int func; + int pf_num; /* absolute PF number */ + int pfid; /* per-path PF number */ int base_fw_ndsb; - -#define BP_PORT(bp) (bp->func % PORT_MAX) -#define BP_FUNC(bp) (bp->func) -#define BP_E1HVN(bp) (bp->func >> 1) +#define BP_PATH(bp) (!CHIP_IS_E2(bp) ? \ + 0 : (bp->pf_num & 1)) +#define BP_PORT(bp) (bp->pfid & 1) +#define BP_FUNC(bp) (bp->pfid) +#define BP_ABS_FUNC(bp) (bp->pf_num) +#define BP_E1HVN(bp) (bp->pfid >> 1) +#define BP_VN(bp) (CHIP_MODE_IS_4_PORT(bp) ? \ + 0 : BP_E1HVN(bp)) #define BP_L_ID(bp) (BP_E1HVN(bp) << 2) +#define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\ + BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1)) #ifdef BCM_CNIC #define BCM_CNIC_CID_START 16 @@ -932,7 +970,8 @@ struct bnx2x { struct cmng_struct_per_port cmng; u32 vn_weight_sum; - u32 mf_config; + u32 mf_config[E1HVN_MAX]; + u32 mf2_config[E2_FUNC_MAX]; u16 mf_ov; u8 mf_mode; #define IS_MF(bp) (bp->mf_mode != 0) @@ -1127,11 +1166,11 @@ struct bnx2x { #define RSS_IPV6_CAP 0x0004 #define RSS_IPV6_TCP_CAP 0x0008 -#define BNX2X_MAX_QUEUES(bp) (IS_MF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ - : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) +#define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE) +#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1) #define RSS_IPV4_CAP_MASK \ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY @@ -1342,14 +1381,40 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, /* DMAE command defines */ -#define DMAE_CMD_SRC_PCI 0 -#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC +#define DMAE_TIMEOUT -1 +#define DMAE_PCI_ERROR -2 /* E2 and onward */ +#define DMAE_NOT_RDY -3 +#define DMAE_PCI_ERR_FLAG 0x80000000 + +#define DMAE_SRC_PCI 0 +#define DMAE_SRC_GRC 1 + +#define DMAE_DST_NONE 0 +#define DMAE_DST_PCI 1 +#define DMAE_DST_GRC 2 + +#define DMAE_COMP_PCI 0 +#define DMAE_COMP_GRC 1 + +/* E2 and onward - PCI error handling in the completion */ + +#define DMAE_COMP_REGULAR 0 +#define DMAE_COM_SET_ERR 1 -#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT) -#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT) +#define DMAE_CMD_SRC_PCI (DMAE_SRC_PCI << \ + DMAE_COMMAND_SRC_SHIFT) +#define DMAE_CMD_SRC_GRC (DMAE_SRC_GRC << \ + DMAE_COMMAND_SRC_SHIFT) -#define DMAE_CMD_C_DST_PCI 0 -#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT) +#define DMAE_CMD_DST_PCI (DMAE_DST_PCI << \ + DMAE_COMMAND_DST_SHIFT) +#define DMAE_CMD_DST_GRC (DMAE_DST_GRC << \ + DMAE_COMMAND_DST_SHIFT) + +#define DMAE_CMD_C_DST_PCI (DMAE_COMP_PCI << \ + DMAE_COMMAND_C_DST_SHIFT) +#define DMAE_CMD_C_DST_GRC (DMAE_COMP_GRC << \ + DMAE_COMMAND_C_DST_SHIFT) #define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE @@ -1365,10 +1430,20 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET #define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT +#define DMAE_SRC_PF 0 +#define DMAE_SRC_VF 1 + +#define DMAE_DST_PF 0 +#define DMAE_DST_VF 1 + +#define DMAE_C_SRC 0 +#define DMAE_C_DST 1 + #define DMAE_LEN32_RD_MAX 0x80 #define DMAE_LEN32_WR_MAX(bp) (CHIP_IS_E1(bp) ? 0x400 : 0x2000) -#define DMAE_COMP_VAL 0xe0d0d0ae +#define DMAE_COMP_VAL 0x60d0d0ae /* E2 and on - upper bit + indicates eror */ #define MAX_DMAE_C_PER_PORT 8 #define INIT_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ @@ -1534,6 +1609,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define GET_FLAG(value, mask) \ (((value) &= (mask)) >> (mask##_SHIFT)) +#define GET_FIELD(value, fname) \ + (((value) & (fname##_MASK)) >> (fname##_SHIFT)) + #define CAM_IS_INVALID(x) \ (GET_FLAG(x.flags, \ MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \ @@ -1553,6 +1631,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0 #endif +#ifndef ETH_MAX_RX_CLIENTS_E2 +#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H +#endif #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 @@ -1570,13 +1651,18 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_EXTERN extern #endif -BNX2X_EXTERN int load_count[3]; /* 0-common, 1-port0, 2-port1 */ +BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ /* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type); + #define WAIT_RAMROD_POLL 0x01 #define WAIT_RAMROD_COMMON 0x02 diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index ae05987e647e..cffa778ec5bf 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include "bnx2x_cmn.h" @@ -118,16 +118,10 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) pkt_cons = TX_BD(sw_cons); - /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */ + DP(NETIF_MSG_TX_DONE, "queue[%d]: hw_cons %u sw_cons %u " + " pkt_cons %u\n", + fp->index, hw_cons, sw_cons, pkt_cons); - DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n", - hw_cons, sw_cons, pkt_cons); - -/* if (NEXT_TX_IDX(sw_cons) != hw_cons) { - rmb(); - prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb); - } -*/ bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons); sw_cons++; } @@ -749,8 +743,9 @@ void bnx2x_link_report(struct bnx2x *bp) u16 vn_max_rate; vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + ((bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT) * 100; if (vn_max_rate < line_speed) line_speed = vn_max_rate; } @@ -912,14 +907,15 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) if (j != 0) continue; - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, - U64_HI(fp->rx_comp_mapping)); + if (!CHIP_IS_E2(bp)) { + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), + U64_LO(fp->rx_comp_mapping)); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, + U64_HI(fp->rx_comp_mapping)); + } } - } static void bnx2x_free_tx_skbs(struct bnx2x *bp) { @@ -1308,23 +1304,27 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } else { + int path = BP_PATH(bp); int port = BP_PORT(bp); - DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]++; - load_count[1 + port]++; - DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 1) + DP(NETIF_MSG_IFUP, "NO MCP - load counts[%d] %d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + load_count[path][0]++; + load_count[path][1 + port]++; + DP(NETIF_MSG_IFUP, "NO MCP - new load counts[%d] %d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + if (load_count[path][0] == 1) load_code = FW_MSG_CODE_DRV_LOAD_COMMON; - else if (load_count[1 + port] == 1) + else if (load_count[path][1 + port] == 1) load_code = FW_MSG_CODE_DRV_LOAD_PORT; else load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; } if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) bp->port.pmf = 1; else @@ -1349,7 +1349,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp, load_code); - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) && + if (((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP)) && (bp->common.shmem2_base)) SHMEM2_WR(bp, dcc_support, (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV | @@ -1389,11 +1390,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif } - if (CHIP_IS_E1H(bp)) - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { - DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; - } + if (!CHIP_IS_E1(bp) && + (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED)) { + DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); + bp->flags |= MF_FUNC_DIS; + } #ifdef BCM_CNIC /* Enable Timer scan */ @@ -1527,8 +1528,10 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->rx_mode = BNX2X_RX_MODE_NONE; bnx2x_set_storm_rx_mode(bp); + /* Stop Tx */ + bnx2x_tx_disable(bp); del_timer_sync(&bp->timer); - SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, + SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb, (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -1855,6 +1858,120 @@ exit_lbl: } #endif +static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, + struct eth_tx_parse_bd_e2 *pbd, + u32 xmit_type) +{ + pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << + ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; + if ((xmit_type & XMIT_GSO_V6) && + (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) + pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; +} + +/** + * Update PBD in GSO case. + * + * @param skb + * @param tx_start_bd + * @param pbd + * @param xmit_type + */ +static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) +{ + pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); + pbd->tcp_flags = pbd_tcp_flags(skb); + + if (xmit_type & XMIT_GSO_V4) { + pbd->ip_id = swab16(ip_hdr(skb)->id); + pbd->tcp_pseudo_csum = + swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + } else + pbd->tcp_pseudo_csum = + swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + pbd->global_data |= ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; +} +/** + * + * @param skb + * @param tx_start_bd + * @param pbd_e2 + * @param xmit_type + * + * @return header len + */ +static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_parse_bd_e2 *pbd, + u32 xmit_type) +{ + pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; + + pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - + skb->data) / 2) << + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; + + return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; +} + +/** + * + * @param skb + * @param tx_start_bd + * @param pbd + * @param xmit_type + * + * @return Header length + */ +static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) +{ + u8 hlen = (skb_network_header(skb) - skb->data) / 2; + + /* for now NS flag is not used in Linux */ + pbd->global_data = + (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << + ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); + + pbd->ip_hlen_w = (skb_transport_header(skb) - + skb_network_header(skb)) / 2; + + hlen += pbd->ip_hlen_w + tcp_hdrlen(skb) / 2; + + pbd->total_hlen_w = cpu_to_le16(hlen); + hlen = hlen*2; + + if (xmit_type & XMIT_CSUM_TCP) { + pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); + + } else { + s8 fix = SKB_CS_OFF(skb); /* signed! */ + + DP(NETIF_MSG_TX_QUEUED, + "hlen %d fix %d csum before fix %x\n", + le16_to_cpu(pbd->total_hlen_w), fix, SKB_CS(skb)); + + /* HW bug: fixup the CSUM */ + pbd->tcp_pseudo_csum = + bnx2x_csum_fix(skb_transport_header(skb), + SKB_CS(skb), fix); + + DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", + pbd->tcp_pseudo_csum); + } + + return hlen; +} /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue() @@ -1868,6 +1985,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_start_bd *tx_start_bd; struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -1895,9 +2013,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } - DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)" - " gso type %x xmit_type %x\n", - skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, + DP(NETIF_MSG_TX_QUEUED, "queue[%d]: SKB: summed %x protocol %x " + "protocol(%x,%x) gso type %x xmit_type %x\n", + fp_index, skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); eth = (struct ethhdr *)skb->data; @@ -1988,44 +2106,21 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IS_UDP; } - pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; - memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); - /* Set PBD in checksum offload case */ - if (xmit_type & XMIT_CSUM) { - hlen = (skb_network_header(skb) - skb->data) / 2; - /* for now NS flag is not used in Linux */ - pbd_e1x->global_data = - (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << - ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); - - pbd_e1x->ip_hlen_w = (skb_transport_header(skb) - - skb_network_header(skb)) / 2; - - hlen += pbd_e1x->ip_hlen_w + tcp_hdrlen(skb) / 2; - - pbd_e1x->total_hlen_w = cpu_to_le16(hlen); - hlen = hlen*2; - - if (xmit_type & XMIT_CSUM_TCP) { - pbd_e1x->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); - - } else { - s8 fix = SKB_CS_OFF(skb); /* signed! */ - - DP(NETIF_MSG_TX_QUEUED, - "hlen %d fix %d csum before fix %x\n", - le16_to_cpu(pbd_e1x->total_hlen_w), - fix, SKB_CS(skb)); - - /* HW bug: fixup the CSUM */ - pbd_e1x->tcp_pseudo_csum = - bnx2x_csum_fix(skb_transport_header(skb), - SKB_CS(skb), fix); + if (CHIP_IS_E2(bp)) { + pbd_e2 = &fp->tx_desc_ring[bd_prod].parse_bd_e2; + memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); + /* Set PBD in checksum offload case */ + if (xmit_type & XMIT_CSUM) + hlen = bnx2x_set_pbd_csum_e2(bp, + skb, pbd_e2, xmit_type); + } else { + pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); + /* Set PBD in checksum offload case */ + if (xmit_type & XMIT_CSUM) + hlen = bnx2x_set_pbd_csum(bp, skb, pbd_e1x, xmit_type); - DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", - pbd_e1x->tcp_pseudo_csum); - } } mapping = dma_map_single(&bp->pdev->dev, skb->data, @@ -2057,26 +2152,10 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(skb_headlen(skb) > hlen)) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); - - pbd_e1x->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - pbd_e1x->tcp_send_seq = swab32(tcp_hdr(skb)->seq); - pbd_e1x->tcp_flags = pbd_tcp_flags(skb); - - if (xmit_type & XMIT_GSO_V4) { - pbd_e1x->ip_id = swab16(ip_hdr(skb)->id); - pbd_e1x->tcp_pseudo_csum = - swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, - ip_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - } else - pbd_e1x->tcp_pseudo_csum = - swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - pbd_e1x->global_data |= - ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; + if (CHIP_IS_E2(bp)) + bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); + else + bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); } tx_data_bd = (struct eth_tx_bd *)tx_start_bd; @@ -2124,7 +2203,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) pbd_e1x->ip_id, pbd_e1x->lso_mss, pbd_e1x->tcp_flags, pbd_e1x->tcp_pseudo_csum, pbd_e1x->tcp_send_seq, le16_to_cpu(pbd_e1x->total_hlen_w)); - + if (pbd_e2) + DP(NETIF_MSG_TX_QUEUED, + "PBD (E2) @%p dst %x %x %x src %x %x %x parsing_data %x\n", + pbd_e2, pbd_e2->dst_mac_addr_hi, pbd_e2->dst_mac_addr_mid, + pbd_e2->dst_mac_addr_lo, pbd_e2->src_mac_addr_hi, + pbd_e2->src_mac_addr_mid, pbd_e2->src_mac_addr_lo, + pbd_e2->parsing_data); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); /* @@ -2327,6 +2412,8 @@ int bnx2x_resume(struct pci_dev *pdev) bnx2x_set_power_state(bp, PCI_D0); netif_device_attach(dev); + /* Since the chip was reset, clear the FW sequence number */ + bp->fw_seq = 0; rc = bnx2x_nic_load(bp, LOAD_OPEN); rtnl_unlock(); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 2fb9045833e1..41d0a177db7f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -366,10 +366,77 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, fp->index, bd_prod, rx_comp_prod, rx_sge_prod); } +static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, + u8 segment, u16 index, u8 op, + u8 update, u32 igu_addr) +{ + struct igu_regular cmd_data = {0}; + + cmd_data.sb_id_and_flags = + ((index << IGU_REGULAR_SB_INDEX_SHIFT) | + (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) | + (update << IGU_REGULAR_BUPDATE_SHIFT) | + (op << IGU_REGULAR_ENABLE_INT_SHIFT)); + DP(NETIF_MSG_HW, "write 0x%08x to IGU addr 0x%x\n", + cmd_data.sb_id_and_flags, igu_addr); + REG_WR(bp, igu_addr, cmd_data.sb_id_and_flags); + + /* Make sure that ACK is written */ + mmiowb(); + barrier(); +} -static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, - u8 storm, u16 index, u8 op, u8 update) +static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, + u8 idu_sb_id, bool is_Pf) +{ + u32 data, ctl, cnt = 100; + u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA; + u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL; + u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4; + u32 sb_bit = 1 << (idu_sb_id%32); + u32 func_encode = BP_FUNC(bp) | + ((is_Pf == true ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT); + u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id; + + /* Not supported in BC mode */ + if (CHIP_INT_MODE_IS_BC(bp)) + return; + + data = (IGU_USE_REGISTER_cstorm_type_0_sb_cleanup + << IGU_REGULAR_CLEANUP_TYPE_SHIFT) | + IGU_REGULAR_CLEANUP_SET | + IGU_REGULAR_BCLEANUP; + + ctl = addr_encode << IGU_CTRL_REG_ADDRESS_SHIFT | + func_encode << IGU_CTRL_REG_FID_SHIFT | + IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT; + + DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n", + data, igu_addr_data); + REG_WR(bp, igu_addr_data, data); + mmiowb(); + barrier(); + DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n", + ctl, igu_addr_ctl); + REG_WR(bp, igu_addr_ctl, ctl); + mmiowb(); + barrier(); + + /* wait for clean up to finish */ + while (!(REG_RD(bp, igu_addr_ack) & sb_bit) && --cnt) + msleep(20); + + + if (!(REG_RD(bp, igu_addr_ack) & sb_bit)) { + DP(NETIF_MSG_HW, "Unable to finish IGU cleanup: " + "idu_sb_id %d offset %d bit %d (cnt %d)\n", + idu_sb_id, idu_sb_id/32, idu_sb_id%32, cnt); + } +} + +static inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id, + u8 storm, u16 index, u8 op, u8 update) { u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + COMMAND_REG_INT_ACK); @@ -390,7 +457,37 @@ static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, mmiowb(); barrier(); } -static inline u16 bnx2x_ack_int(struct bnx2x *bp) + +static inline void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, + u16 index, u8 op, u8 update) +{ + u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8; + + bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update, + igu_addr); +} + +static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm, + u16 index, u8 op, u8 update) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_ack_sb(bp, igu_sb_id, storm, index, op, update); + else { + u8 segment; + + if (CHIP_INT_MODE_IS_BC(bp)) + segment = storm; + else if (igu_sb_id != bp->igu_dsb_id) + segment = IGU_SEG_ACCESS_DEF; + else if (storm == ATTENTION_ID) + segment = IGU_SEG_ACCESS_ATTN; + else + segment = IGU_SEG_ACCESS_DEF; + bnx2x_igu_ack_sb(bp, igu_sb_id, segment, index, op, update); + } +} + +static inline u16 bnx2x_hc_ack_int(struct bnx2x *bp) { u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + COMMAND_REG_SIMD_MASK); @@ -399,13 +496,34 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp) DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n", result, hc_addr); + barrier(); + return result; +} + +static inline u16 bnx2x_igu_ack_int(struct bnx2x *bp) +{ + u32 igu_addr = (BAR_IGU_INTMEM + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8); + u32 result = REG_RD(bp, igu_addr); + + DP(NETIF_MSG_HW, "read 0x%08x from IGU addr 0x%x\n", + result, igu_addr); + + barrier(); return result; } +static inline u16 bnx2x_ack_int(struct bnx2x *bp) +{ + barrier(); + if (bp->common.int_block == INT_BLOCK_HC) + return bnx2x_hc_ack_int(bp); + else + return bnx2x_igu_ack_int(bp); +} + /* * fast path service functions */ - static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) { /* Tell compiler that consumer and producer can change */ @@ -456,6 +574,17 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) rx_cons_sb++; return (fp->rx_comp_cons != rx_cons_sb); } +/** + * disables tx from stack point of view + * + * @param bp + */ +static inline void bnx2x_tx_disable(struct bnx2x *bp) +{ + netif_tx_disable(bp->dev); + netif_carrier_off(bp->dev); +} + static inline void bnx2x_free_rx_sge(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h index 3bb9a91bb3f7..dc18c25ca9e5 100644 --- a/drivers/net/bnx2x/bnx2x_dump.h +++ b/drivers/net/bnx2x/bnx2x_dump.h @@ -31,14 +31,24 @@ struct dump_sign { #define RI_E1 0x1 #define RI_E1H 0x2 +#define RI_E2 0x4 #define RI_ONLINE 0x100 - +#define RI_PATH0_DUMP 0x200 +#define RI_PATH1_DUMP 0x400 #define RI_E1_OFFLINE (RI_E1) #define RI_E1_ONLINE (RI_E1 | RI_ONLINE) #define RI_E1H_OFFLINE (RI_E1H) #define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) -#define RI_ALL_OFFLINE (RI_E1 | RI_E1H) -#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E2_OFFLINE (RI_E2) +#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) +#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) +#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) +#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) +#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) +#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) +#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2) +#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) #define MAX_TIMER_PENDING 200 #define TIMER_SCAN_DONT_CARE 0xFF @@ -513,6 +523,12 @@ static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = { { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE } }; +#define WREGS_COUNT_E2 1 +static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 }; + +static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = { + { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE } +}; static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 }; @@ -531,4 +547,17 @@ static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = { 0x1640d0, 0x1640d4 }; +#define PAGE_MODE_VALUES_E2 2 + +#define PAGE_READ_REGS_E2 1 + +#define PAGE_WRITE_REGS_E2 1 + +static const u32 page_vals_e2[PAGE_MODE_VALUES_E2] = { 0, 128 }; + +static const u32 page_write_regs_e2[PAGE_WRITE_REGS_E2] = { 328476 }; + +static const struct reg_addr page_read_regs_e2[PAGE_READ_REGS_E2] = { + { 0x58000, 4608, RI_E2_ONLINE } }; + #endif /* BNX2X_DUMP_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index fa8f9526f93c..8fb00276dc41 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -41,19 +41,19 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) (bp->link_vars.link_up)) { cmd->speed = bp->link_vars.line_speed; cmd->duplex = bp->link_vars.duplex; - if (IS_MF(bp)) { - u16 vn_max_rate; - - vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; - if (vn_max_rate < cmd->speed) - cmd->speed = vn_max_rate; - } } else { + cmd->speed = bp->link_params.req_line_speed[cfg_idx]; cmd->duplex = bp->link_params.req_duplex[cfg_idx]; } + if (IS_MF(bp)) { + u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * + 100; + + if (vn_max_rate < cmd->speed) + cmd->speed = vn_max_rate; + } if (bp->port.supported[cfg_idx] & SUPPORTED_TP) cmd->port = PORT_TP; @@ -298,6 +298,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) #define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) #define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) +#define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE) static int bnx2x_get_regs_len(struct net_device *dev) { @@ -315,7 +316,7 @@ static int bnx2x_get_regs_len(struct net_device *dev) regdump_len += wreg_addrs_e1[i].size * (1 + wreg_addrs_e1[i].read_regs_count); - } else { /* E1H */ + } else if (CHIP_IS_E1H(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E1H_ONLINE(reg_addrs[i].info)) regdump_len += reg_addrs[i].size; @@ -324,6 +325,15 @@ static int bnx2x_get_regs_len(struct net_device *dev) if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) regdump_len += wreg_addrs_e1h[i].size * (1 + wreg_addrs_e1h[i].read_regs_count); + } else if (CHIP_IS_E2(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E2_ONLINE(reg_addrs[i].info)) + regdump_len += reg_addrs[i].size; + + for (i = 0; i < WREGS_COUNT_E2; i++) + if (IS_E2_ONLINE(wreg_addrs_e2[i].info)) + regdump_len += wreg_addrs_e2[i].size * + (1 + wreg_addrs_e2[i].read_regs_count); } regdump_len *= 4; regdump_len += sizeof(struct dump_hdr); @@ -331,6 +341,23 @@ static int bnx2x_get_regs_len(struct net_device *dev) return regdump_len; } +static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p) +{ + u32 i, j, k, n; + + for (i = 0; i < PAGE_MODE_VALUES_E2; i++) { + for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { + REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]); + for (k = 0; k < PAGE_READ_REGS_E2; k++) + if (IS_E2_ONLINE(page_read_regs_e2[k].info)) + for (n = 0; n < + page_read_regs_e2[k].size; n++) + *p++ = REG_RD(bp, + page_read_regs_e2[k].addr + n*4); + } + } +} + static void bnx2x_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) { @@ -350,7 +377,14 @@ static void bnx2x_get_regs(struct net_device *dev, dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR); dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR); dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR); - dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE; + + if (CHIP_IS_E1(bp)) + dump_hdr.info = RI_E1_ONLINE; + else if (CHIP_IS_E1H(bp)) + dump_hdr.info = RI_E1H_ONLINE; + else if (CHIP_IS_E2(bp)) + dump_hdr.info = RI_E2_ONLINE | + (BP_PATH(bp) ? RI_PATH1_DUMP : RI_PATH0_DUMP); memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); p += dump_hdr.hdr_size + 1; @@ -362,16 +396,25 @@ static void bnx2x_get_regs(struct net_device *dev, *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); - } else { /* E1H */ + } else if (CHIP_IS_E1H(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E1H_ONLINE(reg_addrs[i].info)) for (j = 0; j < reg_addrs[i].size; j++) *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); + + } else if (CHIP_IS_E2(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E2_ONLINE(reg_addrs[i].info)) + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(bp, + reg_addrs[i].addr + j*4); + + bnx2x_read_pages_regs_e2(bp, p); } } -#define PHY_FW_VER_LEN 10 +#define PHY_FW_VER_LEN 20 static void bnx2x_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -474,7 +517,7 @@ static u32 bnx2x_get_link(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); - if (bp->flags & MF_FUNC_DIS) + if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN)) return 0; return bp->link_vars.link_up; @@ -1235,6 +1278,9 @@ static int bnx2x_test_registers(struct bnx2x *bp) for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { u32 offset, mask, save_val, val; + if (CHIP_IS_E2(bp) && + reg_tbl[i].offset0 == HC_REG_AGG_INT_0) + continue; offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; mask = reg_tbl[i].mask; @@ -1286,20 +1332,33 @@ static int bnx2x_test_memory(struct bnx2x *bp) u32 offset; u32 e1_mask; u32 e1h_mask; + u32 e2_mask; } prty_tbl[] = { - { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 }, - { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 }, - { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 }, - { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 }, - { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 }, - { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 }, - - { NULL, 0xffffffff, 0, 0 } + { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2, 0 }, + { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0, 0 }, + { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0, 0 }, + + { NULL, 0xffffffff, 0, 0, 0 } }; if (!netif_running(bp->dev)) return rc; + /* pre-Check the parity status */ + for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { + val = REG_RD(bp, prty_tbl[i].offset); + if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || + (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || + (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { + DP(NETIF_MSG_HW, + "%s is 0x%x\n", prty_tbl[i].name, val); + goto test_mem_exit; + } + } + /* Go through all the memories */ for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) for (j = 0; j < mem_tbl[i].size; j++) @@ -1309,7 +1368,8 @@ static int bnx2x_test_memory(struct bnx2x *bp) for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { val = REG_RD(bp, prty_tbl[i].offset); if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || - (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) { + (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || + (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { DP(NETIF_MSG_HW, "%s is 0x%x\n", prty_tbl[i].name, val); goto test_mem_exit; @@ -1324,7 +1384,7 @@ test_mem_exit: static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) { - int cnt = 1000; + int cnt = 1400; if (link_up) while (bnx2x_link_test(bp, is_serdes) && cnt--) @@ -1343,7 +1403,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) u16 pkt_prod, bd_prod; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; dma_addr_t mapping; union eth_rx_cqe *cqe; u8 cqe_fp_flags; @@ -1411,7 +1472,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; + pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2; + memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); wmb(); @@ -1431,6 +1494,13 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) if (tx_idx != tx_start_idx + num_pkts) goto test_loopback_exit; + /* Unlike HC IGU won't generate an interrupt for status block + * updates that have been performed while interrupts were + * disabled. + */ + if (bp->common.int_block == INT_BLOCK_IGU) + bnx2x_tx_int(fp_tx); + rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); if (rx_idx != rx_start_idx + num_pkts) goto test_loopback_exit; @@ -1573,8 +1643,7 @@ static int bnx2x_test_intr(struct bnx2x *bp) config->hdr.length = 0; if (CHIP_IS_E1(bp)) - /* use last unicast entries */ - config->hdr.offset = (BP_PORT(bp) ? 63 : 31); + config->hdr.offset = (BP_PORT(bp) ? 32 : 0); else config->hdr.offset = BP_FUNC(bp); config->hdr.client_id = bp->fp->cl_id; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 596041cbd977..18c8e23a0e82 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -663,6 +663,7 @@ struct shm_dev_info { /* size */ #define FUNC_7 7 #define E1_FUNC_MAX 2 #define E1H_FUNC_MAX 8 +#define E2_FUNC_MAX 4 /* per path */ #define VN_0 0 #define VN_1 1 @@ -821,6 +822,9 @@ struct drv_func_mb { #define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000 #define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000 #define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000 + /* Load common chip is supported from bc 6.0.0 */ +#define REQ_BC_VER_4_DRV_LOAD_COMMON_CHIP 0x00060000 +#define FW_MSG_CODE_DRV_LOAD_COMMON_CHIP 0x10130000 #define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000 #define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000 #define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000 @@ -1026,7 +1030,17 @@ struct shmem_region { /* SharedMem Offset (size) */ }; /* 57710 = 0x6dc | 57711 = 0x7E4 | 57712 = 0x734 */ +struct fw_flr_ack { + u32 pf_ack; + u32 vf_ack[1]; + u32 iov_dis_ack; +}; +struct fw_flr_mb { + u32 aggint; + u32 opgen_addr; + struct fw_flr_ack ack; +}; struct shmem2_region { @@ -1046,7 +1060,20 @@ struct shmem2_region { * For backwards compatibility, if the mf_cfg_addr does not exist * (the size filed is smaller than 0xc) the mf_cfg resides at the * end of struct shmem_region + */ + u32 mf_cfg_addr; +#define SHMEM_MF_CFG_ADDR_NONE 0x00000000 + + struct fw_flr_mb flr_mb; + u32 reserved[3]; + /* + * The other shmemX_base_addr holds the other path's shmem address + * required for example in case of common phy init, or for path1 to know + * the address of mcp debug trace which is located in offset from shmem + * of path0 */ + u32 other_shmem_base_addr; + u32 other_shmem2_base_addr; }; @@ -1206,10 +1233,126 @@ struct bmac1_stats { u32 rx_stat_gripj_hi; }; +struct bmac2_stats { + u32 tx_stat_gtpk_lo; /* gtpok */ + u32 tx_stat_gtpk_hi; /* gtpok */ + u32 tx_stat_gtxpf_lo; /* gtpf */ + u32 tx_stat_gtxpf_hi; /* gtpf */ + u32 tx_stat_gtpp_lo; /* NEW BMAC2 */ + u32 tx_stat_gtpp_hi; /* NEW BMAC2 */ + u32 tx_stat_gtfcs_lo; + u32 tx_stat_gtfcs_hi; + u32 tx_stat_gtuca_lo; /* NEW BMAC2 */ + u32 tx_stat_gtuca_hi; /* NEW BMAC2 */ + u32 tx_stat_gtmca_lo; + u32 tx_stat_gtmca_hi; + u32 tx_stat_gtbca_lo; + u32 tx_stat_gtbca_hi; + u32 tx_stat_gtovr_lo; + u32 tx_stat_gtovr_hi; + u32 tx_stat_gtfrg_lo; + u32 tx_stat_gtfrg_hi; + u32 tx_stat_gtpkt1_lo; /* gtpkt */ + u32 tx_stat_gtpkt1_hi; /* gtpkt */ + u32 tx_stat_gt64_lo; + u32 tx_stat_gt64_hi; + u32 tx_stat_gt127_lo; + u32 tx_stat_gt127_hi; + u32 tx_stat_gt255_lo; + u32 tx_stat_gt255_hi; + u32 tx_stat_gt511_lo; + u32 tx_stat_gt511_hi; + u32 tx_stat_gt1023_lo; + u32 tx_stat_gt1023_hi; + u32 tx_stat_gt1518_lo; + u32 tx_stat_gt1518_hi; + u32 tx_stat_gt2047_lo; + u32 tx_stat_gt2047_hi; + u32 tx_stat_gt4095_lo; + u32 tx_stat_gt4095_hi; + u32 tx_stat_gt9216_lo; + u32 tx_stat_gt9216_hi; + u32 tx_stat_gt16383_lo; + u32 tx_stat_gt16383_hi; + u32 tx_stat_gtmax_lo; + u32 tx_stat_gtmax_hi; + u32 tx_stat_gtufl_lo; + u32 tx_stat_gtufl_hi; + u32 tx_stat_gterr_lo; + u32 tx_stat_gterr_hi; + u32 tx_stat_gtbyt_lo; + u32 tx_stat_gtbyt_hi; + + u32 rx_stat_gr64_lo; + u32 rx_stat_gr64_hi; + u32 rx_stat_gr127_lo; + u32 rx_stat_gr127_hi; + u32 rx_stat_gr255_lo; + u32 rx_stat_gr255_hi; + u32 rx_stat_gr511_lo; + u32 rx_stat_gr511_hi; + u32 rx_stat_gr1023_lo; + u32 rx_stat_gr1023_hi; + u32 rx_stat_gr1518_lo; + u32 rx_stat_gr1518_hi; + u32 rx_stat_gr2047_lo; + u32 rx_stat_gr2047_hi; + u32 rx_stat_gr4095_lo; + u32 rx_stat_gr4095_hi; + u32 rx_stat_gr9216_lo; + u32 rx_stat_gr9216_hi; + u32 rx_stat_gr16383_lo; + u32 rx_stat_gr16383_hi; + u32 rx_stat_grmax_lo; + u32 rx_stat_grmax_hi; + u32 rx_stat_grpkt_lo; + u32 rx_stat_grpkt_hi; + u32 rx_stat_grfcs_lo; + u32 rx_stat_grfcs_hi; + u32 rx_stat_gruca_lo; + u32 rx_stat_gruca_hi; + u32 rx_stat_grmca_lo; + u32 rx_stat_grmca_hi; + u32 rx_stat_grbca_lo; + u32 rx_stat_grbca_hi; + u32 rx_stat_grxpf_lo; /* grpf */ + u32 rx_stat_grxpf_hi; /* grpf */ + u32 rx_stat_grpp_lo; + u32 rx_stat_grpp_hi; + u32 rx_stat_grxuo_lo; /* gruo */ + u32 rx_stat_grxuo_hi; /* gruo */ + u32 rx_stat_grjbr_lo; + u32 rx_stat_grjbr_hi; + u32 rx_stat_grovr_lo; + u32 rx_stat_grovr_hi; + u32 rx_stat_grxcf_lo; /* grcf */ + u32 rx_stat_grxcf_hi; /* grcf */ + u32 rx_stat_grflr_lo; + u32 rx_stat_grflr_hi; + u32 rx_stat_grpok_lo; + u32 rx_stat_grpok_hi; + u32 rx_stat_grmeg_lo; + u32 rx_stat_grmeg_hi; + u32 rx_stat_grmeb_lo; + u32 rx_stat_grmeb_hi; + u32 rx_stat_grbyt_lo; + u32 rx_stat_grbyt_hi; + u32 rx_stat_grund_lo; + u32 rx_stat_grund_hi; + u32 rx_stat_grfrg_lo; + u32 rx_stat_grfrg_hi; + u32 rx_stat_grerb_lo; /* grerrbyt */ + u32 rx_stat_grerb_hi; /* grerrbyt */ + u32 rx_stat_grfre_lo; /* grfrerr */ + u32 rx_stat_grfre_hi; /* grfrerr */ + u32 rx_stat_gripj_lo; + u32 rx_stat_gripj_hi; +}; union mac_stats { - struct emac_stats emac_stats; - struct bmac1_stats bmac1_stats; + struct emac_stats emac_stats; + struct bmac1_stats bmac1_stats; + struct bmac2_stats bmac2_stats; }; @@ -1593,6 +1736,24 @@ union igu_consprod_reg { }; +/* + * Control register for the IGU command register + */ +struct igu_ctrl_reg { + u32 ctrl_data; +#define IGU_CTRL_REG_ADDRESS (0xFFF<<0) +#define IGU_CTRL_REG_ADDRESS_SHIFT 0 +#define IGU_CTRL_REG_FID (0x7F<<12) +#define IGU_CTRL_REG_FID_SHIFT 12 +#define IGU_CTRL_REG_RESERVED (0x1<<19) +#define IGU_CTRL_REG_RESERVED_SHIFT 19 +#define IGU_CTRL_REG_TYPE (0x1<<20) +#define IGU_CTRL_REG_TYPE_SHIFT 20 +#define IGU_CTRL_REG_UNUSED (0x7FF<<21) +#define IGU_CTRL_REG_UNUSED_SHIFT 21 +}; + + /* * Parser parsing flags field */ @@ -1923,6 +2084,27 @@ struct eth_tx_parse_bd_e1x { __le32 tcp_send_seq; }; +/* + * Tx parsing BD structure for ETH E2 + */ +struct eth_tx_parse_bd_e2 { + __le16 dst_mac_addr_lo; + __le16 dst_mac_addr_mid; + __le16 dst_mac_addr_hi; + __le16 src_mac_addr_lo; + __le16 src_mac_addr_mid; + __le16 src_mac_addr_hi; + __le32 parsing_data; +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x1FFF<<0) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<13) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 13 +#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<17) +#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 17 +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<31) +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 31 +}; + /* * The last BD in the BD memory will hold a pointer to the next BD memory */ @@ -1939,6 +2121,7 @@ union eth_tx_bd_types { struct eth_tx_start_bd start_bd; struct eth_tx_bd reg_bd; struct eth_tx_parse_bd_e1x parse_bd_e1x; + struct eth_tx_parse_bd_e2 parse_bd_e2; struct eth_tx_next_bd next_bd; }; diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 5ae22e085518..a9d54874a559 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -97,6 +97,9 @@ #define MISC_AEU_BLOCK 35 #define PGLUE_B_BLOCK 36 #define IGU_BLOCK 37 +#define ATC_BLOCK 38 +#define QM_4PORT_BLOCK 39 +#define XSEM_4PORT_BLOCK 40 /* Returns the index of start or end of a specific block stage in ops array*/ diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index aae7fea00622..e65de784182c 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -486,18 +486,30 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); - if (r_order == MAX_RD_ORD) + if ((CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) && (r_order == MAX_RD_ORD)) REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); - REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x8 << w_order)); + else + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); - if (CHIP_IS_E1H(bp)) { + if (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) { /* MPS w_order optimal TH presently TH * 128 0 0 2 * 256 1 1 3 * >=512 2 2 3 */ - val = ((w_order == 0) ? 2 : 3); + /* DMAE is special */ + if (CHIP_IS_E2(bp)) { + /* E2 can use optimal TH */ + val = w_order; + REG_WR(bp, PXP2_REG_WR_DMAE_MPS, val); + } else { + val = ((w_order == 0) ? 2 : 3); + REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); + } + REG_WR(bp, PXP2_REG_WR_HC_MPS, val); REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val); @@ -507,9 +519,15 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) REG_WR(bp, PXP2_REG_WR_TM_MPS, val); REG_WR(bp, PXP2_REG_WR_SRC_MPS, val); REG_WR(bp, PXP2_REG_WR_DBG_MPS, val); - REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */ REG_WR(bp, PXP2_REG_WR_CDU_MPS, val); } + + /* Validate number of tags suppoted by device */ +#define PCIE_REG_PCIER_TL_HDR_FC_ST 0x2980 + val = REG_RD(bp, PCIE_REG_PCIER_TL_HDR_FC_ST); + val &= 0xFF; + if (val <= 0x20) + REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x20); } /**************************************************************************** diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 51d468d430ee..3e99bf9c42b9 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -377,9 +377,60 @@ static u8 bnx2x_emac_enable(struct link_params *params, return 0; } +static void bnx2x_update_bmac2(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + /* + * Set rx control: Strip CRC and enable BigMAC to relay + * control packets to the system as well + */ + u32 wb_data[2]; + struct bnx2x *bp = params->bp; + u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 val = 0x14; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + /* Enable BigMAC to react on received Pause packets */ + val |= (1<<5); + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, + wb_data, 2); + udelay(30); -static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, + /* Tx control */ + val = 0xc0; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + val |= 0x800000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, + wb_data, 2); + + val = 0x8000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, + wb_data, 2); + + /* mac control */ + val = 0x3; /* Enable RX and TX */ + if (is_lb) { + val |= 0x4; /* Local loopback */ + DP(NETIF_MSG_LINK, "enable bmac loopback\n"); + } + + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); +} + + +static u8 bnx2x_bmac1_enable(struct link_params *params, + struct link_vars *vars, u8 is_lb) { struct bnx2x *bp = params->bp; @@ -389,17 +440,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, u32 wb_data[2]; u32 val; - DP(NETIF_MSG_LINK, "Enabling BigMAC\n"); - /* reset and unreset the BigMac */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - msleep(1); - - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - - /* enable access for bmac registers */ - REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); + DP(NETIF_MSG_LINK, "Enabling BigMAC1\n"); /* XGXS control */ wb_data[0] = 0x3c; @@ -479,6 +520,103 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, wb_data, 2); } + + return 0; +} + +static u8 bnx2x_bmac2_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + struct bnx2x *bp = params->bp; + u8 port = params->port; + u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 wb_data[2]; + + DP(NETIF_MSG_LINK, "Enabling BigMAC2\n"); + + wb_data[0] = 0; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + udelay(30); + + /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */ + wb_data[0] = 0x3c; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL, + wb_data, 2); + + udelay(30); + + /* tx MAC SA */ + wb_data[0] = ((params->mac_addr[2] << 24) | + (params->mac_addr[3] << 16) | + (params->mac_addr[4] << 8) | + params->mac_addr[5]); + wb_data[1] = ((params->mac_addr[0] << 8) | + params->mac_addr[1]); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR, + wb_data, 2); + + udelay(30); + + /* Configure SAFC */ + wb_data[0] = 0x1000200; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS, + wb_data, 2); + udelay(30); + + /* set rx mtu */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, + wb_data, 2); + udelay(30); + + /* set tx mtu */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, + wb_data, 2); + udelay(30); + /* set cnt max size */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, + wb_data, 2); + udelay(30); + bnx2x_update_bmac2(params, vars, is_lb); + + return 0; +} + +u8 bnx2x_bmac_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + u8 rc, port = params->port; + struct bnx2x *bp = params->bp; + u32 val; + /* reset and unreset the BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + udelay(10); + + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + + /* enable access for bmac registers */ + REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); + + /* Enable BMAC according to BMAC type*/ + if (CHIP_IS_E2(bp)) + rc = bnx2x_bmac2_enable(params, vars, is_lb); + else + rc = bnx2x_bmac1_enable(params, vars, is_lb); REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1); REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); @@ -493,7 +631,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1); vars->mac_type = MAC_TYPE_BMAC; - return 0; + return rc; } @@ -519,13 +657,25 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) && nig_bmac_enable) { - /* Clear Rx Enable bit in BMAC_CONTROL register */ - REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, - wb_data, 2); - wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, - wb_data, 2); - + if (CHIP_IS_E2(bp)) { + /* Clear Rx Enable bit in BMAC_CONTROL register */ + REG_RD_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + } else { + /* Clear Rx Enable bit in BMAC_CONTROL register */ + REG_RD_DMAE(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, + wb_data, 2); + wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, + wb_data, 2); + } msleep(1); } } @@ -821,23 +971,31 @@ u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, return -EINVAL; } -static void bnx2x_set_aer_mmd(struct link_params *params, - struct bnx2x_phy *phy) +static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, + struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; u32 ser_lane; - u16 offset; - + u16 offset, aer_val; + struct bnx2x *bp = params->bp; ser_lane = ((params->lane_config & PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? - (phy->addr + ser_lane) : 0; - + offset = phy->addr + ser_lane; + if (CHIP_IS_E2(bp)) + aer_val = 0x2800 + offset - 1; + else + aer_val = 0x3800 + offset; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); + MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, aer_val); +} +static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + CL45_WR_OVER_CL22(bp, phy, + MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, 0x3800); } /******************************************************************/ @@ -2046,12 +2204,12 @@ static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, u8 rc; vars->phy_flags |= PHY_SGMII_FLAG; bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_serdes(params->bp, phy); rc = bnx2x_reset_unicore(params, phy, 1); /* reset the SerDes and wait for reset bit return low */ if (rc != 0) return rc; - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_serdes(params->bp, phy); return rc; } @@ -2076,7 +2234,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, vars->phy_flags &= ~PHY_SGMII_FLAG; bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_xgxs(params, phy); bnx2x_set_master_ln(params, phy); rc = bnx2x_reset_unicore(params, phy, 0); @@ -2084,7 +2242,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, if (rc != 0) return rc; - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_xgxs(params, phy); /* setting the masterLn_def again after the reset */ bnx2x_set_master_ln(params, phy); @@ -2358,7 +2516,7 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, 0x6041); msleep(200); /* set aer mmd back */ - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_xgxs(params, phy); /* and md_devad */ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, @@ -2721,7 +2879,10 @@ static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u8 gpio_port; /* HW reset */ - gpio_port = params->port; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_OUTPUT_LOW, gpio_port); @@ -2799,8 +2960,9 @@ static u8 bnx2x_update_link_up(struct link_params *params, } /* PBF - link up */ - rc |= bnx2x_pbf_update(params, vars->flow_ctrl, - vars->line_speed); + if (!(CHIP_IS_E2(bp))) + rc |= bnx2x_pbf_update(params, vars->flow_ctrl, + vars->line_speed); /* disable drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); @@ -3443,7 +3605,10 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, u8 gpio_port; DP(NETIF_MSG_LINK, "Init 8073\n"); - gpio_port = params->port; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); @@ -3680,7 +3845,10 @@ static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u8 gpio_port; - gpio_port = params->port; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", gpio_port); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, @@ -6371,7 +6539,10 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->mdio_ctrl = bnx2x_get_emac_base(bp, SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, port); - phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; + if (CHIP_IS_E2(bp)) + phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR; + else + phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", port, phy->addr, phy->mdio_ctrl); @@ -6742,7 +6913,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) } bnx2x_emac_enable(params, vars, 0); - bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); + if (!(CHIP_IS_E2(bp))) + bnx2x_pbf_update(params, vars->flow_ctrl, + vars->line_speed); /* disable drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); @@ -6932,18 +7105,34 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /****************************************************************************/ /* Common function */ /****************************************************************************/ -static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index) +static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; u16 val; s8 port; + s8 port_of_path = 0; /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { + u32 shmem_base, shmem2_base; + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + port_of_path = port; + } + /* Extract the ext phy address for the port */ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, - port, &phy[port]) != + port_of_path, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate_phy failed\n"); return -EINVAL; @@ -6981,9 +7170,15 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; + if (CHIP_IS_E2(bp)) + port_of_path = 0; + else + port_of_path = port; + DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", + phy_blk[port]->addr); bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], - port); + port_of_path); bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, @@ -7039,9 +7234,10 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem } return 0; } - -static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base, u8 phy_index) +static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { u32 val; s8 port; @@ -7056,6 +7252,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, bnx2x_ext_phy_hw_reset(bp, 1); msleep(5); for (port = 0; port < PORT_MAX; port++) { + u32 shmem_base, shmem2_base; + + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + } /* Extract the ext phy address for the port */ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy) != @@ -7077,14 +7283,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, return 0; } -static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base, u8 phy_index) +static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { s8 port; u32 swap_val, swap_override; struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; - DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n"); + s8 port_of_path; swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); @@ -7099,19 +7307,33 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { + u32 shmem_base, shmem2_base; + + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + port_of_path = port; + } + /* Extract the ext phy address for the port */ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, - port, &phy[port]) != + port_of_path, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); return -EINVAL; } /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + + port_of_path*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); /* Reset the phy */ @@ -7133,9 +7355,14 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; - + if (CHIP_IS_E2(bp)) + port_of_path = 0; + else + port_of_path = port; + DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", + phy_blk[port]->addr); bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], - port); + port_of_path); bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); @@ -7151,29 +7378,32 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, return 0; } -static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base, u8 phy_index, - u32 ext_phy_type) +static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 ext_phy_type, u32 chip_id) { u8 rc = 0; switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - rc = bnx2x_8073_common_init_phy(bp, shmem_base, - shmem2_base, phy_index); + rc = bnx2x_8073_common_init_phy(bp, shmem_base_path, + shmem2_base_path, + phy_index, chip_id); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: - rc = bnx2x_8727_common_init_phy(bp, shmem_base, - shmem2_base, phy_index); + rc = bnx2x_8727_common_init_phy(bp, shmem_base_path, + shmem2_base_path, + phy_index, chip_id); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: /* GPIO1 affects both ports, so there's need to pull it for single port alone */ - rc = bnx2x_8726_common_init_phy(bp, shmem_base, - shmem2_base, phy_index); + rc = bnx2x_8726_common_init_phy(bp, shmem_base_path, + shmem2_base_path, + phy_index, chip_id); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: rc = -EINVAL; @@ -7188,8 +7418,8 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, return rc; } -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base) +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u32 chip_id) { u8 rc = 0; u8 phy_index; @@ -7203,12 +7433,13 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; phy_index++) { ext_phy_config = bnx2x_get_ext_phy_config(bp, - shmem_base, + shmem_base_path[0], phy_index, 0); ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); - rc |= bnx2x_ext_phy_common_init(bp, shmem_base, - shmem2_base, - phy_index, ext_phy_type); + rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path, + shmem2_base_path, + phy_index, ext_phy_type, + chip_id); } return rc; } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index e98ea3d19471..58a4c7199276 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -22,7 +22,8 @@ /***********************************************************/ /* Defines */ /***********************************************************/ -#define DEFAULT_PHY_DEV_ADDR 3 +#define DEFAULT_PHY_DEV_ADDR 3 +#define E2_DEFAULT_PHY_DEV_ADDR 5 @@ -315,7 +316,8 @@ u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars, u8 is_serdes); /* One-time initialization for external phy after power up */ -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base); +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u32 chip_id); /* Reset the external PHY using GPIO */ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2c04b97f85a9..0ac416a14202 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -68,6 +67,7 @@ __stringify(BCM_5710_FW_ENGINEERING_VERSION) #define FW_FILE_NAME_E1 "bnx2x/bnx2x-e1-" FW_FILE_VERSION ".fw" #define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) @@ -77,11 +77,13 @@ static char version[] __devinitdata = DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir"); -MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver"); +MODULE_DESCRIPTION("Broadcom NetXtreme II " + "BCM57710/57711/57711E/57712/57712E Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_FIRMWARE(FW_FILE_NAME_E1); MODULE_FIRMWARE(FW_FILE_NAME_E1H); +MODULE_FIRMWARE(FW_FILE_NAME_E2); static int multi_mode = 1; module_param(multi_mode, int, 0); @@ -124,6 +126,8 @@ enum bnx2x_board_type { BCM57710 = 0, BCM57711 = 1, BCM57711E = 2, + BCM57712 = 3, + BCM57712E = 4 }; /* indexed by board_type, above */ @@ -132,14 +136,24 @@ static struct { } board_info[] __devinitdata = { { "Broadcom NetXtreme II BCM57710 XGb" }, { "Broadcom NetXtreme II BCM57711 XGb" }, - { "Broadcom NetXtreme II BCM57711E XGb" } + { "Broadcom NetXtreme II BCM57711E XGb" }, + { "Broadcom NetXtreme II BCM57712 XGb" }, + { "Broadcom NetXtreme II BCM57712E XGb" } }; +#ifndef PCI_DEVICE_ID_NX2_57712 +#define PCI_DEVICE_ID_NX2_57712 0x1662 +#endif +#ifndef PCI_DEVICE_ID_NX2_57712E +#define PCI_DEVICE_ID_NX2_57712E 0x1663 +#endif static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = { { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712), BCM57712 }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712E), BCM57712E }, { 0 } }; @@ -353,7 +367,8 @@ static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port, u8 ticks) { - int index_offset = + int index_offset = CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, index_data) : offsetof(struct hc_status_block_data_e1x, index_data); u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + @@ -369,7 +384,8 @@ static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port, u8 disable) { u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); - int index_offset = + int index_offset = CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, index_data) : offsetof(struct hc_status_block_data_e1x, index_data); u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + @@ -408,6 +424,75 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) return val; } +#define DMAE_DP_SRC_GRC "grc src_addr [%08x]" +#define DMAE_DP_SRC_PCI "pci src_addr [%x:%08x]" +#define DMAE_DP_DST_GRC "grc dst_addr [%08x]" +#define DMAE_DP_DST_PCI "pci dst_addr [%x:%08x]" +#define DMAE_DP_DST_NONE "dst_addr [none]" + +void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae, int msglvl) +{ + u32 src_type = dmae->opcode & DMAE_COMMAND_SRC; + + switch (dmae->opcode & DMAE_COMMAND_DST) { + case DMAE_CMD_DST_PCI: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%x:%08x], len [%d*4], dst [%x:%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%08x], len [%d*4], dst [%x:%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + case DMAE_CMD_DST_GRC: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%x:%08x], len [%d*4], dst_addr [%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->dst_addr_lo >> 2, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%08x], len [%d*4], dst [%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->dst_addr_lo >> 2, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + default: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + DP_LEVEL "src_addr [%x:%08x] len [%d * 4] " + "dst_addr [none]\n" + DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + DP_LEVEL "src_addr [%08x] len [%d * 4] " + "dst_addr [none]\n" + DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + } + +} + const u32 dmae_reg_go_c[] = { DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, @@ -431,85 +516,137 @@ void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx) REG_WR(bp, dmae_reg_go_c[idx], 1); } -void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, - u32 len32) +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type) { - struct dmae_command dmae; - u32 *wb_comp = bnx2x_sp(bp, wb_comp); - int cnt = 200; + return opcode | ((comp_type << DMAE_COMMAND_C_DST_SHIFT) | + DMAE_CMD_C_ENABLE); +} - if (!bp->dmae_ready) { - u32 *data = bnx2x_sp(bp, wb_data[0]); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode) +{ + return opcode & ~DMAE_CMD_SRC_RESET; +} - DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" - " using indirect\n", dst_addr, len32); - bnx2x_init_ind_wr(bp, dst_addr, data, len32); - return; - } +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type) +{ + u32 opcode = 0; + + opcode |= ((src_type << DMAE_COMMAND_SRC_SHIFT) | + (dst_type << DMAE_COMMAND_DST_SHIFT)); - memset(&dmae, 0, sizeof(struct dmae_command)); + opcode |= (DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET); + + opcode |= (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0); + opcode |= ((BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT) | + (BP_E1HVN(bp) << DMAE_COMMAND_DST_VN_SHIFT)); + opcode |= (DMAE_COM_SET_ERR << DMAE_COMMAND_ERR_POLICY_SHIFT); - dmae.opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | #ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | + opcode |= DMAE_CMD_ENDIANITY_B_DW_SWAP; #else - DMAE_CMD_ENDIANITY_DW_SWAP | + opcode |= DMAE_CMD_ENDIANITY_DW_SWAP; #endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - dmae.src_addr_lo = U64_LO(dma_addr); - dmae.src_addr_hi = U64_HI(dma_addr); - dmae.dst_addr_lo = dst_addr >> 2; - dmae.dst_addr_hi = 0; - dmae.len = len32; - dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_val = DMAE_COMP_VAL; - - DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n" - DP_LEVEL "src_addr [%x:%08x] len [%d *4] " - "dst_addr [%x:%08x (%08x)]\n" - DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", - dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo, - dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, dst_addr, - dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val); - DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n", + if (with_comp) + opcode = bnx2x_dmae_opcode_add_comp(opcode, comp_type); + return opcode; +} + +void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae, + u8 src_type, u8 dst_type) +{ + memset(dmae, 0, sizeof(struct dmae_command)); + + /* set the opcode */ + dmae->opcode = bnx2x_dmae_opcode(bp, src_type, dst_type, + true, DMAE_COMP_PCI); + + /* fill in the completion parameters */ + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); + dmae->comp_val = DMAE_COMP_VAL; +} + +/* issue a dmae command over the init-channel and wailt for completion */ +int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae) +{ + u32 *wb_comp = bnx2x_sp(bp, wb_comp); + int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 40; + int rc = 0; + + DP(BNX2X_MSG_OFF, "data before [0x%08x 0x%08x 0x%08x 0x%08x]\n", bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); + /* lock the dmae channel */ mutex_lock(&bp->dmae_mutex); + /* reset completion */ *wb_comp = 0; - bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp)); + /* post the command on the channel used for initializations */ + bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); + /* wait for completion */ udelay(5); - - while (*wb_comp != DMAE_COMP_VAL) { + while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) { DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); if (!cnt) { BNX2X_ERR("DMAE timeout!\n"); - break; + rc = DMAE_TIMEOUT; + goto unlock; } cnt--; - /* adjust delay for emulation/FPGA */ - if (CHIP_REV_IS_SLOW(bp)) - msleep(100); - else - udelay(5); + udelay(50); } + if (*wb_comp & DMAE_PCI_ERR_FLAG) { + BNX2X_ERR("DMAE PCI error!\n"); + rc = DMAE_PCI_ERROR; + } + + DP(BNX2X_MSG_OFF, "data after [0x%08x 0x%08x 0x%08x 0x%08x]\n", + bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], + bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); +unlock: mutex_unlock(&bp->dmae_mutex); + return rc; +} + +void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, + u32 len32) +{ + struct dmae_command dmae; + + if (!bp->dmae_ready) { + u32 *data = bnx2x_sp(bp, wb_data[0]); + + DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" + " using indirect\n", dst_addr, len32); + bnx2x_init_ind_wr(bp, dst_addr, data, len32); + return; + } + + /* set opcode and fixed command fields */ + bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_PCI, DMAE_DST_GRC); + + /* fill in addresses and len */ + dmae.src_addr_lo = U64_LO(dma_addr); + dmae.src_addr_hi = U64_HI(dma_addr); + dmae.dst_addr_lo = dst_addr >> 2; + dmae.dst_addr_hi = 0; + dmae.len = len32; + + bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF); + + /* issue the command and wait for completion */ + bnx2x_issue_dmae_with_comp(bp, &dmae); } void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) { struct dmae_command dmae; - u32 *wb_comp = bnx2x_sp(bp, wb_comp); - int cnt = 200; if (!bp->dmae_ready) { u32 *data = bnx2x_sp(bp, wb_data[0]); @@ -522,62 +659,20 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) return; } - memset(&dmae, 0, sizeof(struct dmae_command)); + /* set opcode and fixed command fields */ + bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_GRC, DMAE_DST_PCI); - dmae.opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + /* fill in addresses and len */ dmae.src_addr_lo = src_addr >> 2; dmae.src_addr_hi = 0; dmae.dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data)); dmae.dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data)); dmae.len = len32; - dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_val = DMAE_COMP_VAL; - - DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n" - DP_LEVEL "src_addr [%x:%08x] len [%d *4] " - "dst_addr [%x:%08x (%08x)]\n" - DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", - dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo, - dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, src_addr, - dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val); - - mutex_lock(&bp->dmae_mutex); - - memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4); - *wb_comp = 0; - - bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp)); - - udelay(5); - while (*wb_comp != DMAE_COMP_VAL) { + bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF); - if (!cnt) { - BNX2X_ERR("DMAE timeout!\n"); - break; - } - cnt--; - /* adjust delay for emulation/FPGA */ - if (CHIP_REV_IS_SLOW(bp)) - msleep(100); - else - udelay(5); - } - DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n", - bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], - bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); - - mutex_unlock(&bp->dmae_mutex); + /* issue the command and wait for completion */ + bnx2x_issue_dmae_with_comp(bp, &dmae); } void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, @@ -744,19 +839,24 @@ static void bnx2x_fw_dump(struct bnx2x *bp) u32 mark, offset; __be32 data[9]; int word; - + u32 trace_shmem_base; if (BP_NOMCP(bp)) { BNX2X_ERR("NO MCP - can not dump\n"); return; } - addr = bp->common.shmem_base - 0x0800 + 4; + if (BP_PATH(bp) == 0) + trace_shmem_base = bp->common.shmem_base; + else + trace_shmem_base = SHMEM2_RD(bp, other_shmem_base_addr); + addr = trace_shmem_base - 0x0800 + 4; mark = REG_RD(bp, addr); - mark = MCP_REG_MCPR_SCRATCH + ((mark + 0x3) & ~0x3) - 0x08000000; + mark = (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH) + + ((mark + 0x3) & ~0x3) - 0x08000000; pr_err("begin fw dump (mark 0x%x)\n", mark); pr_err(""); - for (offset = mark; offset <= bp->common.shmem_base; offset += 0x8*4) { + for (offset = mark; offset <= trace_shmem_base; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, offset + 4*word)); data[8] = 0x0; @@ -822,10 +922,15 @@ void bnx2x_panic_dump(struct bnx2x *bp) for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; int loop; + struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; struct hc_status_block_sm *hc_sm_p = + CHIP_IS_E2(bp) ? + sb_data_e2.common.state_machine : sb_data_e1x.common.state_machine; struct hc_index_data *hc_index_p = + CHIP_IS_E2(bp) ? + sb_data_e2.index_data : sb_data_e1x.index_data; int data_size; u32 *sb_data_p; @@ -849,7 +954,8 @@ void bnx2x_panic_dump(struct bnx2x *bp) i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); - loop = HC_SB_MAX_INDICES_E1X; + loop = CHIP_IS_E2(bp) ? + HC_SB_MAX_INDICES_E2 : HC_SB_MAX_INDICES_E1X; /* host sb data */ @@ -865,23 +971,36 @@ void bnx2x_panic_dump(struct bnx2x *bp) fp->sb_index_values[j], (j == loop - 1) ? ")" : " "); /* fw sb data */ - data_size = + data_size = CHIP_IS_E2(bp) ? + sizeof(struct hc_status_block_data_e2) : sizeof(struct hc_status_block_data_e1x); data_size /= sizeof(u32); - sb_data_p = (u32 *)&sb_data_e1x; + sb_data_p = CHIP_IS_E2(bp) ? + (u32 *)&sb_data_e2 : + (u32 *)&sb_data_e1x; /* copy sb data in here */ for (j = 0; j < data_size; j++) *(sb_data_p + j) = REG_RD(bp, BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + j * sizeof(u32)); - pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " - "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", - sb_data_e1x.common.p_func.pf_id, - sb_data_e1x.common.p_func.vf_id, - sb_data_e1x.common.p_func.vf_valid, - sb_data_e1x.common.p_func.vnic_id, - sb_data_e1x.common.same_igu_sb_1b); + if (CHIP_IS_E2(bp)) { + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e2.common.p_func.pf_id, + sb_data_e2.common.p_func.vf_id, + sb_data_e2.common.p_func.vf_valid, + sb_data_e2.common.p_func.vnic_id, + sb_data_e2.common.same_igu_sb_1b); + } else { + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e1x.common.p_func.pf_id, + sb_data_e1x.common.p_func.vf_id, + sb_data_e1x.common.p_func.vf_valid, + sb_data_e1x.common.p_func.vnic_id, + sb_data_e1x.common.same_igu_sb_1b); + } /* SB_SMs data */ for (j = 0; j < HC_SB_MAX_SM; j++) { @@ -969,7 +1088,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) BNX2X_ERR("end crash dump -----------------\n"); } -void bnx2x_int_enable(struct bnx2x *bp) +static void bnx2x_hc_int_enable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -1011,7 +1130,7 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); barrier(); - if (CHIP_IS_E1H(bp)) { + if (!CHIP_IS_E1(bp)) { /* init leading/trailing edge */ if (IS_MF(bp)) { val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); @@ -1029,7 +1148,66 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); } -void bnx2x_int_disable(struct bnx2x *bp) +static void bnx2x_igu_int_enable(struct bnx2x *bp) +{ + u32 val; + int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; + int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0; + + val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + + if (msix) { + val &= ~(IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_ATTN_BIT_EN); + } else if (msi) { + val &= ~IGU_PF_CONF_INT_LINE_EN; + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_ATTN_BIT_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + } else { + val &= ~IGU_PF_CONF_MSI_MSIX_EN; + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_ATTN_BIT_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + } + + DP(NETIF_MSG_INTR, "write 0x%x to IGU mode %s\n", + val, (msix ? "MSI-X" : (msi ? "MSI" : "INTx"))); + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + + barrier(); + + /* init leading/trailing edge */ + if (IS_MF(bp)) { + val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); + if (bp->port.pmf) + /* enable nig and gpio3 attention */ + val |= 0x1100; + } else + val = 0xffff; + + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val); + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val); + + /* Make sure that interrupts are indeed enabled from here on */ + mmiowb(); +} + +void bnx2x_int_enable(struct bnx2x *bp) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_int_enable(bp); + else + bnx2x_igu_int_enable(bp); +} + +static void bnx2x_hc_int_disable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -1051,6 +1229,32 @@ void bnx2x_int_disable(struct bnx2x *bp) BNX2X_ERR("BUG! proper val not read from IGU!\n"); } +static void bnx2x_igu_int_disable(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + + val &= ~(IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_ATTN_BIT_EN); + + DP(NETIF_MSG_INTR, "write %x to IGU\n", val); + + /* flush all outstanding writes */ + mmiowb(); + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + if (REG_RD(bp, IGU_REG_PF_CONFIGURATION) != val) + BNX2X_ERR("BUG! proper val not read from IGU!\n"); +} + +void bnx2x_int_disable(struct bnx2x *bp) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_int_disable(bp); + else + bnx2x_igu_int_disable(bp); +} + void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) { int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; @@ -1194,7 +1398,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; #endif - for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) { + for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); @@ -1579,7 +1783,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) /* Initialize link parameters structure variables */ /* It is recommended to turn off RX FC for jumbo frames for better performance */ - if (bp->dev->mtu > 5000) + if ((CHIP_IS_E1x(bp)) && (bp->dev->mtu > 5000)) bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX; else bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; @@ -1693,13 +1897,11 @@ static void bnx2x_init_port_minmax(struct bnx2x *bp) static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) { int all_zero = 1; - int port = BP_PORT(bp); int vn; bp->vn_weight_sum = 0; for (vn = VN_0; vn < E1HVN_MAX; vn++) { - int func = 2*vn + port; - u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); + u32 vn_cfg = bp->mf_config[vn]; u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; @@ -1727,11 +1929,12 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) CMNG_FLAGS_PER_PORT_FAIRNESS_VN; } -static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) +static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) { struct rate_shaping_vars_per_vn m_rs_vn; struct fairness_vars_per_vn m_fair_vn; - u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); + u32 vn_cfg = bp->mf_config[vn]; + int func = 2*vn + BP_PORT(bp); u16 vn_min_rate, vn_max_rate; int i; @@ -1744,7 +1947,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; /* If min rate is zero - set it to 1 */ - if (!vn_min_rate) + if (bp->vn_weight_sum && (vn_min_rate == 0)) vn_min_rate = DEF_MIN_RATE; vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * 100; @@ -1807,7 +2010,7 @@ static void bnx2x_read_mf_cfg(struct bnx2x *bp) for (vn = VN_0; vn < E1HVN_MAX; vn++) { int /*abs*/func = 2*vn + BP_PORT(bp); - bp->mf_config = + bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); } } @@ -1878,7 +2081,7 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (bp->link_vars.link_up) { /* dropless flow control */ - if (CHIP_IS_E1H(bp) && bp->dropless_fc) { + if (!CHIP_IS_E1(bp) && bp->dropless_fc) { int port = BP_PORT(bp); u32 pause_enabled = 0; @@ -1906,37 +2109,19 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (prev_link_status != bp->link_vars.link_status) bnx2x_link_report(bp); - if (IS_MF(bp)) { - int port = BP_PORT(bp); - int func; - int vn; - - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; - - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); - } - - if (bp->link_vars.link_up) { - int i; - - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); + if (IS_MF(bp)) + bnx2x_link_sync_notify(bp); - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); + if (bp->link_vars.link_up && bp->link_vars.line_speed) { + int cmng_fns = bnx2x_get_cmng_fns_mode(bp); - /* Store it to internal memory */ - for (i = 0; - i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); - } + if (cmng_fns != CMNG_FNS_NONE) { + bnx2x_cmng_fns_init(bp, false, cmng_fns); + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + } else + /* rate shaping and fairness are disabled */ + DP(NETIF_MSG_IFUP, + "single function mode without fairness\n"); } } @@ -1952,7 +2137,9 @@ void bnx2x__link_status_update(struct bnx2x *bp) else bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_calc_vn_weight_sum(bp); + /* the link status update could be the result of a DCC event + hence re-read the shmem mf configuration */ + bnx2x_read_mf_cfg(bp); /* indicate link status */ bnx2x_link_report(bp); @@ -1968,8 +2155,13 @@ static void bnx2x_pmf_update(struct bnx2x *bp) /* enable nig attention */ val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); + if (bp->common.int_block == INT_BLOCK_HC) { + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); + } else if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val); + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val); + } bnx2x_stats_handle(bp, STATS_EVENT_PMF); } @@ -1985,22 +2177,23 @@ static void bnx2x_pmf_update(struct bnx2x *bp) /* send the MCP a request, block until there is a reply */ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); u32 seq = ++bp->fw_seq; u32 rc = 0; u32 cnt = 1; u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; mutex_lock(&bp->fw_mb_mutex); - SHMEM_WR(bp, func_mb[func].drv_mb_param, param); - SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); + SHMEM_WR(bp, func_mb[mb_idx].drv_mb_param, param); + SHMEM_WR(bp, func_mb[mb_idx].drv_mb_header, (command | seq)); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); do { /* let the FW do it's magic ... */ msleep(delay); - rc = SHMEM_RD(bp, func_mb[func].fw_mb_header); + rc = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_header); /* Give the FW up to 5 second (500*10ms) */ } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500)); @@ -2264,10 +2457,28 @@ void bnx2x_pf_init(struct bnx2x *bp) if (!CHIP_IS_E1(bp)) storm_memset_ov(bp, bp->mf_ov, BP_FUNC(bp)); + if (CHIP_IS_E2(bp)) { + /* reset IGU PF statistics: MSIX + ATTN */ + /* PF */ + REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + + BNX2X_IGU_STAS_MSG_VF_CNT*4 + + (CHIP_MODE_IS_4_PORT(bp) ? + BP_FUNC(bp) : BP_VN(bp))*4, 0); + /* ATTN */ + REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + + BNX2X_IGU_STAS_MSG_VF_CNT*4 + + BNX2X_IGU_STAS_MSG_PF_CNT*4 + + (CHIP_MODE_IS_4_PORT(bp) ? + BP_FUNC(bp) : BP_VN(bp))*4, 0); + } + /* function setup flags */ flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); - flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; + if (CHIP_IS_E1x(bp)) + flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; + else + flags |= FUNC_FLG_TPA; /** * Although RSS is meaningless when there is a single HW queue we @@ -2361,7 +2572,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) * where the bp->flags can change so it is done without any * locks */ - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { + if (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED) { DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); bp->flags |= MF_FUNC_DIS; @@ -2548,14 +2759,13 @@ static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) { int port = BP_PORT(bp); - u32 hc_addr = (HC_REG_COMMAND_REG + port*32 + - COMMAND_REG_ATTN_BITS_SET); u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : MISC_REG_AEU_MASK_ATTN_FUNC_0; u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : NIG_REG_MASK_INTERRUPT_PORT0; u32 aeu_mask; u32 nig_mask = 0; + u32 reg_addr; if (bp->attn_state & asserted) BNX2X_ERR("IGU ERROR\n"); @@ -2630,9 +2840,15 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) } /* if hardwired */ - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - asserted, hc_addr); - REG_WR(bp, hc_addr, asserted); + if (bp->common.int_block == INT_BLOCK_HC) + reg_addr = (HC_REG_COMMAND_REG + port*32 + + COMMAND_REG_ATTN_BITS_SET); + else + reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_SET_UPPER*8); + + DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", asserted, + (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr); + REG_WR(bp, reg_addr, asserted); /* now set back the mask */ if (asserted & ATTN_NIG_FOR_FUNC) { @@ -2753,6 +2969,10 @@ static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) /* RQ_USDMDP_FIFO_OVERFLOW */ if (val & 0x18000) BNX2X_ERR("FATAL error from PXP\n"); + if (CHIP_IS_E2(bp)) { + val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_1); + BNX2X_ERR("PXP hw attention-1 0x%x\n", val); + } } if (attn & HW_INTERRUT_ASSERT_SET_2) { @@ -2783,9 +3003,10 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) int func = BP_FUNC(bp); REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - bp->mf_config = - MF_CFG_RD(bp, func_mf_config[func].config); - val = SHMEM_RD(bp, func_mb[func].drv_status); + bp->mf_config[BP_VN(bp)] = MF_CFG_RD(bp, + func_mf_config[BP_ABS_FUNC(bp)].config); + val = SHMEM_RD(bp, + func_mb[BP_FW_MB_IDX(bp)].drv_status); if (val & DRV_STATUS_DCC_EVENT_MASK) bnx2x_dcc_event(bp, (val & DRV_STATUS_DCC_EVENT_MASK)); @@ -2815,13 +3036,13 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) { BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn); if (attn & BNX2X_GRC_TIMEOUT) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0; + val = CHIP_IS_E1(bp) ? 0 : + REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN); BNX2X_ERR("GRC time-out 0x%08x\n", val); } if (attn & BNX2X_GRC_RSV) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0; + val = CHIP_IS_E1(bp) ? 0 : + REG_RD(bp, MISC_REG_GRC_RSV_ATTN); BNX2X_ERR("GRC reserved 0x%08x\n", val); } REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff); @@ -3126,6 +3347,74 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp) attn.sig[3]); } + +static inline void bnx2x_attn_int_deasserted4(struct bnx2x *bp, u32 attn) +{ + u32 val; + if (attn & AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT) { + + val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS_CLR); + BNX2X_ERR("PGLUE hw attention 0x%x\n", val); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "ADDRESS_ERROR\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "INCORRECT_RCV_BEHAVIOR\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "WAS_ERROR_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_LENGTH_VIOLATION_ATTN\n"); + if (val & + PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_GRC_SPACE_VIOLATION_ATTN\n"); + if (val & + PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_MSIX_BAR_VIOLATION_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "TCPL_ERROR_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "TCPL_IN_TWO_RCBS_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "CSSNOOP_FIFO_OVERFLOW\n"); + } + if (attn & AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT) { + val = REG_RD(bp, ATC_REG_ATC_INT_STS_CLR); + BNX2X_ERR("ATC hw attention 0x%x\n", val); + if (val & ATC_ATC_INT_STS_REG_ADDRESS_ERROR) + BNX2X_ERR("ATC_ATC_INT_STS_REG_ADDRESS_ERROR\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND) + BNX2X_ERR("ATC_ATC_INT_STS_REG" + "_ATC_TCPL_TO_NOT_PEND\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_GPA_MULTIPLE_HITS\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_RCPL_TO_EMPTY_CNT\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR) + BNX2X_ERR("ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_IREQ_LESS_THAN_STU\n"); + } + + if (attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)) { + BNX2X_ERR("FATAL parity attention set4 0x%x\n", + (u32)(attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR))); + } + +} + static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) { struct attn_route attn, *group_mask; @@ -3156,17 +3445,28 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4); attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n", - attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]); + if (CHIP_IS_E2(bp)) + attn.sig[4] = + REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 + port*4); + else + attn.sig[4] = 0; + + DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x %08x\n", + attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3], attn.sig[4]); for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { if (deasserted & (1 << index)) { group_mask = &bp->attn_group[index]; - DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n", - index, group_mask->sig[0], group_mask->sig[1], - group_mask->sig[2], group_mask->sig[3]); + DP(NETIF_MSG_HW, "group[%d]: %08x %08x " + "%08x %08x %08x\n", + index, + group_mask->sig[0], group_mask->sig[1], + group_mask->sig[2], group_mask->sig[3], + group_mask->sig[4]); + bnx2x_attn_int_deasserted4(bp, + attn.sig[4] & group_mask->sig[4]); bnx2x_attn_int_deasserted3(bp, attn.sig[3] & group_mask->sig[3]); bnx2x_attn_int_deasserted1(bp, @@ -3180,11 +3480,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) bnx2x_release_alr(bp); - reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR); + if (bp->common.int_block == INT_BLOCK_HC) + reg_addr = (HC_REG_COMMAND_REG + port*32 + + COMMAND_REG_ATTN_BITS_CLR); + else + reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_CLR_UPPER*8); val = ~deasserted; - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - val, reg_addr); + DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", val, + (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr); REG_WR(bp, reg_addr, val); if (~bp->attn_state & deasserted) @@ -3471,7 +3775,7 @@ static void bnx2x_timer(unsigned long data) } if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); u32 drv_pulse; u32 mcp_pulse; @@ -3479,9 +3783,9 @@ static void bnx2x_timer(unsigned long data) bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; /* TBD - add SYSTEM_TIME */ drv_pulse = bp->fw_drv_pulse_wr_seq; - SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse); + SHMEM_WR(bp, func_mb[mb_idx].drv_pulse_mb, drv_pulse); - mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) & + mcp_pulse = (SHMEM_RD(bp, func_mb[mb_idx].mcp_pulse_mb) & MCP_PULSE_SEQ_MASK); /* The delta between driver pulse and mcp response * should be 1 (before mcp response) or 0 (after mcp response) @@ -3539,17 +3843,26 @@ static inline void bnx2x_zero_fp_sb(struct bnx2x *bp, int fw_sb_id) { u32 *sb_data_p; u32 data_size = 0; + struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; /* disable the function first */ - memset(&sb_data_e1x, 0, - sizeof(struct hc_status_block_data_e1x)); - sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; - sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; - sb_data_e1x.common.p_func.vf_valid = false; - sb_data_p = (u32 *)&sb_data_e1x; - data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); - + if (CHIP_IS_E2(bp)) { + memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); + sb_data_e2.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e2.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e2.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e2; + data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); + } else { + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + } bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); bnx2x_fill(bp, BAR_CSTRORM_INTMEM + @@ -3610,30 +3923,48 @@ void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, { int igu_seg_id; + struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; struct hc_status_block_sm *hc_sm_p; struct hc_index_data *hc_index_p; int data_size; u32 *sb_data_p; - igu_seg_id = HC_SEG_ACCESS_NORM; + if (CHIP_INT_MODE_IS_BC(bp)) + igu_seg_id = HC_SEG_ACCESS_NORM; + else + igu_seg_id = IGU_SEG_ACCESS_NORM; bnx2x_zero_fp_sb(bp, fw_sb_id); - memset(&sb_data_e1x, 0, - sizeof(struct hc_status_block_data_e1x)); - sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); - sb_data_e1x.common.p_func.vf_id = 0xff; - sb_data_e1x.common.p_func.vf_valid = false; - sb_data_e1x.common.p_func.vnic_id = BP_E1HVN(bp); - sb_data_e1x.common.same_igu_sb_1b = true; - sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); - sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); - hc_sm_p = sb_data_e1x.common.state_machine; - hc_index_p = sb_data_e1x.index_data; - sb_data_p = (u32 *)&sb_data_e1x; - data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); - + if (CHIP_IS_E2(bp)) { + memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); + sb_data_e2.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e2.common.p_func.vf_id = vfid; + sb_data_e2.common.p_func.vf_valid = vf_valid; + sb_data_e2.common.p_func.vnic_id = BP_VN(bp); + sb_data_e2.common.same_igu_sb_1b = true; + sb_data_e2.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e2.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e2.common.state_machine; + hc_index_p = sb_data_e2.index_data; + sb_data_p = (u32 *)&sb_data_e2; + data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); + } else { + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e1x.common.p_func.vf_id = 0xff; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_e1x.common.p_func.vnic_id = BP_VN(bp); + sb_data_e1x.common.same_igu_sb_1b = true; + sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e1x.common.state_machine; + hc_index_p = sb_data_e1x.index_data; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + } bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_RX_ID], igu_sb_id, igu_seg_id); @@ -3666,6 +3997,7 @@ static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u16 fw_sb_id, bnx2x_update_coalesce_sb_index(bp, fw_sb_id, C_SB_ETH_TX_CQ_INDEX, false, tx_usec); } + static void bnx2x_init_def_sb(struct bnx2x *bp) { struct host_sp_status_block *def_sb = bp->def_status_blk; @@ -3680,8 +4012,13 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) struct hc_sp_status_block_data sp_sb_data; memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); - igu_sp_sb_index = DEF_SB_IGU_ID; - igu_seg_id = HC_SEG_ACCESS_DEF; + if (CHIP_INT_MODE_IS_BC(bp)) { + igu_sp_sb_index = DEF_SB_IGU_ID; + igu_seg_id = HC_SEG_ACCESS_DEF; + } else { + igu_sp_sb_index = bp->igu_dsb_id; + igu_seg_id = IGU_SEG_ACCESS_DEF; + } /* ATTN */ section = ((u64)mapping) + offsetof(struct host_sp_status_block, @@ -3698,12 +4035,29 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) for (sindex = 0; sindex < 4; sindex++) bp->attn_group[index].sig[sindex] = REG_RD(bp, reg_offset + sindex*0x4 + 0x10*index); + + if (CHIP_IS_E2(bp)) + /* + * enable5 is separate from the rest of the registers, + * and therefore the address skip is 4 + * and not 16 between the different groups + */ + bp->attn_group[index].sig[4] = REG_RD(bp, + reg_offset + 0x10 + 0x4*index); + else + bp->attn_group[index].sig[4] = 0; } - reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : - HC_REG_ATTN_MSG0_ADDR_L); - REG_WR(bp, reg_offset, U64_LO(section)); - REG_WR(bp, reg_offset + 4, U64_HI(section)); + if (bp->common.int_block == INT_BLOCK_HC) { + reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : + HC_REG_ATTN_MSG0_ADDR_L); + + REG_WR(bp, reg_offset, U64_LO(section)); + REG_WR(bp, reg_offset + 4, U64_HI(section)); + } else if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_L, U64_LO(section)); + REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_H, U64_HI(section)); + } section = ((u64)mapping) + offsetof(struct host_sp_status_block, sp_sb); @@ -3715,7 +4069,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) sp_sb_data.igu_sb_id = igu_sp_sb_index; sp_sb_data.igu_seg_id = igu_seg_id; sp_sb_data.p_func.pf_id = func; - sp_sb_data.p_func.vnic_id = BP_E1HVN(bp); + sp_sb_data.p_func.vnic_id = BP_VN(bp); sp_sb_data.p_func.vf_id = 0xff; bnx2x_wr_sp_sb_data(bp, &sp_sb_data); @@ -3870,6 +4224,11 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_AGG_DATA_OFFSET + i * 4, 0); + if (CHIP_IS_E2(bp)) { + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_IGU_MODE_OFFSET, + CHIP_INT_MODE_IS_BC(bp) ? + HC_IGU_BC_MODE : HC_IGU_NBC_MODE); + } } static void bnx2x_init_internal_port(struct bnx2x *bp) @@ -3881,6 +4240,7 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) { switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: + case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: bnx2x_init_internal_common(bp); /* no break */ @@ -3911,9 +4271,11 @@ static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx) fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; /* qZone id equals to FW (per path) client id */ fp->cl_qzone_id = fp->cl_id + - BP_PORT(bp)*(ETH_MAX_RX_CLIENTS_E1H); + BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 : + ETH_MAX_RX_CLIENTS_E1H); /* init shortcut */ - fp->ustorm_rx_prods_offset = + fp->ustorm_rx_prods_offset = CHIP_IS_E2(bp) ? + USTORM_RX_PRODS_E2_OFFSET(fp->cl_qzone_id) : USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); /* Setup SB indicies */ fp->rx_cons_sb = BNX2X_RX_SB_INDEX; @@ -4248,9 +4610,19 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) static void enable_blocks_attention(struct bnx2x *bp) { REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); - REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0x40); + else + REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); + /* + * mask read length error interrupts in brb for parser + * (parsing unit and 'checksum and crc' unit) + * these errors are legal (PU reads fixed length and CAC can cause + * read length error on truncated packets) + */ + REG_WR(bp, BRB1_REG_BRB1_INT_MASK, 0xFC00); REG_WR(bp, QM_REG_QM_INT_MASK, 0); REG_WR(bp, TM_REG_TM_INT_MASK, 0); REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0); @@ -4271,6 +4643,13 @@ static void enable_blocks_attention(struct bnx2x *bp) /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */ if (CHIP_REV_IS_FPGA(bp)) REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); + else if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, + (PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF + | PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT + | PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN + | PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED + | PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED)); else REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000); REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0); @@ -4288,11 +4667,11 @@ static const struct { u32 addr; u32 mask; } bnx2x_parity_mask[] = { - {PXP_REG_PXP_PRTY_MASK, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_1, 0xffffffff}, - {HC_REG_HC_PRTY_MASK, 0xffffffff}, - {MISC_REG_MISC_PRTY_MASK, 0xffffffff}, + {PXP_REG_PXP_PRTY_MASK, 0x3ffffff}, + {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, + {PXP2_REG_PXP2_PRTY_MASK_1, 0x7f}, + {HC_REG_HC_PRTY_MASK, 0x7}, + {MISC_REG_MISC_PRTY_MASK, 0x1}, {QM_REG_QM_PRTY_MASK, 0x0}, {DORQ_REG_DORQ_PRTY_MASK, 0x0}, {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, @@ -4407,23 +4786,97 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); } +static void bnx2x_pretend_func(struct bnx2x *bp, u8 pretend_func_num) +{ + u32 offset = 0; + + if (CHIP_IS_E1(bp)) + return; + if (CHIP_IS_E1H(bp) && (pretend_func_num >= E1H_FUNC_MAX)) + return; + + switch (BP_ABS_FUNC(bp)) { + case 0: + offset = PXP2_REG_PGL_PRETEND_FUNC_F0; + break; + case 1: + offset = PXP2_REG_PGL_PRETEND_FUNC_F1; + break; + case 2: + offset = PXP2_REG_PGL_PRETEND_FUNC_F2; + break; + case 3: + offset = PXP2_REG_PGL_PRETEND_FUNC_F3; + break; + case 4: + offset = PXP2_REG_PGL_PRETEND_FUNC_F4; + break; + case 5: + offset = PXP2_REG_PGL_PRETEND_FUNC_F5; + break; + case 6: + offset = PXP2_REG_PGL_PRETEND_FUNC_F6; + break; + case 7: + offset = PXP2_REG_PGL_PRETEND_FUNC_F7; + break; + default: + return; + } + + REG_WR(bp, offset, pretend_func_num); + REG_RD(bp, offset); + DP(NETIF_MSG_HW, "Pretending to func %d\n", pretend_func_num); +} + +static void bnx2x_pf_disable(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + val &= ~IGU_PF_CONF_FUNC_EN; + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0); + REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 0); +} + static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) { u32 val, i; - DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp)); + DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_ABS_FUNC(bp)); bnx2x_reset_common(bp); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) + if (!CHIP_IS_E1(bp)) REG_WR(bp, MISC_REG_E1HMF_MODE, IS_MF(bp)); - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); - msleep(30); - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); + if (CHIP_IS_E2(bp)) { + u8 fid; + + /** + * 4-port mode or 2-port mode we need to turn of master-enable + * for everyone, after that, turn it back on for self. + * so, we disregard multi-function or not, and always disable + * for all functions on the given path, this means 0,2,4,6 for + * path 0 and 1,3,5,7 for path 1 + */ + for (fid = BP_PATH(bp); fid < E2_FUNC_MAX*2; fid += 2) { + if (fid == BP_ABS_FUNC(bp)) { + REG_WR(bp, + PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, + 1); + continue; + } + + bnx2x_pretend_func(bp, fid); + /* clear pf enable */ + bnx2x_pf_disable(bp); + bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); + } + } bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE); if (CHIP_IS_E1(bp)) { @@ -4471,9 +4924,65 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) return -EBUSY; } + /* Timers bug workaround E2 only. We need to set the entire ILT to + * have entries with value "0" and valid bit on. + * This needs to be done by the first PF that is loaded in a path + * (i.e. common phase) + */ + if (CHIP_IS_E2(bp)) { + struct ilt_client_info ilt_cli; + struct bnx2x_ilt ilt; + memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); + memset(&ilt, 0, sizeof(struct bnx2x_ilt)); + + /* initalize dummy TM client */ + ilt_cli.start = 0; + ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; + ilt_cli.client_num = ILT_CLIENT_TM; + + /* Step 1: set zeroes to all ilt page entries with valid bit on + * Step 2: set the timers first/last ilt entry to point + * to the entire range to prevent ILT range error for 3rd/4th + * vnic (this code assumes existance of the vnic) + * + * both steps performed by call to bnx2x_ilt_client_init_op() + * with dummy TM client + * + * we must use pretend since PXP2_REG_RQ_##blk##_FIRST_ILT + * and his brother are split registers + */ + bnx2x_pretend_func(bp, (BP_PATH(bp) + 6)); + bnx2x_ilt_client_init_op_ilt(bp, &ilt, &ilt_cli, INITOP_CLEAR); + bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); + + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN, BNX2X_PXP_DRAM_ALIGN); + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_RD, BNX2X_PXP_DRAM_ALIGN); + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_SEL, 1); + } + + REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); + if (CHIP_IS_E2(bp)) { + int factor = CHIP_REV_IS_EMUL(bp) ? 1000 : + (CHIP_REV_IS_FPGA(bp) ? 400 : 0); + bnx2x_init_block(bp, PGLUE_B_BLOCK, COMMON_STAGE); + + bnx2x_init_block(bp, ATC_BLOCK, COMMON_STAGE); + + /* let the HW do it's magic ... */ + do { + msleep(200); + val = REG_RD(bp, ATC_REG_ATC_INIT_DONE); + } while (factor-- && (val != 1)); + + if (val != 1) { + BNX2X_ERR("ATC_INIT failed\n"); + return -EBUSY; + } + } + bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE); /* clean the DMAE memory */ @@ -4492,6 +5001,8 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, COMMON_STAGE); /* QM queues pointers table */ bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); @@ -4512,14 +5023,26 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) } bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) { + REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD, 248); + REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD, 328); + } + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); #ifndef BCM_CNIC /* set NIC mode */ REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif - if (CHIP_IS_E1H(bp)) + if (!CHIP_IS_E1(bp)) REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); + if (CHIP_IS_E2(bp)) { + /* Bit-map indicating which L2 hdrs may appear after the + basic Ethernet header */ + int has_ovlan = IS_MF(bp); + REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); + REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); + } bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); @@ -4536,6 +5059,9 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, COMMON_STAGE); + /* sync semi rtc */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x80000000); @@ -4546,6 +5072,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); + if (CHIP_IS_E2(bp)) { + int has_ovlan = IS_MF(bp); + REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); + REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); + } + REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) REG_WR(bp, i, random32()); @@ -4583,6 +5115,11 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE); + + if (CHIP_IS_E2(bp) && BP_NOMCP(bp)) + REG_WR(bp, IGU_REG_RESET_MEMORIES, 0x36); + + bnx2x_init_block(bp, IGU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE); @@ -4590,16 +5127,35 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, 0x2814, 0xffffffff); REG_WR(bp, 0x3820, 0xffffffff); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_CONTROL_5, + (PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 | + PXPCS_TL_CONTROL_5_ERR_UNSPPORT)); + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC345_STAT, + (PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4 | + PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3 | + PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2)); + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC678_STAT, + (PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7 | + PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6 | + PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5)); + } + bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) { + if (!CHIP_IS_E1(bp)) { REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); } + if (CHIP_IS_E2(bp)) { + /* Bit-map indicating which L2 hdrs may appear after the + basic Ethernet header */ + REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6)); + } if (CHIP_REV_IS_SLOW(bp)) msleep(200); @@ -4622,15 +5178,17 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) } REG_WR(bp, CFC_REG_DEBUG0, 0); - /* read NIG statistic - to see if this is our first up since powerup */ - bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); - val = *bnx2x_sp(bp, wb_data[0]); + if (CHIP_IS_E1(bp)) { + /* read NIG statistic + to see if this is our first up since powerup */ + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); - /* do internal memory self test */ - if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) { - BNX2X_ERR("internal mem self test failed\n"); - return -EBUSY; + /* do internal memory self test */ + if ((val == 0) && bnx2x_int_mem_test(bp)) { + BNX2X_ERR("internal mem self test failed\n"); + return -EBUSY; + } } bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, @@ -4647,10 +5205,23 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) enable_blocks_parity(bp); if (!BP_NOMCP(bp)) { - bnx2x_acquire_phy_lock(bp); - bnx2x_common_init_phy(bp, bp->common.shmem_base, - bp->common.shmem2_base); - bnx2x_release_phy_lock(bp); + /* In E2 2-PORT mode, same ext phy is used for the two paths */ + if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || + CHIP_IS_E1x(bp)) { + u32 shmem_base[2], shmem2_base[2]; + shmem_base[0] = bp->common.shmem_base; + shmem2_base[0] = bp->common.shmem2_base; + if (CHIP_IS_E2(bp)) { + shmem_base[1] = + SHMEM2_RD(bp, other_shmem_base_addr); + shmem2_base[1] = + SHMEM2_RD(bp, other_shmem2_base_addr); + } + bnx2x_acquire_phy_lock(bp); + bnx2x_common_init_phy(bp, shmem_base, shmem2_base, + bp->common.chip_id); + bnx2x_release_phy_lock(bp); + } } else BNX2X_ERR("Bootcode is missing - can not initialize link\n"); @@ -4671,6 +5242,14 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, PXP_BLOCK, init_stage); bnx2x_init_block(bp, PXP2_BLOCK, init_stage); + /* Timers bug workaround: disables the pf_master bit in pglue at + * common phase, we need to enable it here before any dmae access are + * attempted. Therefore we manually added the enable-master to the + * port phase (it also happens in the function phase) + */ + if (CHIP_IS_E2(bp)) + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); + bnx2x_init_block(bp, TCM_BLOCK, init_stage); bnx2x_init_block(bp, UCM_BLOCK, init_stage); bnx2x_init_block(bp, CCM_BLOCK, init_stage); @@ -4687,29 +5266,41 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, DQ_BLOCK, init_stage); - bnx2x_init_block(bp, BRB1_BLOCK, init_stage); - if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { - /* no pause for emulation and FPGA */ - low = 0; - high = 513; - } else { - if (IS_MF(bp)) - low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); - else if (bp->dev->mtu > 4096) { - if (bp->flags & ONE_PORT_FLAG) - low = 160; - else { - val = bp->dev->mtu; - /* (24*1024 + val*4)/256 */ - low = 96 + (val/64) + ((val % 64) ? 1 : 0); - } - } else - low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); - high = low + 56; /* 14*1024/256 */ + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, init_stage); + + if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { + bnx2x_init_block(bp, BRB1_BLOCK, init_stage); + if (CHIP_REV_IS_SLOW(bp) && CHIP_IS_E1(bp)) { + /* no pause for emulation and FPGA */ + low = 0; + high = 513; + } else { + if (IS_MF(bp)) + low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); + else if (bp->dev->mtu > 4096) { + if (bp->flags & ONE_PORT_FLAG) + low = 160; + else { + val = bp->dev->mtu; + /* (24*1024 + val*4)/256 */ + low = 96 + (val/64) + + ((val % 64) ? 1 : 0); + } + } else + low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); + high = low + 56; /* 14*1024/256 */ + } + REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); + REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); } - REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); - REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); + if (CHIP_MODE_IS_4_PORT(bp)) { + REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 + port*8, 248); + REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 + port*8, 328); + REG_WR(bp, (BP_PORT(bp) ? BRB1_REG_MAC_GUARANTIED_1 : + BRB1_REG_MAC_GUARANTIED_0), 40); + } bnx2x_init_block(bp, PRS_BLOCK, init_stage); @@ -4722,24 +5313,28 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, USEM_BLOCK, init_stage); bnx2x_init_block(bp, CSEM_BLOCK, init_stage); bnx2x_init_block(bp, XSEM_BLOCK, init_stage); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, init_stage); bnx2x_init_block(bp, UPB_BLOCK, init_stage); bnx2x_init_block(bp, XPB_BLOCK, init_stage); bnx2x_init_block(bp, PBF_BLOCK, init_stage); - /* configure PBF to work without PAUSE mtu 9000 */ - REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); + if (!CHIP_IS_E2(bp)) { + /* configure PBF to work without PAUSE mtu 9000 */ + REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); - /* update threshold */ - REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); - /* update init credit */ - REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); + /* update threshold */ + REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); + /* update init credit */ + REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); - /* probe changes */ - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); - msleep(5); - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + /* probe changes */ + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); + udelay(50); + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + } #ifdef BCM_CNIC bnx2x_init_block(bp, SRCH_BLOCK, init_stage); @@ -4753,6 +5348,8 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) } bnx2x_init_block(bp, HC_BLOCK, init_stage); + bnx2x_init_block(bp, IGU_BLOCK, init_stage); + bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage); /* init aeu_mask_attn_func_0/1: * - SF mode: bits 3-7 are masked. only bits 0-2 are in use @@ -4771,11 +5368,25 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); - if (CHIP_IS_E1H(bp)) { + if (!CHIP_IS_E1(bp)) { /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, (IS_MF(bp) ? 0x1 : 0x2)); + if (CHIP_IS_E2(bp)) { + val = 0; + switch (bp->mf_mode) { + case MULTI_FUNCTION_SD: + val = 1; + break; + case MULTI_FUNCTION_SI: + val = 2; + break; + } + + REG_WR(bp, (BP_PORT(bp) ? NIG_REG_LLH1_CLS_TYPE : + NIG_REG_LLH0_CLS_TYPE), val); + } { REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0); @@ -4805,14 +5416,26 @@ static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) { int reg; - if (CHIP_IS_E1H(bp)) - reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; - else /* E1 */ + if (CHIP_IS_E1(bp)) reg = PXP2_REG_RQ_ONCHIP_AT + index*8; + else + reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr)); } +static inline void bnx2x_igu_clear_sb(struct bnx2x *bp, u8 idu_sb_id) +{ + bnx2x_igu_clear_sb_gen(bp, idu_sb_id, true /*PF*/); +} + +static inline void bnx2x_clear_func_ilt(struct bnx2x *bp, u32 func) +{ + u32 i, base = FUNC_ILT_BASE(func); + for (i = base; i < base + ILT_PER_FUNC; i++) + bnx2x_ilt_wr(bp, i, 0); +} + static int bnx2x_init_hw_func(struct bnx2x *bp) { int port = BP_PORT(bp); @@ -4825,10 +5448,12 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); /* set MSI reconfigure capability */ - addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); - val = REG_RD(bp, addr); - val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; - REG_WR(bp, addr, val); + if (bp->common.int_block == INT_BLOCK_HC) { + addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); + val = REG_RD(bp, addr); + val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; + REG_WR(bp, addr, val); + } ilt = BP_ILT(bp); cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; @@ -4854,10 +5479,38 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif /* BCM_CNIC */ + if (CHIP_IS_E2(bp)) { + u32 pf_conf = IGU_PF_CONF_FUNC_EN; + + /* Turn on a single ISR mode in IGU if driver is going to use + * INT#x or MSI + */ + if (!(bp->flags & USING_MSIX_FLAG)) + pf_conf |= IGU_PF_CONF_SINGLE_ISR_EN; + /* + * Timers workaround bug: function init part. + * Need to wait 20msec after initializing ILT, + * needed to make sure there are no requests in + * one of the PXP internal queues with "old" ILT addresses + */ + msleep(20); + /* + * Master enable - Due to WB DMAE writes performed before this + * register is re-initialized as part of the regular function + * init + */ + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); + /* Enable the function in IGU */ + REG_WR(bp, IGU_REG_PF_CONFIGURATION, pf_conf); + } + bp->dmae_ready = 1; bnx2x_init_block(bp, PGLUE_B_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, func); + bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); @@ -4868,7 +5521,24 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_PATH_ID_OFFSET, + BP_PATH(bp)); + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_PATH_ID_OFFSET, + BP_PATH(bp)); + } + + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) + REG_WR(bp, QM_REG_PF_EN, 1); + bnx2x_init_block(bp, QM_BLOCK, FUNC0_STAGE + func); + + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TIMERS_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, DQ_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, BRB1_BLOCK, FUNC0_STAGE + func); @@ -4880,10 +5550,16 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, UPB_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, XPB_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, PBF_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PBF_REG_DISABLE_PF, 0); + bnx2x_init_block(bp, CDU_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) + REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 1); + if (IS_MF(bp)) { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov); @@ -4892,13 +5568,117 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); /* HC init per function */ - if (CHIP_IS_E1H(bp)) { + if (bp->common.int_block == INT_BLOCK_HC) { + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); + + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } + bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); + + } else { + int num_segs, sb_idx, prod_offset; + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0); + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); + } + + bnx2x_init_block(bp, IGU_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) { + int dsb_idx = 0; + /** + * Producer memory: + * E2 mode: address 0-135 match to the mapping memory; + * 136 - PF0 default prod; 137 - PF1 default prod; + * 138 - PF2 default prod; 139 - PF3 default prod; + * 140 - PF0 attn prod; 141 - PF1 attn prod; + * 142 - PF2 attn prod; 143 - PF3 attn prod; + * 144-147 reserved. + * + * E1.5 mode - In backward compatible mode; + * for non default SB; each even line in the memory + * holds the U producer and each odd line hold + * the C producer. The first 128 producers are for + * NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The last 20 + * producers are for the DSB for each PF. + * Each PF has five segments: (the order inside each + * segment is PF0; PF1; PF2; PF3) - 128-131 U prods; + * 132-135 C prods; 136-139 X prods; 140-143 T prods; + * 144-147 attn prods; + */ + /* non-default-status-blocks */ + num_segs = CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_NDSB_NUM_SEGS : IGU_NORM_NDSB_NUM_SEGS; + for (sb_idx = 0; sb_idx < bp->igu_sb_cnt; sb_idx++) { + prod_offset = (bp->igu_base_sb + sb_idx) * + num_segs; + + for (i = 0; i < num_segs; i++) { + addr = IGU_REG_PROD_CONS_MEMORY + + (prod_offset + i) * 4; + REG_WR(bp, addr, 0); + } + /* send consumer update with value 0 */ + bnx2x_ack_sb(bp, bp->igu_base_sb + sb_idx, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_igu_clear_sb(bp, + bp->igu_base_sb + sb_idx); + } + + /* default-status-blocks */ + num_segs = CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_DSB_NUM_SEGS : IGU_NORM_DSB_NUM_SEGS; + + if (CHIP_MODE_IS_4_PORT(bp)) + dsb_idx = BP_FUNC(bp); + else + dsb_idx = BP_E1HVN(bp); + + prod_offset = (CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_BASE_DSB_PROD + dsb_idx : + IGU_NORM_BASE_DSB_PROD + dsb_idx); + + for (i = 0; i < (num_segs * E1HVN_MAX); + i += E1HVN_MAX) { + addr = IGU_REG_PROD_CONS_MEMORY + + (prod_offset + i)*4; + REG_WR(bp, addr, 0); + } + /* send consumer update with 0 */ + if (CHIP_INT_MODE_IS_BC(bp)) { + bnx2x_ack_sb(bp, bp->igu_dsb_id, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + CSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + XSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + TSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + ATTENTION_ID, 0, IGU_INT_NOP, 1); + } else { + bnx2x_ack_sb(bp, bp->igu_dsb_id, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + ATTENTION_ID, 0, IGU_INT_NOP, 1); + } + bnx2x_igu_clear_sb(bp, bp->igu_dsb_id); + + /* !!! these should become driver const once + rf-tool supports split-68 const */ + REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_LSB, 0); + REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_MSB, 0); + REG_WR(bp, IGU_REG_SB_MASK_LSB, 0); + REG_WR(bp, IGU_REG_SB_MASK_MSB, 0); + REG_WR(bp, IGU_REG_PBA_STATUS_LSB, 0); + REG_WR(bp, IGU_REG_PBA_STATUS_MSB, 0); + } } - bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); @@ -4920,7 +5700,7 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) int rc = 0; DP(BNX2X_MSG_MCP, "function %d load_code %x\n", - BP_FUNC(bp), load_code); + BP_ABS_FUNC(bp), load_code); bp->dmae_ready = 0; mutex_init(&bp->dmae_mutex); @@ -4930,6 +5710,7 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: + case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: rc = bnx2x_init_hw_common(bp, load_code); if (rc) goto init_hw_err; @@ -4953,10 +5734,10 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) } if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) & + (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & DRV_PULSE_SEQ_MASK); DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); } @@ -4993,9 +5774,14 @@ void bnx2x_free_mem(struct bnx2x *bp) /* Common */ for_each_queue(bp, i) { /* status blocks */ - BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), - bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_hc_status_block_e1x)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb), + bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), + bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e1x)); } /* Rx */ for_each_queue(bp, i) { @@ -5041,9 +5827,12 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_FREE(bp->ilt->lines); #ifdef BCM_CNIC - - BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, - sizeof(struct host_hc_status_block_e1x)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); #endif BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); @@ -5055,6 +5844,22 @@ void bnx2x_free_mem(struct bnx2x *bp) #undef BNX2X_KFREE } +static inline void set_sb_shortcuts(struct bnx2x *bp, int index) +{ + union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk); + if (CHIP_IS_E2(bp)) { + bnx2x_fp(bp, index, sb_index_values) = + (__le16 *)status_blk.e2_sb->sb.index_values; + bnx2x_fp(bp, index, sb_running_index) = + (__le16 *)status_blk.e2_sb->sb.running_index; + } else { + bnx2x_fp(bp, index, sb_index_values) = + (__le16 *)status_blk.e1x_sb->sb.index_values; + bnx2x_fp(bp, index, sb_running_index) = + (__le16 *)status_blk.e1x_sb->sb.running_index; + } +} + int bnx2x_alloc_mem(struct bnx2x *bp) { @@ -5074,25 +5879,23 @@ int bnx2x_alloc_mem(struct bnx2x *bp) } while (0) int i; - void *p; /* fastpath */ /* Common */ for_each_queue(bp, i) { + union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk); bnx2x_fp(bp, i, bp) = bp; - /* status blocks */ - BNX2X_PCI_ALLOC(p, + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(sb->e2_sb, + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(sb->e1x_sb, &bnx2x_fp(bp, i, status_blk_mapping), sizeof(struct host_hc_status_block_e1x)); - bnx2x_fp(bp, i, status_blk.e1x_sb) = - (struct host_hc_status_block_e1x *)p; - - bnx2x_fp(bp, i, sb_index_values) = (__le16 *) - (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.index_values); - bnx2x_fp(bp, i, sb_running_index) = (__le16 *) - (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.running_index); + set_sb_shortcuts(bp, i); } /* Rx */ for_each_queue(bp, i) { @@ -5129,8 +5932,12 @@ int bnx2x_alloc_mem(struct bnx2x *bp) /* end of fastpath */ #ifdef BCM_CNIC - BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, - sizeof(struct host_hc_status_block_e1x)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); /* allocate searcher T2 table */ BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); @@ -5210,11 +6017,6 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, bp->set_mac_pending = 1; smp_wmb(); - config->hdr.length = 1 + (is_bcast ? 1 : 0); - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; - config->hdr.length = 1; config->hdr.offset = cam_offset; config->hdr.client_id = 0xff; @@ -5312,7 +6114,12 @@ int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) { - return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); + if (CHIP_IS_E1H(bp)) + return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); + else if (CHIP_MODE_IS_4_PORT(bp)) + return BP_FUNC(bp) * 32 + rel_offset; + else + return BP_VN(bp) * 32 + rel_offset; } void bnx2x_set_eth_mac(struct bnx2x *bp, int set) @@ -5804,9 +6611,11 @@ static void bnx2x_reset_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); - int base, i; + int i; int pfunc_offset_fp = offsetof(struct hc_sb_data, p_func) + - offsetof(struct hc_status_block_data_e1x, common); + (CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, common) : + offsetof(struct hc_status_block_data_e1x, common)); int pfunc_offset_sp = offsetof(struct hc_sp_status_block_data, p_func); int pfid_offset = offsetof(struct pci_entity, pf_id); @@ -5839,8 +6648,13 @@ static void bnx2x_reset_func(struct bnx2x *bp) 0); /* Configure IGU */ - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + if (bp->common.int_block == INT_BLOCK_HC) { + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } else { + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0); + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); + } #ifdef BCM_CNIC /* Disable Timer scan */ @@ -5856,9 +6670,25 @@ static void bnx2x_reset_func(struct bnx2x *bp) } #endif /* Clear ILT */ - base = FUNC_ILT_BASE(func); - for (i = base; i < base + ILT_PER_FUNC; i++) - bnx2x_ilt_wr(bp, i, 0); + bnx2x_clear_func_ilt(bp, func); + + /* Timers workaround bug for E2: if this is vnic-3, + * we need to set the entire ilt range for this timers. + */ + if (CHIP_IS_E2(bp) && BP_VN(bp) == 3) { + struct ilt_client_info ilt_cli; + /* use dummy TM client */ + memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); + ilt_cli.start = 0; + ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; + ilt_cli.client_num = ILT_CLIENT_TM; + + bnx2x_ilt_boundry_init_op(bp, &ilt_cli, 0, INITOP_CLEAR); + } + + /* this assumes that reset_port() called before reset_func()*/ + if (CHIP_IS_E2(bp)) + bnx2x_pf_disable(bp); bp->dmae_ready = 0; } @@ -5892,7 +6722,7 @@ static void bnx2x_reset_port(struct bnx2x *bp) static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) { DP(BNX2X_MSG_MCP, "function %d reset_code %x\n", - BP_FUNC(bp), reset_code); + BP_ABS_FUNC(bp), reset_code); switch (reset_code) { case FW_MSG_CODE_DRV_UNLOAD_COMMON: @@ -6024,15 +6854,20 @@ unload_error: if (!BP_NOMCP(bp)) reset_code = bnx2x_fw_command(bp, reset_code, 0); else { - DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]--; - load_count[1 + port]--; - DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 0) + DP(NETIF_MSG_IFDOWN, "NO MCP - load counts[%d] " + "%d, %d, %d\n", BP_PATH(bp), + load_count[BP_PATH(bp)][0], + load_count[BP_PATH(bp)][1], + load_count[BP_PATH(bp)][2]); + load_count[BP_PATH(bp)][0]--; + load_count[BP_PATH(bp)][1 + port]--; + DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts[%d] " + "%d, %d, %d\n", BP_PATH(bp), + load_count[BP_PATH(bp)][0], load_count[BP_PATH(bp)][1], + load_count[BP_PATH(bp)][2]); + if (load_count[BP_PATH(bp)][0] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; - else if (load_count[1 + port] == 0) + else if (load_count[BP_PATH(bp)][1 + port] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; else reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; @@ -6531,39 +7366,23 @@ reset_task_exit: * Init service functions */ -static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func) -{ - switch (func) { - case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0; - case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1; - case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2; - case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3; - case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4; - case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5; - case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6; - case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7; - default: - BNX2X_ERR("Unsupported function index: %d\n", func); - return (u32)(-1); - } +u32 bnx2x_get_pretend_reg(struct bnx2x *bp) +{ + u32 base = PXP2_REG_PGL_PRETEND_FUNC_F0; + u32 stride = PXP2_REG_PGL_PRETEND_FUNC_F1 - base; + return base + (BP_ABS_FUNC(bp)) * stride; } -static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) +static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp) { - u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val; + u32 reg = bnx2x_get_pretend_reg(bp); /* Flush all outstanding writes */ mmiowb(); /* Pretend to be function 0 */ REG_WR(bp, reg, 0); - /* Flush the GRC transaction (in the chip) */ - new_val = REG_RD(bp, reg); - if (new_val != 0) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n", - new_val); - BUG(); - } + REG_RD(bp, reg); /* Flush the GRC transaction (in the chip) */ /* From now we are in the "like-E1" mode */ bnx2x_int_disable(bp); @@ -6571,22 +7390,17 @@ static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) /* Flush all outstanding writes */ mmiowb(); - /* Restore the original funtion settings */ - REG_WR(bp, reg, orig_func); - new_val = REG_RD(bp, reg); - if (new_val != orig_func) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n", - orig_func, new_val); - BUG(); - } + /* Restore the original function */ + REG_WR(bp, reg, BP_ABS_FUNC(bp)); + REG_RD(bp, reg); } -static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func) +static inline void bnx2x_undi_int_disable(struct bnx2x *bp) { - if (CHIP_IS_E1H(bp)) - bnx2x_undi_int_disable_e1h(bp, func); - else + if (CHIP_IS_E1(bp)) bnx2x_int_disable(bp); + else + bnx2x_undi_int_disable_e1h(bp); } static void __devinit bnx2x_undi_unload(struct bnx2x *bp) @@ -6603,8 +7417,8 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); if (val == 0x7) { u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - /* save our func */ - int func = BP_FUNC(bp); + /* save our pf_num */ + int orig_pf_num = bp->pf_num; u32 swap_en; u32 swap_val; @@ -6614,9 +7428,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) BNX2X_DEV_INFO("UNDI is active! reset device\n"); /* try unload UNDI on port 0 */ - bp->func = 0; + bp->pf_num = 0; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); reset_code = bnx2x_fw_command(bp, reset_code, 0); @@ -6628,9 +7442,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) DRV_MSG_CODE_UNLOAD_DONE, 0); /* unload UNDI on port 1 */ - bp->func = 1; + bp->pf_num = 1; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; @@ -6640,7 +7454,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) /* now it's safe to release the lock */ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - bnx2x_undi_int_disable(bp, func); + bnx2x_undi_int_disable(bp); /* close input traffic and wait for it */ /* Do not rcv packets to BRB */ @@ -6679,9 +7493,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); /* restore our func and fw_seq */ - bp->func = func; + bp->pf_num = orig_pf_num; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); } else @@ -6705,20 +7519,42 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val = REG_RD(bp, MISC_REG_BOND_ID); id |= (val & 0xf); bp->common.chip_id = id; - bp->link_params.chip_id = bp->common.chip_id; - BNX2X_DEV_INFO("chip ID is 0x%x\n", id); - - bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */ /* Set doorbell size */ bp->db_size = (1 << BNX2X_DB_SHIFT); + if (CHIP_IS_E2(bp)) { + val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR); + if ((val & 1) == 0) + val = REG_RD(bp, MISC_REG_PORT4MODE_EN); + else + val = (val >> 1) & 1; + BNX2X_DEV_INFO("chip is in %s\n", val ? "4_PORT_MODE" : + "2_PORT_MODE"); + bp->common.chip_port_mode = val ? CHIP_4_PORT_MODE : + CHIP_2_PORT_MODE; + + if (CHIP_MODE_IS_4_PORT(bp)) + bp->pfid = (bp->pf_num >> 1); /* 0..3 */ + else + bp->pfid = (bp->pf_num & 0x6); /* 0, 2, 4, 6 */ + } else { + bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */ + bp->pfid = bp->pf_num; /* 0..7 */ + } + /* * set base FW non-default (fast path) status block id, this value is * used to initialize the fw_sb_id saved on the fp/queue structure to * determine the id used by the FW. */ - bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; + if (CHIP_IS_E1x(bp)) + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; + else /* E2 */ + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E2; + + bp->link_params.chip_id = bp->common.chip_id; + BNX2X_DEV_INFO("chip ID is 0x%x\n", id); val = (REG_RD(bp, 0x2874) & 0x55); if ((bp->common.chip_id & 0x1) || @@ -6734,15 +7570,15 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->common.flash_size, bp->common.flash_size); bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); - bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); + bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ? + MISC_REG_GENERIC_CR_1 : + MISC_REG_GENERIC_CR_0)); bp->link_params.shmem_base = bp->common.shmem_base; bp->link_params.shmem2_base = bp->common.shmem2_base; BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", bp->common.shmem_base, bp->common.shmem2_base); - if (!bp->common.shmem_base || - (bp->common.shmem_base < 0xA0000) || - (bp->common.shmem_base >= 0xC0000)) { + if (!bp->common.shmem_base) { BNX2X_DEV_INFO("MCP not active\n"); bp->flags |= NO_MCP_FLAG; return; @@ -6751,7 +7587,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - BNX2X_ERROR("BAD MCP validity signature\n"); + BNX2X_ERR("BAD MCP validity signature\n"); bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config); @@ -6775,8 +7611,8 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) if (val < BNX2X_BC_VER) { /* for now only warn * later we might need to enforce this */ - BNX2X_ERROR("This driver needs bc_ver %X but found %X, " - "please upgrade BC\n", BNX2X_BC_VER, val); + BNX2X_ERR("This driver needs bc_ver %X but found %X, " + "please upgrade BC\n", BNX2X_BC_VER, val); } bp->link_params.feature_config_flags |= (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? @@ -6804,6 +7640,57 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val, val2, val3, val4); } +#define IGU_FID(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_FID) +#define IGU_VEC(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_VECTOR) + +static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) +{ + int pfid = BP_FUNC(bp); + int vn = BP_E1HVN(bp); + int igu_sb_id; + u32 val; + u8 fid; + + bp->igu_base_sb = 0xff; + bp->igu_sb_cnt = 0; + if (CHIP_INT_MODE_IS_BC(bp)) { + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, + bp->l2_cid_count); + + bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) * + FP_SB_MAX_E1x; + + bp->igu_dsb_id = E1HVN_MAX * FP_SB_MAX_E1x + + (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn); + + return; + } + + /* IGU in normal mode - read CAM */ + for (igu_sb_id = 0; igu_sb_id < IGU_REG_MAPPING_MEMORY_SIZE; + igu_sb_id++) { + val = REG_RD(bp, IGU_REG_MAPPING_MEMORY + igu_sb_id * 4); + if (!(val & IGU_REG_MAPPING_MEMORY_VALID)) + continue; + fid = IGU_FID(val); + if ((fid & IGU_FID_ENCODE_IS_PF)) { + if ((fid & IGU_FID_PF_NUM_MASK) != pfid) + continue; + if (IGU_VEC(val) == 0) + /* default status block */ + bp->igu_dsb_id = igu_sb_id; + else { + if (bp->igu_base_sb == 0xff) + bp->igu_base_sb = igu_sb_id; + bp->igu_sb_cnt++; + } + } + } + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, bp->l2_cid_count); + if (bp->igu_sb_cnt == 0) + BNX2X_ERR("CAM configuration error\n"); +} + static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) { @@ -7178,26 +8065,49 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) { - int func = BP_FUNC(bp); + int func = BP_ABS_FUNC(bp); + int vn; u32 val, val2; int rc = 0; bnx2x_get_common_hwinfo(bp); - bp->common.int_block = INT_BLOCK_HC; + if (CHIP_IS_E1x(bp)) { + bp->common.int_block = INT_BLOCK_HC; + + bp->igu_dsb_id = DEF_SB_IGU_ID; + bp->igu_base_sb = 0; + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + } else { + bp->common.int_block = INT_BLOCK_IGU; + val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); + if (val & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN) { + DP(NETIF_MSG_PROBE, "IGU Backward Compatible Mode\n"); + bp->common.int_block |= INT_BLOCK_MODE_BW_COMP; + } else + DP(NETIF_MSG_PROBE, "IGU Normal Mode\n"); - bp->igu_dsb_id = DEF_SB_IGU_ID; - bp->igu_base_sb = 0; - bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + bnx2x_get_igu_cam_info(bp); + + } + DP(NETIF_MSG_PROBE, "igu_dsb_id %d igu_base_sb %d igu_sb_cnt %d\n", + bp->igu_dsb_id, bp->igu_base_sb, bp->igu_sb_cnt); + + /* + * Initialize MF configuration + */ bp->mf_ov = 0; bp->mf_mode = 0; - if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { - - bp->common.mf_cfg_base = bp->common.shmem_base + + vn = BP_E1HVN(bp); + if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { + if (SHMEM2_HAS(bp, mf_cfg_addr)) + bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); + else + bp->common.mf_cfg_base = bp->common.shmem_base + offsetof(struct shmem_region, func_mb) + E1H_FUNC_MAX * sizeof(struct drv_func_mb); - bp->mf_config = + bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & @@ -7213,16 +8123,16 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { bp->mf_ov = val; - BNX2X_DEV_INFO("E1HOV for func %d is %d " + BNX2X_DEV_INFO("MF OV for func %d is %d " "(0x%04x)\n", func, bp->mf_ov, bp->mf_ov); } else { - BNX2X_ERROR("No valid E1HOV for func %d," + BNX2X_ERROR("No valid MF OV for func %d," " aborting\n", func); rc = -EPERM; } } else { - if (BP_E1HVN(bp)) { + if (BP_VN(bp)) { BNX2X_ERROR("VN %d in single function mode," " aborting\n", BP_E1HVN(bp)); rc = -EPERM; @@ -7230,15 +8140,25 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } } - /* adjust igu_sb_cnt to MF */ - if (IS_MF(bp)) + /* adjust igu_sb_cnt to MF for E1x */ + if (CHIP_IS_E1x(bp) && IS_MF(bp)) bp->igu_sb_cnt /= E1HVN_MAX; + /* + * adjust E2 sb count: to be removed when FW will support + * more then 16 L2 clients + */ +#define MAX_L2_CLIENTS 16 + if (CHIP_IS_E2(bp)) + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, + MAX_L2_CLIENTS / (IS_MF(bp) ? 4 : 1)); + if (!BP_NOMCP(bp)) { bnx2x_get_port_hwinfo(bp); - bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } @@ -7338,7 +8258,7 @@ out_not_found: static int __devinit bnx2x_init_bp(struct bnx2x *bp) { - int func = BP_FUNC(bp); + int func; int timer_interval; int rc; @@ -7362,6 +8282,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) rc = bnx2x_alloc_mem_bp(bp); bnx2x_read_fwinfo(bp); + + func = BP_FUNC(bp); + /* need to reset chip if undi was active */ if (!BP_NOMCP(bp)) bnx2x_undi_unload(bp); @@ -7650,7 +8573,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, bp->dev = dev; bp->pdev = pdev; bp->flags = 0; - bp->func = PCI_FUNC(pdev->devfn); + bp->pf_num = PCI_FUNC(pdev->devfn); rc = pci_enable_device(pdev); if (rc) { @@ -7964,6 +8887,8 @@ int bnx2x_init_firmware(struct bnx2x *bp) fw_file_name = FW_FILE_NAME_E1; else if (CHIP_IS_E1H(bp)) fw_file_name = FW_FILE_NAME_E1H; + else if (CHIP_IS_E2(bp)) + fw_file_name = FW_FILE_NAME_E2; else { BNX2X_ERR("Unsupported chip revision\n"); return -EINVAL; @@ -8047,8 +8972,25 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, int pcie_width, pcie_speed; int rc, cid_count; - cid_count = FP_SB_MAX_E1x + CNIC_CONTEXT_USE; + switch (ent->driver_data) { + case BCM57710: + case BCM57711: + case BCM57711E: + cid_count = FP_SB_MAX_E1x; + break; + + case BCM57712: + case BCM57712E: + cid_count = FP_SB_MAX_E2; + break; + default: + pr_err("Unknown board_type (%ld), aborting\n", + ent->driver_data); + return ENODEV; + } + + cid_count += CNIC_CONTEXT_USE; /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mq(sizeof(*bp), cid_count); if (!dev) { @@ -8086,7 +9028,10 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," " IRQ %d, ", board_info[ent->driver_data].name, (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4), - pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz", + pcie_width, + ((!CHIP_IS_E2(bp) && pcie_speed == 2) || + (CHIP_IS_E2(bp) && pcie_speed == 1)) ? + "5GHz (Gen2)" : "2.5GHz", dev->base_addr, bp->pdev->irq); pr_cont("node addr %pM\n", dev->dev_addr); @@ -8199,8 +9144,9 @@ static void bnx2x_eeh_recover(struct bnx2x *bp) BNX2X_ERR("BAD MCP validity signature\n"); if (!BP_NOMCP(bp)) { - bp->fw_seq = (SHMEM_RD(bp, func_mb[BP_FUNC(bp)].drv_mb_header) - & DRV_MSG_SEQ_NUMBER_MASK); + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } } @@ -8283,7 +9229,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev) struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + printk(KERN_ERR "Handling parity error recovery. " + "Try again later\n"); return; } @@ -8560,7 +9507,11 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX; cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX; } - cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; + if (CHIP_IS_E2(bp)) + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e2_sb; + else + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; + cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp); cp->irq_arr[0].status_blk_num2 = CNIC_IGU_SB_ID(bp); cp->irq_arr[1].status_blk = bp->def_status_blk; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 6be0d09ad3fd..18a86284ebcc 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2009 Broadcom Corporation + * Copyright (c) 2007-2010 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,20 @@ * */ - +#define ATC_ATC_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS (0x1<<2) +#define ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU (0x1<<5) +#define ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT (0x1<<3) +#define ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR (0x1<<4) +#define ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND (0x1<<1) +/* [RW 1] Initiate the ATC array - reset all the valid bits */ +#define ATC_REG_ATC_INIT_ARRAY 0x1100b8 +/* [R 1] ATC initalization done */ +#define ATC_REG_ATC_INIT_DONE 0x1100bc +/* [RC 6] Interrupt register #0 read clear */ +#define ATC_REG_ATC_INT_STS_CLR 0x1101c0 +/* [RW 19] Interrupt mask register #0 read/write */ +#define BRB1_REG_BRB1_INT_MASK 0x60128 /* [R 19] Interrupt register #0 read */ #define BRB1_REG_BRB1_INT_STS 0x6011c /* [RW 4] Parity mask register #0 read/write */ @@ -27,9 +40,31 @@ /* [R 4] Parity register #0 read */ #define BRB1_REG_BRB1_PRTY_STS 0x6012c /* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At - address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address - BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */ + * address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address + * BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. Warning - + * following reset the first rbc access to this reg must be write; there can + * be no more rbc writes after the first one; there can be any number of rbc + * read following the first write; rbc access not following these rules will + * result in hang condition. */ #define BRB1_REG_FREE_LIST_PRS_CRDT 0x60200 +/* [RW 10] The number of free blocks below which the full signal to class 0 + * is asserted */ +#define BRB1_REG_FULL_0_XOFF_THRESHOLD_0 0x601d0 +/* [RW 10] The number of free blocks above which the full signal to class 0 + * is de-asserted */ +#define BRB1_REG_FULL_0_XON_THRESHOLD_0 0x601d4 +/* [RW 10] The number of free blocks below which the full signal to class 1 + * is asserted */ +#define BRB1_REG_FULL_1_XOFF_THRESHOLD_0 0x601d8 +/* [RW 10] The number of free blocks above which the full signal to class 1 + * is de-asserted */ +#define BRB1_REG_FULL_1_XON_THRESHOLD_0 0x601dc +/* [RW 10] The number of free blocks below which the full signal to the LB + * port is asserted */ +#define BRB1_REG_FULL_LB_XOFF_THRESHOLD 0x601e0 +/* [RW 10] The number of free blocks above which the full signal to the LB + * port is de-asserted */ +#define BRB1_REG_FULL_LB_XON_THRESHOLD 0x601e4 /* [RW 10] The number of free blocks above which the High_llfc signal to interface #n is de-asserted. */ #define BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD_0 0x6014c @@ -44,6 +79,9 @@ /* [RW 10] The number of free blocks below which the Low_llfc signal to interface #n is asserted. */ #define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0 0x6015c +/* [RW 10] The number of blocks guarantied for the MAC port */ +#define BRB1_REG_MAC_GUARANTIED_0 0x601e8 +#define BRB1_REG_MAC_GUARANTIED_1 0x60240 /* [R 24] The number of full blocks. */ #define BRB1_REG_NUM_OF_FULL_BLOCKS 0x60090 /* [ST 32] The number of cycles that the write_full signal towards MAC #0 @@ -55,7 +93,19 @@ asserted. */ #define BRB1_REG_NUM_OF_PAUSE_CYCLES_0 0x600b8 #define BRB1_REG_NUM_OF_PAUSE_CYCLES_1 0x600bc -/* [RW 10] Write client 0: De-assert pause threshold. */ +/* [RW 10] The number of free blocks below which the pause signal to class 0 + * is asserted */ +#define BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 0x601c0 +/* [RW 10] The number of free blocks above which the pause signal to class 0 + * is de-asserted */ +#define BRB1_REG_PAUSE_0_XON_THRESHOLD_0 0x601c4 +/* [RW 10] The number of free blocks below which the pause signal to class 1 + * is asserted */ +#define BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0 0x601c8 +/* [RW 10] The number of free blocks above which the pause signal to class 1 + * is de-asserted */ +#define BRB1_REG_PAUSE_1_XON_THRESHOLD_0 0x601cc +/* [RW 10] Write client 0: De-assert pause threshold. Not Functional */ #define BRB1_REG_PAUSE_HIGH_THRESHOLD_0 0x60078 #define BRB1_REG_PAUSE_HIGH_THRESHOLD_1 0x6007c /* [RW 10] Write client 0: Assert pause threshold. */ @@ -362,6 +412,7 @@ #define CFC_REG_NUM_LCIDS_ARRIVING 0x104004 /* [R 9] Number of Leaving LCIDs in Link List Block */ #define CFC_REG_NUM_LCIDS_LEAVING 0x104018 +#define CFC_REG_WEAK_ENABLE_PF 0x104124 /* [RW 8] The event id for aggregated interrupt 0 */ #define CSDM_REG_AGG_INT_EVENT_0 0xc2038 #define CSDM_REG_AGG_INT_EVENT_10 0xc2060 @@ -590,10 +641,17 @@ #define CSEM_REG_TS_8_AS 0x200058 /* [RW 3] The arbitration scheme of time_slot 9 */ #define CSEM_REG_TS_9_AS 0x20005c +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define CSEM_REG_VFPF_ERR_NUM 0x200380 /* [RW 1] Parity mask register #0 read/write */ #define DBG_REG_DBG_PRTY_MASK 0xc0a8 /* [R 1] Parity register #0 read */ #define DBG_REG_DBG_PRTY_STS 0xc09c +/* [RW 1] When set the DMAE will process the commands as in E1.5. 1.The + * function that is used is always SRC-PCI; 2.VF_Valid = 0; 3.VFID=0; + * 4.Completion function=0; 5.Error handling=0 */ +#define DMAE_REG_BACKWARD_COMP_EN 0x10207c /* [RW 32] Commands memory. The address to command X; row Y is to calculated as 14*X+Y. */ #define DMAE_REG_CMD_MEM 0x102400 @@ -758,6 +816,92 @@ #define HC_REG_USTORM_ADDR_FOR_COALESCE 0x108068 #define HC_REG_VQID_0 0x108008 #define HC_REG_VQID_1 0x10800c +#define IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN (0x1<<1) +#define IGU_REG_ATTENTION_ACK_BITS 0x130108 +/* [R 4] Debug: attn_fsm */ +#define IGU_REG_ATTN_FSM 0x130054 +#define IGU_REG_ATTN_MSG_ADDR_H 0x13011c +#define IGU_REG_ATTN_MSG_ADDR_L 0x130120 +/* [R 4] Debug: [3] - attention write done message is pending (0-no pending; + * 1-pending). [2:0] = PFID. Pending means attention message was sent; but + * write done didnt receive. */ +#define IGU_REG_ATTN_WRITE_DONE_PENDING 0x130030 +#define IGU_REG_BLOCK_CONFIGURATION 0x130000 +#define IGU_REG_COMMAND_REG_32LSB_DATA 0x130124 +#define IGU_REG_COMMAND_REG_CTRL 0x13012c +/* [WB_R 32] Cleanup bit status per SB. 1 = cleanup is set. 0 = cleanup bit + * is clear. The bits in this registers are set and clear via the producer + * command. Data valid only in addresses 0-4. all the rest are zero. */ +#define IGU_REG_CSTORM_TYPE_0_SB_CLEANUP 0x130200 +/* [R 5] Debug: ctrl_fsm */ +#define IGU_REG_CTRL_FSM 0x130064 +/* [R 1] data availble for error memory. If this bit is clear do not red + * from error_handling_memory. */ +#define IGU_REG_ERROR_HANDLING_DATA_VALID 0x130130 +/* [R 11] Parity register #0 read */ +#define IGU_REG_IGU_PRTY_STS 0x13009c +/* [R 4] Debug: int_handle_fsm */ +#define IGU_REG_INT_HANDLE_FSM 0x130050 +#define IGU_REG_LEADING_EDGE_LATCH 0x130134 +/* [RW 14] mapping CAM; relevant for E2 operating mode only. [0] - valid. + * [6:1] - vector number; [13:7] - FID (if VF - [13] = 0; [12:7] = VF + * number; if PF - [13] = 1; [12:10] = 0; [9:7] = PF number); */ +#define IGU_REG_MAPPING_MEMORY 0x131000 +#define IGU_REG_MAPPING_MEMORY_SIZE 136 +#define IGU_REG_PBA_STATUS_LSB 0x130138 +#define IGU_REG_PBA_STATUS_MSB 0x13013c +#define IGU_REG_PCI_PF_MSI_EN 0x130140 +#define IGU_REG_PCI_PF_MSIX_EN 0x130144 +#define IGU_REG_PCI_PF_MSIX_FUNC_MASK 0x130148 +/* [WB_R 32] Each bit represent the pending bits status for that SB. 0 = no + * pending; 1 = pending. Pendings means interrupt was asserted; and write + * done was not received. Data valid only in addresses 0-4. all the rest are + * zero. */ +#define IGU_REG_PENDING_BITS_STATUS 0x130300 +#define IGU_REG_PF_CONFIGURATION 0x130154 +/* [RW 20] producers only. E2 mode: address 0-135 match to the mapping + * memory; 136 - PF0 default prod; 137 PF1 default prod; 138 - PF2 default + * prod; 139 PF3 default prod; 140 - PF0 - ATTN prod; 141 - PF1 - ATTN prod; + * 142 - PF2 - ATTN prod; 143 - PF3 - ATTN prod; 144-147 reserved. E1.5 mode + * - In backward compatible mode; for non default SB; each even line in the + * memory holds the U producer and each odd line hold the C producer. The + * first 128 producer are for NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The + * last 20 producers are for the DSB for each PF. each PF has five segments + * (the order inside each segment is PF0; PF1; PF2; PF3) - 128-131 U prods; + * 132-135 C prods; 136-139 X prods; 140-143 T prods; 144-147 ATTN prods; */ +#define IGU_REG_PROD_CONS_MEMORY 0x132000 +/* [R 3] Debug: pxp_arb_fsm */ +#define IGU_REG_PXP_ARB_FSM 0x130068 +/* [RW 6] Write one for each bit will reset the appropriate memory. When the + * memory reset finished the appropriate bit will be clear. Bit 0 - mapping + * memory; Bit 1 - SB memory; Bit 2 - SB interrupt and mask register; Bit 3 + * - MSIX memory; Bit 4 - PBA memory; Bit 5 - statistics; */ +#define IGU_REG_RESET_MEMORIES 0x130158 +/* [R 4] Debug: sb_ctrl_fsm */ +#define IGU_REG_SB_CTRL_FSM 0x13004c +#define IGU_REG_SB_INT_BEFORE_MASK_LSB 0x13015c +#define IGU_REG_SB_INT_BEFORE_MASK_MSB 0x130160 +#define IGU_REG_SB_MASK_LSB 0x130164 +#define IGU_REG_SB_MASK_MSB 0x130168 +/* [RW 16] Number of command that were dropped without causing an interrupt + * due to: read access for WO BAR address; or write access for RO BAR + * address or any access for reserved address or PCI function error is set + * and address is not MSIX; PBA or cleanup */ +#define IGU_REG_SILENT_DROP 0x13016c +/* [RW 10] Number of MSI/MSIX/ATTN messages sent for the function: 0-63 - + * number of MSIX messages per VF; 64-67 - number of MSI/MSIX messages per + * PF; 68-71 number of ATTN messages per PF */ +#define IGU_REG_STATISTIC_NUM_MESSAGE_SENT 0x130800 +/* [RW 32] Number of cycles the timer mask masking the IGU interrupt when a + * timer mask command arrives. Value must be bigger than 100. */ +#define IGU_REG_TIMER_MASKING_VALUE 0x13003c +#define IGU_REG_TRAILING_EDGE_LATCH 0x130104 +#define IGU_REG_VF_CONFIGURATION 0x130170 +/* [WB_R 32] Each bit represent write done pending bits status for that SB + * (MSI/MSIX message was sent and write done was not received yet). 0 = + * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */ +#define IGU_REG_WRITE_DONE_PENDING 0x130480 +#define MCP_A_REG_MCPR_SCRATCH 0x3a0000 #define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 #define MCP_REG_MCPR_NVM_ADDR 0x8640c #define MCP_REG_MCPR_NVM_CFG4 0x8642c @@ -880,6 +1024,11 @@ rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched scpad_parity; */ #define MISC_REG_AEU_AFTER_INVERT_4_MCP 0xa458 +/* [R 32] Read fifth 32 bit after inversion of function 0. Mapped as + * follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC + * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6] + * CNIG attention (reserved); [7] CNIG parity (reserved); [31-8] Reserved; */ +#define MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 0xa700 /* [W 14] write to this register results with the clear of the latched signals; one in d0 clears RBCR latch; one in d1 clears RBCT latch; one in d2 clears RBCN latch; one in d3 clears RBCU latch; one in d4 clears RBCP @@ -1251,6 +1400,7 @@ #define MISC_REG_E1HMF_MODE 0xa5f8 /* [RW 32] Debug only: spare RW register reset by core reset */ #define MISC_REG_GENERIC_CR_0 0xa460 +#define MISC_REG_GENERIC_CR_1 0xa464 /* [RW 32] Debug only: spare RW register reset by por reset */ #define MISC_REG_GENERIC_POR_1 0xa474 /* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of @@ -1373,6 +1523,14 @@ #define MISC_REG_PLL_STORM_CTRL_2 0xa298 #define MISC_REG_PLL_STORM_CTRL_3 0xa29c #define MISC_REG_PLL_STORM_CTRL_4 0xa2a0 +/* [R 1] Status of 4 port mode enable input pin. */ +#define MISC_REG_PORT4MODE_EN 0xa750 +/* [RW 2] 4 port mode enable overwrite.[0] - Overwrite control; if it is 0 - + * the port4mode_en output is equal to 4 port mode input pin; if it is 1 - + * the port4mode_en output is equal to bit[1] of this register; [1] - + * Overwrite value. If bit[0] of this register is 1 this is the value that + * receives the port4mode_en output . */ +#define MISC_REG_PORT4MODE_EN_OVWR 0xa720 /* [RW 32] reset reg#2; rite/read one = the specific block is out of reset; write/read zero = the specific block is in reset; addr 0-wr- the write value will be written to the register; addr 1-set - one will be written @@ -1656,8 +1814,91 @@ /* [R 32] Interrupt register #0 read */ #define NIG_REG_NIG_INT_STS_0 0x103b0 #define NIG_REG_NIG_INT_STS_1 0x103c0 -/* [R 32] Parity register #0 read */ +/* [R 32] Legacy E1 and E1H location for parity error status register. */ #define NIG_REG_NIG_PRTY_STS 0x103d0 +/* [R 32] Parity register #0 read */ +#define NIG_REG_NIG_PRTY_STS_0 0x183bc +#define NIG_REG_NIG_PRTY_STS_1 0x183cc +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038 +/* [RW 1] HW PFC enable bit. Set this bit to enable the PFC functionality in + * the NIG. Other flow control modes such as PAUSE and SAFC/LLFC should be + * disabled when this bit is set. */ +#define NIG_REG_P0_HWPFC_ENABLE 0x18078 +#define NIG_REG_P0_LLH_FUNC_MEM2 0x18480 +#define NIG_REG_P0_LLH_FUNC_MEM2_ENABLE 0x18440 +/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for + * future expansion) each priorty is to be mapped to. Bits 3:0 specify the + * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit + * priority field is extracted from the outer-most VLAN in receive packet. + * Only COS 0 and COS 1 are supported in E2. */ +#define NIG_REG_P0_PKT_PRIORITY_TO_COS 0x18054 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A + * priority is mapped to COS 0 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS0_PRIORITY_MASK 0x18058 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A + * priority is mapped to COS 1 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS1_PRIORITY_MASK 0x1805c +/* [RW 15] Specify which of the credit registers the client is to be mapped + * to. Bits[2:0] are for client 0; bits [14:12] are for client 4. For + * clients that are not subject to WFQ credit blocking - their + * specifications here are not used. */ +#define NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP 0x180f0 +/* [RW 5] Specify whether the client competes directly in the strict + * priority arbiter. The bits are mapped according to client ID (client IDs + * are defined in tx_arb_priority_client). Default value is set to enable + * strict priorities for clients 0-2 -- management and debug traffic. */ +#define NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT 0x180e8 +/* [RW 5] Specify whether the client is subject to WFQ credit blocking. The + * bits are mapped according to client ID (client IDs are defined in + * tx_arb_priority_client). Default value is 0 for not using WFQ credit + * blocking. */ +#define NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ 0x180ec +/* [RW 32] Specify the upper bound that credit register 0 is allowed to + * reach. */ +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0 0x1810c +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1 0x18110 +/* [RW 32] Specify the weight (in bytes) to be added to credit register 0 + * when it is time to increment. */ +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0 0x180f8 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1 0x180fc +/* [RW 12] Specify the number of strict priority arbitration slots between + * two round-robin arbitration slots to avoid starvation. A value of 0 means + * no strict priority cycles - the strict priority with anti-starvation + * arbiter becomes a round-robin arbiter. */ +#define NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS 0x180f4 +/* [RW 15] Specify the client number to be assigned to each priority of the + * strict priority arbiter. Priority 0 is the highest priority. Bits [2:0] + * are for priority 0 client; bits [14:12] are for priority 4 client. The + * clients are assigned the following IDs: 0-management; 1-debug traffic + * from this port; 2-debug traffic from other port; 3-COS0 traffic; 4-COS1 + * traffic. The reset value[14:0] is set to 0x4688 (15'b100_011_010_001_000) + * for management at priority 0; debug traffic at priorities 1 and 2; COS0 + * traffic at priority 3; and COS1 traffic at priority 4. */ +#define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT 0x180e4 +#define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 +#define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460 +/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for + * future expansion) each priorty is to be mapped to. Bits 3:0 specify the + * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit + * priority field is extracted from the outer-most VLAN in receive packet. + * Only COS 0 and COS 1 are supported in E2. */ +#define NIG_REG_P1_PKT_PRIORITY_TO_COS 0x181a8 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A + * priority is mapped to COS 0 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P1_RX_COS0_PRIORITY_MASK 0x181ac +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A + * priority is mapped to COS 1 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P1_RX_COS1_PRIORITY_MASK 0x181b0 /* [RW 1] Pause enable for port0. This register may get 1 only when ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same port */ @@ -1742,6 +1983,10 @@ /* [RW 1] Disable processing further tasks from port 4 (after ending the current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c +#define PBF_REG_DISABLE_PF 0x1402e8 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 #define PBF_REG_IF_ENABLE_REG 0x140044 /* [RW 1] Init bit. When set the initial credits are copied to the credit registers (except the port credits). Should be set and then reset after @@ -1765,6 +2010,8 @@ #define PBF_REG_MAC_IF1_ENABLE 0x140034 /* [RW 1] Enable for the loopback interface. */ #define PBF_REG_MAC_LB_ENABLE 0x140040 +/* [RW 6] Bit-map indicating which headers must appear in the packet */ +#define PBF_REG_MUST_HAVE_HDRS 0x15c0c4 /* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause not suppoterd. */ #define PBF_REG_P0_ARB_THRSH 0x1400e4 @@ -1804,6 +2051,259 @@ #define PB_REG_PB_PRTY_MASK 0x38 /* [R 4] Parity register #0 read */ #define PB_REG_PB_PRTY_STS 0x2c +#define PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW (0x1<<8) +#define PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR (0x1<<1) +#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN (0x1<<6) +#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN (0x1<<7) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN (0x1<<4) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN (0x1<<3) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN (0x1<<5) +#define PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN (0x1<<2) +/* [R 8] Config space A attention dirty bits. Each bit indicates that the + * corresponding PF generates config space A attention. Set by PXP. Reset by + * MCP writing 1 to icfg_space_a_request_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_CFG_SPACE_A_REQUEST 0x9010 +/* [R 8] Config space B attention dirty bits. Each bit indicates that the + * corresponding PF generates config space B attention. Set by PXP. Reset by + * MCP writing 1 to icfg_space_b_request_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_CFG_SPACE_B_REQUEST 0x9014 +/* [RW 1] Type A PF enable inbound interrupt table for CSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_CSDM_INB_INT_A_PF_ENABLE 0x9194 +/* [RW 18] Type B VF inbound interrupt table for CSDM: bits[17:9]-mask; + * its[8:0]-address. Bits [1:0] must be zero (DW resolution address). */ +#define PGLUE_B_REG_CSDM_INB_INT_B_VF 0x916c +/* [RW 1] Type B VF enable inbound interrupt table for CSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_CSDM_INB_INT_B_VF_ENABLE 0x919c +/* [RW 16] Start offset of CSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_START_OFFSET_A 0x9100 +/* [RW 16] Start offset of CSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_START_OFFSET_B 0x9108 +/* [RW 5] VF Shift of CSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_VF_SHIFT_B 0x9110 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_CSDM_ZONE_A_SIZE_PF 0x91ac +/* [R 8] FLR request attention dirty bits for PFs 0 to 7. Each bit indicates + * that the FLR register of the corresponding PF was set. Set by PXP. Reset + * by MCP writing 1 to flr_request_pf_7_0_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_FLR_REQUEST_PF_7_0 0x9028 +/* [W 8] FLR request attention dirty bits clear for PFs 0 to 7. MCP writes 1 + * to a bit in this register in order to clear the corresponding bit in + * flr_request_pf_7_0 register. Note: register contains bits from both + * paths. */ +#define PGLUE_B_REG_FLR_REQUEST_PF_7_0_CLR 0x9418 +/* [R 32] FLR request attention dirty bits for VFs 96 to 127. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_127_96_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_127_96 0x9024 +/* [R 32] FLR request attention dirty bits for VFs 0 to 31. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_31_0_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_31_0 0x9018 +/* [R 32] FLR request attention dirty bits for VFs 32 to 63. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_63_32_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_63_32 0x901c +/* [R 32] FLR request attention dirty bits for VFs 64 to 95. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_95_64_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_95_64 0x9020 +/* [R 8] Each bit indicates an incorrect behavior in user RX interface. Bit + * 0 - Target memory read arrived with a correctable error. Bit 1 - Target + * memory read arrived with an uncorrectable error. Bit 2 - Configuration RW + * arrived with a correctable error. Bit 3 - Configuration RW arrived with + * an uncorrectable error. Bit 4 - Completion with Configuration Request + * Retry Status. Bit 5 - Expansion ROM access received with a write request. + * Bit 6 - Completion with pcie_rx_err of 0000; CMPL_STATUS of non-zero; and + * pcie_rx_last not asserted. Bit 7 - Completion with pcie_rx_err of 1010; + * and pcie_rx_last not asserted. */ +#define PGLUE_B_REG_INCORRECT_RCV_DETAILS 0x9068 +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER 0x942c +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ 0x9430 +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_WRITE 0x9434 +#define PGLUE_B_REG_INTERNAL_VFID_ENABLE 0x9438 +/* [R 9] Interrupt register #0 read */ +#define PGLUE_B_REG_PGLUE_B_INT_STS 0x9298 +/* [RC 9] Interrupt register #0 read clear */ +#define PGLUE_B_REG_PGLUE_B_INT_STS_CLR 0x929c +/* [R 2] Parity register #0 read */ +#define PGLUE_B_REG_PGLUE_B_PRTY_STS 0x92a8 +/* [R 13] Details of first request received with error. [2:0] - PFID. [3] - + * VF_VALID. [9:4] - VFID. [11:10] - Error Code - 0 - Indicates Completion + * Timeout of a User Tx non-posted request. 1 - unsupported request. 2 - + * completer abort. 3 - Illegal value for this field. [12] valid - indicates + * if there was a completion error since the last time this register was + * cleared. */ +#define PGLUE_B_REG_RX_ERR_DETAILS 0x9080 +/* [R 18] Details of first ATS Translation Completion request received with + * error. [2:0] - PFID. [3] - VF_VALID. [9:4] - VFID. [11:10] - Error Code - + * 0 - Indicates Completion Timeout of a User Tx non-posted request. 1 - + * unsupported request. 2 - completer abort. 3 - Illegal value for this + * field. [16:12] - ATC OTB EntryID. [17] valid - indicates if there was a + * completion error since the last time this register was cleared. */ +#define PGLUE_B_REG_RX_TCPL_ERR_DETAILS 0x9084 +/* [W 8] Debug only - Shadow BME bits clear for PFs 0 to 7. MCP writes 1 to + * a bit in this register in order to clear the corresponding bit in + * shadow_bme_pf_7_0 register. MCP should never use this unless a + * work-around is needed. Note: register contains bits from both paths. */ +#define PGLUE_B_REG_SHADOW_BME_PF_7_0_CLR 0x9458 +/* [R 8] SR IOV disabled attention dirty bits. Each bit indicates that the + * VF enable register of the corresponding PF is written to 0 and was + * previously 1. Set by PXP. Reset by MCP writing 1 to + * sr_iov_disabled_request_clr. Note: register contains bits from both + * paths. */ +#define PGLUE_B_REG_SR_IOV_DISABLED_REQUEST 0x9030 +/* [R 32] Indicates the status of tags 32-63. 0 - tags is used - read + * completion did not return yet. 1 - tag is unused. Same functionality as + * pxp2_registers_pgl_exp_rom_data2 for tags 0-31. */ +#define PGLUE_B_REG_TAGS_63_32 0x9244 +/* [RW 1] Type A PF enable inbound interrupt table for TSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_TSDM_INB_INT_A_PF_ENABLE 0x9170 +/* [RW 16] Start offset of TSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_START_OFFSET_A 0x90c4 +/* [RW 16] Start offset of TSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_START_OFFSET_B 0x90cc +/* [RW 5] VF Shift of TSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_VF_SHIFT_B 0x90d4 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_TSDM_ZONE_A_SIZE_PF 0x91a0 +/* [R 32] Address [31:0] of first read request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_RD_ADD_31_0 0x9098 +/* [R 32] Address [63:32] of first read request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_RD_ADD_63_32 0x909c +/* [R 31] Details of first read request not submitted due to error. [4:0] + * VQID. [5] TREQ. 1 - Indicates the request is a Translation Request. + * [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25] - + * VFID. */ +#define PGLUE_B_REG_TX_ERR_RD_DETAILS 0x90a0 +/* [R 26] Details of first read request not submitted due to error. [15:0] + * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type - + * [21] - Indicates was_error was set; [22] - Indicates BME was cleared; + * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent + * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid - + * indicates if there was a request not submitted due to error since the + * last time this register was cleared. */ +#define PGLUE_B_REG_TX_ERR_RD_DETAILS2 0x90a4 +/* [R 32] Address [31:0] of first write request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_WR_ADD_31_0 0x9088 +/* [R 32] Address [63:32] of first write request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_WR_ADD_63_32 0x908c +/* [R 31] Details of first write request not submitted due to error. [4:0] + * VQID. [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25] + * - VFID. */ +#define PGLUE_B_REG_TX_ERR_WR_DETAILS 0x9090 +/* [R 26] Details of first write request not submitted due to error. [15:0] + * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type - + * [21] - Indicates was_error was set; [22] - Indicates BME was cleared; + * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent + * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid - + * indicates if there was a request not submitted due to error since the + * last time this register was cleared. */ +#define PGLUE_B_REG_TX_ERR_WR_DETAILS2 0x9094 +/* [RW 10] Type A PF/VF inbound interrupt table for USDM: bits[9:5]-mask; + * its[4:0]-address relative to start_offset_a. Bits [1:0] can have any + * value (Byte resolution address). */ +#define PGLUE_B_REG_USDM_INB_INT_A_0 0x9128 +#define PGLUE_B_REG_USDM_INB_INT_A_1 0x912c +#define PGLUE_B_REG_USDM_INB_INT_A_2 0x9130 +#define PGLUE_B_REG_USDM_INB_INT_A_3 0x9134 +#define PGLUE_B_REG_USDM_INB_INT_A_4 0x9138 +#define PGLUE_B_REG_USDM_INB_INT_A_5 0x913c +#define PGLUE_B_REG_USDM_INB_INT_A_6 0x9140 +/* [RW 1] Type A PF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_A_PF_ENABLE 0x917c +/* [RW 1] Type A VF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_A_VF_ENABLE 0x9180 +/* [RW 1] Type B VF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_B_VF_ENABLE 0x9184 +/* [RW 16] Start offset of USDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_START_OFFSET_A 0x90d8 +/* [RW 16] Start offset of USDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_START_OFFSET_B 0x90e0 +/* [RW 5] VF Shift of USDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_VF_SHIFT_B 0x90e8 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_USDM_ZONE_A_SIZE_PF 0x91a4 +/* [R 26] Details of first target VF request accessing VF GRC space that + * failed permission check. [14:0] Address. [15] w_nr: 0 - Read; 1 - Write. + * [21:16] VFID. [24:22] - PFID. [25] valid - indicates if there was a + * request accessing VF GRC space that failed permission check since the + * last time this register was cleared. Permission checks are: function + * permission; R/W permission; address range permission. */ +#define PGLUE_B_REG_VF_GRC_SPACE_VIOLATION_DETAILS 0x9234 +/* [R 31] Details of first target VF request with length violation (too many + * DWs) accessing BAR0. [12:0] Address in DWs (bits [14:2] of byte address). + * [14:13] BAR. [20:15] VFID. [23:21] - PFID. [29:24] - Length in DWs. [30] + * valid - indicates if there was a request with length violation since the + * last time this register was cleared. Length violations: length of more + * than 2DWs; length of 2DWs and address not QW aligned; window is GRC and + * length is more than 1 DW. */ +#define PGLUE_B_REG_VF_LENGTH_VIOLATION_DETAILS 0x9230 +/* [R 8] Was_error indication dirty bits for PFs 0 to 7. Each bit indicates + * that there was a completion with uncorrectable error for the + * corresponding PF. Set by PXP. Reset by MCP writing 1 to + * was_error_pf_7_0_clr. */ +#define PGLUE_B_REG_WAS_ERROR_PF_7_0 0x907c +/* [W 8] Was_error indication dirty bits clear for PFs 0 to 7. MCP writes 1 + * to a bit in this register in order to clear the corresponding bit in + * flr_request_pf_7_0 register. */ +#define PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR 0x9470 +/* [R 32] Was_error indication dirty bits for VFs 96 to 127. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_127_96_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_127_96 0x9078 +/* [W 32] Was_error indication dirty bits clear for VFs 96 to 127. MCP + * writes 1 to a bit in this register in order to clear the corresponding + * bit in was_error_vf_127_96 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_127_96_CLR 0x9474 +/* [R 32] Was_error indication dirty bits for VFs 0 to 31. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_31_0_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_31_0 0x906c +/* [W 32] Was_error indication dirty bits clear for VFs 0 to 31. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_31_0 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_31_0_CLR 0x9478 +/* [R 32] Was_error indication dirty bits for VFs 32 to 63. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_63_32_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_63_32 0x9070 +/* [W 32] Was_error indication dirty bits clear for VFs 32 to 63. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_63_32 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_63_32_CLR 0x947c +/* [R 32] Was_error indication dirty bits for VFs 64 to 95. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_95_64_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_95_64 0x9074 +/* [W 32] Was_error indication dirty bits clear for VFs 64 to 95. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_95_64 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_95_64_CLR 0x9480 +/* [RW 1] Type A PF enable inbound interrupt table for XSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_XSDM_INB_INT_A_PF_ENABLE 0x9188 +/* [RW 16] Start offset of XSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_START_OFFSET_A 0x90ec +/* [RW 16] Start offset of XSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_START_OFFSET_B 0x90f4 +/* [RW 5] VF Shift of XSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_VF_SHIFT_B 0x90fc +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_XSDM_ZONE_A_SIZE_PF 0x91a8 #define PRS_REG_A_PRSU_20 0x40134 /* [R 8] debug only: CFC load request current credit. Transaction based. */ #define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164 @@ -1866,9 +2366,13 @@ #define PRS_REG_FLUSH_REGIONS_TYPE_5 0x40018 #define PRS_REG_FLUSH_REGIONS_TYPE_6 0x4001c #define PRS_REG_FLUSH_REGIONS_TYPE_7 0x40020 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define PRS_REG_HDRS_AFTER_BASIC 0x40238 /* [RW 4] The increment value to send in the CFC load request message */ #define PRS_REG_INC_VALUE 0x40048 -/* [RW 1] If set indicates not to send messages to CFC on received packets */ +/* [RW 6] Bit-map indicating which headers must appear in the packet */ +#define PRS_REG_MUST_HAVE_HDRS 0x40254 #define PRS_REG_NIC_MODE 0x40138 /* [RW 8] The 8-bit event ID for cases where there is no match on the connection. Used in packet start message to TCM. */ @@ -1919,6 +2423,13 @@ #define PRS_REG_TCM_CURRENT_CREDIT 0x40160 /* [R 8] debug only: TSDM current credit. Transaction based. */ #define PRS_REG_TSDM_CURRENT_CREDIT 0x4015c +#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT (0x1<<19) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF (0x1<<20) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN (0x1<<22) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED (0x1<<23) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED (0x1<<24) +#define PXP2_PXP2_INT_STS_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7) +#define PXP2_PXP2_INT_STS_CLR_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7) /* [R 6] Debug only: Number of used entries in the data FIFO */ #define PXP2_REG_HST_DATA_FIFO_STATUS 0x12047c /* [R 7] Debug only: Number of used entries in the header FIFO */ @@ -2244,8 +2755,17 @@ /* [RW 1] When '1'; requests will enter input buffers but wont get out towards the glue */ #define PXP2_REG_RQ_DISABLE_INPUTS 0x120330 -/* [RW 1] 1 - SR will be aligned by 64B; 0 - SR will be aligned by 8B */ +/* [RW 4] Determines alignment of write SRs when a request is split into + * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B + * aligned. 4 - 512B aligned. */ #define PXP2_REG_RQ_DRAM_ALIGN 0x1205b0 +/* [RW 4] Determines alignment of read SRs when a request is split into + * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B + * aligned. 4 - 512B aligned. */ +#define PXP2_REG_RQ_DRAM_ALIGN_RD 0x12092c +/* [RW 1] when set the new alignment method (E2) will be applied; when reset + * the original alignment method (E1 E1H) will be applied */ +#define PXP2_REG_RQ_DRAM_ALIGN_SEL 0x120930 /* [RW 1] If 1 ILT failiue will not result in ELT access; An interrupt will be asserted */ #define PXP2_REG_RQ_ELT_DISABLE 0x12066c @@ -2436,7 +2956,8 @@ #define PXP_REG_PXP_INT_STS_1 0x103078 /* [RC 32] Interrupt register #0 read clear */ #define PXP_REG_PXP_INT_STS_CLR_0 0x10306c -/* [RW 26] Parity mask register #0 read/write */ +#define PXP_REG_PXP_INT_STS_CLR_1 0x10307c +/* [RW 27] Parity mask register #0 read/write */ #define PXP_REG_PXP_PRTY_MASK 0x103094 /* [R 26] Parity register #0 read */ #define PXP_REG_PXP_PRTY_STS 0x103088 @@ -2566,6 +3087,7 @@ #define QM_REG_PAUSESTATE7 0x16e698 /* [RW 2] The PCI attributes field used in the PCI request. */ #define QM_REG_PCIREQAT 0x168054 +#define QM_REG_PF_EN 0x16e70c /* [R 16] The byte credit of port 0 */ #define QM_REG_PORT0BYTECRD 0x168300 /* [R 16] The byte credit of port 1 */ @@ -3402,6 +3924,14 @@ /* [R 32] Parity register #0 read */ #define TSEM_REG_TSEM_PRTY_STS_0 0x180114 #define TSEM_REG_TSEM_PRTY_STS_1 0x180124 +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define TSEM_REG_VFPF_ERR_NUM 0x180380 +/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits + * [10:8] of the address should be the offset within the accessed LCID + * context; the bits [7:0] are the accessed LCID.Example: to write to REG10 + * LCID100. The RBC address should be 12'ha64. */ +#define UCM_REG_AG_CTX 0xe2000 /* [R 5] Used to read the XX protection CAM occupancy counter. */ #define UCM_REG_CAM_OCCUP 0xe0170 /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -3851,6 +4381,17 @@ /* [R 32] Parity register #0 read */ #define USEM_REG_USEM_PRTY_STS_0 0x300124 #define USEM_REG_USEM_PRTY_STS_1 0x300134 +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define USEM_REG_VFPF_ERR_NUM 0x300380 +#define VFC_MEMORIES_RST_REG_CAM_RST (0x1<<0) +#define VFC_MEMORIES_RST_REG_RAM_RST (0x1<<1) +#define VFC_REG_MEMORIES_RST 0x1943c +/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits + * [12:8] of the address should be the offset within the accessed LCID + * context; the bits [7:0] are the accessed LCID.Example: to write to REG10 + * LCID100. The RBC address should be 13'ha64. */ +#define XCM_REG_AG_CTX 0x28000 /* [RW 2] The queue index for registration on Aux1 counter flag. */ #define XCM_REG_AUX1_Q 0x20134 /* [RW 2] Per each decision rule the queue index to register to. */ @@ -4333,6 +4874,9 @@ #define XSEM_REG_TS_8_AS 0x280058 /* [RW 3] The arbitration scheme of time_slot 9 */ #define XSEM_REG_TS_9_AS 0x28005c +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define XSEM_REG_VFPF_ERR_NUM 0x280380 /* [RW 32] Interrupt mask register #0 read/write */ #define XSEM_REG_XSEM_INT_MASK_0 0x280110 #define XSEM_REG_XSEM_INT_MASK_1 0x280120 @@ -4371,6 +4915,23 @@ #define BIGMAC_REGISTER_TX_SOURCE_ADDR (0x08<<3) #define BIGMAC_REGISTER_TX_STAT_GTBYT (0x20<<3) #define BIGMAC_REGISTER_TX_STAT_GTPKT (0x0C<<3) +#define BIGMAC2_REGISTER_BMAC_CONTROL (0x00<<3) +#define BIGMAC2_REGISTER_BMAC_XGXS_CONTROL (0x01<<3) +#define BIGMAC2_REGISTER_CNT_MAX_SIZE (0x05<<3) +#define BIGMAC2_REGISTER_PFC_CONTROL (0x06<<3) +#define BIGMAC2_REGISTER_RX_CONTROL (0x3A<<3) +#define BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS (0x62<<3) +#define BIGMAC2_REGISTER_RX_MAX_SIZE (0x3C<<3) +#define BIGMAC2_REGISTER_RX_STAT_GR64 (0x40<<3) +#define BIGMAC2_REGISTER_RX_STAT_GRIPJ (0x5f<<3) +#define BIGMAC2_REGISTER_RX_STAT_GRPP (0x51<<3) +#define BIGMAC2_REGISTER_TX_CONTROL (0x1C<<3) +#define BIGMAC2_REGISTER_TX_MAX_SIZE (0x1E<<3) +#define BIGMAC2_REGISTER_TX_PAUSE_CONTROL (0x20<<3) +#define BIGMAC2_REGISTER_TX_SOURCE_ADDR (0x1D<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTBYT (0x39<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTPOK (0x22<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTPP (0x24<<3) #define EMAC_LED_1000MB_OVERRIDE (1L<<1) #define EMAC_LED_100MB_OVERRIDE (1L<<2) #define EMAC_LED_10MB_OVERRIDE (1L<<3) @@ -4478,6 +5039,8 @@ #define HW_LOCK_RESOURCE_SPIO 2 #define HW_LOCK_RESOURCE_UNDI 5 #define PRS_FLAG_OVERETH_IPV4 1 +#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) +#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) #define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31) #define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9) @@ -4504,6 +5067,8 @@ #define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (1<<20) #define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (1<<0) #define AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT (1<<31) +#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2) +#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3) #define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (1<<3) #define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (1<<2) #define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (1<<5) @@ -4796,6 +5361,253 @@ #define PCI_ID_VAL1 0x434 #define PCI_ID_VAL2 0x438 +#define PXPCS_TL_CONTROL_5 0x814 +#define PXPCS_TL_CONTROL_5_UNKNOWNTYPE_ERR_ATTN (1 << 29) /*WC*/ +#define PXPCS_TL_CONTROL_5_BOUNDARY4K_ERR_ATTN (1 << 28) /*WC*/ +#define PXPCS_TL_CONTROL_5_MRRS_ERR_ATTN (1 << 27) /*WC*/ +#define PXPCS_TL_CONTROL_5_MPS_ERR_ATTN (1 << 26) /*WC*/ +#define PXPCS_TL_CONTROL_5_TTX_BRIDGE_FORWARD_ERR (1 << 25) /*WC*/ +#define PXPCS_TL_CONTROL_5_TTX_TXINTF_OVERFLOW (1 << 24) /*WC*/ +#define PXPCS_TL_CONTROL_5_PHY_ERR_ATTN (1 << 23) /*RO*/ +#define PXPCS_TL_CONTROL_5_DL_ERR_ATTN (1 << 22) /*RO*/ +#define PXPCS_TL_CONTROL_5_TTX_ERR_NP_TAG_IN_USE (1 << 21) /*WC*/ +#define PXPCS_TL_CONTROL_5_TRX_ERR_UNEXP_RTAG (1 << 20) /*WC*/ +#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT1 (1 << 19) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 (1 << 18) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_ECRC1 (1 << 17) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP1 (1 << 16) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW1 (1 << 15) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL1 (1 << 14) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT1 (1 << 13) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT1 (1 << 12) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL1 (1 << 11) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP1 (1 << 10) /*WC*/ +#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT (1 << 9) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT (1 << 8) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_ECRC (1 << 7) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP (1 << 6) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW (1 << 5) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL (1 << 4) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT (1 << 3) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT (1 << 2) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL (1 << 1) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP (1 << 0) /*WC*/ + + +#define PXPCS_TL_FUNC345_STAT 0x854 +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT4 (1 << 29) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4\ + (1 << 28) /* Unsupported Request Error Status in function4, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC4\ + (1 << 27) /* ECRC Error TLP Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP4\ + (1 << 26) /* Malformed TLP Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW4\ + (1 << 25) /* Receiver Overflow Status Status in function 4, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL4\ + (1 << 24) /* Unexpected Completion Status Status in function 4, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT4\ + (1 << 23) /* Receive UR Statusin function 4. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT4\ + (1 << 22) /* Completer Timeout Status Status in function 4, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL4\ + (1 << 21) /* Flow Control Protocol Error Status Status in \ + function 4, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP4\ + (1 << 20) /* Poisoned Error Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT3 (1 << 19) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3\ + (1 << 18) /* Unsupported Request Error Status in function3, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC3\ + (1 << 17) /* ECRC Error TLP Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP3\ + (1 << 16) /* Malformed TLP Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW3\ + (1 << 15) /* Receiver Overflow Status Status in function 3, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL3\ + (1 << 14) /* Unexpected Completion Status Status in function 3, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT3\ + (1 << 13) /* Receive UR Statusin function 3. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT3\ + (1 << 12) /* Completer Timeout Status Status in function 3, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL3\ + (1 << 11) /* Flow Control Protocol Error Status Status in \ + function 3, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP3\ + (1 << 10) /* Poisoned Error Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT2 (1 << 9) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2\ + (1 << 8) /* Unsupported Request Error Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC2\ + (1 << 7) /* ECRC Error TLP Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP2\ + (1 << 6) /* Malformed TLP Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW2\ + (1 << 5) /* Receiver Overflow Status Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL2\ + (1 << 4) /* Unexpected Completion Status Status for Function 2, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT2\ + (1 << 3) /* Receive UR Statusfor Function 2. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT2\ + (1 << 2) /* Completer Timeout Status Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL2\ + (1 << 1) /* Flow Control Protocol Error Status Status for \ + Function 2, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP2\ + (1 << 0) /* Poisoned Error Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ + + +#define PXPCS_TL_FUNC678_STAT 0x85C +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT7 (1 << 29) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7\ + (1 << 28) /* Unsupported Request Error Status in function7, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC7\ + (1 << 27) /* ECRC Error TLP Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP7\ + (1 << 26) /* Malformed TLP Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW7\ + (1 << 25) /* Receiver Overflow Status Status in function 7, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL7\ + (1 << 24) /* Unexpected Completion Status Status in function 7, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT7\ + (1 << 23) /* Receive UR Statusin function 7. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT7\ + (1 << 22) /* Completer Timeout Status Status in function 7, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL7\ + (1 << 21) /* Flow Control Protocol Error Status Status in \ + function 7, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP7\ + (1 << 20) /* Poisoned Error Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT6 (1 << 19) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6\ + (1 << 18) /* Unsupported Request Error Status in function6, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC6\ + (1 << 17) /* ECRC Error TLP Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP6\ + (1 << 16) /* Malformed TLP Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW6\ + (1 << 15) /* Receiver Overflow Status Status in function 6, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL6\ + (1 << 14) /* Unexpected Completion Status Status in function 6, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT6\ + (1 << 13) /* Receive UR Statusin function 6. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT6\ + (1 << 12) /* Completer Timeout Status Status in function 6, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL6\ + (1 << 11) /* Flow Control Protocol Error Status Status in \ + function 6, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP6\ + (1 << 10) /* Poisoned Error Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT5 (1 << 9) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5\ + (1 << 8) /* Unsupported Request Error Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC5\ + (1 << 7) /* ECRC Error TLP Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP5\ + (1 << 6) /* Malformed TLP Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW5\ + (1 << 5) /* Receiver Overflow Status Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL5\ + (1 << 4) /* Unexpected Completion Status Status for Function 5, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT5\ + (1 << 3) /* Receive UR Statusfor Function 5. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT5\ + (1 << 2) /* Completer Timeout Status Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL5\ + (1 << 1) /* Flow Control Protocol Error Status Status for \ + Function 5, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP5\ + (1 << 0) /* Poisoned Error Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ + + +#define BAR_USTRORM_INTMEM 0x400000 +#define BAR_CSTRORM_INTMEM 0x410000 +#define BAR_XSTRORM_INTMEM 0x420000 +#define BAR_TSTRORM_INTMEM 0x430000 + +/* for accessing the IGU in case of status block ACK */ +#define BAR_IGU_INTMEM 0x440000 + +#define BAR_DOORBELL_OFFSET 0x800000 + +#define BAR_ME_REGISTER 0x450000 +#define ME_REG_PF_NUM_SHIFT 0 +#define ME_REG_PF_NUM\ + (7L<executer_idx) { int loader_idx = PMF_DMAE_C(bp); + u32 opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_GRC); + opcode = bnx2x_dmae_opcode_clr_src_reset(opcode); memset(dmae, 0, sizeof(struct dmae_command)); - - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : - DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = opcode; dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + @@ -257,19 +249,10 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) bp->executer_idx = 0; - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, false, 0); dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC); dmae->src_addr_lo = bp->port.port_stx >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); @@ -280,7 +263,7 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) dmae->comp_val = 1; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI); dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) + @@ -301,7 +284,6 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) { struct dmae_command *dmae; int port = BP_PORT(bp); - int vn = BP_E1HVN(bp); u32 opcode; int loader_idx = PMF_DMAE_C(bp); u32 mac_addr; @@ -316,16 +298,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) bp->executer_idx = 0; /* MCP */ - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_GRC); if (bp->port.port_stx) { @@ -356,16 +330,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) } /* MAC */ - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_GRC); if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { @@ -376,13 +342,21 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_TX_STAT_GTBYT */ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + + if (CHIP_IS_E1x(bp)) { + dmae->src_addr_lo = (mac_addr + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + } else { + dmae->src_addr_lo = (mac_addr + + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + dmae->len = (8 + BIGMAC2_REGISTER_TX_STAT_GTBYT - + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + } + dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); - dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - - BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_hi = 0; dmae->comp_val = 1; @@ -391,15 +365,31 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_RX_STAT_GRIPJ */ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + if (CHIP_IS_E1x(bp)) { + dmae->src_addr_lo = (mac_addr + + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + dmae->dst_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, mac_stats) + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + dmae->dst_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, mac_stats) + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); - dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + } else { + dmae->src_addr_lo = + (mac_addr + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + dmae->dst_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac2_stats, rx_stat_gr64_lo)); + dmae->dst_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac2_stats, rx_stat_gr64_lo)); + dmae->len = (8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ - + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + } + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_hi = 0; dmae->comp_val = 1; @@ -480,16 +470,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) dmae->comp_val = 1; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_PCI); dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; dmae->src_addr_hi = 0; @@ -519,16 +501,8 @@ static void bnx2x_func_stats_init(struct bnx2x *bp) bp->executer_idx = 0; memset(dmae, 0, sizeof(struct dmae_command)); - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); dmae->dst_addr_lo = bp->func_stx >> 2; @@ -568,7 +542,6 @@ static void bnx2x_stats_restart(struct bnx2x *bp) static void bnx2x_bmac_stats_update(struct bnx2x *bp) { - struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats); struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); struct bnx2x_eth_stats *estats = &bp->eth_stats; struct { @@ -576,35 +549,74 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) u32 hi; } diff; - UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); - UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); - UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); - UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); - UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); - UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); - UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); - UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); - UPDATE_STAT64(tx_stat_gt127, + if (CHIP_IS_E1x(bp)) { + struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats); + + /* the macros below will use "bmac1_stats" type */ + UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); + UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); + UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); + UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); + UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); + UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); + UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); + UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); + UPDATE_STAT64(tx_stat_gt127, tx_stat_etherstatspkts65octetsto127octets); - UPDATE_STAT64(tx_stat_gt255, + UPDATE_STAT64(tx_stat_gt255, tx_stat_etherstatspkts128octetsto255octets); - UPDATE_STAT64(tx_stat_gt511, + UPDATE_STAT64(tx_stat_gt511, tx_stat_etherstatspkts256octetsto511octets); - UPDATE_STAT64(tx_stat_gt1023, + UPDATE_STAT64(tx_stat_gt1023, tx_stat_etherstatspkts512octetsto1023octets); - UPDATE_STAT64(tx_stat_gt1518, + UPDATE_STAT64(tx_stat_gt1518, tx_stat_etherstatspkts1024octetsto1522octets); - UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); - UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); - UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); - UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); - UPDATE_STAT64(tx_stat_gterr, + UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gterr, tx_stat_dot3statsinternalmactransmiterrors); - UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + + } else { + struct bmac2_stats *new = bnx2x_sp(bp, mac_stats.bmac2_stats); + + /* the macros below will use "bmac2_stats" type */ + UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); + UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); + UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); + UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); + UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); + UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); + UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); + UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); + UPDATE_STAT64(tx_stat_gt127, + tx_stat_etherstatspkts65octetsto127octets); + UPDATE_STAT64(tx_stat_gt255, + tx_stat_etherstatspkts128octetsto255octets); + UPDATE_STAT64(tx_stat_gt511, + tx_stat_etherstatspkts256octetsto511octets); + UPDATE_STAT64(tx_stat_gt1023, + tx_stat_etherstatspkts512octetsto1023octets); + UPDATE_STAT64(tx_stat_gt1518, + tx_stat_etherstatspkts1024octetsto1522octets); + UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gterr, + tx_stat_dot3statsinternalmactransmiterrors); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + } estats->pause_frames_received_hi = pstats->mac_stx[1].rx_stat_bmac_xpf_hi; @@ -1121,24 +1133,17 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) bp->executer_idx = 0; - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, false, 0); if (bp->port.port_stx) { dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); if (bp->func_stx) - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + dmae->opcode = bnx2x_dmae_opcode_add_comp( + opcode, DMAE_COMP_GRC); else - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = bnx2x_dmae_opcode_add_comp( + opcode, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); dmae->dst_addr_lo = bp->port.port_stx >> 2; @@ -1162,7 +1167,8 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) if (bp->func_stx) { dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = + bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); dmae->dst_addr_lo = bp->func_stx >> 2; @@ -1255,16 +1261,8 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) bp->executer_idx = 0; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); dmae->dst_addr_lo = bp->port.port_stx >> 2; @@ -1282,8 +1280,6 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) static void bnx2x_func_stats_base_init(struct bnx2x *bp) { int vn, vn_max = IS_MF(bp) ? E1HVN_MAX : E1VN_MAX; - int port = BP_PORT(bp); - int func; u32 func_stx; /* sanity */ @@ -1296,9 +1292,9 @@ static void bnx2x_func_stats_base_init(struct bnx2x *bp) func_stx = bp->func_stx; for (vn = VN_0; vn < vn_max; vn++) { - func = 2*vn + port; + int mb_idx = !CHIP_IS_E2(bp) ? 2*vn + BP_PORT(bp) : vn; - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param); bnx2x_func_stats_init(bp); bnx2x_hw_stats_post(bp); bnx2x_stats_comp(bp); @@ -1322,16 +1318,8 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp) bp->executer_idx = 0; memset(dmae, 0, sizeof(struct dmae_command)); - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_PCI); dmae->src_addr_lo = bp->func_stx >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); @@ -1349,7 +1337,7 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp) void bnx2x_stats_init(struct bnx2x *bp) { int port = BP_PORT(bp); - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); int i; bp->stats_pending = 0; @@ -1359,7 +1347,7 @@ void bnx2x_stats_init(struct bnx2x *bp) /* port and func stats for management */ if (!BP_NOMCP(bp)) { bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param); } else { bp->port.port_stx = 0; diff --git a/firmware/Makefile b/firmware/Makefile index e0a3439ab312..494a167c6552 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -33,7 +33,8 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \ - bnx2x/bnx2x-e1h-6.0.34.0.fw + bnx2x/bnx2x-e1h-6.0.34.0.fw \ + bnx2x/bnx2x-e2-6.0.34.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \ bnx2/bnx2-rv2p-09-5.0.0.j10.fw \ bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \ -- cgit v1.2.3 From 749a85033ec7c5c0fa54a0023fd5d59eb5e57a20 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:29:05 +0000 Subject: bnx2x: remove unused parameter in reuse_rx_skb() Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 4 ++-- drivers/net/bnx2x/bnx2x_cmn.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index cffa778ec5bf..5b8c0b6369ff 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -595,7 +595,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb_reserve(new_skb, pad); skb_put(new_skb, len); - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); skb = new_skb; @@ -614,7 +614,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) "of alloc failure\n"); fp->eth_q_stats.rx_skb_alloc_failed++; reuse_rx: - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); goto next_rx; } diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 41d0a177db7f..73ed5a63761f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -696,7 +696,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, * so there is no need to check for dma_mapping_error(). */ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, - struct sk_buff *skb, u16 cons, u16 prod) + u16 cons, u16 prod) { struct bnx2x *bp = fp->bp; struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; -- cgit v1.2.3 From 4bca60f44b4adca3197f61294956edda5bf9acea Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:30:27 +0000 Subject: bnx2x: use proper constants for dma_unmap* calls Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 5b8c0b6369ff..7ee9af020ed6 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -54,7 +54,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd; dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), - BD_UNMAP_LEN(tx_start_bd), PCI_DMA_TODEVICE); + BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE); nbd = le16_to_cpu(tx_start_bd->nbd) - 1; #ifdef BNX2X_STOP_ON_ERROR diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 73ed5a63761f..f08a42ad6b47 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -597,7 +597,7 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, return; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping), - SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE); __free_pages(page, PAGES_PER_SGE_SHIFT); sw_buf->page = NULL; -- cgit v1.2.3 From 217de5aaed833982c420fc37d82272d84eaefe64 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:31:20 +0000 Subject: bnx2x: use L1_CACHE_BYTES instead of magic number Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 7ee9af020ed6..da46309a855c 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -358,7 +358,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, #endif prefetch(skb); - prefetch(((char *)(skb)) + 128); + prefetch(((char *)(skb)) + L1_CACHE_BYTES); #ifdef BNX2X_STOP_ON_ERROR if (pad + len > bp->rx_buf_size) { @@ -561,7 +561,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) dma_unmap_addr(rx_buf, mapping), pad + RX_COPY_THRESH, DMA_FROM_DEVICE); - prefetch(((char *)(skb)) + 128); + prefetch(((char *)(skb)) + L1_CACHE_BYTES); /* is this an error packet? */ if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { -- cgit v1.2.3 From d6214d7aaa9a82b206dac9e3b0665c49c522a271 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:32:10 +0000 Subject: bnx2x: move msix table initialization to probe() Decide which interrupt mode to use (MSI-X, MSI, INTa) only once in probe() and initialize appropriate structures. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 3 + drivers/net/bnx2x/bnx2x_cmn.c | 206 +++++++++++++++++++---------------------- drivers/net/bnx2x/bnx2x_cmn.h | 75 ++++++++++++++- drivers/net/bnx2x/bnx2x_main.c | 78 ++++++++++++---- 4 files changed, 228 insertions(+), 134 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 9b78a0487791..d80809f5ffc9 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -308,6 +308,7 @@ union host_hc_status_block { struct bnx2x_fastpath { +#define BNX2X_NAPI_WEIGHT 128 struct napi_struct napi; union host_hc_status_block status_blk; /* chip independed shortcuts into sb structure */ @@ -920,8 +921,10 @@ struct bnx2x { #define USING_DAC_FLAG 0x10 #define USING_MSIX_FLAG 0x20 #define USING_MSI_FLAG 0x40 + #define TPA_ENABLE_FLAG 0x80 #define NO_MCP_FLAG 0x100 +#define DISABLE_MSI_FLAG 0x200 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) #define HW_VLAN_TX_FLAG 0x400 #define HW_VLAN_RX_FLAG 0x800 diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index da46309a855c..2998969beacc 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -29,7 +29,6 @@ #include "bnx2x_init.h" -static int bnx2x_poll(struct napi_struct *napi, int budget); /* free skb in the packet ring at pos idx * return idx of last bd freed @@ -989,55 +988,49 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) } } -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only) +void bnx2x_free_irq(struct bnx2x *bp) { - if (bp->flags & USING_MSIX_FLAG) { - if (!disable_only) - bnx2x_free_msix_irqs(bp); - pci_disable_msix(bp->pdev); - bp->flags &= ~USING_MSIX_FLAG; - - } else if (bp->flags & USING_MSI_FLAG) { - if (!disable_only) - free_irq(bp->pdev->irq, bp->dev); - pci_disable_msi(bp->pdev); - bp->flags &= ~USING_MSI_FLAG; - - } else if (!disable_only) + if (bp->flags & USING_MSIX_FLAG) + bnx2x_free_msix_irqs(bp); + else if (bp->flags & USING_MSI_FLAG) + free_irq(bp->pdev->irq, bp->dev); + else free_irq(bp->pdev->irq, bp->dev); } -static int bnx2x_enable_msix(struct bnx2x *bp) +int bnx2x_enable_msix(struct bnx2x *bp) { - int i, rc, offset = 1; - int igu_vec = 0; + int msix_vec = 0, i, rc, req_cnt; - bp->msix_table[0].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec); + bp->msix_table[msix_vec].entry = msix_vec; + DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", + bp->msix_table[0].entry); + msix_vec++; #ifdef BCM_CNIC - igu_vec = BP_L_ID(bp) + offset; - bp->msix_table[1].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[1].entry = %d (CNIC)\n", igu_vec); - offset++; + bp->msix_table[msix_vec].entry = msix_vec; + DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d (CNIC)\n", + bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry); + msix_vec++; #endif for_each_queue(bp, i) { - igu_vec = BP_L_ID(bp) + offset + i; - bp->msix_table[i + offset].entry = igu_vec; + bp->msix_table[msix_vec].entry = msix_vec; DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " - "(fastpath #%u)\n", i + offset, igu_vec, i); + "(fastpath #%u)\n", msix_vec, msix_vec, i); + msix_vec++; } - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], - BNX2X_NUM_QUEUES(bp) + offset); + req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1; + + rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); /* * reconfigure number of tx/rx queues according to available * MSI-X vectors */ if (rc >= BNX2X_MIN_MSIX_VEC_CNT) { - /* vectors available for FP */ - int fp_vec = rc - BNX2X_MSIX_VEC_FP_START; + /* how less vectors we will have? */ + int diff = req_cnt - rc; DP(NETIF_MSG_IFUP, "Trying to use less MSI-X vectors: %d\n", rc); @@ -1049,12 +1042,17 @@ static int bnx2x_enable_msix(struct bnx2x *bp) "MSI-X is not attainable rc %d\n", rc); return rc; } - - bp->num_queues = min(bp->num_queues, fp_vec); + /* + * decrease number of queues by number of unallocated entries + */ + bp->num_queues -= diff; DP(NETIF_MSG_IFUP, "New queue configuration set: %d\n", bp->num_queues); } else if (rc) { + /* fall to INTx if not enough memory */ + if (rc == -ENOMEM) + bp->flags |= DISABLE_MSI_FLAG; DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc); return rc; } @@ -1083,7 +1081,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", bp->dev->name, i); - rc = request_irq(bp->msix_table[i + offset].vector, + rc = request_irq(bp->msix_table[offset].vector, bnx2x_msix_fp_int, 0, fp->name, fp); if (rc) { BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc); @@ -1091,10 +1089,12 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) return -EBUSY; } + offset++; fp->state = BNX2X_FP_STATE_IRQ; } i = BNX2X_NUM_QUEUES(bp); + offset = 1 + CNIC_CONTEXT_USE; netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" " ... fp[%d] %d\n", bp->msix_table[0].vector, @@ -1104,7 +1104,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) return 0; } -static int bnx2x_enable_msi(struct bnx2x *bp) +int bnx2x_enable_msi(struct bnx2x *bp) { int rc; @@ -1175,44 +1175,20 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) bnx2x_napi_disable(bp); netif_tx_disable(bp->dev); } -static int bnx2x_set_num_queues(struct bnx2x *bp) -{ - int rc = 0; - switch (bp->int_mode) { - case INT_MODE_MSI: - bnx2x_enable_msi(bp); - /* falling through... */ - case INT_MODE_INTx: +void bnx2x_set_num_queues(struct bnx2x *bp) +{ + switch (bp->multi_mode) { + case ETH_RSS_MODE_DISABLED: bp->num_queues = 1; - DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); + break; + case ETH_RSS_MODE_REGULAR: + bp->num_queues = bnx2x_calc_num_queues(bp); break; default: - /* Set number of queues according to bp->multi_mode value */ - bnx2x_set_num_queues_msix(bp); - - DP(NETIF_MSG_IFUP, "set number of queues to %d\n", - bp->num_queues); - - /* if we can't use MSI-X we only need one fp, - * so try to enable MSI-X with the requested number of fp's - * and fallback to MSI or legacy INTx with one fp - */ - rc = bnx2x_enable_msix(bp); - if (rc) { - /* failed to enable MSI-X */ - bp->num_queues = 1; - - /* Fall to INTx if failed to enable MSI-X due to lack of - * memory (in bnx2x_set_num_queues()) */ - if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) - bnx2x_enable_msi(bp); - } - + bp->num_queues = 1; break; } - netif_set_real_num_tx_queues(bp->dev, bp->num_queues); - return netif_set_real_num_rx_queues(bp->dev, bp->num_queues); } static void bnx2x_release_firmware(struct bnx2x *bp) @@ -1243,49 +1219,25 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; - rc = bnx2x_set_num_queues(bp); - if (rc) - return rc; - /* must be called before memory allocation and HW init */ bnx2x_ilt_set_info(bp); - if (bnx2x_alloc_mem(bp)) { - bnx2x_free_irq(bp, true); + if (bnx2x_alloc_mem(bp)) return -ENOMEM; + + netif_set_real_num_tx_queues(bp->dev, bp->num_queues); + rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues); + if (rc) { + BNX2X_ERR("Unable to update real_num_rx_queues\n"); + goto load_error0; } for_each_queue(bp, i) bnx2x_fp(bp, i, disable_tpa) = ((bp->flags & TPA_ENABLE_FLAG) == 0); - for_each_queue(bp, i) - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, 128); - bnx2x_napi_enable(bp); - if (bp->flags & USING_MSIX_FLAG) { - rc = bnx2x_req_msix_irqs(bp); - if (rc) { - bnx2x_free_irq(bp, true); - goto load_error1; - } - } else { - bnx2x_ack_int(bp); - rc = bnx2x_req_irq(bp); - if (rc) { - BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); - bnx2x_free_irq(bp, true); - goto load_error1; - } - if (bp->flags & USING_MSI_FLAG) { - bp->dev->irq = bp->pdev->irq; - netdev_info(bp->dev, "using MSI IRQ %d\n", - bp->pdev->irq); - } - } - /* Send LOAD_REQUEST command to MCP Returns the type of LOAD command: if it is the first port to be initialized @@ -1296,11 +1248,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; - goto load_error2; + goto load_error1; } if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { rc = -EBUSY; /* other port in diagnostic mode */ - goto load_error2; + goto load_error1; } } else { @@ -1341,6 +1293,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) goto load_error2; } + /* Connect to IRQs */ + rc = bnx2x_setup_irqs(bp); if (rc) { bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); goto load_error2; @@ -1481,22 +1435,24 @@ load_error4: #endif load_error3: bnx2x_int_disable_sync(bp, 1); - if (!BP_NOMCP(bp)) { - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); - } - bp->port.pmf = 0; + /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); -load_error2: + /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); +load_error2: + if (!BP_NOMCP(bp)) { + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); + } + + bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); +load_error0: bnx2x_free_mem(bp); bnx2x_release_firmware(bp); @@ -1544,7 +1500,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_netif_stop(bp, 1); /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); } bp->port.pmf = 0; @@ -1553,8 +1509,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; @@ -1624,7 +1579,7 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) * net_device service functions */ -static int bnx2x_poll(struct napi_struct *napi, int budget) +int bnx2x_poll(struct napi_struct *napi, int budget) { int work_done = 0; struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath, @@ -2261,6 +2216,31 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) return 0; } + +int bnx2x_setup_irqs(struct bnx2x *bp) +{ + int rc = 0; + if (bp->flags & USING_MSIX_FLAG) { + rc = bnx2x_req_msix_irqs(bp); + if (rc) + return rc; + } else { + bnx2x_ack_int(bp); + rc = bnx2x_req_irq(bp); + if (rc) { + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); + return rc; + } + if (bp->flags & USING_MSI_FLAG) { + bp->dev->irq = bp->pdev->irq; + netdev_info(bp->dev, "using MSI IRQ %d\n", + bp->pdev->irq); + } + } + + return 0; +} + void bnx2x_free_mem_bp(struct bnx2x *bp) { kfree(bp->fp); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index f08a42ad6b47..1d9686ea6b66 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -23,6 +23,7 @@ #include "bnx2x.h" +extern int num_queues; /*********************** Interfaces **************************** * Functions that need to be implemented by each driver version @@ -193,12 +194,12 @@ int bnx2x_stop_fw_client(struct bnx2x *bp, struct bnx2x_client_ramrod_params *p); /** - * Set number of quueus according to mode + * Set number of queues according to mode * * @param bp * */ -void bnx2x_set_num_queues_msix(struct bnx2x *bp); +void bnx2x_set_num_queues(struct bnx2x *bp); /** * Cleanup chip internals: @@ -325,6 +326,42 @@ int bnx2x_func_stop(struct bnx2x *bp); */ void bnx2x_ilt_set_info(struct bnx2x *bp); +/** + * Fill msix_table, request vectors, update num_queues according + * to number of available vectors + * + * @param bp + * + * @return int + */ +int bnx2x_enable_msix(struct bnx2x *bp); + +/** + * Request msi mode from OS, updated internals accordingly + * + * @param bp + * + * @return int + */ +int bnx2x_enable_msi(struct bnx2x *bp); + +/** + * Request IRQ vectors from OS. + * + * @param bp + * + * @return int + */ +int bnx2x_setup_irqs(struct bnx2x *bp); +/** + * NAPI callback + * + * @param napi + * @param budget + * + * @return int + */ +int bnx2x_poll(struct napi_struct *napi, int budget); static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { barrier(); /* status block is written to by the chip */ @@ -605,9 +642,41 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, sge->addr_lo = 0; } +static inline void bnx2x_add_all_napi(struct bnx2x *bp) +{ + int i; + /* Add NAPI objects */ + for_each_queue(bp, i) + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), + bnx2x_poll, BNX2X_NAPI_WEIGHT); +} +static inline void bnx2x_del_all_napi(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) + netif_napi_del(&bnx2x_fp(bp, i, napi)); +} +static inline void bnx2x_disable_msi(struct bnx2x *bp) +{ + if (bp->flags & USING_MSIX_FLAG) { + pci_disable_msix(bp->pdev); + bp->flags &= ~USING_MSIX_FLAG; + } else if (bp->flags & USING_MSI_FLAG) { + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + } +} + +static inline int bnx2x_calc_num_queues(struct bnx2x *bp) +{ + return num_queues ? + min_t(int, num_queues, BNX2X_MAX_QUEUES(bp)) : + min_t(int, num_online_cpus(), BNX2X_MAX_QUEUES(bp)); +} static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) { @@ -877,7 +946,7 @@ void bnx2x_tx_timeout(struct net_device *dev); void bnx2x_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp); void bnx2x_netif_start(struct bnx2x *bp); void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only); +void bnx2x_free_irq(struct bnx2x *bp); int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); int bnx2x_resume(struct pci_dev *pdev); void bnx2x_free_skbs(struct bnx2x *bp); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 0ac416a14202..2572eb40c0ed 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -90,7 +90,7 @@ module_param(multi_mode, int, 0); MODULE_PARM_DESC(multi_mode, " Multi queue mode " "(0 Disable; 1 Enable (default))"); -static int num_queues; +int num_queues; module_param(num_queues, int, 0); MODULE_PARM_DESC(num_queues, " Number of queues for multi_mode=1" " (default is as a number of CPUs)"); @@ -6409,28 +6409,57 @@ int bnx2x_setup_fw_client(struct bnx2x *bp, return rc; } -void bnx2x_set_num_queues_msix(struct bnx2x *bp) +/** + * Configure interrupt mode according to current configuration. + * In case of MSI-X it will also try to enable MSI-X. + * + * @param bp + * + * @return int + */ +static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) { + int rc = 0; - switch (bp->multi_mode) { - case ETH_RSS_MODE_DISABLED: + switch (bp->int_mode) { + case INT_MODE_MSI: + bnx2x_enable_msi(bp); + /* falling through... */ + case INT_MODE_INTx: bp->num_queues = 1; + DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; + default: + /* Set number of queues according to bp->multi_mode value */ + bnx2x_set_num_queues(bp); - case ETH_RSS_MODE_REGULAR: - if (num_queues) - bp->num_queues = min_t(u32, num_queues, - BNX2X_MAX_QUEUES(bp)); - else - bp->num_queues = min_t(u32, num_online_cpus(), - BNX2X_MAX_QUEUES(bp)); - break; + DP(NETIF_MSG_IFUP, "set number of queues to %d\n", + bp->num_queues); + /* if we can't use MSI-X we only need one fp, + * so try to enable MSI-X with the requested number of fp's + * and fallback to MSI or legacy INTx with one fp + */ + rc = bnx2x_enable_msix(bp); + if (rc) { + /* failed to enable MSI-X */ + if (bp->multi_mode) + DP(NETIF_MSG_IFUP, + "Multi requested but failed to " + "enable MSI-X (%d), " + "set number of queues to %d\n", + bp->num_queues, + 1); + bp->num_queues = 1; + + if (!(bp->flags & DISABLE_MSI_FLAG)) + bnx2x_enable_msi(bp); + } - default: - bp->num_queues = 1; break; } + + return rc; } void bnx2x_ilt_set_info(struct bnx2x *bp) @@ -6881,7 +6910,7 @@ unload_error: bnx2x_netif_stop(bp, 1); /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); /* Reset the chip */ bnx2x_reset_chip(bp, reset_code); @@ -9024,7 +9053,16 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, goto init_one_exit; } + /* Configure interupt mode: try to enable MSI-X/MSI if + * needed, set bp->num_queues appropriately. + */ + bnx2x_set_int_mode(bp); + + /* Add all NAPI objects */ + bnx2x_add_all_napi(bp); + bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); + netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," " IRQ %d, ", board_info[ent->driver_data].name, (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4), @@ -9068,6 +9106,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) unregister_netdev(dev); + /* Delete all NAPI objects */ + bnx2x_del_all_napi(bp); + + /* Disable MSI/MSI-X */ + bnx2x_disable_msi(bp); /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->reset_task); @@ -9104,15 +9147,14 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; -- cgit v1.2.3 From c2bff63fad94eeecf59e4ba8e4cb51688ccae1ec Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:33:18 +0000 Subject: bnx2x, cnic: Fix SPQ return credit Return proper L2 and L5 SPQ (slow path queue) credits. Previously, all SPQ events were counted as L5 types. Signed-off-by: Dmitry Kravkov Signed-off-by: Michael Chan Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 13 ------- drivers/net/bnx2x/bnx2x_main.c | 86 +++++++++++++++++++++++++++++++++--------- drivers/net/cnic.c | 18 +++++---- drivers/net/cnic_if.h | 21 ++++++----- 4 files changed, 91 insertions(+), 47 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 2998969beacc..68181cdd2096 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1369,19 +1369,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_set_eth_mac(bp, 1); -#ifdef BCM_CNIC - /* Set iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_init_sb(bp, bp->cnic_sb_mapping, - BNX2X_VF_ID_INVALID, false, - CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); - } - mutex_unlock(&bp->cnic_mutex); -#endif - if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2572eb40c0ed..a686a4c15710 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -6462,6 +6462,12 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) return rc; } +/* must be called prioir to any HW initializations */ +static inline u16 bnx2x_cid_ilt_lines(struct bnx2x *bp) +{ + return L2_ILT_LINES(bp); +} + void bnx2x_ilt_set_info(struct bnx2x *bp) { struct ilt_client_info *ilt_client; @@ -9347,19 +9353,53 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) #endif spin_lock_bh(&bp->spq_lock); + BUG_ON(bp->cnic_spq_pending < count); bp->cnic_spq_pending -= count; - for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending; - bp->cnic_spq_pending++) { - if (!bp->cnic_kwq_pending) + for (; bp->cnic_kwq_pending; bp->cnic_kwq_pending--) { + u16 type = (le16_to_cpu(bp->cnic_kwq_cons->hdr.type) + & SPE_HDR_CONN_TYPE) >> + SPE_HDR_CONN_TYPE_SHIFT; + + /* Set validation for iSCSI L2 client before sending SETUP + * ramrod + */ + if (type == ETH_CONNECTION_TYPE) { + u8 cmd = (le32_to_cpu(bp->cnic_kwq_cons-> + hdr.conn_and_cmd_data) >> + SPE_HDR_CMD_ID_SHIFT) & 0xff; + + if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) + bnx2x_set_ctx_validation(&bp->context. + vcxt[BNX2X_ISCSI_ETH_CID].eth, + HW_CID(bp, BNX2X_ISCSI_ETH_CID)); + } + + /* There may be not more than 8 L2 and COMMON SPEs and not more + * than 8 L5 SPEs in the air. + */ + if ((type == NONE_CONNECTION_TYPE) || + (type == ETH_CONNECTION_TYPE)) { + if (!atomic_read(&bp->spq_left)) + break; + else + atomic_dec(&bp->spq_left); + } else if (type == ISCSI_CONNECTION_TYPE) { + if (bp->cnic_spq_pending >= + bp->cnic_eth_dev.max_kwqe_pending) + break; + else + bp->cnic_spq_pending++; + } else { + BNX2X_ERR("Unknown SPE type: %d\n", type); + bnx2x_panic(); break; + } spe = bnx2x_sp_get_next(bp); *spe = *bp->cnic_kwq_cons; - bp->cnic_kwq_pending--; - DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n", bp->cnic_spq_pending, bp->cnic_kwq_pending, count); @@ -9464,7 +9504,7 @@ static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid) ctl.data.comp.cid = cid; bnx2x_cnic_ctl_send_bh(bp, &ctl); - bnx2x_cnic_sp_post(bp, 1); + bnx2x_cnic_sp_post(bp, 0); } static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) @@ -9481,8 +9521,8 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) break; } - case DRV_CTL_COMPLETION_CMD: { - int count = ctl->data.comp.comp_count; + case DRV_CTL_RET_L5_SPQ_CREDIT_CMD: { + int count = ctl->data.credit.credit_count; bnx2x_cnic_sp_post(bp, count); break; @@ -9528,6 +9568,14 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) bnx2x_set_iscsi_eth_mac_addr(bp, 0); break; } + case DRV_CTL_RET_L2_SPQ_CREDIT_CMD: { + int count = ctl->data.credit.credit_count; + + smp_mb__before_atomic_inc(); + atomic_add(count, &bp->spq_left); + smp_mb__after_atomic_inc(); + break; + } default: BNX2X_ERR("unknown command %x\n", ctl->cmd); @@ -9592,13 +9640,8 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, cp->drv_state = CNIC_DRV_STATE_REGD; cp->iro_arr = bp->iro_arr; - bnx2x_init_sb(bp, bp->cnic_sb_mapping, - BNX2X_VF_ID_INVALID, false, - CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); - bnx2x_setup_cnic_irq_info(bp); - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; + rcu_assign_pointer(bp->cnic_ops, ops); return 0; @@ -9636,14 +9679,23 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->io_base2 = bp->doorbells; cp->max_kwqe_pending = 8; cp->ctx_blk_size = CDU_ILT_PAGE_SZ; - cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1; + cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + + bnx2x_cid_ilt_lines(bp); cp->ctx_tbl_len = CNIC_ILT_LINES; - cp->starting_cid = BCM_CNIC_CID_START; + cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS; cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue; cp->drv_ctl = bnx2x_drv_ctl; cp->drv_register_cnic = bnx2x_register_cnic; cp->drv_unregister_cnic = bnx2x_unregister_cnic; - + cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID; + cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; + + DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, " + "starting cid %d\n", + cp->ctx_blk_size, + cp->ctx_tbl_offset, + cp->ctx_tbl_len, + cp->starting_cid); return cp; } EXPORT_SYMBOL(bnx2x_cnic_probe); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 80259815af06..27449bf775e3 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -242,14 +242,14 @@ static int cnic_in_use(struct cnic_sock *csk) return test_bit(SK_F_INUSE, &csk->flags); } -static void cnic_kwq_completion(struct cnic_dev *dev, u32 count) +static void cnic_spq_completion(struct cnic_dev *dev, int cmd, u32 count) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; struct drv_ctl_info info; - info.cmd = DRV_CTL_COMPLETION_CMD; - info.data.comp.comp_count = count; + info.cmd = cmd; + info.data.credit.credit_count = count; ethdev->drv_ctl(dev->netdev, &info); } @@ -2069,7 +2069,7 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[], static void service_kcqes(struct cnic_dev *dev, int num_cqes) { struct cnic_local *cp = dev->cnic_priv; - int i, j; + int i, j, comp = 0; i = 0; j = 1; @@ -2080,7 +2080,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK; if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION)) - cnic_kwq_completion(dev, 1); + comp++; while (j < num_cqes) { u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag; @@ -2089,7 +2089,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) break; if (unlikely(next_op & KCQE_RAMROD_COMPLETION)) - cnic_kwq_completion(dev, 1); + comp++; j++; } @@ -2119,6 +2119,8 @@ end: i += j; j = 1; } + if (unlikely(comp)) + cnic_spq_completion(dev, DRV_CTL_RET_L5_SPQ_CREDIT_CMD, comp); } static u16 cnic_bnx2_next_idx(u16 idx) @@ -4246,7 +4248,7 @@ static void cnic_init_rings(struct cnic_dev *dev) if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) netdev_err(dev->netdev, "iSCSI CLIENT_SETUP did not complete\n"); - cnic_kwq_completion(dev, 1); + cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1); } } @@ -4283,7 +4285,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) netdev_err(dev->netdev, "iSCSI CLIENT_HALT did not complete\n"); - cnic_kwq_completion(dev, 1); + cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); memset(&l5_data, 0, sizeof(l5_data)); type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 4018de12f819..98ebac52013e 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.1.3" -#define CNIC_MODULE_RELDATE "June 24, 2010" +#define CNIC_MODULE_VERSION "2.2.5" +#define CNIC_MODULE_RELDATE "September 29, 2010" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -80,18 +80,15 @@ struct kcqe { #define DRV_CTL_IO_RD_CMD 0x102 #define DRV_CTL_CTX_WR_CMD 0x103 #define DRV_CTL_CTXTBL_WR_CMD 0x104 -#define DRV_CTL_COMPLETION_CMD 0x105 +#define DRV_CTL_RET_L5_SPQ_CREDIT_CMD 0x105 #define DRV_CTL_START_L2_CMD 0x106 #define DRV_CTL_STOP_L2_CMD 0x107 +#define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c struct cnic_ctl_completion { u32 cid; }; -struct drv_ctl_completion { - u32 comp_count; -}; - struct cnic_ctl_info { int cmd; union { @@ -100,6 +97,10 @@ struct cnic_ctl_info { } data; }; +struct drv_ctl_spq_credit { + u32 credit_count; +}; + struct drv_ctl_io { u32 cid_addr; u32 offset; @@ -115,7 +116,7 @@ struct drv_ctl_l2_ring { struct drv_ctl_info { int cmd; union { - struct drv_ctl_completion comp; + struct drv_ctl_spq_credit credit; struct drv_ctl_io io; struct drv_ctl_l2_ring ring; char bytes[MAX_DRV_CTL_DATA]; @@ -162,7 +163,9 @@ struct cnic_eth_dev { u32 max_iscsi_conn; u32 max_fcoe_conn; u32 max_rdma_conn; - u32 reserved0[2]; + u32 fcoe_init_cid; + u16 iscsi_l2_client_id; + u16 iscsi_l2_cid; int num_irq; struct cnic_irq irq_arr[MAX_CNIC_VEC]; -- cgit v1.2.3 From f85582f8c48addd8166727ef692d88b0ff618c5e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:34:21 +0000 Subject: bnx2x: code beautify This patch does not include any functional changes. The changes are: empty lines, indentation and comments. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 54 ++++---- drivers/net/bnx2x/bnx2x_cmn.c | 60 +++++---- drivers/net/bnx2x/bnx2x_cmn.h | 145 ++++++++++++++------ drivers/net/bnx2x/bnx2x_ethtool.c | 5 +- drivers/net/bnx2x/bnx2x_main.c | 275 +++++++++++++++++++------------------- drivers/net/bnx2x/bnx2x_stats.c | 4 +- drivers/net/bnx2x/bnx2x_stats.h | 8 +- 7 files changed, 318 insertions(+), 233 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index d80809f5ffc9..6fc77a4a5de6 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -180,13 +180,14 @@ void bnx2x_panic_dump(struct bnx2x *bp); #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) #define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ offsetof(struct mf_cfg, field)) -#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \ +#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \ offsetof(struct mf2_cfg, field)) #define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) #define MF_CFG_WR(bp, field, val) REG_WR(bp,\ MF_CFG_ADDR(bp, field), (val)) #define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field)) + #define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \ (SHMEM2_RD((bp), size) > \ offsetof(struct shmem2_region, field))) @@ -310,7 +311,7 @@ struct bnx2x_fastpath { #define BNX2X_NAPI_WEIGHT 128 struct napi_struct napi; - union host_hc_status_block status_blk; + union host_hc_status_block status_blk; /* chip independed shortcuts into sb structure */ __le16 *sb_index_values; __le16 *sb_running_index; @@ -349,8 +350,8 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_TERMINATING 0xd0000 #define BNX2X_FP_STATE_TERMINATED 0xe0000 - u8 index; /* number in fp array */ - u8 cl_id; /* eth client id */ + u8 index; /* number in fp array */ + u8 cl_id; /* eth client id */ u8 cl_qzone_id; u8 fw_sb_id; /* status block number in FW */ u8 igu_sb_id; /* status block number in HW */ @@ -375,8 +376,6 @@ struct bnx2x_fastpath { u16 last_max_sge; __le16 *rx_cons_sb; - - unsigned long tx_pkt, rx_pkt, rx_calls; @@ -977,7 +976,7 @@ struct bnx2x { u32 mf2_config[E2_FUNC_MAX]; u16 mf_ov; u8 mf_mode; -#define IS_MF(bp) (bp->mf_mode != 0) +#define IS_MF(bp) (bp->mf_mode != 0) u8 wol; @@ -1302,21 +1301,35 @@ struct bnx2x_func_init_params { for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) +#define WAIT_RAMROD_POLL 0x01 +#define WAIT_RAMROD_COMMON 0x02 +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); + +/* dmae */ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, u32 len32); +void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, + u32 addr, u32 len); +void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type); + int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); -void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, - u32 addr, u32 len); + void bnx2x_calc_fc_adv(struct bnx2x *bp); int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); void bnx2x_update_coalesce(struct bnx2x *bp); int bnx2x_get_link_cfg_idx(struct bnx2x *bp); + static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int wait) { @@ -1333,6 +1346,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, return val; } + #define BNX2X_ILT_ZALLOC(x, y, size) \ do { \ x = pci_alloc_consistent(bp->pdev, size, y); \ @@ -1353,6 +1367,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define ILT_NUM_PAGE_ENTRIES (3072) /* In 57710/11 we use whole table since we have 8 func + * In 57712 we have only 4 func, but use same size per func, then only half of + * the table in use */ #define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8) @@ -1366,14 +1382,13 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) #define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) - /* load/unload mode */ #define LOAD_NORMAL 0 #define LOAD_OPEN 1 #define LOAD_DIAG 2 #define UNLOAD_NORMAL 0 #define UNLOAD_CLOSE 1 -#define UNLOAD_RECOVERY 2 +#define UNLOAD_RECOVERY 2 /* DMAE command defines */ @@ -1447,7 +1462,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ E1HVN_MAX) - /* PCIE link and speed */ #define PCICFG_LINK_WIDTH 0x1f00000 #define PCICFG_LINK_WIDTH_SHIFT 20 @@ -1596,6 +1610,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_SP_DSB_INDEX \ (&bp->def_status_blk->sp_sb.\ index_values[HC_SP_INDEX_ETH_DEF_CONS]) + #define SET_FLAG(value, mask, flag) \ do {\ (value) &= ~(mask);\ @@ -1630,6 +1645,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #ifndef ETH_MAX_RX_CLIENTS_E2 #define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H #endif + #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 @@ -1649,20 +1665,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ -/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */ - extern void bnx2x_set_ethtool_ops(struct net_device *netdev); -void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); -u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type); -u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); -u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, - bool with_comp, u8 comp_type); - - -#define WAIT_RAMROD_POLL 0x01 -#define WAIT_RAMROD_COMMON 0x02 - -int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 68181cdd2096..97ef674dcc34 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -15,7 +15,6 @@ * */ - #include #include #include @@ -136,7 +135,6 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) */ smp_mb(); - /* TBD need a thresh? */ if (unlikely(netif_tx_queue_stopped(txq))) { /* Taking tx_lock() is needed to prevent reenabling the queue * while it's empty. This could have happen if rx_action() gets @@ -623,6 +621,7 @@ reuse_rx: bnx2x_set_skb_rxhash(bp, cqe, skb); skb_checksum_none_assert(skb); + if (bp->rx_csum) { if (likely(BNX2X_RX_CSUM_OK(cqe))) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -704,7 +703,6 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) return IRQ_HANDLED; } - /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp) { @@ -916,6 +914,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) } } } + static void bnx2x_free_tx_skbs(struct bnx2x *bp) { int i; @@ -1185,6 +1184,7 @@ void bnx2x_set_num_queues(struct bnx2x *bp) case ETH_RSS_MODE_REGULAR: bp->num_queues = bnx2x_calc_num_queues(bp); break; + default: bp->num_queues = 1; break; @@ -1354,6 +1354,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Enable Timer scan */ REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); #endif + for_each_nondefault_queue(bp, i) { rc = bnx2x_setup_client(bp, &bp->fp[i], 0); if (rc) @@ -1473,11 +1474,13 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Stop Tx */ bnx2x_tx_disable(bp); + del_timer_sync(&bp->timer); + SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb, (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); - bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_stats_handle(bp, STATS_EVENT_STOP); /* Cleanup the chip if needed */ if (unload_mode != UNLOAD_RECOVERY) @@ -1514,6 +1517,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) return 0; } + int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) { u16 pmcsr; @@ -1560,12 +1564,9 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) return 0; } - - /* * net_device service functions */ - int bnx2x_poll(struct napi_struct *napi, int budget) { int work_done = 0; @@ -1595,19 +1596,19 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* Fall out from the NAPI loop if needed */ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { bnx2x_update_fpsb_idx(fp); - /* bnx2x_has_rx_work() reads the status block, - * thus we need to ensure that status block indices - * have been actually read (bnx2x_update_fpsb_idx) - * prior to this check (bnx2x_has_rx_work) so that - * we won't write the "newer" value of the status block - * to IGU (if there was a DMA right after - * bnx2x_has_rx_work and if there is no rmb, the memory - * reading (bnx2x_update_fpsb_idx) may be postponed - * to right before bnx2x_ack_sb). In this case there - * will never be another interrupt until there is - * another update of the status block, while there - * is still unhandled work. - */ + /* bnx2x_has_rx_work() reads the status block, + * thus we need to ensure that status block indices + * have been actually read (bnx2x_update_fpsb_idx) + * prior to this check (bnx2x_has_rx_work) so that + * we won't write the "newer" value of the status block + * to IGU (if there was a DMA right after + * bnx2x_has_rx_work and if there is no rmb, the memory + * reading (bnx2x_update_fpsb_idx) may be postponed + * to right before bnx2x_ack_sb). In this case there + * will never be another interrupt until there is + * another update of the status block, while there + * is still unhandled work. + */ rmb(); if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { @@ -1626,7 +1627,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget) return work_done; } - /* we split the first BD into headers and data BDs * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs @@ -1842,6 +1842,7 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, pbd->global_data |= ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; } + /** * * @param skb @@ -1914,6 +1915,7 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, return hlen; } + /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue() @@ -2003,13 +2005,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - SET_FLAG(tx_start_bd->general_data, - ETH_TX_START_BD_ETH_ADDR_TYPE, - mac_type); + SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_ETH_ADDR_TYPE, + mac_type); + /* header nbd */ - SET_FLAG(tx_start_bd->general_data, - ETH_TX_START_BD_HDR_NBDS, - 1); + SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_HDR_NBDS, 1); /* remember the first BD of the packet */ tx_buf->first_bd = fp->tx_bd_prod; @@ -2065,9 +2065,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) } + /* Map skb linear data for DMA */ mapping = dma_map_single(&bp->pdev->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); + /* Setup the data pointer of the first BD of the packet */ tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */ @@ -2101,6 +2103,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) } tx_data_bd = (struct eth_tx_bd *)tx_start_bd; + /* Handle fragmented skb */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; @@ -2165,6 +2168,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) fp->tx_db.data.prod += nbd; barrier(); + DOORBELL(bp, fp->cid, fp->tx_db.raw); mmiowb(); @@ -2187,6 +2191,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } + /* called with rtnl_lock */ int bnx2x_change_mac_addr(struct net_device *dev, void *p) { @@ -2319,6 +2324,7 @@ void bnx2x_vlan_rx_register(struct net_device *dev, } #endif + int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 1d9686ea6b66..7f52cec9bb99 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -63,6 +63,15 @@ u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes); */ void bnx2x__link_status_update(struct bnx2x *bp); +/** + * Report link status to upper layer + * + * @param bp + * + * @return int + */ +void bnx2x_link_report(struct bnx2x *bp); + /** * MSI-X slowpath interrupt handler * @@ -234,7 +243,7 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); /** * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57711 + * netdev->dev_addr. * * @param bp driver handle * @param set @@ -270,10 +279,11 @@ void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, u8 vf_valid, int fw_sb_id, int igu_sb_id); /** - * Reconfigure FW/HW according to dev->flags rx mode + * Set MAC filtering configurations. * - * @param dev net_device + * @remarks called with netif_tx_lock from dev_mcast.c * + * @param dev net_device */ void bnx2x_set_rx_mode(struct net_device *dev); @@ -295,17 +305,17 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp); * Perform statistics handling according to event * * @param bp driver handle - * @param even tbnx2x_stats_event + * @param event bnx2x_stats_event */ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); /** - * Handle sp events + * Handle ramrods completion * * @param fp fastpath handle for the event * @param rr_cqe eth_rx_cqe */ -void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); +void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); /** * Init/halt function before/after sending @@ -326,6 +336,46 @@ int bnx2x_func_stop(struct bnx2x *bp); */ void bnx2x_ilt_set_info(struct bnx2x *bp); +/** + * Set power state to the requested value. Currently only D0 and + * D3hot are supported. + * + * @param bp + * @param state D0 or D3hot + * + * @return int + */ +int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); + +/* dev_close main block */ +int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); + +/* dev_open main block */ +int bnx2x_nic_load(struct bnx2x *bp, int load_mode); + +/* hard_xmit callback */ +netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); + +int bnx2x_change_mac_addr(struct net_device *dev, void *p); + +/* NAPI poll Rx part */ +int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); + +/* NAPI poll Tx part */ +int bnx2x_tx_int(struct bnx2x_fastpath *fp); + +/* suspend/resume callbacks */ +int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); +int bnx2x_resume(struct pci_dev *pdev); + +/* Release IRQ vectors */ +void bnx2x_free_irq(struct bnx2x *bp); + +void bnx2x_init_rx_rings(struct bnx2x *bp); +void bnx2x_free_skbs(struct bnx2x *bp); +void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); +void bnx2x_netif_start(struct bnx2x *bp); + /** * Fill msix_table, request vectors, update num_queues according * to number of available vectors @@ -362,6 +412,51 @@ int bnx2x_setup_irqs(struct bnx2x *bp); * @return int */ int bnx2x_poll(struct napi_struct *napi, int budget); + +/** + * Allocate/release memories outsize main driver structure + * + * @param bp + * + * @return int + */ +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp); +void bnx2x_free_mem_bp(struct bnx2x *bp); + +/** + * Change mtu netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +int bnx2x_change_mtu(struct net_device *dev, int new_mtu); + +/** + * tx timeout netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +void bnx2x_tx_timeout(struct net_device *dev); + +#ifdef BCM_VLAN +/** + * vlan rx register netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +void bnx2x_vlan_rx_register(struct net_device *dev, + struct vlan_group *vlgrp); + +#endif + static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { barrier(); /* status block is written to by the chip */ @@ -558,9 +653,6 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp) return bnx2x_igu_ack_int(bp); } -/* - * fast path service functions - */ static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) { /* Tell compiler that consumer and producer can change */ @@ -611,6 +703,7 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) rx_cons_sb++; return (fp->rx_comp_cons != rx_cons_sb); } + /** * disables tx from stack point of view * @@ -731,6 +824,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, return 0; } + static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { @@ -782,6 +876,7 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, dma_unmap_addr(cons_rx_buf, mapping)); *prod_bd = *cons_bd; } + static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, struct bnx2x_fastpath *fp, int last) { @@ -846,6 +941,7 @@ static inline void bnx2x_init_tx_rings(struct bnx2x *bp) fp->tx_pkt = 0; } } + static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) { int i; @@ -931,40 +1027,11 @@ static inline void storm_memset_cmng(struct bnx2x *bp, __storm_memset_struct(bp, addr, size, (u32 *)cmng); } + /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); -void bnx2x_link_report(struct bnx2x *bp); -int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); -int bnx2x_tx_int(struct bnx2x_fastpath *fp); -void bnx2x_init_rx_rings(struct bnx2x *bp); -netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); - -int bnx2x_change_mac_addr(struct net_device *dev, void *p); -void bnx2x_tx_timeout(struct net_device *dev); -void bnx2x_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp); -void bnx2x_netif_start(struct bnx2x *bp); -void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); -void bnx2x_free_irq(struct bnx2x *bp); -int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); -int bnx2x_resume(struct pci_dev *pdev); -void bnx2x_free_skbs(struct bnx2x *bp); -int bnx2x_change_mtu(struct net_device *dev, int new_mtu); -int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); -int bnx2x_nic_load(struct bnx2x *bp, int load_mode); -int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); - -/** - * Allocate/release memories outsize main driver structure - * - * @param bp - * - * @return int - */ -int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp); -void bnx2x_free_mem_bp(struct bnx2x *bp); - #define BNX2X_FW_IP_HDR_ALIGN_PAD 2 /* FW places hdr with this padding */ #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 8fb00276dc41..54fe0615a8b9 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -25,7 +25,6 @@ #include "bnx2x_cmn.h" #include "bnx2x_dump.h" - static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); @@ -963,6 +962,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, return rc; } + static int bnx2x_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) { @@ -1288,6 +1288,7 @@ static int bnx2x_test_registers(struct bnx2x *bp) save_val = REG_RD(bp, offset); REG_WR(bp, offset, (wr_val & mask)); + val = REG_RD(bp, offset); /* Restore the original register's value */ @@ -1471,6 +1472,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2; @@ -1714,6 +1716,7 @@ static void bnx2x_self_test(struct net_device *dev, buf[1] = 1; etest->flags |= ETH_TEST_FL_FAILED; } + buf[2] = bnx2x_test_loopback(bp, link_up); if (buf[2] != 0) etest->flags |= ETH_TEST_FL_FAILED; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index a686a4c15710..7a9556b5b55d 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -56,7 +56,6 @@ #include "bnx2x_init_ops.h" #include "bnx2x_cmn.h" - #include #include "bnx2x_fw_file_hdr.h" /* FW files */ @@ -1325,7 +1324,6 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) return false; } - #ifdef BCM_CNIC static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid); #endif @@ -1754,12 +1752,12 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp) MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: @@ -1768,12 +1766,11 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp) default: bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + ADVERTISED_Pause); break; } } - u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) { if (!BP_NOMCP(bp)) { @@ -1952,6 +1949,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * 100; } + DP(NETIF_MSG_IFUP, "func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n", func, vn_min_rate, vn_max_rate, bp->vn_weight_sum); @@ -1991,6 +1989,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4, ((u32 *)(&m_fair_vn))[i]); } + static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) { if (CHIP_REV_IS_SLOW(bp)) @@ -2625,13 +2624,13 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) wmb(); REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); + bp->spq_prod_idx); mmiowb(); } /* the slow path queue is odd since completions arrive on the fastpath ring */ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common) + u32 data_hi, u32 data_lo, int common) { struct eth_spe *spe; u16 type; @@ -3055,6 +3054,7 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) #define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK) #define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS #define CHIP_PARITY_SUPPORTED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) + /* * should be run under rtnl lock */ @@ -4376,7 +4376,6 @@ gunzip_nomem1: static void bnx2x_gunzip_end(struct bnx2x *bp) { kfree(bp->strm->workspace); - kfree(bp->strm); bp->strm = NULL; @@ -4641,6 +4640,7 @@ static void enable_blocks_attention(struct bnx2x *bp) REG_WR(bp, CCM_REG_CCM_INT_MASK, 0); /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */ /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */ + if (CHIP_REV_IS_FPGA(bp)) REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); else if (CHIP_IS_E2(bp)) @@ -4672,29 +4672,29 @@ static const struct { {PXP2_REG_PXP2_PRTY_MASK_1, 0x7f}, {HC_REG_HC_PRTY_MASK, 0x7}, {MISC_REG_MISC_PRTY_MASK, 0x1}, - {QM_REG_QM_PRTY_MASK, 0x0}, - {DORQ_REG_DORQ_PRTY_MASK, 0x0}, + {QM_REG_QM_PRTY_MASK, 0x0}, + {DORQ_REG_DORQ_PRTY_MASK, 0x0}, {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 0x0}, - {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ - {CDU_REG_CDU_PRTY_MASK, 0x0}, - {CFC_REG_CFC_PRTY_MASK, 0x0}, - {DBG_REG_DBG_PRTY_MASK, 0x0}, - {DMAE_REG_DMAE_PRTY_MASK, 0x0}, - {BRB1_REG_BRB1_PRTY_MASK, 0x0}, - {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ - {TSDM_REG_TSDM_PRTY_MASK, 0x18},/* bit 3,4 */ - {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {USDM_REG_USDM_PRTY_MASK, 0x38},/* bit 3,4,5 */ - {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, - {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, - {USEM_REG_USEM_PRTY_MASK_0, 0x0}, - {USEM_REG_USEM_PRTY_MASK_1, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} + {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ + {CDU_REG_CDU_PRTY_MASK, 0x0}, + {CFC_REG_CFC_PRTY_MASK, 0x0}, + {DBG_REG_DBG_PRTY_MASK, 0x0}, + {DMAE_REG_DMAE_PRTY_MASK, 0x0}, + {BRB1_REG_BRB1_PRTY_MASK, 0x0}, + {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ + {TSDM_REG_TSDM_PRTY_MASK, 0x18}, /* bit 3,4 */ + {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {USDM_REG_USDM_PRTY_MASK, 0x38}, /* bit 3,4,5 */ + {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, + {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, + {USEM_REG_USEM_PRTY_MASK_0, 0x0}, + {USEM_REG_USEM_PRTY_MASK_1, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} }; static void enable_blocks_parity(struct bnx2x *bp) @@ -4906,7 +4906,6 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_ilt_init_page_size(bp, INITOP_SET); - if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1); @@ -5003,6 +5002,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) if (CHIP_MODE_IS_4_PORT(bp)) bnx2x_init_block(bp, QM_4PORT_BLOCK, COMMON_STAGE); + /* QM queues pointers table */ bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); @@ -5036,6 +5036,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) #endif if (!CHIP_IS_E1(bp)) REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); + if (CHIP_IS_E2(bp)) { /* Bit-map indicating which L2 hdrs may appear after the basic Ethernet header */ @@ -5081,6 +5082,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) REG_WR(bp, i, random32()); + bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE); #ifdef BCM_CNIC REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); @@ -5467,6 +5469,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) set the size */ } bnx2x_ilt_init_op(bp, INITOP_SET); + #ifdef BCM_CNIC bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM); @@ -5692,6 +5695,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func); bnx2x_phy_probe(&bp->link_params); + return 0; } @@ -5826,6 +5830,7 @@ void bnx2x_free_mem(struct bnx2x *bp) bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); BNX2X_FREE(bp->ilt->lines); + #ifdef BCM_CNIC if (CHIP_IS_E2(bp)) BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, @@ -5833,8 +5838,10 @@ void bnx2x_free_mem(struct bnx2x *bp) else BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, sizeof(struct host_hc_status_block_e1x)); + BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); #endif + BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, @@ -5862,7 +5869,6 @@ static inline void set_sb_shortcuts(struct bnx2x *bp, int index) int bnx2x_alloc_mem(struct bnx2x *bp) { - #define BNX2X_PCI_ALLOC(x, y, size) \ do { \ x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ @@ -5951,6 +5957,7 @@ int bnx2x_alloc_mem(struct bnx2x *bp) sizeof(struct bnx2x_slowpath)); bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count; + BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, bp->context.size); @@ -5997,7 +6004,7 @@ int bnx2x_func_stop(struct bnx2x *bp) } /** - * Sets a MAC in a CAM for a few L2 Clients for E1x chip + * Sets a MAC in a CAM for a few L2 Clients for E1x chips * * @param bp driver descriptor * @param set set or clear an entry (1 or 0) @@ -6007,8 +6014,8 @@ int bnx2x_func_stop(struct bnx2x *bp) * @param is_bcast is the set MAC a broadcast address (for E1 only) */ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 is_bcast) + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast) { struct mac_configuration_cmd *config = (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); @@ -6060,9 +6067,8 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); } - int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags) + int *state_p, int flags) { /* can take a while if any port is running */ int cnt = 5000; @@ -6220,7 +6226,6 @@ static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp) } - #ifdef BCM_CNIC /** * Set iSCSI MAC(s) at the next enties in the CAM after the ETH @@ -6564,6 +6569,7 @@ void bnx2x_ilt_set_info(struct bnx2x *bp) ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); #endif } + int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, int is_leading) { @@ -6949,7 +6955,6 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp) } } - /* Close gates #2, #3 and #4: */ static void bnx2x_set_234_gates(struct bnx2x *bp, bool close) { @@ -6995,15 +7000,13 @@ static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val) static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val) { /* Restore the `magic' bit value... */ - /* u32 val = SHMEM_RD(bp, mf_cfg.shared_mf_config.clp_mb); - SHMEM_WR(bp, mf_cfg.shared_mf_config.clp_mb, - (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); */ u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb); MF_CFG_WR(bp, shared_mf_config.clp_mb, (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); } -/* Prepares for MCP reset: takes care of CLP configurations. +/** + * Prepares for MCP reset: takes care of CLP configurations. * * @param bp * @param magic_val Old value of 'magic' bit. @@ -7532,7 +7535,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bp->fw_seq = (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - } else bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); } @@ -7651,7 +7653,8 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) } bp->link_params.feature_config_flags |= (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + bp->link_params.feature_config_flags |= (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ? FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0; @@ -7768,7 +7771,7 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, SHMEM_RD(bp, dev_info.port_hw_config[port].external_phy_config2)); return; - } + } switch (switch_cfg) { case SWITCH_CFG_1G: @@ -7781,7 +7784,6 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + port*0x18); BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - break; default: @@ -7810,7 +7812,7 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); + SUPPORTED_1000baseT_Full); if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) @@ -7844,41 +7846,41 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) bp->link_params.req_duplex[idx] = DUPLEX_FULL; link_config = bp->port.link_config[idx]; switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { - case PORT_FEATURE_LINK_SPEED_AUTO: + case PORT_FEATURE_LINK_SPEED_AUTO: if (bp->port.supported[idx] & SUPPORTED_Autoneg) { bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG; bp->port.advertising[idx] |= bp->port.supported[idx]; - } else { - /* force 10G, no AN */ + } else { + /* force 10G, no AN */ bp->link_params.req_line_speed[idx] = SPEED_10000; bp->port.advertising[idx] |= (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); + ADVERTISED_FIBRE); continue; - } - break; + } + break; - case PORT_FEATURE_LINK_SPEED_10M_FULL: + case PORT_FEATURE_LINK_SPEED_10M_FULL: if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) { bp->link_params.req_line_speed[idx] = SPEED_10; bp->port.advertising[idx] |= (ADVERTISED_10baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - link_config, + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, bp->link_params.speed_cap_mask[idx]); - return; - } - break; + return; + } + break; - case PORT_FEATURE_LINK_SPEED_10M_HALF: + case PORT_FEATURE_LINK_SPEED_10M_HALF: if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) { bp->link_params.req_line_speed[idx] = SPEED_10; @@ -7886,70 +7888,74 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) DUPLEX_HALF; bp->port.advertising[idx] |= (ADVERTISED_10baseT_Half | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->port.supported[idx] & SUPPORTED_100baseT_Full) { + case PORT_FEATURE_LINK_SPEED_100M_FULL: + if (bp->port.supported[idx] & + SUPPORTED_100baseT_Full) { bp->link_params.req_line_speed[idx] = SPEED_100; bp->port.advertising[idx] |= (ADVERTISED_100baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->port.supported[idx] & SUPPORTED_100baseT_Half) { - bp->link_params.req_line_speed[idx] = SPEED_100; - bp->link_params.req_duplex[idx] = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_100M_HALF: + if (bp->port.supported[idx] & + SUPPORTED_100baseT_Half) { + bp->link_params.req_line_speed[idx] = + SPEED_100; + bp->link_params.req_duplex[idx] = + DUPLEX_HALF; bp->port.advertising[idx] |= (ADVERTISED_100baseT_Half | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, bp->link_params.speed_cap_mask[idx]); - return; - } - break; + return; + } + break; - case PORT_FEATURE_LINK_SPEED_1G: + case PORT_FEATURE_LINK_SPEED_1G: if (bp->port.supported[idx] & SUPPORTED_1000baseT_Full) { bp->link_params.req_line_speed[idx] = SPEED_1000; bp->port.advertising[idx] |= (ADVERTISED_1000baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, bp->link_params.speed_cap_mask[idx]); - return; - } - break; + return; + } + break; - case PORT_FEATURE_LINK_SPEED_2_5G: + case PORT_FEATURE_LINK_SPEED_2_5G: if (bp->port.supported[idx] & SUPPORTED_2500baseX_Full) { bp->link_params.req_line_speed[idx] = @@ -7957,19 +7963,19 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) bp->port.advertising[idx] |= (ADVERTISED_2500baseX_Full | ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_10G_CX4: - case PORT_FEATURE_LINK_SPEED_10G_KX4: - case PORT_FEATURE_LINK_SPEED_10G_KR: + case PORT_FEATURE_LINK_SPEED_10G_CX4: + case PORT_FEATURE_LINK_SPEED_10G_KX4: + case PORT_FEATURE_LINK_SPEED_10G_KR: if (bp->port.supported[idx] & SUPPORTED_10000baseT_Full) { bp->link_params.req_line_speed[idx] = @@ -7977,24 +7983,26 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) bp->port.advertising[idx] |= (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); - } else { - BNX2X_ERROR("NVRAM config error. " + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - default: - BNX2X_ERROR("NVRAM config error. " - "BAD link speed link_config 0x%x\n", - link_config); - bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG; - bp->port.advertising[idx] = bp->port.supported[idx]; - break; - } + default: + BNX2X_ERROR("NVRAM config error. " + "BAD link speed link_config 0x%x\n", + link_config); + bp->link_params.req_line_speed[idx] = + SPEED_AUTO_NEG; + bp->port.advertising[idx] = + bp->port.supported[idx]; + break; + } bp->link_params.req_flow_ctrl[idx] = (link_config & PORT_FEATURE_FLOW_CONTROL_MASK); @@ -8056,14 +8064,14 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->wol = (!(bp->flags & NO_WOL_FLAG) && (config & PORT_FEATURE_WOL_ENABLED)); - BNX2X_DEV_INFO("lane_config 0x%08x" + BNX2X_DEV_INFO("lane_config 0x%08x " "speed_cap_mask0 0x%08x link_config0 0x%08x\n", bp->link_params.lane_config, bp->link_params.speed_cap_mask[0], bp->port.link_config[0]); bp->link_params.switch_cfg = (bp->port.link_config[0] & - PORT_FEATURE_CONNECTED_SWITCH_MASK); + PORT_FEATURE_CONNECTED_SWITCH_MASK); bnx2x_phy_probe(&bp->link_params); bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); @@ -8458,12 +8466,10 @@ void bnx2x_set_rx_mode(struct net_device *dev) if (dev->flags & IFF_PROMISC) rx_mode = BNX2X_RX_MODE_PROMISC; - else if ((dev->flags & IFF_ALLMULTI) || ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) && CHIP_IS_E1(bp))) rx_mode = BNX2X_RX_MODE_ALLMULTI; - else { /* some multicasts */ if (CHIP_IS_E1(bp)) { /* @@ -8503,12 +8509,10 @@ void bnx2x_set_rx_mode(struct net_device *dev) } } - bp->rx_mode = rx_mode; bnx2x_set_storm_rx_mode(bp); } - /* called with rtnl_lock */ static int bnx2x_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr) @@ -8999,6 +9003,7 @@ static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) #endif return roundup(cid_count, QM_CID_ROUND); } + static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -9026,6 +9031,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, } cid_count += CNIC_CONTEXT_USE; + /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mq(sizeof(*bp), cid_count); if (!dev) { @@ -9117,6 +9123,7 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) /* Disable MSI/MSI-X */ bnx2x_disable_msi(bp); + /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->reset_task); diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index ad7aa55efb63..5644bddb3d19 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -14,8 +14,8 @@ * Statistics and Link management by Yitchak Gertner * */ - #include "bnx2x_cmn.h" - #include "bnx2x_stats.h" +#include "bnx2x_cmn.h" +#include "bnx2x_stats.h" /* Statistics */ diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h index 38a4e908f4fb..afd15efa429a 100644 --- a/drivers/net/bnx2x/bnx2x_stats.h +++ b/drivers/net/bnx2x/bnx2x_stats.h @@ -9,6 +9,10 @@ * Maintained by: Eilon Greenstein * Written by: Eliezer Tamir * Based on code from Michael Chan's bnx2 driver + * UDP CSUM errata workaround by Arik Gendelman + * Slowpath and fastpath rework by Vladislav Zolotarov + * Statistics and Link management by Yitchak Gertner + * */ #ifndef BNX2X_STATS_H @@ -228,12 +232,8 @@ struct bnx2x_eth_stats { /* Forward declaration */ struct bnx2x; - void bnx2x_stats_init(struct bnx2x *bp); extern const u32 dmae_reg_go_c[]; -extern int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common); - #endif /* BNX2X_STATS_H */ -- cgit v1.2.3 From fe78d2637ad9acc6414e36ce781aadc8c77d560d Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 17 Oct 2010 23:02:20 +0000 Subject: bnx2x: Optimized the branching in the bnx2x_rx_int() Optimized the branching in the bnx2x_rx_int() based on the fact that FP CQE will always have at least one of START or STOP flags set, so if not both bits are set and START bit is not set, then it's a STOP bit that is set. Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 97ef674dcc34..cb2a3d625ad1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -507,8 +507,11 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); pad = cqe->fast_path_cqe.placement_offset; - /* If CQE is marked both TPA_START and TPA_END - it is a non-TPA CQE */ + /* - If CQE is marked both TPA_START and TPA_END it is + * a non-TPA CQE. + * - FP CQE will always have either TPA_START or/and + * TPA_STOP flags set. + */ if ((!fp->disable_tpa) && (TPA_TYPE(cqe_fp_flags) != (TPA_TYPE_START | TPA_TYPE_END))) { @@ -526,9 +529,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) bnx2x_set_skb_rxhash(bp, cqe, skb); goto next_rx; - } - - if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) { + } else { /* TPA_STOP */ DP(NETIF_MSG_RX_STATUS, "calling tpa_stop on queue %d\n", queue); -- cgit v1.2.3 From e3dba8141b651dd8f560a2fd9513b1d26f447f9d Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:05:09 +0000 Subject: bnx2x: remove redundant commands during error handling Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index cb2a3d625ad1..b037dd2db8e5 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1289,8 +1289,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (rc) { BNX2X_ERR("HW init failed, aborting\n"); bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); goto load_error2; } -- cgit v1.2.3 From adf5f6a18f2cbb215394599981fb48473b526faa Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:10:02 +0000 Subject: bnx2x: do not deal with power if no capability Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index b037dd2db8e5..afff58c52d4f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1521,6 +1521,12 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) { u16 pmcsr; + /* If there is no power capability, silently succeed */ + if (!bp->pm_cap) { + DP(NETIF_MSG_HW, "No power capability. Breaking.\n"); + return 0; + } + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); switch (state) { -- cgit v1.2.3 From c8e4f48a8eb236eb672c6da0731ee01a633844f0 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:09:30 +0000 Subject: bnx2x: Use correct FW constant for header padding the value of the constant is the same, but it's clearer to use original constant provided by HSI Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index afff58c52d4f..1966ceeefcd4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -831,7 +831,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) int i, j; bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + - BNX2X_FW_IP_HDR_ALIGN_PAD; + IP_HEADER_ALIGNMENT_PADDING; DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 7f52cec9bb99..5bfe0ab1d2d4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1032,6 +1032,4 @@ static inline void storm_memset_cmng(struct bnx2x *bp, void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); -#define BNX2X_FW_IP_HDR_ALIGN_PAD 2 /* FW places hdr with this padding */ - #endif /* BNX2X_CMN_H */ -- cgit v1.2.3 From eab6d18d20fc5b5ba04a7e7fcd6f357197870e51 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:03 +0000 Subject: vlan: Don't check for vlan group before vlan_tx_tag_present. Many (but not all) drivers check to see whether there is a vlan group configured before using a tag stored in the skb. There's not much point in this check since it just throws away data that should only be present in the expected circumstances. However, it will soon be legal and expected to get a vlan tag when no vlan group is configured, so remove this check from all drivers to avoid dropping the tags. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- drivers/net/8139cp.c | 2 +- drivers/net/amd8111e.c | 2 +- drivers/net/atl1c/atl1c_main.c | 2 +- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/atlx/atl1.c | 2 +- drivers/net/atlx/atl2.c | 2 +- drivers/net/benet/be_main.c | 7 +++---- drivers/net/bna/bnad.c | 2 +- drivers/net/bnx2.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.c | 3 +-- drivers/net/chelsio/sge.c | 2 +- drivers/net/cxgb3/sge.c | 4 ++-- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/netdev.c | 2 +- drivers/net/ehea/ehea_main.c | 2 +- drivers/net/enic/enic_main.c | 2 +- drivers/net/forcedeth.c | 11 ++++------- drivers/net/gianfar.c | 4 ++-- drivers/net/igb/igb_main.c | 2 +- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/mlx4/en_tx.c | 4 ++-- drivers/net/qlge/qlge_main.c | 2 +- drivers/net/r8169.c | 2 +- drivers/net/s2io.c | 2 +- drivers/net/sky2.c | 2 +- drivers/net/tg3.c | 4 ++-- drivers/net/via-velocity.c | 2 +- drivers/net/vxge/vxge-main.c | 2 +- 29 files changed, 38 insertions(+), 43 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 237d4ea5a416..ac422cd332ea 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -754,7 +754,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, } #if CP_VLAN_TAG_USED - if (cp->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb)); #endif diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 58a0ab4923ee..2ca880b4c0db 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1315,7 +1315,7 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb, lp->tx_ring[tx_index].tx_flags = 0; #if AMD8111E_VLAN_TAG_USED - if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){ + if (vlan_tx_tag_present(skb)) { lp->tx_ring[tx_index].tag_ctrl_cmd |= cpu_to_le16(TCC_VLAN_INSERT); lp->tx_ring[tx_index].tag_ctrl_info = diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 553230eb365c..99ffcf667d1f 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -2243,7 +2243,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, return NETDEV_TX_OK; } - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { u16 vlan = vlan_tx_tag_get(skb); __le16 tag; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 56ace3fbe40d..ef6349bf3b33 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1814,7 +1814,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, tpd = atl1e_get_tpd(adapter); - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { u16 vlan_tag = vlan_tx_tag_get(skb); u16 atl1e_vlan_tag; diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index b8c053f76878..dbd27b8e66bd 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2408,7 +2408,7 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, (u16) atomic_read(&tpd_ring->next_to_use)); memset(ptpd, 0, sizeof(struct tx_packet_desc)); - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | ((vlan_tag >> 9) & 0x8); diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 29c0265ccc5d..35b14bec1207 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -870,7 +870,7 @@ static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb, offset = ((u32)(skb->len-copy_len + 3) & ~3); } #ifdef NETIF_F_HW_VLAN_TX - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 4b59e53890b2..d5e796832fdd 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -430,7 +430,7 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) } static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, - bool vlan, u32 wrb_cnt, u32 len) + u32 wrb_cnt, u32 len) { memset(hdr, 0, sizeof(*hdr)); @@ -449,7 +449,7 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); } - if (vlan && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tx_tag_get(skb)); @@ -532,8 +532,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, queue_head_inc(txq); } - wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false, - wrb_cnt, copied); + wrb_fill_hdr(hdr, first_skb, wrb_cnt, copied); be_dws_cpu_to_le(hdr, sizeof(*hdr)); return copied; diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 74c64d6c8801..7e839b9cec22 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -2501,7 +2501,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO : BNA_TXQ_WI_SEND)); - if (bnad->vlan_grp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag = (u16) vlan_tx_tag_get(skb); flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); } diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ae894bca4afb..363ca8bcc974 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6429,7 +6429,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) } #ifdef BCM_VLAN - if (bp->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 1966ceeefcd4..6905b2e0609e 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2026,8 +2026,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && - (bp->flags & HW_VLAN_TX_FLAG)) { + if (vlan_tx_tag_present(skb)) { tx_start_bd->vlan_or_ethertype = cpu_to_le16(vlan_tx_tag_get(skb)); tx_start_bd->bd_flags.as_bitfield |= diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 340b537dc97e..70221ca32683 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1870,7 +1870,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev) cpl->iff = dev->if_port; #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { cpl->vlan_valid = 1; cpl->vlan = htons(vlan_tx_tag_get(skb)); st->vlan_insert++; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index c5a142bea5e9..7ad4625dac62 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -1145,7 +1145,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, cpl->len = htonl(skb->len); cntrl = V_TXPKT_INTF(pi->port_id); - if (vlan_tx_tag_present(skb) && pi->vlan_grp) + if (vlan_tx_tag_present(skb)) cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(vlan_tx_tag_get(skb)); tso_info = V_LSO_MSS(skb_shinfo(skb)->gso_size); @@ -1279,7 +1279,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) qs->port_stats[SGE_PSTAT_TX_CSUM]++; if (skb_shinfo(skb)->gso_size) qs->port_stats[SGE_PSTAT_TSO]++; - if (vlan_tx_tag_present(skb) && pi->vlan_grp) + if (vlan_tx_tag_present(skb)) qs->port_stats[SGE_PSTAT_VLANINS]++; /* diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 232ac2dcb497..a117f2a0252e 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3119,7 +3119,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, } } - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5d6cdea0eb14..ec8cf3f51423 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4800,7 +4800,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (e1000_maybe_stop_tx(netdev, count + 2)) return NETDEV_TX_BUSY; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 6932578816d3..a0d117022be6 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2272,7 +2272,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) } pr->swqe_id_counter += 1; - if (port->vgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { swqe->tx_control |= EHEA_SWQE_VLAN_INSERT; swqe->vlan_tag = vlan_tx_tag_get(skb); } diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index f47fbb63d8b6..a466ef91dd43 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -805,7 +805,7 @@ static inline void enic_queue_wq_skb(struct enic *enic, int vlan_tag_insert = 0; int loopback = 0; - if (enic->vlan_group && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { /* VLAN tag from trunking driver */ vlan_tag_insert = 1; vlan_tag = vlan_tx_tag_get(skb); diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index ddac63cefbaa..0fa1776563a3 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2321,14 +2321,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0; /* vlan tag */ - if (likely(!np->vlangrp)) { + if (vlan_tx_tag_present(skb)) + start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | + vlan_tx_tag_get(skb)); + else start_tx->txvlan = 0; - } else { - if (vlan_tx_tag_present(skb)) - start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb)); - else - start_tx->txvlan = 0; - } spin_lock_irqsave(&np->lock, flags); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6180089bf67a..4c4cc80ec0a1 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2075,7 +2075,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* make space for additional header when fcb is needed */ if (((skb->ip_summed == CHECKSUM_PARTIAL) || - (priv->vlgrp && vlan_tx_tag_present(skb)) || + vlan_tx_tag_present(skb) || unlikely(do_tstamp)) && (skb_headroom(skb) < GMAC_FCB_LEN)) { struct sk_buff *skb_new; @@ -2161,7 +2161,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) gfar_tx_checksum(skb, fcb); } - if (priv->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { if (unlikely(NULL == fcb)) { fcb = gfar_add_fcb(skb); lstatus |= BD_LFLAG(TXBD_TOE); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0f0939caf091..75155a27fdde 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -4128,7 +4128,7 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, tx_flags |= IGB_TX_FLAGS_TSTAMP; } - if (vlan_tx_tag_present(skb) && adapter->vlgrp) { + if (vlan_tx_tag_present(skb)) { tx_flags |= IGB_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT); } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1d424428079f..998debe8023b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6311,7 +6311,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev int count = 0; unsigned int f; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 78bfbe42ca9b..dc03c9652389 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -3134,7 +3134,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tx_ring = &adapter->tx_ring[r_idx]; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; tx_flags |= IXGBE_TX_FLAGS_VLAN; diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 98dd620042a8..a680cd4a5ab6 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -583,7 +583,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) /* If we support per priority flow control and the packet contains * a vlan tag, send the packet to the TX ring assigned to that priority */ - if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) { + if (priv->prof->rx_ppp && vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13); } @@ -634,7 +634,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) tx_ind = skb->queue_mapping; ring = &priv->tx_ring[tx_ind]; - if (priv->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = vlan_tx_tag_get(skb); /* Check available TXBBs And 2K spare for prefetch */ diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 4ffebe83d883..ba0053d8515e 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2572,7 +2572,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev) mac_iocb_ptr->frame_len = cpu_to_le16((u16) skb->len); - if (qdev->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev, "Adding a vlan tag %d.\n", vlan_tx_tag_get(skb)); mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1760533852a4..242748b2c357 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1034,7 +1034,7 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, struct sk_buff *skb) { - return (tp->vlgrp && vlan_tx_tag_present(skb)) ? + return (vlan_tx_tag_present(skb)) ? TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; } diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index c70ad515383a..ecc25aab896a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -4101,7 +4101,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) } queue = 0; - if (sp->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = vlan_tx_tag_get(skb); if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) { if (skb->protocol == htons(ETH_P_IP)) { diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3ef9b67ac6e6..d6577084ce70 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1782,7 +1782,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, ctrl = 0; #ifdef SKY2_VLAN_TAG_USED /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ - if (sky2->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { if (!le) { le = get_tx_le(sky2, &slot); le->addr = 0; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5b4c510dbced..22720eeabddb 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5745,7 +5745,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, } #if TG3_VLAN_TAG_USED - if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); #endif @@ -5991,7 +5991,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, } } #if TG3_VLAN_TAG_USED - if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); #endif diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f1995615dc84..cab96ad49e60 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2592,7 +2592,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb, td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16; - if (vptr->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { td_ptr->tdesc1.vlan = cpu_to_le16(vlan_tx_tag_get(skb)); td_ptr->tdesc1.TCR |= TCR0_VETAG; } diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 0bda7fe05d4b..a69542ecb68d 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -822,7 +822,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) dev->name, __func__, __LINE__, fifo_hw, dtr, dtr_priv); - if (vdev->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); vxge_hw_fifo_txdl_vlan_set(dtr, vlan_tag); } -- cgit v1.2.3 From 9bcc08939223c5a2bad42748ee53ab69f5338a32 Mon Sep 17 00:00:00 2001 From: Hao Zheng Date: Wed, 20 Oct 2010 13:56:11 +0000 Subject: bnx2x: Update bnx2x to use new vlan accleration. Make the bnx2x driver use the new vlan accleration model. Signed-off-by: Hao Zheng Signed-off-by: Jesse Gross CC: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 10 ------- drivers/net/bnx2x/bnx2x_cmn.c | 60 +++++++-------------------------------- drivers/net/bnx2x/bnx2x_ethtool.c | 33 +++++++++++---------- drivers/net/bnx2x/bnx2x_main.c | 8 ------ 4 files changed, 27 insertions(+), 84 deletions(-) (limited to 'drivers/net/bnx2x/bnx2x_cmn.c') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 3bf236b160dd..9571ecf48f35 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -24,10 +24,6 @@ #define DRV_MODULE_RELDATE "2010/10/19" #define BNX2X_BC_VER 0x040200 -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define BCM_VLAN 1 -#endif - #define BNX2X_MULTI_QUEUE #define BNX2X_NEW_NAPI @@ -858,10 +854,6 @@ struct bnx2x { int tx_ring_size; -#ifdef BCM_VLAN - struct vlan_group *vlgrp; -#endif - u32 rx_csum; u32 rx_buf_size; /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ @@ -925,8 +917,6 @@ struct bnx2x { #define NO_MCP_FLAG 0x100 #define DISABLE_MSI_FLAG 0x200 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) -#define HW_VLAN_TX_FLAG 0x400 -#define HW_VLAN_RX_FLAG 0x800 #define MF_FUNC_DIS 0x1000 int pf_num; /* absolute PF number */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 6905b2e0609e..bc5837514074 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -16,16 +16,13 @@ */ #include +#include #include #include #include #include #include "bnx2x_cmn.h" -#ifdef BCM_VLAN -#include -#endif - #include "bnx2x_init.h" @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ /* (no need to map the new skb) */ -#ifdef BCM_VLAN - int is_vlan_cqe = - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN); - int is_not_hwaccel_vlan_cqe = - (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG))); -#endif prefetch(skb); prefetch(((char *)(skb)) + L1_CACHE_BYTES); @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct iphdr *iph; iph = (struct iphdr *)skb->data; -#ifdef BCM_VLAN - /* If there is no Rx VLAN offloading - - take VLAN tag into an account */ - if (unlikely(is_not_hwaccel_vlan_cqe)) - iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN); -#endif iph->check = 0; iph->check = ip_fast_csum((u8 *)iph, iph->ihl); } if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && - (le16_to_cpu(cqe->fast_path_cqe. - pars_flags.flags) & PARSING_FLAGS_VLAN)) - vlan_gro_receive(&fp->napi, bp->vlgrp, + if ((le16_to_cpu(cqe->fast_path_cqe. + pars_flags.flags) & PARSING_FLAGS_VLAN)) + __vlan_hwaccel_put_tag(skb, le16_to_cpu(cqe->fast_path_cqe. - vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); + vlan_tag)); + napi_gro_receive(&fp->napi, skb); } else { DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages" " - dropping packet!\n"); @@ -633,15 +613,11 @@ reuse_rx: skb_record_rx_queue(skb, fp->index); -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) && - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN)) - vlan_gro_receive(&fp->napi, bp->vlgrp, - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); + if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & + PARSING_FLAGS_VLAN) + __vlan_hwaccel_put_tag(skb, + le16_to_cpu(cqe->fast_path_cqe.vlan_tag)); + napi_gro_receive(&fp->napi, skb); next_rx: @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) "sending pkt %u @%p next_idx %u bd %u @%p\n", pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); -#ifdef BCM_VLAN if (vlan_tx_tag_present(skb)) { tx_start_bd->vlan_or_ethertype = cpu_to_le16(vlan_tx_tag_get(skb)); tx_start_bd->bd_flags.as_bitfield |= (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); } else -#endif tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); /* turn on parsing and get a BD */ @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev) schedule_delayed_work(&bp->reset_task, 0); } -#ifdef BCM_VLAN -/* called with rtnl_lock */ -void bnx2x_vlan_rx_register(struct net_device *dev, - struct vlan_group *vlgrp) -{ - struct bnx2x *bp = netdev_priv(dev); - - bp->vlgrp = vlgrp; -} - -#endif - int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 54fe0615a8b9..daefef618ef7 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device *dev, u32 data) int changed = 0; int rc = 0; - if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH)) - return -EINVAL; - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); return -EAGAIN; } + if (!(data & ETH_FLAG_RXVLAN)) + return -EOPNOTSUPP; + + if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa) + return -EINVAL; + + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH); + if (rc) + return rc; + /* TPA requires Rx CSUM offloading */ if ((data & ETH_FLAG_LRO) && bp->rx_csum) { - if (!bp->disable_tpa) { - if (!(dev->features & NETIF_F_LRO)) { - dev->features |= NETIF_F_LRO; - bp->flags |= TPA_ENABLE_FLAG; - changed = 1; - } - } else - rc = -EINVAL; - } else if (dev->features & NETIF_F_LRO) { + if (!(bp->flags & TPA_ENABLE_FLAG)) { + bp->flags |= TPA_ENABLE_FLAG; + changed = 1; + } + } else if (bp->flags & TPA_ENABLE_FLAG) { dev->features &= ~NETIF_F_LRO; bp->flags &= ~TPA_ENABLE_FLAG; changed = 1; } - if (data & ETH_FLAG_RXHASH) - dev->features |= NETIF_F_RXHASH; - else - dev->features &= ~NETIF_F_RXHASH; - if (changed && netif_running(dev)) { bnx2x_nic_unload(bp, UNLOAD_NORMAL); rc = bnx2x_nic_load(bp, LOAD_NORMAL); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f22e283cabef..ff99a2fc0426 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, flags |= QUEUE_FLG_HC; flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; -#ifdef BCM_VLAN flags |= QUEUE_FLG_VLAN; DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); -#endif if (!fp->disable_tpa) flags |= QUEUE_FLG_TPA; @@ -8630,9 +8628,6 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_do_ioctl = bnx2x_ioctl, .ndo_change_mtu = bnx2x_change_mtu, .ndo_tx_timeout = bnx2x_tx_timeout, -#ifdef BCM_VLAN - .ndo_vlan_rx_register = bnx2x_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2x, #endif @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->features |= NETIF_F_HIGHDMA; dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->features |= NETIF_F_TSO6; -#ifdef BCM_VLAN dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); dev->vlan_features |= NETIF_F_SG; dev->vlan_features |= NETIF_F_HW_CSUM; @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->vlan_features |= NETIF_F_HIGHDMA; dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->vlan_features |= NETIF_F_TSO6; -#endif /* get_port_hwinfo() will set prtad and mmds properly */ bp->mdio.prtad = MDIO_PRTAD_NONE; -- cgit v1.2.3