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

Commit 3a430fa5 authored by Mark Starovoytov's avatar Mark Starovoytov Committed by Gerrit - the friendly Code Review server
Browse files

atlantic forwarding driver v1.1.8



  [ATLDRV-1438] - Fwd: port PTP from Linux driver

Change-Id: I1ce01c227f8fdc25c011480ffcd18247320263b9
Signed-off-by: default avatarMark Starovoytov <mstarovoitov@marvell.com>
Git-commit: c6141c29b8b25fd345c7e5b0dd3e186735258000
Git-repo: https://github.com/aquantia/linux-4.14-atlantic-forwarding


[ltyagi@codeaurora.org: Fix compilation error in atl_ptp_hwtstamp_config_set/get]
Signed-off-by: default avatarLakshit Tyagi <ltyagi@codeaurora.org>
parent 09b17074
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ atlantic-fwd-objs := atl_fw.o \
		     atl_ethtool.o \
		     atl_trace.o \
		     atl_compat.o \
		     atl_hwmon.o
		     atl_hwmon.o \
		     atl_ptp.o \
		     atl_hw_ptp.o

atlantic-fwd-$(CONFIG_ATLFWD_FWD) += atl_fwd.o
atlantic-fwd-$(CONFIG_ATLFWD_FWD_NETLINK) += atl_fwdnl.o \
+11 −2
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
#include <linux/netdevice.h>
#include <linux/moduleparam.h>

#define ATL_VERSION "1.1.7"
#define ATL_VERSION "1.1.8"

struct atl_nic;

@@ -34,6 +34,8 @@ struct atl_nic;

#include "atl_fwd.h"

struct atl_ptp;

enum {
	ATL_RXF_VLAN_BASE = 0,
	ATL_RXF_VLAN_MAX = ATL_VLAN_FLT_NUM,
@@ -192,7 +194,11 @@ struct atl_queue_vec;
#define ATL_FWD_RING_BASE ATL_MAX_QUEUES /* Use TC 1 for offload
					  * engine rings */
#define ATL_NUM_MSI_VECS 32
#define ATL_NUM_NON_RING_IRQS 1
enum {
	ATL_IRQ_LINK = 0,
	ATL_IRQ_PTP,
	ATL_NUM_NON_RING_IRQS,
};

#define ATL_RXF_RING_ANY 32

@@ -253,6 +259,9 @@ struct atl_nic {
	struct atl_rxf_vlan rxf_vlan;
	struct atl_rxf_etype rxf_etype;
	struct atl_rxf_flex rxf_flex;

	/* PTP support */
	struct atl_ptp *ptp;
};

/* Flags only modified with RTNL lock held */
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,12 @@

#include <linux/pci.h>
#include <linux/msi.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>

#ifndef IS_REACHABLE
#define IS_REACHABLE defined
#endif

/* If the kernel is not RHEL / CentOS, then the 2 identifiers below will be
 * undefined. Define them this way to simplify the checks below.
+23 −11
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
#include <linux/kernel.h>

#if defined(__LITTLE_ENDIAN_BITFIELD)
struct atl_tx_ctx {
struct __packed atl_tx_ctx {
	unsigned long long :40; //0
	unsigned tun_len:8;     //40
	unsigned out_len:16;    //48
@@ -27,9 +27,9 @@ struct atl_tx_ctx {
	unsigned l3_len:9;      //95
	unsigned l4_len:8;      //104
	unsigned mss_len:16;    //112
} __attribute__((packed));
};

struct atl_tx_desc {
struct __packed atl_tx_desc {
	unsigned long long daddr:64; //0
	unsigned type:3;        //64
	unsigned :1;            //67
@@ -41,7 +41,7 @@ struct atl_tx_desc {
	unsigned ct_idx:1;      //108
	unsigned ct_en:1;       //109
	unsigned pay_len:18;    //110
} __attribute__((packed));
};

#define ATL_DATA_PER_TXD 16384 // despite ->len being 16 bits

@@ -65,7 +65,7 @@ enum atl_tx_ctx_cmd {
	ctx_cmd_tcp = 4,  // TCP / ~UDP
};

struct atl_rx_desc {
struct __packed atl_rx_desc {
	uint64_t daddr;      			//0
	union {
		struct {
@@ -74,9 +74,9 @@ struct atl_rx_desc {
		};
		uint64_t haddr;
	};
} __attribute__((packed));
};

struct atl_rx_desc_wb {
struct __packed atl_rx_desc_wb {
	unsigned rss_type:4;    //0
	unsigned pkt_type:8;    //4
	unsigned rdm_err:1;     //12
@@ -93,7 +93,16 @@ struct atl_rx_desc_wb {
	unsigned pkt_len:16;    //80
	unsigned next_desp:16;  //96
	unsigned vlan_tag:16;   //112
} __attribute__((packed));
};

struct __packed atl_rx_desc_hwts_wb {
	u32 sec_hw;
	u32 ns;
	u32 dd:1;
	u32 rsvd:1;
	u32 sec_lw0:30;
	u32 sec_lw1;
};

enum atl_rx_stat {
	atl_rx_stat_mac_err = 1,
@@ -135,13 +144,16 @@ enum atl_rx_pkt_type {
#error XXX Fix bigendian bitfields
#endif // defined(__LITTLE_ENDIAN_BITFIELD)

union atl_desc{
union __packed atl_desc {
	struct atl_rx_desc rx;
	union {
		struct atl_rx_desc_wb wb;
		struct atl_rx_desc_hwts_wb hwts_wb;
	};
	struct atl_tx_ctx ctx;
	struct atl_tx_desc tx;
	uint8_t raw[16];
}__attribute__((packed));
};


#endif
+77 −1
Original line number Diff line number Diff line
@@ -11,12 +11,15 @@

#include <linux/ethtool.h>
#include <linux/pm_runtime.h>
#include <linux/ptp_clock_kernel.h>

#include "atl_ethtool.h"
#include "atl_common.h"
#include "atl_mdio.h"
#include "atl_ring.h"
#include "atl_fwdnl.h"
#include "atl_macsec.h"
#include "atl_ptp.h"

static uint32_t atl_ethtool_get_link(struct net_device *ndev)
{
@@ -1186,6 +1189,38 @@ static int atl_set_coalesce(struct net_device *ndev,
	return 0;
}

static int atl_get_ts_info(struct net_device *ndev,
			   struct ethtool_ts_info *info)
{
	struct atl_nic *nic = netdev_priv(ndev);
	struct ptp_clock *ptp_clock;

	ethtool_op_get_ts_info(ndev, info);

	if (!nic->ptp)
		return 0;

	info->so_timestamping |=
		SOF_TIMESTAMPING_TX_HARDWARE |
		SOF_TIMESTAMPING_RX_HARDWARE |
		SOF_TIMESTAMPING_RAW_HARDWARE;

	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
			 BIT(HWTSTAMP_TX_ON);

	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);

	info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
			    BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
			    BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);

	ptp_clock = atl_ptp_get_ptp_clock(nic);
	if (ptp_clock)
		info->phc_index = ptp_clock_index(ptp_clock);

	return 0;
}

struct atl_rxf_flt_desc {
	int base;
	int max;
@@ -2360,7 +2395,7 @@ static void atl_rxf_update_flex(struct atl_nic *nic, int idx)
	}
}

static const struct atl_rxf_flt_desc atl_rxf_descs[] = {
static struct atl_rxf_flt_desc atl_rxf_descs[] = {
	{
		.base = ATL_RXF_VLAN_BASE,
		.max = ATL_RXF_VLAN_MAX,
@@ -2408,6 +2443,46 @@ static const struct atl_rxf_flt_desc atl_rxf_descs[] = {
	},
};

s8 atl_reserve_filter(enum atl_rxf_type type)
{
	switch (type) {
	case ATL_RXF_ETYPE:
		WARN_ONCE(atl_rxf_descs[type].max != ATL_RXF_ETYPE_MAX,
			  "already reserved");
		atl_rxf_descs[type].max--;
		return atl_rxf_descs[type].max;
	case ATL_RXF_NTUPLE:
		WARN_ONCE(atl_rxf_descs[type].max != ATL_RXF_NTUPLE_MAX,
			  "already reserved");
		atl_rxf_descs[type].max--;
		return atl_rxf_descs[type].max;
	default:
		WARN_ONCE(true, "unexpected type");
		break;
	}

	return -1;
}

void atl_release_filter(enum atl_rxf_type type)
{
	switch (type) {
	case ATL_RXF_ETYPE:
		WARN_ONCE(atl_rxf_descs[type].max == ATL_RXF_ETYPE_MAX,
			  "already released");
		atl_rxf_descs[type].max++;
		break;
	case ATL_RXF_NTUPLE:
		WARN_ONCE(atl_rxf_descs[type].max == ATL_RXF_NTUPLE_MAX,
			  "already released");
		atl_rxf_descs[type].max++;
		break;
	default:
		WARN_ONCE(true, "unexpected type");
		break;
	}
}

static uint32_t *atl_rxf_cmd(const struct atl_rxf_flt_desc *desc,
	struct atl_nic *nic)
{
@@ -2863,6 +2938,7 @@ const struct ethtool_ops atl_ethtool_ops = {
	.set_priv_flags = atl_set_priv_flags,
	.get_coalesce = atl_get_coalesce,
	.set_coalesce = atl_set_coalesce,
	.get_ts_info = atl_get_ts_info,
	.get_wol = atl_get_wol,
	.set_wol = atl_set_wol,
	.begin = atl_ethtool_begin,
Loading