Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c32ec8f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bnx2x-next'



Yuval Mintz says:

====================
bnx2x: Start utilizing 7.10.51

This series will enable bnx2x to start utlizing its 7.10.51 FW.
In addition, it will also add timestamping support, as well as a couple
of routine semantic cleanups.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c0b80236 97539f1e
Loading
Loading
Loading
Loading
+31 −9
Original line number Diff line number Diff line
@@ -20,13 +20,17 @@
#include <linux/types.h>
#include <linux/pci_regs.h>

#include <linux/ptp_clock_kernel.h>
#include <linux/net_tstamp.h>
#include <linux/clocksource.h>

/* compilation time flags */

/* define this to make the driver freeze on error to allow getting debug info
 * (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */

#define DRV_MODULE_VERSION      "1.78.19-0"
#define DRV_MODULE_VERSION      "1.710.51-0"
#define DRV_MODULE_RELDATE      "2014/02/10"
#define BNX2X_BC_VER            0x040200

@@ -70,6 +74,7 @@ enum bnx2x_int_mode {
#define BNX2X_MSG_SP			0x0100000 /* was: NETIF_MSG_INTR */
#define BNX2X_MSG_FP			0x0200000 /* was: NETIF_MSG_INTR */
#define BNX2X_MSG_IOV			0x0800000
#define BNX2X_MSG_PTP			0x1000000
#define BNX2X_MSG_IDLE			0x2000000 /* used for idle check*/
#define BNX2X_MSG_ETHTOOL		0x4000000
#define BNX2X_MSG_DCB			0x8000000
@@ -1587,10 +1592,11 @@ struct bnx2x {
#define USING_SINGLE_MSIX_FLAG		(1 << 20)
#define BC_SUPPORTS_DCBX_MSG_NON_PMF	(1 << 21)
#define IS_VF_FLAG			(1 << 22)
#define INTERRUPTS_ENABLED_FLAG		(1 << 23)
#define BC_SUPPORTS_RMMOD_CMD		(1 << 24)
#define HAS_PHYS_PORT_ID		(1 << 25)
#define AER_ENABLED			(1 << 26)
#define BC_SUPPORTS_RMMOD_CMD		(1 << 23)
#define HAS_PHYS_PORT_ID		(1 << 24)
#define AER_ENABLED			(1 << 25)
#define PTP_SUPPORTED			(1 << 26)
#define TX_TIMESTAMPING_EN		(1 << 27)

#define BP_NOMCP(bp)			((bp)->flags & NO_MCP_FLAG)

@@ -1684,13 +1690,9 @@ struct bnx2x {
#define BNX2X_STATE_ERROR		0xf000

#define BNX2X_MAX_PRIORITY		8
#define BNX2X_MAX_ENTRIES_PER_PRI	16
#define BNX2X_MAX_COS			3
#define BNX2X_MAX_TX_COS		2
	int			num_queues;
	uint			num_ethernet_queues;
	uint			num_cnic_queues;
	int			num_napi_queues;
	int			disable_tpa;

	u32			rx_mode;
@@ -1933,6 +1935,19 @@ struct bnx2x {

	u8					phys_port_id[ETH_ALEN];

	/* PTP related context */
	struct ptp_clock *ptp_clock;
	struct ptp_clock_info ptp_clock_info;
	struct work_struct ptp_task;
	struct cyclecounter cyclecounter;
	struct timecounter timecounter;
	bool timecounter_init_done;
	struct sk_buff *ptp_tx_skb;
	unsigned long ptp_tx_start;
	bool hwtstamp_ioctl_called;
	u16 tx_type;
	u16 rx_filter;

	struct bnx2x_link_report_data		vf_link_vars;
};

@@ -2559,4 +2574,11 @@ void bnx2x_update_mng_version(struct bnx2x *bp);

#define E1H_MAX_MF_SB_COUNT (HC_SB_MAX_SB_E1X/(E1HVN_MAX * PORT_MAX))

void bnx2x_init_ptp(struct bnx2x *bp);
int bnx2x_configure_ptp_filters(struct bnx2x *bp);
void bnx2x_set_rx_ts(struct bnx2x *bp, struct sk_buff *skb);

#define BNX2X_MAX_PHC_DRIFT 31000000
#define BNX2X_PTP_TX_TIMEOUT

#endif /* bnx2x.h */
+57 −33
Original line number Diff line number Diff line
@@ -1067,6 +1067,11 @@ reuse_rx:

		skb_record_rx_queue(skb, fp->rx_queue);

		/* Check if this packet was timestamped */
		if (unlikely(le16_to_cpu(cqe->fast_path_cqe.type_error_flags) &
			     (1 << ETH_FAST_PATH_RX_CQE_PTP_PKT_SHIFT)))
			bnx2x_set_rx_ts(bp, skb);

		if (le16_to_cpu(cqe_fp->pars_flags.flags) &
		    PARSING_FLAGS_VLAN)
			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
@@ -2082,6 +2087,10 @@ int bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
			__set_bit(BNX2X_RSS_IPV4_UDP, &params.rss_flags);
		if (rss_obj->udp_rss_v6)
			__set_bit(BNX2X_RSS_IPV6_UDP, &params.rss_flags);

		if (!CHIP_IS_E1x(bp))
			/* valid only for TUNN_MODE_GRE tunnel mode */
			__set_bit(BNX2X_RSS_GRE_INNER_HDRS, &params.rss_flags);
	} else {
		__set_bit(BNX2X_RSS_MODE_DISABLED, &params.rss_flags);
	}
@@ -2804,7 +2813,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
	/* Initialize Rx filter. */
	bnx2x_set_rx_mode_inner(bp);

	/* Start the Tx */
	if (bp->flags & PTP_SUPPORTED) {
		bnx2x_init_ptp(bp);
		bnx2x_configure_ptp_filters(bp);
	}
	/* Start Tx */
	switch (load_mode) {
	case LOAD_NORMAL:
		/* Tx queue should be only re-enabled */
@@ -3441,26 +3454,6 @@ exit_lbl:
}
#endif

static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
				 u32 xmit_type)
{
	struct ipv6hdr *ipv6;

	*parsing_data |= (skb_shinfo(skb)->gso_size <<
			      ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
			      ETH_TX_PARSE_BD_E2_LSO_MSS;

	if (xmit_type & XMIT_GSO_ENC_V6)
		ipv6 = inner_ipv6_hdr(skb);
	else if (xmit_type & XMIT_GSO_V6)
		ipv6 = ipv6_hdr(skb);
	else
		ipv6 = NULL;

	if (ipv6 && ipv6->nexthdr == NEXTHDR_IPV6)
		*parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
}

/**
 * bnx2x_set_pbd_gso - update PBD in GSO case.
 *
@@ -3470,7 +3463,6 @@ static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
 */
static void bnx2x_set_pbd_gso(struct sk_buff *skb,
			      struct eth_tx_parse_bd_e1x *pbd,
			      struct eth_tx_start_bd *tx_start_bd,
			      u32 xmit_type)
{
	pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
@@ -3483,9 +3475,6 @@ static void bnx2x_set_pbd_gso(struct sk_buff *skb,
			bswab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
						   ip_hdr(skb)->daddr,
						   0, IPPROTO_TCP, 0));

		/* GSO on 57710/57711 needs FW to calculate IP checksum */
		tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM;
	} else {
		pbd->tcp_pseudo_csum =
			bswab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
@@ -3657,18 +3646,23 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,
			   (__force u32)iph->tot_len -
			   (__force u32)iph->frag_off;

		outerip_len = iph->ihl << 1;

		pbd2->fw_ip_csum_wo_len_flags_frag =
			bswab16(csum_fold((__force __wsum)csum));
	} else {
		pbd2->fw_ip_hdr_to_payload_w =
			hlen_w - ((sizeof(struct ipv6hdr)) >> 1);
		pbd_e2->data.tunnel_data.flags |=
			1 /*IPv6*/ << ETH_TUNNEL_DATA_IP_HDR_TYPE_OUTER;
	}

	pbd2->tcp_send_seq = bswab32(inner_tcp_hdr(skb)->seq);

	pbd2->tcp_flags = pbd_tcp_flags(inner_tcp_hdr(skb));

	if (xmit_type & XMIT_GSO_V4) {
	/* inner IP header info */
	if (xmit_type & XMIT_CSUM_ENC_V4) {
		pbd2->hw_ip_id = bswab16(inner_ip_hdr(skb)->id);

		pbd_e2->data.tunnel_data.pseudo_csum =
@@ -3676,8 +3670,6 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,
					inner_ip_hdr(skb)->saddr,
					inner_ip_hdr(skb)->daddr,
					0, IPPROTO_TCP, 0));

		outerip_len = ip_hdr(skb)->ihl << 1;
	} else {
		pbd_e2->data.tunnel_data.pseudo_csum =
			bswab16(~csum_ipv6_magic(
@@ -3690,8 +3682,6 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,

	*global_data |=
		outerip_off |
		(!!(xmit_type & XMIT_CSUM_V6) <<
			ETH_TX_PARSE_2ND_BD_IP_HDR_TYPE_OUTER_SHIFT) |
		(outerip_len <<
			ETH_TX_PARSE_2ND_BD_IP_HDR_LEN_OUTER_W_SHIFT) |
		((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
@@ -3703,6 +3693,23 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,
	}
}

static inline void bnx2x_set_ipv6_ext_e2(struct sk_buff *skb, u32 *parsing_data,
					 u32 xmit_type)
{
	struct ipv6hdr *ipv6;

	if (!(xmit_type & (XMIT_GSO_ENC_V6 | XMIT_GSO_V6)))
		return;

	if (xmit_type & XMIT_GSO_ENC_V6)
		ipv6 = inner_ipv6_hdr(skb);
	else /* XMIT_GSO_V6 */
		ipv6 = ipv6_hdr(skb);

	if (ipv6->nexthdr == NEXTHDR_IPV6)
		*parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
}

/* called with netif_tx_lock
 * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
 * netif_wake_queue()
@@ -3835,6 +3842,20 @@ 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_START_BD;

	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
		if (!(bp->flags & TX_TIMESTAMPING_EN)) {
			BNX2X_ERR("Tx timestamping was not enabled, this packet will not be timestamped\n");
		} else if (bp->ptp_tx_skb) {
			BNX2X_ERR("The device supports only a single outstanding packet to timestamp, this packet will not be timestamped\n");
		} else {
			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
			/* schedule check for Tx timestamp */
			bp->ptp_tx_skb = skb_get(skb);
			bp->ptp_tx_start = jiffies;
			schedule_work(&bp->ptp_task);
		}
	}

	/* header nbd: indirectly zero other flags! */
	tx_start_bd->general_data = 1 << ETH_TX_START_BD_HDR_NBDS_SHIFT;

@@ -3919,6 +3940,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
						     xmit_type);
		}

		bnx2x_set_ipv6_ext_e2(skb, &pbd_e2_parsing_data, xmit_type);
		/* Add the macs to the parsing BD if this is a vf or if
		 * Tx Switching is enabled.
		 */
@@ -3984,10 +4006,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
						 bd_prod);
		}
		if (!CHIP_IS_E1x(bp))
			bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
					     xmit_type);
			pbd_e2_parsing_data |=
				(skb_shinfo(skb)->gso_size <<
				 ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
				 ETH_TX_PARSE_BD_E2_LSO_MSS;
		else
			bnx2x_set_pbd_gso(skb, pbd_e1x, first_bd, xmit_type);
			bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
	}

	/* Set the PBD's parsing_data field if not zero
+3 −2
Original line number Diff line number Diff line
@@ -932,8 +932,9 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
	else /* CHIP_IS_E1X */
		start_params->network_cos_mode = FW_WRR;

	start_params->gre_tunnel_mode = L2GRE_TUNNEL;
	start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS;
	start_params->tunnel_mode	= TUNN_MODE_GRE;
	start_params->gre_tunnel_type	= IPGRE_TUNNEL;
	start_params->inner_gre_rss_en	= 1;

	return bnx2x_func_state_change(bp, &func_params);
}
+1 −4
Original line number Diff line number Diff line
@@ -2092,7 +2092,6 @@ static void bnx2x_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio,
static u8 bnx2x_dcbnl_set_all(struct net_device *netdev)
{
	struct bnx2x *bp = netdev_priv(netdev);
	int rc = 0;

	DP(BNX2X_MSG_DCB, "SET-ALL\n");

@@ -2110,9 +2109,7 @@ static u8 bnx2x_dcbnl_set_all(struct net_device *netdev)
				       1);
		bnx2x_dcbx_init(bp, true);
	}
	DP(BNX2X_MSG_DCB, "set_dcbx_params done (%d)\n", rc);
	if (rc)
		return 1;
	DP(BNX2X_MSG_DCB, "set_dcbx_params done\n");

	return 0;
}
+41 −1
Original line number Diff line number Diff line
@@ -3481,6 +3481,46 @@ static int bnx2x_set_channels(struct net_device *dev,
	return bnx2x_nic_load(bp, LOAD_NORMAL);
}

static int bnx2x_get_ts_info(struct net_device *dev,
			     struct ethtool_ts_info *info)
{
	struct bnx2x *bp = netdev_priv(dev);

	if (bp->flags & PTP_SUPPORTED) {
		info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
					SOF_TIMESTAMPING_RX_SOFTWARE |
					SOF_TIMESTAMPING_SOFTWARE |
					SOF_TIMESTAMPING_TX_HARDWARE |
					SOF_TIMESTAMPING_RX_HARDWARE |
					SOF_TIMESTAMPING_RAW_HARDWARE;

		if (bp->ptp_clock)
			info->phc_index = ptp_clock_index(bp->ptp_clock);
		else
			info->phc_index = -1;

		info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
				   (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
				   (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
				   (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
				   (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);

		info->tx_types = (1 << HWTSTAMP_TX_OFF)|(1 << HWTSTAMP_TX_ON);

		return 0;
	}

	return ethtool_op_get_ts_info(dev, info);
}

static const struct ethtool_ops bnx2x_ethtool_ops = {
	.get_settings		= bnx2x_get_settings,
	.set_settings		= bnx2x_set_settings,
@@ -3522,7 +3562,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
	.get_module_eeprom	= bnx2x_get_module_eeprom,
	.get_eee		= bnx2x_get_eee,
	.set_eee		= bnx2x_set_eee,
	.get_ts_info		= ethtool_op_get_ts_info,
	.get_ts_info		= bnx2x_get_ts_info,
};

static const struct ethtool_ops bnx2x_vf_ethtool_ops = {
Loading