162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * IBM Power Virtual Ethernet Device Driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) IBM Corporation, 2003, 2010
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Authors: Dave Larson <larson1@us.ibm.com>
862306a36Sopenharmony_ci *	    Santiago Leon <santil@linux.vnet.ibm.com>
962306a36Sopenharmony_ci *	    Brian King <brking@linux.vnet.ibm.com>
1062306a36Sopenharmony_ci *	    Robert Jennings <rcj@linux.vnet.ibm.com>
1162306a36Sopenharmony_ci *	    Anton Blanchard <anton@au.ibm.com>
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#ifndef _IBMVETH_H
1562306a36Sopenharmony_ci#define _IBMVETH_H
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* constants for H_MULTICAST_CTRL */
1862306a36Sopenharmony_ci#define IbmVethMcastReceptionModifyBit     0x80000UL
1962306a36Sopenharmony_ci#define IbmVethMcastReceptionEnableBit     0x20000UL
2062306a36Sopenharmony_ci#define IbmVethMcastFilterModifyBit        0x40000UL
2162306a36Sopenharmony_ci#define IbmVethMcastFilterEnableBit        0x10000UL
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define IbmVethMcastEnableRecv       (IbmVethMcastReceptionModifyBit | IbmVethMcastReceptionEnableBit)
2462306a36Sopenharmony_ci#define IbmVethMcastDisableRecv      (IbmVethMcastReceptionModifyBit)
2562306a36Sopenharmony_ci#define IbmVethMcastEnableFiltering  (IbmVethMcastFilterModifyBit | IbmVethMcastFilterEnableBit)
2662306a36Sopenharmony_ci#define IbmVethMcastDisableFiltering (IbmVethMcastFilterModifyBit)
2762306a36Sopenharmony_ci#define IbmVethMcastAddFilter        0x1UL
2862306a36Sopenharmony_ci#define IbmVethMcastRemoveFilter     0x2UL
2962306a36Sopenharmony_ci#define IbmVethMcastClearFilterTable 0x3UL
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define IBMVETH_ILLAN_LRG_SR_ENABLED	0x0000000000010000UL
3262306a36Sopenharmony_ci#define IBMVETH_ILLAN_LRG_SND_SUPPORT	0x0000000000008000UL
3362306a36Sopenharmony_ci#define IBMVETH_ILLAN_PADDED_PKT_CSUM	0x0000000000002000UL
3462306a36Sopenharmony_ci#define IBMVETH_ILLAN_TRUNK_PRI_MASK	0x0000000000000F00UL
3562306a36Sopenharmony_ci#define IBMVETH_ILLAN_IPV6_TCP_CSUM		0x0000000000000004UL
3662306a36Sopenharmony_ci#define IBMVETH_ILLAN_IPV4_TCP_CSUM		0x0000000000000002UL
3762306a36Sopenharmony_ci#define IBMVETH_ILLAN_ACTIVE_TRUNK		0x0000000000000001UL
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* hcall macros */
4062306a36Sopenharmony_ci#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
4162306a36Sopenharmony_ci  plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac)
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define h_free_logical_lan(ua) \
4462306a36Sopenharmony_ci  plpar_hcall_norets(H_FREE_LOGICAL_LAN, ua)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#define h_add_logical_lan_buffer(ua, buf) \
4762306a36Sopenharmony_ci  plpar_hcall_norets(H_ADD_LOGICAL_LAN_BUFFER, ua, buf)
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* FW allows us to send 6 descriptors but we only use one so mark
5062306a36Sopenharmony_ci * the other 5 as unused (0)
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_cistatic inline long h_send_logical_lan(unsigned long unit_address,
5362306a36Sopenharmony_ci		unsigned long desc, unsigned long corellator_in,
5462306a36Sopenharmony_ci		unsigned long *corellator_out, unsigned long mss,
5562306a36Sopenharmony_ci		unsigned long large_send_support)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	long rc;
5862306a36Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	if (large_send_support)
6162306a36Sopenharmony_ci		rc = plpar_hcall9(H_SEND_LOGICAL_LAN, retbuf, unit_address,
6262306a36Sopenharmony_ci				  desc, 0, 0, 0, 0, 0, corellator_in, mss);
6362306a36Sopenharmony_ci	else
6462306a36Sopenharmony_ci		rc = plpar_hcall9(H_SEND_LOGICAL_LAN, retbuf, unit_address,
6562306a36Sopenharmony_ci				  desc, 0, 0, 0, 0, 0, corellator_in);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	*corellator_out = retbuf[0];
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	return rc;
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_cistatic inline long h_illan_attributes(unsigned long unit_address,
7362306a36Sopenharmony_ci				      unsigned long reset_mask, unsigned long set_mask,
7462306a36Sopenharmony_ci				      unsigned long *ret_attributes)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	long rc;
7762306a36Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	rc = plpar_hcall(H_ILLAN_ATTRIBUTES, retbuf, unit_address,
8062306a36Sopenharmony_ci			 reset_mask, set_mask);
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	*ret_attributes = retbuf[0];
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	return rc;
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci#define h_multicast_ctrl(ua, cmd, mac) \
8862306a36Sopenharmony_ci  plpar_hcall_norets(H_MULTICAST_CTRL, ua, cmd, mac)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define h_change_logical_lan_mac(ua, mac) \
9162306a36Sopenharmony_ci  plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci#define IBMVETH_NUM_BUFF_POOLS 5
9462306a36Sopenharmony_ci#define IBMVETH_IO_ENTITLEMENT_DEFAULT 4243456 /* MTU of 1500 needs 4.2Mb */
9562306a36Sopenharmony_ci#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
9662306a36Sopenharmony_ci#define IBMVETH_MIN_MTU 68
9762306a36Sopenharmony_ci#define IBMVETH_MAX_POOL_COUNT 4096
9862306a36Sopenharmony_ci#define IBMVETH_BUFF_LIST_SIZE 4096
9962306a36Sopenharmony_ci#define IBMVETH_FILT_LIST_SIZE 4096
10062306a36Sopenharmony_ci#define IBMVETH_MAX_BUF_SIZE (1024 * 128)
10162306a36Sopenharmony_ci#define IBMVETH_MAX_TX_BUF_SIZE (1024 * 64)
10262306a36Sopenharmony_ci#define IBMVETH_MAX_QUEUES 16U
10362306a36Sopenharmony_ci#define IBMVETH_DEFAULT_QUEUES 8U
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 };
10662306a36Sopenharmony_cistatic int pool_count[] = { 256, 512, 256, 256, 256 };
10762306a36Sopenharmony_cistatic int pool_count_cmo[] = { 256, 512, 256, 256, 64 };
10862306a36Sopenharmony_cistatic int pool_active[] = { 1, 1, 0, 0, 1};
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#define IBM_VETH_INVALID_MAP ((u16)0xffff)
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistruct ibmveth_buff_pool {
11362306a36Sopenharmony_ci    u32 size;
11462306a36Sopenharmony_ci    u32 index;
11562306a36Sopenharmony_ci    u32 buff_size;
11662306a36Sopenharmony_ci    u32 threshold;
11762306a36Sopenharmony_ci    atomic_t available;
11862306a36Sopenharmony_ci    u32 consumer_index;
11962306a36Sopenharmony_ci    u32 producer_index;
12062306a36Sopenharmony_ci    u16 *free_map;
12162306a36Sopenharmony_ci    dma_addr_t *dma_addr;
12262306a36Sopenharmony_ci    struct sk_buff **skbuff;
12362306a36Sopenharmony_ci    int active;
12462306a36Sopenharmony_ci    struct kobject kobj;
12562306a36Sopenharmony_ci};
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistruct ibmveth_rx_q {
12862306a36Sopenharmony_ci    u64        index;
12962306a36Sopenharmony_ci    u64        num_slots;
13062306a36Sopenharmony_ci    u64        toggle;
13162306a36Sopenharmony_ci    dma_addr_t queue_dma;
13262306a36Sopenharmony_ci    u32        queue_len;
13362306a36Sopenharmony_ci    struct ibmveth_rx_q_entry *queue_addr;
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistruct ibmveth_adapter {
13762306a36Sopenharmony_ci    struct vio_dev *vdev;
13862306a36Sopenharmony_ci    struct net_device *netdev;
13962306a36Sopenharmony_ci    struct napi_struct napi;
14062306a36Sopenharmony_ci    unsigned int mcastFilterSize;
14162306a36Sopenharmony_ci    void * buffer_list_addr;
14262306a36Sopenharmony_ci    void * filter_list_addr;
14362306a36Sopenharmony_ci    void *tx_ltb_ptr[IBMVETH_MAX_QUEUES];
14462306a36Sopenharmony_ci    unsigned int tx_ltb_size;
14562306a36Sopenharmony_ci    dma_addr_t tx_ltb_dma[IBMVETH_MAX_QUEUES];
14662306a36Sopenharmony_ci    dma_addr_t buffer_list_dma;
14762306a36Sopenharmony_ci    dma_addr_t filter_list_dma;
14862306a36Sopenharmony_ci    struct ibmveth_buff_pool rx_buff_pool[IBMVETH_NUM_BUFF_POOLS];
14962306a36Sopenharmony_ci    struct ibmveth_rx_q rx_queue;
15062306a36Sopenharmony_ci    int rx_csum;
15162306a36Sopenharmony_ci    int large_send;
15262306a36Sopenharmony_ci    bool is_active_trunk;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci    u64 fw_ipv6_csum_support;
15562306a36Sopenharmony_ci    u64 fw_ipv4_csum_support;
15662306a36Sopenharmony_ci    u64 fw_large_send_support;
15762306a36Sopenharmony_ci    /* adapter specific stats */
15862306a36Sopenharmony_ci    u64 replenish_task_cycles;
15962306a36Sopenharmony_ci    u64 replenish_no_mem;
16062306a36Sopenharmony_ci    u64 replenish_add_buff_failure;
16162306a36Sopenharmony_ci    u64 replenish_add_buff_success;
16262306a36Sopenharmony_ci    u64 rx_invalid_buffer;
16362306a36Sopenharmony_ci    u64 rx_no_buffer;
16462306a36Sopenharmony_ci    u64 tx_map_failed;
16562306a36Sopenharmony_ci    u64 tx_send_failed;
16662306a36Sopenharmony_ci    u64 tx_large_packets;
16762306a36Sopenharmony_ci    u64 rx_large_packets;
16862306a36Sopenharmony_ci    /* Ethtool settings */
16962306a36Sopenharmony_ci	u8 duplex;
17062306a36Sopenharmony_ci	u32 speed;
17162306a36Sopenharmony_ci};
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci/*
17462306a36Sopenharmony_ci * We pass struct ibmveth_buf_desc_fields to the hypervisor in registers,
17562306a36Sopenharmony_ci * so we don't need to byteswap the two elements. However since we use
17662306a36Sopenharmony_ci * a union (ibmveth_buf_desc) to convert from the struct to a u64 we
17762306a36Sopenharmony_ci * do end up with endian specific ordering of the elements and that
17862306a36Sopenharmony_ci * needs correcting.
17962306a36Sopenharmony_ci */
18062306a36Sopenharmony_cistruct ibmveth_buf_desc_fields {
18162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN
18262306a36Sopenharmony_ci	u32 flags_len;
18362306a36Sopenharmony_ci	u32 address;
18462306a36Sopenharmony_ci#else
18562306a36Sopenharmony_ci	u32 address;
18662306a36Sopenharmony_ci	u32 flags_len;
18762306a36Sopenharmony_ci#endif
18862306a36Sopenharmony_ci#define IBMVETH_BUF_VALID	0x80000000
18962306a36Sopenharmony_ci#define IBMVETH_BUF_TOGGLE	0x40000000
19062306a36Sopenharmony_ci#define IBMVETH_BUF_LRG_SND     0x04000000
19162306a36Sopenharmony_ci#define IBMVETH_BUF_NO_CSUM	0x02000000
19262306a36Sopenharmony_ci#define IBMVETH_BUF_CSUM_GOOD	0x01000000
19362306a36Sopenharmony_ci#define IBMVETH_BUF_LEN_MASK	0x00FFFFFF
19462306a36Sopenharmony_ci};
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ciunion ibmveth_buf_desc {
19762306a36Sopenharmony_ci    u64 desc;
19862306a36Sopenharmony_ci    struct ibmveth_buf_desc_fields fields;
19962306a36Sopenharmony_ci};
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cistruct ibmveth_rx_q_entry {
20262306a36Sopenharmony_ci	__be32 flags_off;
20362306a36Sopenharmony_ci#define IBMVETH_RXQ_TOGGLE		0x80000000
20462306a36Sopenharmony_ci#define IBMVETH_RXQ_TOGGLE_SHIFT	31
20562306a36Sopenharmony_ci#define IBMVETH_RXQ_VALID		0x40000000
20662306a36Sopenharmony_ci#define IBMVETH_RXQ_LRG_PKT		0x04000000
20762306a36Sopenharmony_ci#define IBMVETH_RXQ_NO_CSUM		0x02000000
20862306a36Sopenharmony_ci#define IBMVETH_RXQ_CSUM_GOOD		0x01000000
20962306a36Sopenharmony_ci#define IBMVETH_RXQ_OFF_MASK		0x0000FFFF
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	__be32 length;
21262306a36Sopenharmony_ci	/* correlator is only used by the OS, no need to byte swap */
21362306a36Sopenharmony_ci	u64 correlator;
21462306a36Sopenharmony_ci};
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci#endif /* _IBMVETH_H */
217