aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h15
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c35
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c54
3 files changed, 54 insertions, 50 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index e30e2a2f354c..7de824184979 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -747,21 +747,6 @@ struct bnx2x_fastpath {
747 747
748#define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG 748#define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG
749 749
750#define BNX2X_IP_CSUM_ERR(cqe) \
751 (!((cqe)->fast_path_cqe.status_flags & \
752 ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG) && \
753 ((cqe)->fast_path_cqe.type_error_flags & \
754 ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG))
755
756#define BNX2X_L4_CSUM_ERR(cqe) \
757 (!((cqe)->fast_path_cqe.status_flags & \
758 ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) && \
759 ((cqe)->fast_path_cqe.type_error_flags & \
760 ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG))
761
762#define BNX2X_RX_CSUM_OK(cqe) \
763 (!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe)))
764
765#define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \ 750#define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \
766 (((le16_to_cpu(flags) & \ 751 (((le16_to_cpu(flags) & \
767 PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \ 752 PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index ad0743bf4bde..8098eea9704d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -190,7 +190,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata)
190 190
191 if ((netif_tx_queue_stopped(txq)) && 191 if ((netif_tx_queue_stopped(txq)) &&
192 (bp->state == BNX2X_STATE_OPEN) && 192 (bp->state == BNX2X_STATE_OPEN) &&
193 (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) 193 (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4))
194 netif_tx_wake_queue(txq); 194 netif_tx_wake_queue(txq);
195 195
196 __netif_tx_unlock(txq); 196 __netif_tx_unlock(txq);
@@ -617,6 +617,25 @@ static int bnx2x_alloc_rx_data(struct bnx2x *bp,
617 return 0; 617 return 0;
618} 618}
619 619
620static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe,
621 struct bnx2x_fastpath *fp)
622{
623 /* Do nothing if no IP/L4 csum validation was done */
624
625 if (cqe->fast_path_cqe.status_flags &
626 (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG |
627 ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG))
628 return;
629
630 /* If both IP/L4 validation were done, check if an error was found. */
631
632 if (cqe->fast_path_cqe.type_error_flags &
633 (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG |
634 ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG))
635 fp->eth_q_stats.hw_csum_err++;
636 else
637 skb->ip_summed = CHECKSUM_UNNECESSARY;
638}
620 639
621int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) 640int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
622{ 641{
@@ -806,13 +825,9 @@ reuse_rx:
806 825
807 skb_checksum_none_assert(skb); 826 skb_checksum_none_assert(skb);
808 827
809 if (bp->dev->features & NETIF_F_RXCSUM) { 828 if (bp->dev->features & NETIF_F_RXCSUM)
829 bnx2x_csum_validate(skb, cqe, fp);
810 830
811 if (likely(BNX2X_RX_CSUM_OK(cqe)))
812 skb->ip_summed = CHECKSUM_UNNECESSARY;
813 else
814 fp->eth_q_stats.hw_csum_err++;
815 }
816 831
817 skb_record_rx_queue(skb, fp->rx_queue); 832 skb_record_rx_queue(skb, fp->rx_queue);
818 833
@@ -2501,8 +2516,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget)
2501/* we split the first BD into headers and data BDs 2516/* we split the first BD into headers and data BDs
2502 * to ease the pain of our fellow microcode engineers 2517 * to ease the pain of our fellow microcode engineers
2503 * we use one mapping for both BDs 2518 * we use one mapping for both BDs
2504 * So far this has only been observed to happen
2505 * in Other Operating Systems(TM)
2506 */ 2519 */
2507static noinline u16 bnx2x_tx_split(struct bnx2x *bp, 2520static noinline u16 bnx2x_tx_split(struct bnx2x *bp,
2508 struct bnx2x_fp_txdata *txdata, 2521 struct bnx2x_fp_txdata *txdata,
@@ -3156,7 +3169,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
3156 3169
3157 txdata->tx_bd_prod += nbd; 3170 txdata->tx_bd_prod += nbd;
3158 3171
3159 if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { 3172 if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) {
3160 netif_tx_stop_queue(txq); 3173 netif_tx_stop_queue(txq);
3161 3174
3162 /* paired memory barrier is in bnx2x_tx_int(), we have to keep 3175 /* paired memory barrier is in bnx2x_tx_int(), we have to keep
@@ -3165,7 +3178,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
3165 smp_mb(); 3178 smp_mb();
3166 3179
3167 fp->eth_q_stats.driver_xoff++; 3180 fp->eth_q_stats.driver_xoff++;
3168 if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) 3181 if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)
3169 netif_tx_wake_queue(txq); 3182 netif_tx_wake_queue(txq);
3170 } 3183 }
3171 txdata->tx_pkt++; 3184 txdata->tx_pkt++;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index a3fb7215cd89..6e7d5c0843b4 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -40,6 +40,7 @@
40#define I2C_BSC0 0 40#define I2C_BSC0 0
41#define I2C_BSC1 1 41#define I2C_BSC1 1
42#define I2C_WA_RETRY_CNT 3 42#define I2C_WA_RETRY_CNT 3
43#define I2C_WA_PWR_ITER (I2C_WA_RETRY_CNT - 1)
43#define MCPR_IMC_COMMAND_READ_OP 1 44#define MCPR_IMC_COMMAND_READ_OP 1
44#define MCPR_IMC_COMMAND_WRITE_OP 2 45#define MCPR_IMC_COMMAND_WRITE_OP 2
45 46
@@ -7659,6 +7660,28 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7659 return -EINVAL; 7660 return -EINVAL;
7660} 7661}
7661 7662
7663static void bnx2x_warpcore_power_module(struct link_params *params,
7664 struct bnx2x_phy *phy,
7665 u8 power)
7666{
7667 u32 pin_cfg;
7668 struct bnx2x *bp = params->bp;
7669
7670 pin_cfg = (REG_RD(bp, params->shmem_base +
7671 offsetof(struct shmem_region,
7672 dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
7673 PORT_HW_CFG_E3_PWR_DIS_MASK) >>
7674 PORT_HW_CFG_E3_PWR_DIS_SHIFT;
7675
7676 if (pin_cfg == PIN_CFG_NA)
7677 return;
7678 DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
7679 power, pin_cfg);
7680 /* Low ==> corresponding SFP+ module is powered
7681 * high ==> the SFP+ module is powered down
7682 */
7683 bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
7684}
7662static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, 7685static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7663 struct link_params *params, 7686 struct link_params *params,
7664 u16 addr, u8 byte_cnt, 7687 u16 addr, u8 byte_cnt,
@@ -7678,6 +7701,12 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7678 /* 4 byte aligned address */ 7701 /* 4 byte aligned address */
7679 addr32 = addr & (~0x3); 7702 addr32 = addr & (~0x3);
7680 do { 7703 do {
7704 if (cnt == I2C_WA_PWR_ITER) {
7705 bnx2x_warpcore_power_module(params, phy, 0);
7706 /* Note that 100us are not enough here */
7707 usleep_range(1000,1000);
7708 bnx2x_warpcore_power_module(params, phy, 1);
7709 }
7681 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, 7710 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
7682 data_array); 7711 data_array);
7683 } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); 7712 } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
@@ -8200,29 +8229,6 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
8200 bnx2x_set_e1e2_module_fault_led(params, gpio_mode); 8229 bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
8201} 8230}
8202 8231
8203static void bnx2x_warpcore_power_module(struct link_params *params,
8204 struct bnx2x_phy *phy,
8205 u8 power)
8206{
8207 u32 pin_cfg;
8208 struct bnx2x *bp = params->bp;
8209
8210 pin_cfg = (REG_RD(bp, params->shmem_base +
8211 offsetof(struct shmem_region,
8212 dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8213 PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8214 PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8215
8216 if (pin_cfg == PIN_CFG_NA)
8217 return;
8218 DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
8219 power, pin_cfg);
8220 /* Low ==> corresponding SFP+ module is powered
8221 * high ==> the SFP+ module is powered down
8222 */
8223 bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
8224}
8225
8226static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy, 8232static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,
8227 struct link_params *params) 8233 struct link_params *params)
8228{ 8234{
@@ -9748,7 +9754,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9748 9754
9749 msleep(1); 9755 msleep(1);
9750 9756
9751 if (!(CHIP_IS_E1(bp))) 9757 if (!(CHIP_IS_E1x(bp)))
9752 port = BP_PATH(bp); 9758 port = BP_PATH(bp);
9753 else 9759 else
9754 port = params->port; 9760 port = params->port;