cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sxgbe_desc.c (13137B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* 10G controller driver for Samsung SoCs
      3 *
      4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
      5 *		http://www.samsung.com
      6 *
      7 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
      8 */
      9
     10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     11
     12#include <linux/bitops.h>
     13#include <linux/export.h>
     14#include <linux/io.h>
     15#include <linux/netdevice.h>
     16#include <linux/phy.h>
     17
     18#include "sxgbe_common.h"
     19#include "sxgbe_dma.h"
     20#include "sxgbe_desc.h"
     21
     22/* DMA TX descriptor ring initialization */
     23static void sxgbe_init_tx_desc(struct sxgbe_tx_norm_desc *p)
     24{
     25	p->tdes23.tx_rd_des23.own_bit = 0;
     26}
     27
     28static void sxgbe_tx_desc_enable_tse(struct sxgbe_tx_norm_desc *p, u8 is_tse,
     29				     u32 total_hdr_len, u32 tcp_hdr_len,
     30				     u32 tcp_payload_len)
     31{
     32	p->tdes23.tx_rd_des23.tse_bit = is_tse;
     33	p->tdes23.tx_rd_des23.buf1_size = total_hdr_len;
     34	p->tdes23.tx_rd_des23.tcp_hdr_len = tcp_hdr_len / 4;
     35	p->tdes23.tx_rd_des23.tx_pkt_len.tcp_payload_len  = tcp_payload_len;
     36}
     37
     38/* Assign buffer lengths for descriptor */
     39static void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd,
     40				  int buf1_len, int pkt_len, int cksum)
     41{
     42	p->tdes23.tx_rd_des23.first_desc = is_fd;
     43	p->tdes23.tx_rd_des23.buf1_size = buf1_len;
     44
     45	p->tdes23.tx_rd_des23.tx_pkt_len.pkt_len.total_pkt_len = pkt_len;
     46
     47	if (cksum)
     48		p->tdes23.tx_rd_des23.cksum_ctl = cic_full;
     49}
     50
     51/* Set VLAN control information */
     52static void sxgbe_tx_vlanctl_desc(struct sxgbe_tx_norm_desc *p, int vlan_ctl)
     53{
     54	p->tdes23.tx_rd_des23.vlan_tag_ctl = vlan_ctl;
     55}
     56
     57/* Set the owner of Normal descriptor */
     58static void sxgbe_set_tx_owner(struct sxgbe_tx_norm_desc *p)
     59{
     60	p->tdes23.tx_rd_des23.own_bit = 1;
     61}
     62
     63/* Get the owner of Normal descriptor */
     64static int sxgbe_get_tx_owner(struct sxgbe_tx_norm_desc *p)
     65{
     66	return p->tdes23.tx_rd_des23.own_bit;
     67}
     68
     69/* Invoked by the xmit function to close the tx descriptor */
     70static void sxgbe_close_tx_desc(struct sxgbe_tx_norm_desc *p)
     71{
     72	p->tdes23.tx_rd_des23.last_desc = 1;
     73	p->tdes23.tx_rd_des23.int_on_com = 1;
     74}
     75
     76/* Clean the tx descriptor as soon as the tx irq is received */
     77static void sxgbe_release_tx_desc(struct sxgbe_tx_norm_desc *p)
     78{
     79	memset(p, 0, sizeof(*p));
     80}
     81
     82/* Clear interrupt on tx frame completion. When this bit is
     83 * set an interrupt happens as soon as the frame is transmitted
     84 */
     85static void sxgbe_clear_tx_ic(struct sxgbe_tx_norm_desc *p)
     86{
     87	p->tdes23.tx_rd_des23.int_on_com = 0;
     88}
     89
     90/* Last tx segment reports the transmit status */
     91static int sxgbe_get_tx_ls(struct sxgbe_tx_norm_desc *p)
     92{
     93	return p->tdes23.tx_rd_des23.last_desc;
     94}
     95
     96/* Get the buffer size from the descriptor */
     97static int sxgbe_get_tx_len(struct sxgbe_tx_norm_desc *p)
     98{
     99	return p->tdes23.tx_rd_des23.buf1_size;
    100}
    101
    102/* Set tx timestamp enable bit */
    103static void sxgbe_tx_enable_tstamp(struct sxgbe_tx_norm_desc *p)
    104{
    105	p->tdes23.tx_rd_des23.timestmp_enable = 1;
    106}
    107
    108/* get tx timestamp status */
    109static int sxgbe_get_tx_timestamp_status(struct sxgbe_tx_norm_desc *p)
    110{
    111	return p->tdes23.tx_rd_des23.timestmp_enable;
    112}
    113
    114/* TX Context Descripto Specific */
    115static void sxgbe_tx_ctxt_desc_set_ctxt(struct sxgbe_tx_ctxt_desc *p)
    116{
    117	p->ctxt_bit = 1;
    118}
    119
    120/* Set the owner of TX context descriptor */
    121static void sxgbe_tx_ctxt_desc_set_owner(struct sxgbe_tx_ctxt_desc *p)
    122{
    123	p->own_bit = 1;
    124}
    125
    126/* Get the owner of TX context descriptor */
    127static int sxgbe_tx_ctxt_desc_get_owner(struct sxgbe_tx_ctxt_desc *p)
    128{
    129	return p->own_bit;
    130}
    131
    132/* Set TX mss in TX context Descriptor */
    133static void sxgbe_tx_ctxt_desc_set_mss(struct sxgbe_tx_ctxt_desc *p, u16 mss)
    134{
    135	p->maxseg_size = mss;
    136}
    137
    138/* Get TX mss from TX context Descriptor */
    139static int sxgbe_tx_ctxt_desc_get_mss(struct sxgbe_tx_ctxt_desc *p)
    140{
    141	return p->maxseg_size;
    142}
    143
    144/* Set TX tcmssv in TX context Descriptor */
    145static void sxgbe_tx_ctxt_desc_set_tcmssv(struct sxgbe_tx_ctxt_desc *p)
    146{
    147	p->tcmssv = 1;
    148}
    149
    150/* Reset TX ostc in TX context Descriptor */
    151static void sxgbe_tx_ctxt_desc_reset_ostc(struct sxgbe_tx_ctxt_desc *p)
    152{
    153	p->ostc = 0;
    154}
    155
    156/* Set IVLAN information */
    157static void sxgbe_tx_ctxt_desc_set_ivlantag(struct sxgbe_tx_ctxt_desc *p,
    158					    int is_ivlanvalid, int ivlan_tag,
    159					    int ivlan_ctl)
    160{
    161	if (is_ivlanvalid) {
    162		p->ivlan_tag_valid = is_ivlanvalid;
    163		p->ivlan_tag = ivlan_tag;
    164		p->ivlan_tag_ctl = ivlan_ctl;
    165	}
    166}
    167
    168/* Return IVLAN Tag */
    169static int sxgbe_tx_ctxt_desc_get_ivlantag(struct sxgbe_tx_ctxt_desc *p)
    170{
    171	return p->ivlan_tag;
    172}
    173
    174/* Set VLAN Tag */
    175static void sxgbe_tx_ctxt_desc_set_vlantag(struct sxgbe_tx_ctxt_desc *p,
    176					   int is_vlanvalid, int vlan_tag)
    177{
    178	if (is_vlanvalid) {
    179		p->vltag_valid = is_vlanvalid;
    180		p->vlan_tag = vlan_tag;
    181	}
    182}
    183
    184/* Return VLAN Tag */
    185static int sxgbe_tx_ctxt_desc_get_vlantag(struct sxgbe_tx_ctxt_desc *p)
    186{
    187	return p->vlan_tag;
    188}
    189
    190/* Set Time stamp */
    191static void sxgbe_tx_ctxt_desc_set_tstamp(struct sxgbe_tx_ctxt_desc *p,
    192					  u8 ostc_enable, u64 tstamp)
    193{
    194	if (ostc_enable) {
    195		p->ostc = ostc_enable;
    196		p->tstamp_lo = (u32) tstamp;
    197		p->tstamp_hi = (u32) (tstamp>>32);
    198	}
    199}
    200/* Close TX context descriptor */
    201static void sxgbe_tx_ctxt_desc_close(struct sxgbe_tx_ctxt_desc *p)
    202{
    203	p->own_bit = 1;
    204}
    205
    206/* WB status of context descriptor */
    207static int sxgbe_tx_ctxt_desc_get_cde(struct sxgbe_tx_ctxt_desc *p)
    208{
    209	return p->ctxt_desc_err;
    210}
    211
    212/* DMA RX descriptor ring initialization */
    213static void sxgbe_init_rx_desc(struct sxgbe_rx_norm_desc *p, int disable_rx_ic,
    214			       int mode, int end)
    215{
    216	p->rdes23.rx_rd_des23.own_bit = 1;
    217	if (disable_rx_ic)
    218		p->rdes23.rx_rd_des23.int_on_com = disable_rx_ic;
    219}
    220
    221/* Get RX own bit */
    222static int sxgbe_get_rx_owner(struct sxgbe_rx_norm_desc *p)
    223{
    224	return p->rdes23.rx_rd_des23.own_bit;
    225}
    226
    227/* Set RX own bit */
    228static void sxgbe_set_rx_owner(struct sxgbe_rx_norm_desc *p)
    229{
    230	p->rdes23.rx_rd_des23.own_bit = 1;
    231}
    232
    233/* Set Interrupt on completion bit */
    234static void sxgbe_set_rx_int_on_com(struct sxgbe_rx_norm_desc *p)
    235{
    236	p->rdes23.rx_rd_des23.int_on_com = 1;
    237}
    238
    239/* Get the receive frame size */
    240static int sxgbe_get_rx_frame_len(struct sxgbe_rx_norm_desc *p)
    241{
    242	return p->rdes23.rx_wb_des23.pkt_len;
    243}
    244
    245/* Return first Descriptor status */
    246static int sxgbe_get_rx_fd_status(struct sxgbe_rx_norm_desc *p)
    247{
    248	return p->rdes23.rx_wb_des23.first_desc;
    249}
    250
    251/* Return Last Descriptor status */
    252static int sxgbe_get_rx_ld_status(struct sxgbe_rx_norm_desc *p)
    253{
    254	return p->rdes23.rx_wb_des23.last_desc;
    255}
    256
    257
    258/* Return the RX status looking at the WB fields */
    259static int sxgbe_rx_wbstatus(struct sxgbe_rx_norm_desc *p,
    260			     struct sxgbe_extra_stats *x, int *checksum)
    261{
    262	int status = 0;
    263
    264	*checksum = CHECKSUM_UNNECESSARY;
    265	if (p->rdes23.rx_wb_des23.err_summary) {
    266		switch (p->rdes23.rx_wb_des23.err_l2_type) {
    267		case RX_GMII_ERR:
    268			status = -EINVAL;
    269			x->rx_code_gmii_err++;
    270			break;
    271		case RX_WATCHDOG_ERR:
    272			status = -EINVAL;
    273			x->rx_watchdog_err++;
    274			break;
    275		case RX_CRC_ERR:
    276			status = -EINVAL;
    277			x->rx_crc_err++;
    278			break;
    279		case RX_GAINT_ERR:
    280			status = -EINVAL;
    281			x->rx_gaint_pkt_err++;
    282			break;
    283		case RX_IP_HDR_ERR:
    284			*checksum = CHECKSUM_NONE;
    285			x->ip_hdr_err++;
    286			break;
    287		case RX_PAYLOAD_ERR:
    288			*checksum = CHECKSUM_NONE;
    289			x->ip_payload_err++;
    290			break;
    291		case RX_OVERFLOW_ERR:
    292			status = -EINVAL;
    293			x->overflow_error++;
    294			break;
    295		default:
    296			pr_err("Invalid Error type\n");
    297			break;
    298		}
    299	} else {
    300		switch (p->rdes23.rx_wb_des23.err_l2_type) {
    301		case RX_LEN_PKT:
    302			x->len_pkt++;
    303			break;
    304		case RX_MACCTL_PKT:
    305			x->mac_ctl_pkt++;
    306			break;
    307		case RX_DCBCTL_PKT:
    308			x->dcb_ctl_pkt++;
    309			break;
    310		case RX_ARP_PKT:
    311			x->arp_pkt++;
    312			break;
    313		case RX_OAM_PKT:
    314			x->oam_pkt++;
    315			break;
    316		case RX_UNTAG_PKT:
    317			x->untag_okt++;
    318			break;
    319		case RX_OTHER_PKT:
    320			x->other_pkt++;
    321			break;
    322		case RX_SVLAN_PKT:
    323			x->svlan_tag_pkt++;
    324			break;
    325		case RX_CVLAN_PKT:
    326			x->cvlan_tag_pkt++;
    327			break;
    328		case RX_DVLAN_OCVLAN_ICVLAN_PKT:
    329			x->dvlan_ocvlan_icvlan_pkt++;
    330			break;
    331		case RX_DVLAN_OSVLAN_ISVLAN_PKT:
    332			x->dvlan_osvlan_isvlan_pkt++;
    333			break;
    334		case RX_DVLAN_OSVLAN_ICVLAN_PKT:
    335			x->dvlan_osvlan_icvlan_pkt++;
    336			break;
    337		case RX_DVLAN_OCVLAN_ISVLAN_PKT:
    338			x->dvlan_ocvlan_icvlan_pkt++;
    339			break;
    340		default:
    341			pr_err("Invalid L2 Packet type\n");
    342			break;
    343		}
    344	}
    345
    346	/* L3/L4 Pkt type */
    347	switch (p->rdes23.rx_wb_des23.layer34_pkt_type) {
    348	case RX_NOT_IP_PKT:
    349		x->not_ip_pkt++;
    350		break;
    351	case RX_IPV4_TCP_PKT:
    352		x->ip4_tcp_pkt++;
    353		break;
    354	case RX_IPV4_UDP_PKT:
    355		x->ip4_udp_pkt++;
    356		break;
    357	case RX_IPV4_ICMP_PKT:
    358		x->ip4_icmp_pkt++;
    359		break;
    360	case RX_IPV4_UNKNOWN_PKT:
    361		x->ip4_unknown_pkt++;
    362		break;
    363	case RX_IPV6_TCP_PKT:
    364		x->ip6_tcp_pkt++;
    365		break;
    366	case RX_IPV6_UDP_PKT:
    367		x->ip6_udp_pkt++;
    368		break;
    369	case RX_IPV6_ICMP_PKT:
    370		x->ip6_icmp_pkt++;
    371		break;
    372	case RX_IPV6_UNKNOWN_PKT:
    373		x->ip6_unknown_pkt++;
    374		break;
    375	default:
    376		pr_err("Invalid L3/L4 Packet type\n");
    377		break;
    378	}
    379
    380	/* Filter */
    381	if (p->rdes23.rx_wb_des23.vlan_filter_match)
    382		x->vlan_filter_match++;
    383
    384	if (p->rdes23.rx_wb_des23.sa_filter_fail) {
    385		status = -EINVAL;
    386		x->sa_filter_fail++;
    387	}
    388	if (p->rdes23.rx_wb_des23.da_filter_fail) {
    389		status = -EINVAL;
    390		x->da_filter_fail++;
    391	}
    392	if (p->rdes23.rx_wb_des23.hash_filter_pass)
    393		x->hash_filter_pass++;
    394
    395	if (p->rdes23.rx_wb_des23.l3_filter_match)
    396		x->l3_filter_match++;
    397
    398	if (p->rdes23.rx_wb_des23.l4_filter_match)
    399		x->l4_filter_match++;
    400
    401	return status;
    402}
    403
    404/* Get own bit of context descriptor */
    405static int sxgbe_get_rx_ctxt_owner(struct sxgbe_rx_ctxt_desc *p)
    406{
    407	return p->own_bit;
    408}
    409
    410/* Set own bit for context descriptor */
    411static void sxgbe_set_ctxt_rx_owner(struct sxgbe_rx_ctxt_desc *p)
    412{
    413	p->own_bit = 1;
    414}
    415
    416
    417/* Return the reception status looking at Context control information */
    418static void sxgbe_rx_ctxt_wbstatus(struct sxgbe_rx_ctxt_desc *p,
    419				   struct sxgbe_extra_stats *x)
    420{
    421	if (p->tstamp_dropped)
    422		x->timestamp_dropped++;
    423
    424	/* ptp */
    425	if (p->ptp_msgtype == RX_NO_PTP)
    426		x->rx_msg_type_no_ptp++;
    427	else if (p->ptp_msgtype == RX_PTP_SYNC)
    428		x->rx_ptp_type_sync++;
    429	else if (p->ptp_msgtype == RX_PTP_FOLLOW_UP)
    430		x->rx_ptp_type_follow_up++;
    431	else if (p->ptp_msgtype == RX_PTP_DELAY_REQ)
    432		x->rx_ptp_type_delay_req++;
    433	else if (p->ptp_msgtype == RX_PTP_DELAY_RESP)
    434		x->rx_ptp_type_delay_resp++;
    435	else if (p->ptp_msgtype == RX_PTP_PDELAY_REQ)
    436		x->rx_ptp_type_pdelay_req++;
    437	else if (p->ptp_msgtype == RX_PTP_PDELAY_RESP)
    438		x->rx_ptp_type_pdelay_resp++;
    439	else if (p->ptp_msgtype == RX_PTP_PDELAY_FOLLOW_UP)
    440		x->rx_ptp_type_pdelay_follow_up++;
    441	else if (p->ptp_msgtype == RX_PTP_ANNOUNCE)
    442		x->rx_ptp_announce++;
    443	else if (p->ptp_msgtype == RX_PTP_MGMT)
    444		x->rx_ptp_mgmt++;
    445	else if (p->ptp_msgtype == RX_PTP_SIGNAL)
    446		x->rx_ptp_signal++;
    447	else if (p->ptp_msgtype == RX_PTP_RESV_MSG)
    448		x->rx_ptp_resv_msg_type++;
    449}
    450
    451/* Get rx timestamp status */
    452static int sxgbe_get_rx_ctxt_tstamp_status(struct sxgbe_rx_ctxt_desc *p)
    453{
    454	if ((p->tstamp_hi == 0xffffffff) && (p->tstamp_lo == 0xffffffff)) {
    455		pr_err("Time stamp corrupted\n");
    456		return 0;
    457	}
    458
    459	return p->tstamp_available;
    460}
    461
    462
    463static u64 sxgbe_get_rx_timestamp(struct sxgbe_rx_ctxt_desc *p)
    464{
    465	u64 ns;
    466
    467	ns = p->tstamp_lo;
    468	ns |= ((u64)p->tstamp_hi) << 32;
    469
    470	return ns;
    471}
    472
    473static const struct sxgbe_desc_ops desc_ops = {
    474	.init_tx_desc			= sxgbe_init_tx_desc,
    475	.tx_desc_enable_tse		= sxgbe_tx_desc_enable_tse,
    476	.prepare_tx_desc		= sxgbe_prepare_tx_desc,
    477	.tx_vlanctl_desc		= sxgbe_tx_vlanctl_desc,
    478	.set_tx_owner			= sxgbe_set_tx_owner,
    479	.get_tx_owner			= sxgbe_get_tx_owner,
    480	.close_tx_desc			= sxgbe_close_tx_desc,
    481	.release_tx_desc		= sxgbe_release_tx_desc,
    482	.clear_tx_ic			= sxgbe_clear_tx_ic,
    483	.get_tx_ls			= sxgbe_get_tx_ls,
    484	.get_tx_len			= sxgbe_get_tx_len,
    485	.tx_enable_tstamp		= sxgbe_tx_enable_tstamp,
    486	.get_tx_timestamp_status	= sxgbe_get_tx_timestamp_status,
    487	.tx_ctxt_desc_set_ctxt		= sxgbe_tx_ctxt_desc_set_ctxt,
    488	.tx_ctxt_desc_set_owner		= sxgbe_tx_ctxt_desc_set_owner,
    489	.get_tx_ctxt_owner		= sxgbe_tx_ctxt_desc_get_owner,
    490	.tx_ctxt_desc_set_mss		= sxgbe_tx_ctxt_desc_set_mss,
    491	.tx_ctxt_desc_get_mss		= sxgbe_tx_ctxt_desc_get_mss,
    492	.tx_ctxt_desc_set_tcmssv	= sxgbe_tx_ctxt_desc_set_tcmssv,
    493	.tx_ctxt_desc_reset_ostc	= sxgbe_tx_ctxt_desc_reset_ostc,
    494	.tx_ctxt_desc_set_ivlantag	= sxgbe_tx_ctxt_desc_set_ivlantag,
    495	.tx_ctxt_desc_get_ivlantag	= sxgbe_tx_ctxt_desc_get_ivlantag,
    496	.tx_ctxt_desc_set_vlantag	= sxgbe_tx_ctxt_desc_set_vlantag,
    497	.tx_ctxt_desc_get_vlantag	= sxgbe_tx_ctxt_desc_get_vlantag,
    498	.tx_ctxt_set_tstamp		= sxgbe_tx_ctxt_desc_set_tstamp,
    499	.close_tx_ctxt_desc		= sxgbe_tx_ctxt_desc_close,
    500	.get_tx_ctxt_cde		= sxgbe_tx_ctxt_desc_get_cde,
    501	.init_rx_desc			= sxgbe_init_rx_desc,
    502	.get_rx_owner			= sxgbe_get_rx_owner,
    503	.set_rx_owner			= sxgbe_set_rx_owner,
    504	.set_rx_int_on_com		= sxgbe_set_rx_int_on_com,
    505	.get_rx_frame_len		= sxgbe_get_rx_frame_len,
    506	.get_rx_fd_status		= sxgbe_get_rx_fd_status,
    507	.get_rx_ld_status		= sxgbe_get_rx_ld_status,
    508	.rx_wbstatus			= sxgbe_rx_wbstatus,
    509	.get_rx_ctxt_owner		= sxgbe_get_rx_ctxt_owner,
    510	.set_rx_ctxt_owner		= sxgbe_set_ctxt_rx_owner,
    511	.rx_ctxt_wbstatus		= sxgbe_rx_ctxt_wbstatus,
    512	.get_rx_ctxt_tstamp_status	= sxgbe_get_rx_ctxt_tstamp_status,
    513	.get_timestamp			= sxgbe_get_rx_timestamp,
    514};
    515
    516const struct sxgbe_desc_ops *sxgbe_get_desc_ops(void)
    517{
    518	return &desc_ops;
    519}