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.h137
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c9
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h15
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c94
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c31
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c4
11 files changed, 170 insertions, 134 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 4085c4b31047..355d5fea5be9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -531,20 +531,8 @@ struct bnx2x_fastpath {
struct napi_struct napi;
#ifdef CONFIG_NET_RX_BUSY_POLL
- unsigned int state;
-#define BNX2X_FP_STATE_IDLE 0
-#define BNX2X_FP_STATE_NAPI (1 << 0) /* NAPI owns this FP */
-#define BNX2X_FP_STATE_POLL (1 << 1) /* poll owns this FP */
-#define BNX2X_FP_STATE_DISABLED (1 << 2)
-#define BNX2X_FP_STATE_NAPI_YIELD (1 << 3) /* NAPI yielded this FP */
-#define BNX2X_FP_STATE_POLL_YIELD (1 << 4) /* poll yielded this FP */
-#define BNX2X_FP_OWNED (BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
-#define BNX2X_FP_YIELD (BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)
-#define BNX2X_FP_LOCKED (BNX2X_FP_OWNED | BNX2X_FP_STATE_DISABLED)
-#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
- /* protect state */
- spinlock_t lock;
-#endif /* CONFIG_NET_RX_BUSY_POLL */
+ unsigned long busy_poll_state;
+#endif
union host_hc_status_block status_blk;
/* chip independent shortcuts into sb structure */
@@ -619,104 +607,83 @@ struct bnx2x_fastpath {
#define bnx2x_fp_qstats(bp, fp) (&((bp)->fp_stats[(fp)->index].eth_q_stats))
#ifdef CONFIG_NET_RX_BUSY_POLL
-static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
+
+enum bnx2x_fp_state {
+ BNX2X_STATE_FP_NAPI = BIT(0), /* NAPI handler owns the queue */
+
+ BNX2X_STATE_FP_NAPI_REQ_BIT = 1, /* NAPI would like to own the queue */
+ BNX2X_STATE_FP_NAPI_REQ = BIT(1),
+
+ BNX2X_STATE_FP_POLL_BIT = 2,
+ BNX2X_STATE_FP_POLL = BIT(2), /* busy_poll owns the queue */
+
+ BNX2X_STATE_FP_DISABLE_BIT = 3, /* queue is dismantled */
+};
+
+static inline void bnx2x_fp_busy_poll_init(struct bnx2x_fastpath *fp)
{
- spin_lock_init(&fp->lock);
- fp->state = BNX2X_FP_STATE_IDLE;
+ WRITE_ONCE(fp->busy_poll_state, 0);
}
/* called from the device poll routine to get ownership of a FP */
static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
{
- bool rc = true;
-
- spin_lock_bh(&fp->lock);
- if (fp->state & BNX2X_FP_LOCKED) {
- WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
- fp->state |= BNX2X_FP_STATE_NAPI_YIELD;
- rc = false;
- } else {
- /* we don't care if someone yielded */
- fp->state = BNX2X_FP_STATE_NAPI;
+ unsigned long prev, old = READ_ONCE(fp->busy_poll_state);
+
+ while (1) {
+ switch (old) {
+ case BNX2X_STATE_FP_POLL:
+ /* make sure bnx2x_fp_lock_poll() wont starve us */
+ set_bit(BNX2X_STATE_FP_NAPI_REQ_BIT,
+ &fp->busy_poll_state);
+ /* fallthrough */
+ case BNX2X_STATE_FP_POLL | BNX2X_STATE_FP_NAPI_REQ:
+ return false;
+ default:
+ break;
+ }
+ prev = cmpxchg(&fp->busy_poll_state, old, BNX2X_STATE_FP_NAPI);
+ if (unlikely(prev != old)) {
+ old = prev;
+ continue;
+ }
+ return true;
}
- spin_unlock_bh(&fp->lock);
- return rc;
}
-/* returns true is someone tried to get the FP while napi had it */
-static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
+static inline void bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
{
- bool rc = false;
-
- spin_lock_bh(&fp->lock);
- WARN_ON(fp->state &
- (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));
-
- if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
- rc = true;
-
- /* state ==> idle, unless currently disabled */
- fp->state &= BNX2X_FP_STATE_DISABLED;
- spin_unlock_bh(&fp->lock);
- return rc;
+ smp_wmb();
+ fp->busy_poll_state = 0;
}
/* called from bnx2x_low_latency_poll() */
static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
{
- bool rc = true;
-
- spin_lock_bh(&fp->lock);
- if ((fp->state & BNX2X_FP_LOCKED)) {
- fp->state |= BNX2X_FP_STATE_POLL_YIELD;
- rc = false;
- } else {
- /* preserve yield marks */
- fp->state |= BNX2X_FP_STATE_POLL;
- }
- spin_unlock_bh(&fp->lock);
- return rc;
+ return cmpxchg(&fp->busy_poll_state, 0, BNX2X_STATE_FP_POLL) == 0;
}
-/* returns true if someone tried to get the FP while it was locked */
-static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
+static inline void bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
{
- bool rc = false;
-
- spin_lock_bh(&fp->lock);
- WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
-
- if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
- rc = true;
-
- /* state ==> idle, unless currently disabled */
- fp->state &= BNX2X_FP_STATE_DISABLED;
- spin_unlock_bh(&fp->lock);
- return rc;
+ smp_mb__before_atomic();
+ clear_bit(BNX2X_STATE_FP_POLL_BIT, &fp->busy_poll_state);
}
-/* true if a socket is polling, even if it did not get the lock */
+/* true if a socket is polling */
static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
{
- WARN_ON(!(fp->state & BNX2X_FP_OWNED));
- return fp->state & BNX2X_FP_USER_PEND;
+ return READ_ONCE(fp->busy_poll_state) & BNX2X_STATE_FP_POLL;
}
/* false if fp is currently owned */
static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
{
- int rc = true;
-
- spin_lock_bh(&fp->lock);
- if (fp->state & BNX2X_FP_OWNED)
- rc = false;
- fp->state |= BNX2X_FP_STATE_DISABLED;
- spin_unlock_bh(&fp->lock);
+ set_bit(BNX2X_STATE_FP_DISABLE_BIT, &fp->busy_poll_state);
+ return !bnx2x_fp_ll_polling(fp);
- return rc;
}
#else
-static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
+static inline void bnx2x_fp_busy_poll_init(struct bnx2x_fastpath *fp)
{
}
@@ -725,9 +692,8 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
return true;
}
-static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
+static inline void bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
{
- return false;
}
static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
@@ -735,9 +701,8 @@ static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
return false;
}
-static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
+static inline void bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
{
- return false;
}
static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 0a9faa134a9a..2f63467bce46 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1849,7 +1849,7 @@ static void bnx2x_napi_enable_cnic(struct bnx2x *bp)
int i;
for_each_rx_queue_cnic(bp, i) {
- bnx2x_fp_init_lock(&bp->fp[i]);
+ bnx2x_fp_busy_poll_init(&bp->fp[i]);
napi_enable(&bnx2x_fp(bp, i, napi));
}
}
@@ -1859,7 +1859,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp)
int i;
for_each_eth_queue(bp, i) {
- bnx2x_fp_init_lock(&bp->fp[i]);
+ bnx2x_fp_busy_poll_init(&bp->fp[i]);
napi_enable(&bnx2x_fp(bp, i, napi));
}
}
@@ -3191,9 +3191,10 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
}
}
+ bnx2x_fp_unlock_napi(fp);
+
/* Fall out from the NAPI loop if needed */
- if (!bnx2x_fp_unlock_napi(fp) &&
- !(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
+ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
/* No need to update SB for FCoE L2 ring as long as
* it's connected to the default SB and the SB
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index ffe4e003e636..e3d853cab7c9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -2446,7 +2446,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
}
packet = skb_put(skb, pkt_size);
memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
- memset(packet + ETH_ALEN, 0, ETH_ALEN);
+ eth_zero_addr(packet + ETH_ALEN);
memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN));
for (i = ETH_HLEN; i < pkt_size; i++)
packet[i] = (unsigned char) (i & 0xff);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index 583591d52497..058bc7328220 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -521,6 +521,17 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
*/
#define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000
#define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16
+ /* Set non-default values for TXFIR in SFP mode. */
+ #define PORT_HW_CFG_TX_DRV_IFIR_MASK 0x00F00000
+ #define PORT_HW_CFG_TX_DRV_IFIR_SHIFT 20
+
+ /* Set non-default values for IPREDRIVER in SFP mode. */
+ #define PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK 0x0F000000
+ #define PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT 24
+
+ /* Set non-default values for POST2 in SFP mode. */
+ #define PORT_HW_CFG_TX_DRV_POST2_MASK 0xF0000000
+ #define PORT_HW_CFG_TX_DRV_POST2_SHIFT 28
u32 reserved0[5]; /* 0x17c */
@@ -2247,8 +2258,8 @@ struct shmem2_region {
#define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000
u32 reserved5[2];
- u32 reserved6[PORT_MAX];
-
+ u32 link_change_count[PORT_MAX]; /* Offset 0x160-0x164 */
+ #define LINK_CHANGE_COUNT_MASK 0xff /* Offset 0x168 */
/* driver version for each personality */
struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
index bd90e50bd8e6..d6e1975b7b69 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
@@ -278,7 +278,7 @@ static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode,
}
-/* congestion managment port init api description
+/* congestion management port init api description
* the api works as follows:
* the driver should pass the cmng_init_input struct, the port_init function
* will prepare the required internal ram structure which will be passed back
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 778e4cd32571..21a0d6afca4a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -195,6 +195,10 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
#define MAX_PACKET_SIZE (9700)
#define MAX_KR_LINK_RETRY 4
+#define DEFAULT_TX_DRV_BRDCT 2
+#define DEFAULT_TX_DRV_IFIR 0
+#define DEFAULT_TX_DRV_POST2 3
+#define DEFAULT_TX_DRV_IPRE_DRIVER 6
/**********************************************************/
/* INTERFACE */
@@ -563,7 +567,7 @@ static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
* Will return the NIG ETS registers to init values.Except
* credit_upper_bound.
* That isn't used in this configuration (No WFQ is enabled) and will be
-* configured acording to spec
+* configured according to spec
*.
******************************************************************************/
static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
@@ -680,7 +684,7 @@ static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
* Will return the PBF ETS registers to init values.Except
* credit_upper_bound.
* That isn't used in this configuration (No WFQ is enabled) and will be
-* configured acording to spec
+* configured according to spec
*.
******************************************************************************/
static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
@@ -738,7 +742,7 @@ static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
}
/******************************************************************************
* Description:
-* E3B0 disable will return basicly the values to init values.
+* E3B0 disable will return basically the values to init values.
*.
******************************************************************************/
static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
@@ -761,7 +765,7 @@ static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
/******************************************************************************
* Description:
-* Disable will return basicly the values to init values.
+* Disable will return basically the values to init values.
*
******************************************************************************/
int bnx2x_ets_disabled(struct link_params *params,
@@ -2938,7 +2942,7 @@ static int bnx2x_eee_initial_config(struct link_params *params,
{
vars->eee_status |= ((u32) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
- /* Propogate params' bits --> vars (for migration exposure) */
+ /* Propagate params' bits --> vars (for migration exposure) */
if (params->eee_mode & EEE_MODE_ENABLE_LPI)
vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
else
@@ -3595,10 +3599,11 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
* init configuration, and set/clear SGMII flag. Internal
* phy init is done purely in phy_init stage.
*/
-#define WC_TX_DRIVER(post2, idriver, ipre) \
+#define WC_TX_DRIVER(post2, idriver, ipre, ifir) \
((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
(idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
- (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))
+ (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \
+ (ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET))
#define WC_TX_FIR(post, main, pre) \
((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
@@ -3765,12 +3770,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
lane = bnx2x_get_warpcore_lane(phy, params);
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
- WC_TX_DRIVER(0x02, 0x06, 0x09));
+ WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
/* Configure the next lane if dual mode */
if (phy->flags & FLAGS_WC_DUAL_MODE)
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1),
- WC_TX_DRIVER(0x02, 0x06, 0x09));
+ WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
0x03f0);
@@ -3933,6 +3938,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
struct bnx2x *bp = params->bp;
u16 misc1_val, tap_val, tx_driver_val, lane, val;
u32 cfg_tap_val, tx_drv_brdct, tx_equal;
+ u32 ifir_val, ipost2_val, ipre_driver_val;
/* Hold rxSeqStart */
bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
@@ -3978,7 +3984,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
if (is_xfi) {
misc1_val |= 0x5;
tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
- tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03);
+ tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0);
} else {
cfg_tap_val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
@@ -3987,10 +3993,6 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
- tx_drv_brdct = (cfg_tap_val &
- PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
- PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
-
misc1_val |= 0x9;
/* TAP values are controlled by nvram, if value there isn't 0 */
@@ -3999,11 +4001,36 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
else
tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
- if (tx_drv_brdct)
- tx_driver_val = WC_TX_DRIVER(0x03, (u16)tx_drv_brdct,
- 0x06);
- else
- tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06);
+ ifir_val = DEFAULT_TX_DRV_IFIR;
+ ipost2_val = DEFAULT_TX_DRV_POST2;
+ ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER;
+ tx_drv_brdct = DEFAULT_TX_DRV_BRDCT;
+
+ /* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all
+ * configuration.
+ */
+ if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK |
+ PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK |
+ PORT_HW_CFG_TX_DRV_POST2_MASK)) {
+ ifir_val = (cfg_tap_val &
+ PORT_HW_CFG_TX_DRV_IFIR_MASK) >>
+ PORT_HW_CFG_TX_DRV_IFIR_SHIFT;
+ ipre_driver_val = (cfg_tap_val &
+ PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK)
+ >> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT;
+ ipost2_val = (cfg_tap_val &
+ PORT_HW_CFG_TX_DRV_POST2_MASK) >>
+ PORT_HW_CFG_TX_DRV_POST2_SHIFT;
+ }
+
+ if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) {
+ tx_drv_brdct = (cfg_tap_val &
+ PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
+ PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
+ }
+
+ tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct,
+ ipre_driver_val, ifir_val);
}
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
@@ -4144,7 +4171,7 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
MDIO_WC_REG_TX_FIR_TAP_ENABLE));
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
- WC_TX_DRIVER(0x02, 0x02, 0x02));
+ WC_TX_DRIVER(0x02, 0x02, 0x02, 0));
}
static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
@@ -6731,6 +6758,25 @@ static int bnx2x_update_link_up(struct link_params *params,
msleep(20);
return rc;
}
+
+static void bnx2x_chng_link_count(struct link_params *params, bool clear)
+{
+ struct bnx2x *bp = params->bp;
+ u32 addr, val;
+
+ /* Verify the link_change_count is supported by the MFW */
+ if (!(SHMEM2_HAS(bp, link_change_count)))
+ return;
+
+ addr = params->shmem2_base +
+ offsetof(struct shmem2_region, link_change_count[params->port]);
+ if (clear)
+ val = 0;
+ else
+ val = REG_RD(bp, addr) + 1;
+ REG_WR(bp, addr, val);
+}
+
/* The bnx2x_link_update function should be called upon link
* interrupt.
* Link is considered up as follows:
@@ -6749,6 +6795,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
struct link_vars phy_vars[MAX_PHYS];
u8 port = params->port;
u8 link_10g_plus, phy_index;
+ u32 prev_link_status = vars->link_status;
u8 ext_phy_link_up = 0, cur_link_up;
int rc = 0;
u8 is_mi_int = 0;
@@ -6988,6 +7035,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
else
rc = bnx2x_update_link_down(params, vars);
+ if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP)
+ bnx2x_chng_link_count(params, false);
+
/* Update MCP link status was changed */
if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX)
bnx2x_fw_command(bp, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
@@ -12631,6 +12681,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
params->link_flags = PHY_INITIALIZED;
/* Driver opens NIG-BRB filters */
bnx2x_set_rx_filter(params, 1);
+ bnx2x_chng_link_count(params, true);
/* Check if link flap can be avoided */
lfa_status = bnx2x_check_lfa(params);
@@ -12705,6 +12756,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
/* Disable attentions */
vars->link_status = 0;
+ bnx2x_chng_link_count(params, true);
bnx2x_update_mng(params, vars->link_status);
vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
SHMEM_EEE_ACTIVE_BIT);
@@ -13308,7 +13360,7 @@ static void bnx2x_check_over_curr(struct link_params *params,
vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
}
-/* Returns 0 if no change occured since last check; 1 otherwise. */
+/* Returns 0 if no change occurred since last check; 1 otherwise. */
static u8 bnx2x_analyze_link_error(struct link_params *params,
struct link_vars *vars, u32 status,
u32 phy_flag, u32 link_flag, u8 notify)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 1ec635f54994..b9f85fccb419 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -11556,13 +11556,13 @@ static void bnx2x_get_cnic_mac_hwinfo(struct bnx2x *bp)
/* Disable iSCSI OOO if MAC configuration is invalid. */
if (!is_valid_ether_addr(iscsi_mac)) {
bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
- memset(iscsi_mac, 0, ETH_ALEN);
+ eth_zero_addr(iscsi_mac);
}
/* Disable FCoE if MAC configuration is invalid. */
if (!is_valid_ether_addr(fip_mac)) {
bp->flags |= NO_FCOE_FLAG;
- memset(bp->fip_mac, 0, ETH_ALEN);
+ eth_zero_addr(bp->fip_mac);
}
}
@@ -11573,7 +11573,7 @@ static void bnx2x_get_mac_hwinfo(struct bnx2x *bp)
int port = BP_PORT(bp);
/* Zero primary MAC configuration */
- memset(bp->dev->dev_addr, 0, ETH_ALEN);
+ eth_zero_addr(bp->dev->dev_addr);
if (BP_NOMCP(bp)) {
BNX2X_ERROR("warning: random MAC workaround active\n");
@@ -11620,7 +11620,7 @@ static bool bnx2x_get_dropless_info(struct bnx2x *bp)
u32 cfg;
if (IS_VF(bp))
- return 0;
+ return false;
if (IS_MF(bp) && !CHIP_IS_E1x(bp)) {
/* Take function: tmp = func */
@@ -11660,6 +11660,13 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
u32 val = 0, val2 = 0;
int rc = 0;
+ /* Validate that chip access is feasible */
+ if (REG_RD(bp, MISC_REG_CHIP_NUM) == 0xffffffff) {
+ dev_err(&bp->pdev->dev,
+ "Chip read returns all Fs. Preventing probe from continuing\n");
+ return -EINVAL;
+ }
+
bnx2x_get_common_hwinfo(bp);
/*
@@ -12566,6 +12573,7 @@ static netdev_features_t bnx2x_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
+ features = vlan_features_check(skb, features);
return vxlan_features_check(skb, features);
}
@@ -13287,30 +13295,27 @@ static int bnx2x_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
return 0;
}
-static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info);
u64 ns;
- u32 remainder;
ns = timecounter_read(&bp->timecounter);
DP(BNX2X_MSG_PTP, "PTP gettime called, ns = %llu\n", ns);
- ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder);
- ts->tv_nsec = remainder;
+ *ts = ns_to_timespec64(ns);
return 0;
}
static int bnx2x_ptp_settime(struct ptp_clock_info *ptp,
- const struct timespec *ts)
+ const struct timespec64 *ts)
{
struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info);
u64 ns;
- ns = ts->tv_sec * 1000000000ULL;
- ns += ts->tv_nsec;
+ ns = timespec64_to_ns(ts);
DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns);
@@ -13342,8 +13347,8 @@ static void bnx2x_register_phc(struct bnx2x *bp)
bp->ptp_clock_info.pps = 0;
bp->ptp_clock_info.adjfreq = bnx2x_ptp_adjfreq;
bp->ptp_clock_info.adjtime = bnx2x_ptp_adjtime;
- bp->ptp_clock_info.gettime = bnx2x_ptp_gettime;
- bp->ptp_clock_info.settime = bnx2x_ptp_settime;
+ bp->ptp_clock_info.gettime64 = bnx2x_ptp_gettime;
+ bp->ptp_clock_info.settime64 = bnx2x_ptp_settime;
bp->ptp_clock_info.enable = bnx2x_ptp_enable;
bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &bp->pdev->dev);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index 6fe547c93e74..49d511092c82 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -29,7 +29,7 @@
#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 */
+/* [R 1] ATC initialization done */
#define ATC_REG_ATC_INIT_DONE 0x1100bc
/* [RC 6] Interrupt register #0 read clear */
#define ATC_REG_ATC_INT_STS_CLR 0x1101c0
@@ -7341,6 +7341,8 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081
#define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091
#define MDIO_WC_REG_TX0_TX_DRIVER 0x8067
+#define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET 0x01
+#define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_MASK 0x000e
#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04
#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0
#define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index cfe3c7695455..f67348d16966 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -592,7 +592,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf,
mc = kzalloc(mc_num * sizeof(struct bnx2x_mcast_list_elem),
GFP_KERNEL);
if (!mc) {
- BNX2X_ERR("Cannot Configure mulicasts due to lack of memory\n");
+ BNX2X_ERR("Cannot Configure multicasts due to lack of memory\n");
return -ENOMEM;
}
}
@@ -2695,7 +2695,7 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
memcpy(&ivi->mac, bulletin->mac, ETH_ALEN);
else
/* function has not been loaded yet. Show mac as 0s */
- memset(&ivi->mac, 0, ETH_ALEN);
+ eth_zero_addr(ivi->mac);
/* vlan */
if (bulletin->valid_bitmap & (1 << VLAN_VALID))
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 800ab44a07ce..266b055c2360 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -1583,7 +1583,7 @@ void bnx2x_memset_stats(struct bnx2x *bp)
if (bp->port.pmf && bp->port.port_stx)
bnx2x_port_stats_base_init(bp);
- /* mark the end of statistics initializiation */
+ /* mark the end of statistics initialization */
bp->stats_init = false;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index be40eabc5304..15b2d1647560 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -800,7 +800,7 @@ int bnx2x_vfpf_config_rss(struct bnx2x *bp,
req->rss_key_size = T_ETH_RSS_KEY;
req->rss_result_mask = params->rss_result_mask;
- /* flags handled individually for backward/forward compatability */
+ /* flags handled individually for backward/forward compatibility */
if (params->rss_flags & (1 << BNX2X_RSS_MODE_DISABLED))
req->rss_flags |= VFPF_RSS_MODE_DISABLED;
if (params->rss_flags & (1 << BNX2X_RSS_MODE_REGULAR))
@@ -1869,7 +1869,7 @@ static void bnx2x_vf_mbx_update_rss(struct bnx2x *bp, struct bnx2x_virtf *vf,
rss.rss_obj = &vf->rss_conf_obj;
rss.rss_result_mask = rss_tlv->rss_result_mask;
- /* flags handled individually for backward/forward compatability */
+ /* flags handled individually for backward/forward compatibility */
rss.rss_flags = 0;
rss.ramrod_flags = 0;