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