18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/* 10G controller driver for Samsung SoCs
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2013 Samsung Electronics Co., Ltd.
58c2ecf20Sopenharmony_ci *		http://www.samsung.com
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/bitops.h>
138c2ecf20Sopenharmony_ci#include <linux/export.h>
148c2ecf20Sopenharmony_ci#include <linux/io.h>
158c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
168c2ecf20Sopenharmony_ci#include <linux/phy.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "sxgbe_common.h"
198c2ecf20Sopenharmony_ci#include "sxgbe_dma.h"
208c2ecf20Sopenharmony_ci#include "sxgbe_desc.h"
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/* DMA TX descriptor ring initialization */
238c2ecf20Sopenharmony_cistatic void sxgbe_init_tx_desc(struct sxgbe_tx_norm_desc *p)
248c2ecf20Sopenharmony_ci{
258c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.own_bit = 0;
268c2ecf20Sopenharmony_ci}
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistatic void sxgbe_tx_desc_enable_tse(struct sxgbe_tx_norm_desc *p, u8 is_tse,
298c2ecf20Sopenharmony_ci				     u32 total_hdr_len, u32 tcp_hdr_len,
308c2ecf20Sopenharmony_ci				     u32 tcp_payload_len)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.tse_bit = is_tse;
338c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.buf1_size = total_hdr_len;
348c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.tcp_hdr_len = tcp_hdr_len / 4;
358c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.tx_pkt_len.tcp_payload_len  = tcp_payload_len;
368c2ecf20Sopenharmony_ci}
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci/* Assign buffer lengths for descriptor */
398c2ecf20Sopenharmony_cistatic void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd,
408c2ecf20Sopenharmony_ci				  int buf1_len, int pkt_len, int cksum)
418c2ecf20Sopenharmony_ci{
428c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.first_desc = is_fd;
438c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.buf1_size = buf1_len;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.tx_pkt_len.pkt_len.total_pkt_len = pkt_len;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	if (cksum)
488c2ecf20Sopenharmony_ci		p->tdes23.tx_rd_des23.cksum_ctl = cic_full;
498c2ecf20Sopenharmony_ci}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci/* Set VLAN control information */
528c2ecf20Sopenharmony_cistatic void sxgbe_tx_vlanctl_desc(struct sxgbe_tx_norm_desc *p, int vlan_ctl)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.vlan_tag_ctl = vlan_ctl;
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci/* Set the owner of Normal descriptor */
588c2ecf20Sopenharmony_cistatic void sxgbe_set_tx_owner(struct sxgbe_tx_norm_desc *p)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.own_bit = 1;
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci/* Get the owner of Normal descriptor */
648c2ecf20Sopenharmony_cistatic int sxgbe_get_tx_owner(struct sxgbe_tx_norm_desc *p)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	return p->tdes23.tx_rd_des23.own_bit;
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/* Invoked by the xmit function to close the tx descriptor */
708c2ecf20Sopenharmony_cistatic void sxgbe_close_tx_desc(struct sxgbe_tx_norm_desc *p)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.last_desc = 1;
738c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.int_on_com = 1;
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci/* Clean the tx descriptor as soon as the tx irq is received */
778c2ecf20Sopenharmony_cistatic void sxgbe_release_tx_desc(struct sxgbe_tx_norm_desc *p)
788c2ecf20Sopenharmony_ci{
798c2ecf20Sopenharmony_ci	memset(p, 0, sizeof(*p));
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/* Clear interrupt on tx frame completion. When this bit is
838c2ecf20Sopenharmony_ci * set an interrupt happens as soon as the frame is transmitted
848c2ecf20Sopenharmony_ci */
858c2ecf20Sopenharmony_cistatic void sxgbe_clear_tx_ic(struct sxgbe_tx_norm_desc *p)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.int_on_com = 0;
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci/* Last tx segment reports the transmit status */
918c2ecf20Sopenharmony_cistatic int sxgbe_get_tx_ls(struct sxgbe_tx_norm_desc *p)
928c2ecf20Sopenharmony_ci{
938c2ecf20Sopenharmony_ci	return p->tdes23.tx_rd_des23.last_desc;
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/* Get the buffer size from the descriptor */
978c2ecf20Sopenharmony_cistatic int sxgbe_get_tx_len(struct sxgbe_tx_norm_desc *p)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	return p->tdes23.tx_rd_des23.buf1_size;
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/* Set tx timestamp enable bit */
1038c2ecf20Sopenharmony_cistatic void sxgbe_tx_enable_tstamp(struct sxgbe_tx_norm_desc *p)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	p->tdes23.tx_rd_des23.timestmp_enable = 1;
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci/* get tx timestamp status */
1098c2ecf20Sopenharmony_cistatic int sxgbe_get_tx_timestamp_status(struct sxgbe_tx_norm_desc *p)
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci	return p->tdes23.tx_rd_des23.timestmp_enable;
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci/* TX Context Descripto Specific */
1158c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_set_ctxt(struct sxgbe_tx_ctxt_desc *p)
1168c2ecf20Sopenharmony_ci{
1178c2ecf20Sopenharmony_ci	p->ctxt_bit = 1;
1188c2ecf20Sopenharmony_ci}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci/* Set the owner of TX context descriptor */
1218c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_set_owner(struct sxgbe_tx_ctxt_desc *p)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	p->own_bit = 1;
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci/* Get the owner of TX context descriptor */
1278c2ecf20Sopenharmony_cistatic int sxgbe_tx_ctxt_desc_get_owner(struct sxgbe_tx_ctxt_desc *p)
1288c2ecf20Sopenharmony_ci{
1298c2ecf20Sopenharmony_ci	return p->own_bit;
1308c2ecf20Sopenharmony_ci}
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci/* Set TX mss in TX context Descriptor */
1338c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_set_mss(struct sxgbe_tx_ctxt_desc *p, u16 mss)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	p->maxseg_size = mss;
1368c2ecf20Sopenharmony_ci}
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci/* Get TX mss from TX context Descriptor */
1398c2ecf20Sopenharmony_cistatic int sxgbe_tx_ctxt_desc_get_mss(struct sxgbe_tx_ctxt_desc *p)
1408c2ecf20Sopenharmony_ci{
1418c2ecf20Sopenharmony_ci	return p->maxseg_size;
1428c2ecf20Sopenharmony_ci}
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci/* Set TX tcmssv in TX context Descriptor */
1458c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_set_tcmssv(struct sxgbe_tx_ctxt_desc *p)
1468c2ecf20Sopenharmony_ci{
1478c2ecf20Sopenharmony_ci	p->tcmssv = 1;
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci/* Reset TX ostc in TX context Descriptor */
1518c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_reset_ostc(struct sxgbe_tx_ctxt_desc *p)
1528c2ecf20Sopenharmony_ci{
1538c2ecf20Sopenharmony_ci	p->ostc = 0;
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci/* Set IVLAN information */
1578c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_set_ivlantag(struct sxgbe_tx_ctxt_desc *p,
1588c2ecf20Sopenharmony_ci					    int is_ivlanvalid, int ivlan_tag,
1598c2ecf20Sopenharmony_ci					    int ivlan_ctl)
1608c2ecf20Sopenharmony_ci{
1618c2ecf20Sopenharmony_ci	if (is_ivlanvalid) {
1628c2ecf20Sopenharmony_ci		p->ivlan_tag_valid = is_ivlanvalid;
1638c2ecf20Sopenharmony_ci		p->ivlan_tag = ivlan_tag;
1648c2ecf20Sopenharmony_ci		p->ivlan_tag_ctl = ivlan_ctl;
1658c2ecf20Sopenharmony_ci	}
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci/* Return IVLAN Tag */
1698c2ecf20Sopenharmony_cistatic int sxgbe_tx_ctxt_desc_get_ivlantag(struct sxgbe_tx_ctxt_desc *p)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	return p->ivlan_tag;
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/* Set VLAN Tag */
1758c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_set_vlantag(struct sxgbe_tx_ctxt_desc *p,
1768c2ecf20Sopenharmony_ci					   int is_vlanvalid, int vlan_tag)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	if (is_vlanvalid) {
1798c2ecf20Sopenharmony_ci		p->vltag_valid = is_vlanvalid;
1808c2ecf20Sopenharmony_ci		p->vlan_tag = vlan_tag;
1818c2ecf20Sopenharmony_ci	}
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci/* Return VLAN Tag */
1858c2ecf20Sopenharmony_cistatic int sxgbe_tx_ctxt_desc_get_vlantag(struct sxgbe_tx_ctxt_desc *p)
1868c2ecf20Sopenharmony_ci{
1878c2ecf20Sopenharmony_ci	return p->vlan_tag;
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci/* Set Time stamp */
1918c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_set_tstamp(struct sxgbe_tx_ctxt_desc *p,
1928c2ecf20Sopenharmony_ci					  u8 ostc_enable, u64 tstamp)
1938c2ecf20Sopenharmony_ci{
1948c2ecf20Sopenharmony_ci	if (ostc_enable) {
1958c2ecf20Sopenharmony_ci		p->ostc = ostc_enable;
1968c2ecf20Sopenharmony_ci		p->tstamp_lo = (u32) tstamp;
1978c2ecf20Sopenharmony_ci		p->tstamp_hi = (u32) (tstamp>>32);
1988c2ecf20Sopenharmony_ci	}
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ci/* Close TX context descriptor */
2018c2ecf20Sopenharmony_cistatic void sxgbe_tx_ctxt_desc_close(struct sxgbe_tx_ctxt_desc *p)
2028c2ecf20Sopenharmony_ci{
2038c2ecf20Sopenharmony_ci	p->own_bit = 1;
2048c2ecf20Sopenharmony_ci}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/* WB status of context descriptor */
2078c2ecf20Sopenharmony_cistatic int sxgbe_tx_ctxt_desc_get_cde(struct sxgbe_tx_ctxt_desc *p)
2088c2ecf20Sopenharmony_ci{
2098c2ecf20Sopenharmony_ci	return p->ctxt_desc_err;
2108c2ecf20Sopenharmony_ci}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci/* DMA RX descriptor ring initialization */
2138c2ecf20Sopenharmony_cistatic void sxgbe_init_rx_desc(struct sxgbe_rx_norm_desc *p, int disable_rx_ic,
2148c2ecf20Sopenharmony_ci			       int mode, int end)
2158c2ecf20Sopenharmony_ci{
2168c2ecf20Sopenharmony_ci	p->rdes23.rx_rd_des23.own_bit = 1;
2178c2ecf20Sopenharmony_ci	if (disable_rx_ic)
2188c2ecf20Sopenharmony_ci		p->rdes23.rx_rd_des23.int_on_com = disable_rx_ic;
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci/* Get RX own bit */
2228c2ecf20Sopenharmony_cistatic int sxgbe_get_rx_owner(struct sxgbe_rx_norm_desc *p)
2238c2ecf20Sopenharmony_ci{
2248c2ecf20Sopenharmony_ci	return p->rdes23.rx_rd_des23.own_bit;
2258c2ecf20Sopenharmony_ci}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci/* Set RX own bit */
2288c2ecf20Sopenharmony_cistatic void sxgbe_set_rx_owner(struct sxgbe_rx_norm_desc *p)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	p->rdes23.rx_rd_des23.own_bit = 1;
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci/* Set Interrupt on completion bit */
2348c2ecf20Sopenharmony_cistatic void sxgbe_set_rx_int_on_com(struct sxgbe_rx_norm_desc *p)
2358c2ecf20Sopenharmony_ci{
2368c2ecf20Sopenharmony_ci	p->rdes23.rx_rd_des23.int_on_com = 1;
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci/* Get the receive frame size */
2408c2ecf20Sopenharmony_cistatic int sxgbe_get_rx_frame_len(struct sxgbe_rx_norm_desc *p)
2418c2ecf20Sopenharmony_ci{
2428c2ecf20Sopenharmony_ci	return p->rdes23.rx_wb_des23.pkt_len;
2438c2ecf20Sopenharmony_ci}
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci/* Return first Descriptor status */
2468c2ecf20Sopenharmony_cistatic int sxgbe_get_rx_fd_status(struct sxgbe_rx_norm_desc *p)
2478c2ecf20Sopenharmony_ci{
2488c2ecf20Sopenharmony_ci	return p->rdes23.rx_wb_des23.first_desc;
2498c2ecf20Sopenharmony_ci}
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci/* Return Last Descriptor status */
2528c2ecf20Sopenharmony_cistatic int sxgbe_get_rx_ld_status(struct sxgbe_rx_norm_desc *p)
2538c2ecf20Sopenharmony_ci{
2548c2ecf20Sopenharmony_ci	return p->rdes23.rx_wb_des23.last_desc;
2558c2ecf20Sopenharmony_ci}
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci/* Return the RX status looking at the WB fields */
2598c2ecf20Sopenharmony_cistatic int sxgbe_rx_wbstatus(struct sxgbe_rx_norm_desc *p,
2608c2ecf20Sopenharmony_ci			     struct sxgbe_extra_stats *x, int *checksum)
2618c2ecf20Sopenharmony_ci{
2628c2ecf20Sopenharmony_ci	int status = 0;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	*checksum = CHECKSUM_UNNECESSARY;
2658c2ecf20Sopenharmony_ci	if (p->rdes23.rx_wb_des23.err_summary) {
2668c2ecf20Sopenharmony_ci		switch (p->rdes23.rx_wb_des23.err_l2_type) {
2678c2ecf20Sopenharmony_ci		case RX_GMII_ERR:
2688c2ecf20Sopenharmony_ci			status = -EINVAL;
2698c2ecf20Sopenharmony_ci			x->rx_code_gmii_err++;
2708c2ecf20Sopenharmony_ci			break;
2718c2ecf20Sopenharmony_ci		case RX_WATCHDOG_ERR:
2728c2ecf20Sopenharmony_ci			status = -EINVAL;
2738c2ecf20Sopenharmony_ci			x->rx_watchdog_err++;
2748c2ecf20Sopenharmony_ci			break;
2758c2ecf20Sopenharmony_ci		case RX_CRC_ERR:
2768c2ecf20Sopenharmony_ci			status = -EINVAL;
2778c2ecf20Sopenharmony_ci			x->rx_crc_err++;
2788c2ecf20Sopenharmony_ci			break;
2798c2ecf20Sopenharmony_ci		case RX_GAINT_ERR:
2808c2ecf20Sopenharmony_ci			status = -EINVAL;
2818c2ecf20Sopenharmony_ci			x->rx_gaint_pkt_err++;
2828c2ecf20Sopenharmony_ci			break;
2838c2ecf20Sopenharmony_ci		case RX_IP_HDR_ERR:
2848c2ecf20Sopenharmony_ci			*checksum = CHECKSUM_NONE;
2858c2ecf20Sopenharmony_ci			x->ip_hdr_err++;
2868c2ecf20Sopenharmony_ci			break;
2878c2ecf20Sopenharmony_ci		case RX_PAYLOAD_ERR:
2888c2ecf20Sopenharmony_ci			*checksum = CHECKSUM_NONE;
2898c2ecf20Sopenharmony_ci			x->ip_payload_err++;
2908c2ecf20Sopenharmony_ci			break;
2918c2ecf20Sopenharmony_ci		case RX_OVERFLOW_ERR:
2928c2ecf20Sopenharmony_ci			status = -EINVAL;
2938c2ecf20Sopenharmony_ci			x->overflow_error++;
2948c2ecf20Sopenharmony_ci			break;
2958c2ecf20Sopenharmony_ci		default:
2968c2ecf20Sopenharmony_ci			pr_err("Invalid Error type\n");
2978c2ecf20Sopenharmony_ci			break;
2988c2ecf20Sopenharmony_ci		}
2998c2ecf20Sopenharmony_ci	} else {
3008c2ecf20Sopenharmony_ci		switch (p->rdes23.rx_wb_des23.err_l2_type) {
3018c2ecf20Sopenharmony_ci		case RX_LEN_PKT:
3028c2ecf20Sopenharmony_ci			x->len_pkt++;
3038c2ecf20Sopenharmony_ci			break;
3048c2ecf20Sopenharmony_ci		case RX_MACCTL_PKT:
3058c2ecf20Sopenharmony_ci			x->mac_ctl_pkt++;
3068c2ecf20Sopenharmony_ci			break;
3078c2ecf20Sopenharmony_ci		case RX_DCBCTL_PKT:
3088c2ecf20Sopenharmony_ci			x->dcb_ctl_pkt++;
3098c2ecf20Sopenharmony_ci			break;
3108c2ecf20Sopenharmony_ci		case RX_ARP_PKT:
3118c2ecf20Sopenharmony_ci			x->arp_pkt++;
3128c2ecf20Sopenharmony_ci			break;
3138c2ecf20Sopenharmony_ci		case RX_OAM_PKT:
3148c2ecf20Sopenharmony_ci			x->oam_pkt++;
3158c2ecf20Sopenharmony_ci			break;
3168c2ecf20Sopenharmony_ci		case RX_UNTAG_PKT:
3178c2ecf20Sopenharmony_ci			x->untag_okt++;
3188c2ecf20Sopenharmony_ci			break;
3198c2ecf20Sopenharmony_ci		case RX_OTHER_PKT:
3208c2ecf20Sopenharmony_ci			x->other_pkt++;
3218c2ecf20Sopenharmony_ci			break;
3228c2ecf20Sopenharmony_ci		case RX_SVLAN_PKT:
3238c2ecf20Sopenharmony_ci			x->svlan_tag_pkt++;
3248c2ecf20Sopenharmony_ci			break;
3258c2ecf20Sopenharmony_ci		case RX_CVLAN_PKT:
3268c2ecf20Sopenharmony_ci			x->cvlan_tag_pkt++;
3278c2ecf20Sopenharmony_ci			break;
3288c2ecf20Sopenharmony_ci		case RX_DVLAN_OCVLAN_ICVLAN_PKT:
3298c2ecf20Sopenharmony_ci			x->dvlan_ocvlan_icvlan_pkt++;
3308c2ecf20Sopenharmony_ci			break;
3318c2ecf20Sopenharmony_ci		case RX_DVLAN_OSVLAN_ISVLAN_PKT:
3328c2ecf20Sopenharmony_ci			x->dvlan_osvlan_isvlan_pkt++;
3338c2ecf20Sopenharmony_ci			break;
3348c2ecf20Sopenharmony_ci		case RX_DVLAN_OSVLAN_ICVLAN_PKT:
3358c2ecf20Sopenharmony_ci			x->dvlan_osvlan_icvlan_pkt++;
3368c2ecf20Sopenharmony_ci			break;
3378c2ecf20Sopenharmony_ci		case RX_DVLAN_OCVLAN_ISVLAN_PKT:
3388c2ecf20Sopenharmony_ci			x->dvlan_ocvlan_icvlan_pkt++;
3398c2ecf20Sopenharmony_ci			break;
3408c2ecf20Sopenharmony_ci		default:
3418c2ecf20Sopenharmony_ci			pr_err("Invalid L2 Packet type\n");
3428c2ecf20Sopenharmony_ci			break;
3438c2ecf20Sopenharmony_ci		}
3448c2ecf20Sopenharmony_ci	}
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci	/* L3/L4 Pkt type */
3478c2ecf20Sopenharmony_ci	switch (p->rdes23.rx_wb_des23.layer34_pkt_type) {
3488c2ecf20Sopenharmony_ci	case RX_NOT_IP_PKT:
3498c2ecf20Sopenharmony_ci		x->not_ip_pkt++;
3508c2ecf20Sopenharmony_ci		break;
3518c2ecf20Sopenharmony_ci	case RX_IPV4_TCP_PKT:
3528c2ecf20Sopenharmony_ci		x->ip4_tcp_pkt++;
3538c2ecf20Sopenharmony_ci		break;
3548c2ecf20Sopenharmony_ci	case RX_IPV4_UDP_PKT:
3558c2ecf20Sopenharmony_ci		x->ip4_udp_pkt++;
3568c2ecf20Sopenharmony_ci		break;
3578c2ecf20Sopenharmony_ci	case RX_IPV4_ICMP_PKT:
3588c2ecf20Sopenharmony_ci		x->ip4_icmp_pkt++;
3598c2ecf20Sopenharmony_ci		break;
3608c2ecf20Sopenharmony_ci	case RX_IPV4_UNKNOWN_PKT:
3618c2ecf20Sopenharmony_ci		x->ip4_unknown_pkt++;
3628c2ecf20Sopenharmony_ci		break;
3638c2ecf20Sopenharmony_ci	case RX_IPV6_TCP_PKT:
3648c2ecf20Sopenharmony_ci		x->ip6_tcp_pkt++;
3658c2ecf20Sopenharmony_ci		break;
3668c2ecf20Sopenharmony_ci	case RX_IPV6_UDP_PKT:
3678c2ecf20Sopenharmony_ci		x->ip6_udp_pkt++;
3688c2ecf20Sopenharmony_ci		break;
3698c2ecf20Sopenharmony_ci	case RX_IPV6_ICMP_PKT:
3708c2ecf20Sopenharmony_ci		x->ip6_icmp_pkt++;
3718c2ecf20Sopenharmony_ci		break;
3728c2ecf20Sopenharmony_ci	case RX_IPV6_UNKNOWN_PKT:
3738c2ecf20Sopenharmony_ci		x->ip6_unknown_pkt++;
3748c2ecf20Sopenharmony_ci		break;
3758c2ecf20Sopenharmony_ci	default:
3768c2ecf20Sopenharmony_ci		pr_err("Invalid L3/L4 Packet type\n");
3778c2ecf20Sopenharmony_ci		break;
3788c2ecf20Sopenharmony_ci	}
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	/* Filter */
3818c2ecf20Sopenharmony_ci	if (p->rdes23.rx_wb_des23.vlan_filter_match)
3828c2ecf20Sopenharmony_ci		x->vlan_filter_match++;
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci	if (p->rdes23.rx_wb_des23.sa_filter_fail) {
3858c2ecf20Sopenharmony_ci		status = -EINVAL;
3868c2ecf20Sopenharmony_ci		x->sa_filter_fail++;
3878c2ecf20Sopenharmony_ci	}
3888c2ecf20Sopenharmony_ci	if (p->rdes23.rx_wb_des23.da_filter_fail) {
3898c2ecf20Sopenharmony_ci		status = -EINVAL;
3908c2ecf20Sopenharmony_ci		x->da_filter_fail++;
3918c2ecf20Sopenharmony_ci	}
3928c2ecf20Sopenharmony_ci	if (p->rdes23.rx_wb_des23.hash_filter_pass)
3938c2ecf20Sopenharmony_ci		x->hash_filter_pass++;
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	if (p->rdes23.rx_wb_des23.l3_filter_match)
3968c2ecf20Sopenharmony_ci		x->l3_filter_match++;
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_ci	if (p->rdes23.rx_wb_des23.l4_filter_match)
3998c2ecf20Sopenharmony_ci		x->l4_filter_match++;
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci	return status;
4028c2ecf20Sopenharmony_ci}
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci/* Get own bit of context descriptor */
4058c2ecf20Sopenharmony_cistatic int sxgbe_get_rx_ctxt_owner(struct sxgbe_rx_ctxt_desc *p)
4068c2ecf20Sopenharmony_ci{
4078c2ecf20Sopenharmony_ci	return p->own_bit;
4088c2ecf20Sopenharmony_ci}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci/* Set own bit for context descriptor */
4118c2ecf20Sopenharmony_cistatic void sxgbe_set_ctxt_rx_owner(struct sxgbe_rx_ctxt_desc *p)
4128c2ecf20Sopenharmony_ci{
4138c2ecf20Sopenharmony_ci	p->own_bit = 1;
4148c2ecf20Sopenharmony_ci}
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ci/* Return the reception status looking at Context control information */
4188c2ecf20Sopenharmony_cistatic void sxgbe_rx_ctxt_wbstatus(struct sxgbe_rx_ctxt_desc *p,
4198c2ecf20Sopenharmony_ci				   struct sxgbe_extra_stats *x)
4208c2ecf20Sopenharmony_ci{
4218c2ecf20Sopenharmony_ci	if (p->tstamp_dropped)
4228c2ecf20Sopenharmony_ci		x->timestamp_dropped++;
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci	/* ptp */
4258c2ecf20Sopenharmony_ci	if (p->ptp_msgtype == RX_NO_PTP)
4268c2ecf20Sopenharmony_ci		x->rx_msg_type_no_ptp++;
4278c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_SYNC)
4288c2ecf20Sopenharmony_ci		x->rx_ptp_type_sync++;
4298c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_FOLLOW_UP)
4308c2ecf20Sopenharmony_ci		x->rx_ptp_type_follow_up++;
4318c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_DELAY_REQ)
4328c2ecf20Sopenharmony_ci		x->rx_ptp_type_delay_req++;
4338c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_DELAY_RESP)
4348c2ecf20Sopenharmony_ci		x->rx_ptp_type_delay_resp++;
4358c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_PDELAY_REQ)
4368c2ecf20Sopenharmony_ci		x->rx_ptp_type_pdelay_req++;
4378c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_PDELAY_RESP)
4388c2ecf20Sopenharmony_ci		x->rx_ptp_type_pdelay_resp++;
4398c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_PDELAY_FOLLOW_UP)
4408c2ecf20Sopenharmony_ci		x->rx_ptp_type_pdelay_follow_up++;
4418c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_ANNOUNCE)
4428c2ecf20Sopenharmony_ci		x->rx_ptp_announce++;
4438c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_MGMT)
4448c2ecf20Sopenharmony_ci		x->rx_ptp_mgmt++;
4458c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_SIGNAL)
4468c2ecf20Sopenharmony_ci		x->rx_ptp_signal++;
4478c2ecf20Sopenharmony_ci	else if (p->ptp_msgtype == RX_PTP_RESV_MSG)
4488c2ecf20Sopenharmony_ci		x->rx_ptp_resv_msg_type++;
4498c2ecf20Sopenharmony_ci}
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci/* Get rx timestamp status */
4528c2ecf20Sopenharmony_cistatic int sxgbe_get_rx_ctxt_tstamp_status(struct sxgbe_rx_ctxt_desc *p)
4538c2ecf20Sopenharmony_ci{
4548c2ecf20Sopenharmony_ci	if ((p->tstamp_hi == 0xffffffff) && (p->tstamp_lo == 0xffffffff)) {
4558c2ecf20Sopenharmony_ci		pr_err("Time stamp corrupted\n");
4568c2ecf20Sopenharmony_ci		return 0;
4578c2ecf20Sopenharmony_ci	}
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci	return p->tstamp_available;
4608c2ecf20Sopenharmony_ci}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_cistatic u64 sxgbe_get_rx_timestamp(struct sxgbe_rx_ctxt_desc *p)
4648c2ecf20Sopenharmony_ci{
4658c2ecf20Sopenharmony_ci	u64 ns;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	ns = p->tstamp_lo;
4688c2ecf20Sopenharmony_ci	ns |= ((u64)p->tstamp_hi) << 32;
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	return ns;
4718c2ecf20Sopenharmony_ci}
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_cistatic const struct sxgbe_desc_ops desc_ops = {
4748c2ecf20Sopenharmony_ci	.init_tx_desc			= sxgbe_init_tx_desc,
4758c2ecf20Sopenharmony_ci	.tx_desc_enable_tse		= sxgbe_tx_desc_enable_tse,
4768c2ecf20Sopenharmony_ci	.prepare_tx_desc		= sxgbe_prepare_tx_desc,
4778c2ecf20Sopenharmony_ci	.tx_vlanctl_desc		= sxgbe_tx_vlanctl_desc,
4788c2ecf20Sopenharmony_ci	.set_tx_owner			= sxgbe_set_tx_owner,
4798c2ecf20Sopenharmony_ci	.get_tx_owner			= sxgbe_get_tx_owner,
4808c2ecf20Sopenharmony_ci	.close_tx_desc			= sxgbe_close_tx_desc,
4818c2ecf20Sopenharmony_ci	.release_tx_desc		= sxgbe_release_tx_desc,
4828c2ecf20Sopenharmony_ci	.clear_tx_ic			= sxgbe_clear_tx_ic,
4838c2ecf20Sopenharmony_ci	.get_tx_ls			= sxgbe_get_tx_ls,
4848c2ecf20Sopenharmony_ci	.get_tx_len			= sxgbe_get_tx_len,
4858c2ecf20Sopenharmony_ci	.tx_enable_tstamp		= sxgbe_tx_enable_tstamp,
4868c2ecf20Sopenharmony_ci	.get_tx_timestamp_status	= sxgbe_get_tx_timestamp_status,
4878c2ecf20Sopenharmony_ci	.tx_ctxt_desc_set_ctxt		= sxgbe_tx_ctxt_desc_set_ctxt,
4888c2ecf20Sopenharmony_ci	.tx_ctxt_desc_set_owner		= sxgbe_tx_ctxt_desc_set_owner,
4898c2ecf20Sopenharmony_ci	.get_tx_ctxt_owner		= sxgbe_tx_ctxt_desc_get_owner,
4908c2ecf20Sopenharmony_ci	.tx_ctxt_desc_set_mss		= sxgbe_tx_ctxt_desc_set_mss,
4918c2ecf20Sopenharmony_ci	.tx_ctxt_desc_get_mss		= sxgbe_tx_ctxt_desc_get_mss,
4928c2ecf20Sopenharmony_ci	.tx_ctxt_desc_set_tcmssv	= sxgbe_tx_ctxt_desc_set_tcmssv,
4938c2ecf20Sopenharmony_ci	.tx_ctxt_desc_reset_ostc	= sxgbe_tx_ctxt_desc_reset_ostc,
4948c2ecf20Sopenharmony_ci	.tx_ctxt_desc_set_ivlantag	= sxgbe_tx_ctxt_desc_set_ivlantag,
4958c2ecf20Sopenharmony_ci	.tx_ctxt_desc_get_ivlantag	= sxgbe_tx_ctxt_desc_get_ivlantag,
4968c2ecf20Sopenharmony_ci	.tx_ctxt_desc_set_vlantag	= sxgbe_tx_ctxt_desc_set_vlantag,
4978c2ecf20Sopenharmony_ci	.tx_ctxt_desc_get_vlantag	= sxgbe_tx_ctxt_desc_get_vlantag,
4988c2ecf20Sopenharmony_ci	.tx_ctxt_set_tstamp		= sxgbe_tx_ctxt_desc_set_tstamp,
4998c2ecf20Sopenharmony_ci	.close_tx_ctxt_desc		= sxgbe_tx_ctxt_desc_close,
5008c2ecf20Sopenharmony_ci	.get_tx_ctxt_cde		= sxgbe_tx_ctxt_desc_get_cde,
5018c2ecf20Sopenharmony_ci	.init_rx_desc			= sxgbe_init_rx_desc,
5028c2ecf20Sopenharmony_ci	.get_rx_owner			= sxgbe_get_rx_owner,
5038c2ecf20Sopenharmony_ci	.set_rx_owner			= sxgbe_set_rx_owner,
5048c2ecf20Sopenharmony_ci	.set_rx_int_on_com		= sxgbe_set_rx_int_on_com,
5058c2ecf20Sopenharmony_ci	.get_rx_frame_len		= sxgbe_get_rx_frame_len,
5068c2ecf20Sopenharmony_ci	.get_rx_fd_status		= sxgbe_get_rx_fd_status,
5078c2ecf20Sopenharmony_ci	.get_rx_ld_status		= sxgbe_get_rx_ld_status,
5088c2ecf20Sopenharmony_ci	.rx_wbstatus			= sxgbe_rx_wbstatus,
5098c2ecf20Sopenharmony_ci	.get_rx_ctxt_owner		= sxgbe_get_rx_ctxt_owner,
5108c2ecf20Sopenharmony_ci	.set_rx_ctxt_owner		= sxgbe_set_ctxt_rx_owner,
5118c2ecf20Sopenharmony_ci	.rx_ctxt_wbstatus		= sxgbe_rx_ctxt_wbstatus,
5128c2ecf20Sopenharmony_ci	.get_rx_ctxt_tstamp_status	= sxgbe_get_rx_ctxt_tstamp_status,
5138c2ecf20Sopenharmony_ci	.get_timestamp			= sxgbe_get_rx_timestamp,
5148c2ecf20Sopenharmony_ci};
5158c2ecf20Sopenharmony_ci
5168c2ecf20Sopenharmony_ciconst struct sxgbe_desc_ops *sxgbe_get_desc_ops(void)
5178c2ecf20Sopenharmony_ci{
5188c2ecf20Sopenharmony_ci	return &desc_ops;
5198c2ecf20Sopenharmony_ci}
520