162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net> 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * This file is free software: you may copy, redistribute and/or modify it 562306a36Sopenharmony_ci * under the terms of the GNU General Public License as published by the 662306a36Sopenharmony_ci * Free Software Foundation, either version 2 of the License, or (at your 762306a36Sopenharmony_ci * option) any later version. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * This file is distributed in the hope that it will be useful, but 1062306a36Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 1162306a36Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1262306a36Sopenharmony_ci * General Public License for more details. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * You should have received a copy of the GNU General Public License 1562306a36Sopenharmony_ci * along with this program. If not, see <http://www.gnu.org/licenses/>. 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * This file incorporates work covered by the following copyright and 1862306a36Sopenharmony_ci * permission notice: 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * Copyright (c) 2012 Qualcomm Atheros, Inc. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 2362306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 2462306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 2762306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 2862306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 2962306a36Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 3062306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 3162306a36Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 3262306a36Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#ifndef ALX_HW_H_ 3662306a36Sopenharmony_ci#define ALX_HW_H_ 3762306a36Sopenharmony_ci#include <linux/types.h> 3862306a36Sopenharmony_ci#include <linux/mdio.h> 3962306a36Sopenharmony_ci#include <linux/pci.h> 4062306a36Sopenharmony_ci#include <linux/if_vlan.h> 4162306a36Sopenharmony_ci#include "reg.h" 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* Transmit Packet Descriptor, contains 4 32-bit words. 4462306a36Sopenharmony_ci * 4562306a36Sopenharmony_ci * 31 16 0 4662306a36Sopenharmony_ci * +----------------+----------------+ 4762306a36Sopenharmony_ci * | vlan-tag | buf length | 4862306a36Sopenharmony_ci * +----------------+----------------+ 4962306a36Sopenharmony_ci * | Word 1 | 5062306a36Sopenharmony_ci * +----------------+----------------+ 5162306a36Sopenharmony_ci * | Word 2: buf addr lo | 5262306a36Sopenharmony_ci * +----------------+----------------+ 5362306a36Sopenharmony_ci * | Word 3: buf addr hi | 5462306a36Sopenharmony_ci * +----------------+----------------+ 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * Word 2 and 3 combine to form a 64-bit buffer address 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * Word 1 has three forms, depending on the state of bit 8/12/13: 5962306a36Sopenharmony_ci * if bit8 =='1', the definition is just for custom checksum offload. 6062306a36Sopenharmony_ci * if bit8 == '0' && bit12 == '1' && bit13 == '1', the *FIRST* descriptor 6162306a36Sopenharmony_ci * for the skb is special for LSO V2, Word 2 become total skb length , 6262306a36Sopenharmony_ci * Word 3 is meaningless. 6362306a36Sopenharmony_ci * other condition, the definition is for general skb or ip/tcp/udp 6462306a36Sopenharmony_ci * checksum or LSO(TSO) offload. 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * Here is the depiction: 6762306a36Sopenharmony_ci * 6862306a36Sopenharmony_ci * 0-+ 0-+ 6962306a36Sopenharmony_ci * 1 | 1 | 7062306a36Sopenharmony_ci * 2 | 2 | 7162306a36Sopenharmony_ci * 3 | Payload offset 3 | L4 header offset 7262306a36Sopenharmony_ci * 4 | (7:0) 4 | (7:0) 7362306a36Sopenharmony_ci * 5 | 5 | 7462306a36Sopenharmony_ci * 6 | 6 | 7562306a36Sopenharmony_ci * 7-+ 7-+ 7662306a36Sopenharmony_ci * 8 Custom csum enable = 1 8 Custom csum enable = 0 7762306a36Sopenharmony_ci * 9 General IPv4 checksum 9 General IPv4 checksum 7862306a36Sopenharmony_ci * 10 General TCP checksum 10 General TCP checksum 7962306a36Sopenharmony_ci * 11 General UDP checksum 11 General UDP checksum 8062306a36Sopenharmony_ci * 12 Large Send Segment enable 12 Large Send Segment enable 8162306a36Sopenharmony_ci * 13 Large Send Segment type 13 Large Send Segment type 8262306a36Sopenharmony_ci * 14 VLAN tagged 14 VLAN tagged 8362306a36Sopenharmony_ci * 15 Insert VLAN tag 15 Insert VLAN tag 8462306a36Sopenharmony_ci * 16 IPv4 packet 16 IPv4 packet 8562306a36Sopenharmony_ci * 17 Ethernet frame type 17 Ethernet frame type 8662306a36Sopenharmony_ci * 18-+ 18-+ 8762306a36Sopenharmony_ci * 19 | 19 | 8862306a36Sopenharmony_ci * 20 | 20 | 8962306a36Sopenharmony_ci * 21 | Custom csum offset 21 | 9062306a36Sopenharmony_ci * 22 | (25:18) 22 | 9162306a36Sopenharmony_ci * 23 | 23 | MSS (30:18) 9262306a36Sopenharmony_ci * 24 | 24 | 9362306a36Sopenharmony_ci * 25-+ 25 | 9462306a36Sopenharmony_ci * 26-+ 26 | 9562306a36Sopenharmony_ci * 27 | 27 | 9662306a36Sopenharmony_ci * 28 | Reserved 28 | 9762306a36Sopenharmony_ci * 29 | 29 | 9862306a36Sopenharmony_ci * 30-+ 30-+ 9962306a36Sopenharmony_ci * 31 End of packet 31 End of packet 10062306a36Sopenharmony_ci */ 10162306a36Sopenharmony_cistruct alx_txd { 10262306a36Sopenharmony_ci __le16 len; 10362306a36Sopenharmony_ci __le16 vlan_tag; 10462306a36Sopenharmony_ci __le32 word1; 10562306a36Sopenharmony_ci union { 10662306a36Sopenharmony_ci __le64 addr; 10762306a36Sopenharmony_ci struct { 10862306a36Sopenharmony_ci __le32 pkt_len; 10962306a36Sopenharmony_ci __le32 resvd; 11062306a36Sopenharmony_ci } l; 11162306a36Sopenharmony_ci } adrl; 11262306a36Sopenharmony_ci} __packed; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/* tpd word 1 */ 11562306a36Sopenharmony_ci#define TPD_CXSUMSTART_MASK 0x00FF 11662306a36Sopenharmony_ci#define TPD_CXSUMSTART_SHIFT 0 11762306a36Sopenharmony_ci#define TPD_L4HDROFFSET_MASK 0x00FF 11862306a36Sopenharmony_ci#define TPD_L4HDROFFSET_SHIFT 0 11962306a36Sopenharmony_ci#define TPD_CXSUM_EN_MASK 0x0001 12062306a36Sopenharmony_ci#define TPD_CXSUM_EN_SHIFT 8 12162306a36Sopenharmony_ci#define TPD_IP_XSUM_MASK 0x0001 12262306a36Sopenharmony_ci#define TPD_IP_XSUM_SHIFT 9 12362306a36Sopenharmony_ci#define TPD_TCP_XSUM_MASK 0x0001 12462306a36Sopenharmony_ci#define TPD_TCP_XSUM_SHIFT 10 12562306a36Sopenharmony_ci#define TPD_UDP_XSUM_MASK 0x0001 12662306a36Sopenharmony_ci#define TPD_UDP_XSUM_SHIFT 11 12762306a36Sopenharmony_ci#define TPD_LSO_EN_MASK 0x0001 12862306a36Sopenharmony_ci#define TPD_LSO_EN_SHIFT 12 12962306a36Sopenharmony_ci#define TPD_LSO_V2_MASK 0x0001 13062306a36Sopenharmony_ci#define TPD_LSO_V2_SHIFT 13 13162306a36Sopenharmony_ci#define TPD_VLTAGGED_MASK 0x0001 13262306a36Sopenharmony_ci#define TPD_VLTAGGED_SHIFT 14 13362306a36Sopenharmony_ci#define TPD_INS_VLTAG_MASK 0x0001 13462306a36Sopenharmony_ci#define TPD_INS_VLTAG_SHIFT 15 13562306a36Sopenharmony_ci#define TPD_IPV4_MASK 0x0001 13662306a36Sopenharmony_ci#define TPD_IPV4_SHIFT 16 13762306a36Sopenharmony_ci#define TPD_ETHTYPE_MASK 0x0001 13862306a36Sopenharmony_ci#define TPD_ETHTYPE_SHIFT 17 13962306a36Sopenharmony_ci#define TPD_CXSUMOFFSET_MASK 0x00FF 14062306a36Sopenharmony_ci#define TPD_CXSUMOFFSET_SHIFT 18 14162306a36Sopenharmony_ci#define TPD_MSS_MASK 0x1FFF 14262306a36Sopenharmony_ci#define TPD_MSS_SHIFT 18 14362306a36Sopenharmony_ci#define TPD_EOP_MASK 0x0001 14462306a36Sopenharmony_ci#define TPD_EOP_SHIFT 31 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#define DESC_GET(_x, _name) ((_x) >> _name##SHIFT & _name##MASK) 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* Receive Free Descriptor */ 14962306a36Sopenharmony_cistruct alx_rfd { 15062306a36Sopenharmony_ci __le64 addr; /* data buffer address, length is 15162306a36Sopenharmony_ci * declared in register --- every 15262306a36Sopenharmony_ci * buffer has the same size 15362306a36Sopenharmony_ci */ 15462306a36Sopenharmony_ci} __packed; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci/* Receive Return Descriptor, contains 4 32-bit words. 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * 31 16 0 15962306a36Sopenharmony_ci * +----------------+----------------+ 16062306a36Sopenharmony_ci * | Word 0 | 16162306a36Sopenharmony_ci * +----------------+----------------+ 16262306a36Sopenharmony_ci * | Word 1: RSS Hash value | 16362306a36Sopenharmony_ci * +----------------+----------------+ 16462306a36Sopenharmony_ci * | Word 2 | 16562306a36Sopenharmony_ci * +----------------+----------------+ 16662306a36Sopenharmony_ci * | Word 3 | 16762306a36Sopenharmony_ci * +----------------+----------------+ 16862306a36Sopenharmony_ci * 16962306a36Sopenharmony_ci * Word 0 depiction & Word 2 depiction: 17062306a36Sopenharmony_ci * 17162306a36Sopenharmony_ci * 0--+ 0--+ 17262306a36Sopenharmony_ci * 1 | 1 | 17362306a36Sopenharmony_ci * 2 | 2 | 17462306a36Sopenharmony_ci * 3 | 3 | 17562306a36Sopenharmony_ci * 4 | 4 | 17662306a36Sopenharmony_ci * 5 | 5 | 17762306a36Sopenharmony_ci * 6 | 6 | 17862306a36Sopenharmony_ci * 7 | IP payload checksum 7 | VLAN tag 17962306a36Sopenharmony_ci * 8 | (15:0) 8 | (15:0) 18062306a36Sopenharmony_ci * 9 | 9 | 18162306a36Sopenharmony_ci * 10 | 10 | 18262306a36Sopenharmony_ci * 11 | 11 | 18362306a36Sopenharmony_ci * 12 | 12 | 18462306a36Sopenharmony_ci * 13 | 13 | 18562306a36Sopenharmony_ci * 14 | 14 | 18662306a36Sopenharmony_ci * 15-+ 15-+ 18762306a36Sopenharmony_ci * 16-+ 16-+ 18862306a36Sopenharmony_ci * 17 | Number of RFDs 17 | 18962306a36Sopenharmony_ci * 18 | (19:16) 18 | 19062306a36Sopenharmony_ci * 19-+ 19 | Protocol ID 19162306a36Sopenharmony_ci * 20-+ 20 | (23:16) 19262306a36Sopenharmony_ci * 21 | 21 | 19362306a36Sopenharmony_ci * 22 | 22 | 19462306a36Sopenharmony_ci * 23 | 23-+ 19562306a36Sopenharmony_ci * 24 | 24 | Reserved 19662306a36Sopenharmony_ci * 25 | Start index of RFD-ring 25-+ 19762306a36Sopenharmony_ci * 26 | (31:20) 26 | RSS Q-num (27:25) 19862306a36Sopenharmony_ci * 27 | 27-+ 19962306a36Sopenharmony_ci * 28 | 28-+ 20062306a36Sopenharmony_ci * 29 | 29 | RSS Hash algorithm 20162306a36Sopenharmony_ci * 30 | 30 | (31:28) 20262306a36Sopenharmony_ci * 31-+ 31-+ 20362306a36Sopenharmony_ci * 20462306a36Sopenharmony_ci * Word 3 depiction: 20562306a36Sopenharmony_ci * 20662306a36Sopenharmony_ci * 0--+ 20762306a36Sopenharmony_ci * 1 | 20862306a36Sopenharmony_ci * 2 | 20962306a36Sopenharmony_ci * 3 | 21062306a36Sopenharmony_ci * 4 | 21162306a36Sopenharmony_ci * 5 | 21262306a36Sopenharmony_ci * 6 | 21362306a36Sopenharmony_ci * 7 | Packet length (include FCS) 21462306a36Sopenharmony_ci * 8 | (13:0) 21562306a36Sopenharmony_ci * 9 | 21662306a36Sopenharmony_ci * 10 | 21762306a36Sopenharmony_ci * 11 | 21862306a36Sopenharmony_ci * 12 | 21962306a36Sopenharmony_ci * 13-+ 22062306a36Sopenharmony_ci * 14 L4 Header checksum error 22162306a36Sopenharmony_ci * 15 IPv4 checksum error 22262306a36Sopenharmony_ci * 16 VLAN tagged 22362306a36Sopenharmony_ci * 17-+ 22462306a36Sopenharmony_ci * 18 | Protocol ID (19:17) 22562306a36Sopenharmony_ci * 19-+ 22662306a36Sopenharmony_ci * 20 Receive error summary 22762306a36Sopenharmony_ci * 21 FCS(CRC) error 22862306a36Sopenharmony_ci * 22 Frame alignment error 22962306a36Sopenharmony_ci * 23 Truncated packet 23062306a36Sopenharmony_ci * 24 Runt packet 23162306a36Sopenharmony_ci * 25 Incomplete packet due to insufficient rx-desc 23262306a36Sopenharmony_ci * 26 Broadcast packet 23362306a36Sopenharmony_ci * 27 Multicast packet 23462306a36Sopenharmony_ci * 28 Ethernet type (EII or 802.3) 23562306a36Sopenharmony_ci * 29 FIFO overflow 23662306a36Sopenharmony_ci * 30 Length error (for 802.3, length field mismatch with actual len) 23762306a36Sopenharmony_ci * 31 Updated, indicate to driver that this RRD is refreshed. 23862306a36Sopenharmony_ci */ 23962306a36Sopenharmony_cistruct alx_rrd { 24062306a36Sopenharmony_ci __le32 word0; 24162306a36Sopenharmony_ci __le32 rss_hash; 24262306a36Sopenharmony_ci __le32 word2; 24362306a36Sopenharmony_ci __le32 word3; 24462306a36Sopenharmony_ci} __packed; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci/* rrd word 0 */ 24762306a36Sopenharmony_ci#define RRD_XSUM_MASK 0xFFFF 24862306a36Sopenharmony_ci#define RRD_XSUM_SHIFT 0 24962306a36Sopenharmony_ci#define RRD_NOR_MASK 0x000F 25062306a36Sopenharmony_ci#define RRD_NOR_SHIFT 16 25162306a36Sopenharmony_ci#define RRD_SI_MASK 0x0FFF 25262306a36Sopenharmony_ci#define RRD_SI_SHIFT 20 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci/* rrd word 2 */ 25562306a36Sopenharmony_ci#define RRD_VLTAG_MASK 0xFFFF 25662306a36Sopenharmony_ci#define RRD_VLTAG_SHIFT 0 25762306a36Sopenharmony_ci#define RRD_PID_MASK 0x00FF 25862306a36Sopenharmony_ci#define RRD_PID_SHIFT 16 25962306a36Sopenharmony_ci/* non-ip packet */ 26062306a36Sopenharmony_ci#define RRD_PID_NONIP 0 26162306a36Sopenharmony_ci/* ipv4(only) */ 26262306a36Sopenharmony_ci#define RRD_PID_IPV4 1 26362306a36Sopenharmony_ci/* tcp/ipv6 */ 26462306a36Sopenharmony_ci#define RRD_PID_IPV6TCP 2 26562306a36Sopenharmony_ci/* tcp/ipv4 */ 26662306a36Sopenharmony_ci#define RRD_PID_IPV4TCP 3 26762306a36Sopenharmony_ci/* udp/ipv6 */ 26862306a36Sopenharmony_ci#define RRD_PID_IPV6UDP 4 26962306a36Sopenharmony_ci/* udp/ipv4 */ 27062306a36Sopenharmony_ci#define RRD_PID_IPV4UDP 5 27162306a36Sopenharmony_ci/* ipv6(only) */ 27262306a36Sopenharmony_ci#define RRD_PID_IPV6 6 27362306a36Sopenharmony_ci/* LLDP packet */ 27462306a36Sopenharmony_ci#define RRD_PID_LLDP 7 27562306a36Sopenharmony_ci/* 1588 packet */ 27662306a36Sopenharmony_ci#define RRD_PID_1588 8 27762306a36Sopenharmony_ci#define RRD_RSSQ_MASK 0x0007 27862306a36Sopenharmony_ci#define RRD_RSSQ_SHIFT 25 27962306a36Sopenharmony_ci#define RRD_RSSALG_MASK 0x000F 28062306a36Sopenharmony_ci#define RRD_RSSALG_SHIFT 28 28162306a36Sopenharmony_ci#define RRD_RSSALG_TCPV6 0x1 28262306a36Sopenharmony_ci#define RRD_RSSALG_IPV6 0x2 28362306a36Sopenharmony_ci#define RRD_RSSALG_TCPV4 0x4 28462306a36Sopenharmony_ci#define RRD_RSSALG_IPV4 0x8 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci/* rrd word 3 */ 28762306a36Sopenharmony_ci#define RRD_PKTLEN_MASK 0x3FFF 28862306a36Sopenharmony_ci#define RRD_PKTLEN_SHIFT 0 28962306a36Sopenharmony_ci#define RRD_ERR_L4_MASK 0x0001 29062306a36Sopenharmony_ci#define RRD_ERR_L4_SHIFT 14 29162306a36Sopenharmony_ci#define RRD_ERR_IPV4_MASK 0x0001 29262306a36Sopenharmony_ci#define RRD_ERR_IPV4_SHIFT 15 29362306a36Sopenharmony_ci#define RRD_VLTAGGED_MASK 0x0001 29462306a36Sopenharmony_ci#define RRD_VLTAGGED_SHIFT 16 29562306a36Sopenharmony_ci#define RRD_OLD_PID_MASK 0x0007 29662306a36Sopenharmony_ci#define RRD_OLD_PID_SHIFT 17 29762306a36Sopenharmony_ci#define RRD_ERR_RES_MASK 0x0001 29862306a36Sopenharmony_ci#define RRD_ERR_RES_SHIFT 20 29962306a36Sopenharmony_ci#define RRD_ERR_FCS_MASK 0x0001 30062306a36Sopenharmony_ci#define RRD_ERR_FCS_SHIFT 21 30162306a36Sopenharmony_ci#define RRD_ERR_FAE_MASK 0x0001 30262306a36Sopenharmony_ci#define RRD_ERR_FAE_SHIFT 22 30362306a36Sopenharmony_ci#define RRD_ERR_TRUNC_MASK 0x0001 30462306a36Sopenharmony_ci#define RRD_ERR_TRUNC_SHIFT 23 30562306a36Sopenharmony_ci#define RRD_ERR_RUNT_MASK 0x0001 30662306a36Sopenharmony_ci#define RRD_ERR_RUNT_SHIFT 24 30762306a36Sopenharmony_ci#define RRD_ERR_ICMP_MASK 0x0001 30862306a36Sopenharmony_ci#define RRD_ERR_ICMP_SHIFT 25 30962306a36Sopenharmony_ci#define RRD_BCAST_MASK 0x0001 31062306a36Sopenharmony_ci#define RRD_BCAST_SHIFT 26 31162306a36Sopenharmony_ci#define RRD_MCAST_MASK 0x0001 31262306a36Sopenharmony_ci#define RRD_MCAST_SHIFT 27 31362306a36Sopenharmony_ci#define RRD_ETHTYPE_MASK 0x0001 31462306a36Sopenharmony_ci#define RRD_ETHTYPE_SHIFT 28 31562306a36Sopenharmony_ci#define RRD_ERR_FIFOV_MASK 0x0001 31662306a36Sopenharmony_ci#define RRD_ERR_FIFOV_SHIFT 29 31762306a36Sopenharmony_ci#define RRD_ERR_LEN_MASK 0x0001 31862306a36Sopenharmony_ci#define RRD_ERR_LEN_SHIFT 30 31962306a36Sopenharmony_ci#define RRD_UPDATED_MASK 0x0001 32062306a36Sopenharmony_ci#define RRD_UPDATED_SHIFT 31 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci#define ALX_MAX_SETUP_LNK_CYCLE 50 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci/* for FlowControl */ 32662306a36Sopenharmony_ci#define ALX_FC_RX 0x01 32762306a36Sopenharmony_ci#define ALX_FC_TX 0x02 32862306a36Sopenharmony_ci#define ALX_FC_ANEG 0x04 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci/* for sleep control */ 33162306a36Sopenharmony_ci#define ALX_SLEEP_WOL_PHY 0x00000001 33262306a36Sopenharmony_ci#define ALX_SLEEP_WOL_MAGIC 0x00000002 33362306a36Sopenharmony_ci#define ALX_SLEEP_CIFS 0x00000004 33462306a36Sopenharmony_ci#define ALX_SLEEP_ACTIVE (ALX_SLEEP_WOL_PHY | \ 33562306a36Sopenharmony_ci ALX_SLEEP_WOL_MAGIC | \ 33662306a36Sopenharmony_ci ALX_SLEEP_CIFS) 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci/* for RSS hash type */ 33962306a36Sopenharmony_ci#define ALX_RSS_HASH_TYPE_IPV4 0x1 34062306a36Sopenharmony_ci#define ALX_RSS_HASH_TYPE_IPV4_TCP 0x2 34162306a36Sopenharmony_ci#define ALX_RSS_HASH_TYPE_IPV6 0x4 34262306a36Sopenharmony_ci#define ALX_RSS_HASH_TYPE_IPV6_TCP 0x8 34362306a36Sopenharmony_ci#define ALX_RSS_HASH_TYPE_ALL (ALX_RSS_HASH_TYPE_IPV4 | \ 34462306a36Sopenharmony_ci ALX_RSS_HASH_TYPE_IPV4_TCP | \ 34562306a36Sopenharmony_ci ALX_RSS_HASH_TYPE_IPV6 | \ 34662306a36Sopenharmony_ci ALX_RSS_HASH_TYPE_IPV6_TCP) 34762306a36Sopenharmony_ci#define ALX_FRAME_PAD 16 34862306a36Sopenharmony_ci#define ALX_RAW_MTU(_mtu) (_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN) 34962306a36Sopenharmony_ci#define ALX_MAX_FRAME_LEN(_mtu) (ALIGN((ALX_RAW_MTU(_mtu) + ALX_FRAME_PAD), 8)) 35062306a36Sopenharmony_ci#define ALX_DEF_RXBUF_SIZE ALX_MAX_FRAME_LEN(1500) 35162306a36Sopenharmony_ci#define ALX_MAX_JUMBO_PKT_SIZE (9*1024) 35262306a36Sopenharmony_ci#define ALX_MAX_TSO_PKT_SIZE (7*1024) 35362306a36Sopenharmony_ci#define ALX_MAX_FRAME_SIZE ALX_MAX_JUMBO_PKT_SIZE 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci#define ALX_MAX_RX_QUEUES 8 35662306a36Sopenharmony_ci#define ALX_MAX_TX_QUEUES 4 35762306a36Sopenharmony_ci#define ALX_MAX_HANDLED_INTRS 5 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci#define ALX_ISR_MISC (ALX_ISR_PCIE_LNKDOWN | \ 36062306a36Sopenharmony_ci ALX_ISR_DMAW | \ 36162306a36Sopenharmony_ci ALX_ISR_DMAR | \ 36262306a36Sopenharmony_ci ALX_ISR_SMB | \ 36362306a36Sopenharmony_ci ALX_ISR_MANU | \ 36462306a36Sopenharmony_ci ALX_ISR_TIMER) 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci#define ALX_ISR_FATAL (ALX_ISR_PCIE_LNKDOWN | \ 36762306a36Sopenharmony_ci ALX_ISR_DMAW | ALX_ISR_DMAR) 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci#define ALX_ISR_ALERT (ALX_ISR_RXF_OV | \ 37062306a36Sopenharmony_ci ALX_ISR_TXF_UR | \ 37162306a36Sopenharmony_ci ALX_ISR_RFD_UR) 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci#define ALX_ISR_ALL_QUEUES (ALX_ISR_TX_Q0 | \ 37462306a36Sopenharmony_ci ALX_ISR_TX_Q1 | \ 37562306a36Sopenharmony_ci ALX_ISR_TX_Q2 | \ 37662306a36Sopenharmony_ci ALX_ISR_TX_Q3 | \ 37762306a36Sopenharmony_ci ALX_ISR_RX_Q0 | \ 37862306a36Sopenharmony_ci ALX_ISR_RX_Q1 | \ 37962306a36Sopenharmony_ci ALX_ISR_RX_Q2 | \ 38062306a36Sopenharmony_ci ALX_ISR_RX_Q3 | \ 38162306a36Sopenharmony_ci ALX_ISR_RX_Q4 | \ 38262306a36Sopenharmony_ci ALX_ISR_RX_Q5 | \ 38362306a36Sopenharmony_ci ALX_ISR_RX_Q6 | \ 38462306a36Sopenharmony_ci ALX_ISR_RX_Q7) 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci/* Statistics counters collected by the MAC 38762306a36Sopenharmony_ci * 38862306a36Sopenharmony_ci * The order of the fields must match the strings in alx_gstrings_stats 38962306a36Sopenharmony_ci * All stats fields should be u64 39062306a36Sopenharmony_ci * See ethtool.c 39162306a36Sopenharmony_ci */ 39262306a36Sopenharmony_cistruct alx_hw_stats { 39362306a36Sopenharmony_ci /* rx */ 39462306a36Sopenharmony_ci u64 rx_ok; /* good RX packets */ 39562306a36Sopenharmony_ci u64 rx_bcast; /* good RX broadcast packets */ 39662306a36Sopenharmony_ci u64 rx_mcast; /* good RX multicast packets */ 39762306a36Sopenharmony_ci u64 rx_pause; /* RX pause frames */ 39862306a36Sopenharmony_ci u64 rx_ctrl; /* RX control packets other than pause frames */ 39962306a36Sopenharmony_ci u64 rx_fcs_err; /* RX packets with bad FCS */ 40062306a36Sopenharmony_ci u64 rx_len_err; /* RX packets with length != actual size */ 40162306a36Sopenharmony_ci u64 rx_byte_cnt; /* good bytes received. FCS is NOT included */ 40262306a36Sopenharmony_ci u64 rx_runt; /* RX packets < 64 bytes with good FCS */ 40362306a36Sopenharmony_ci u64 rx_frag; /* RX packets < 64 bytes with bad FCS */ 40462306a36Sopenharmony_ci u64 rx_sz_64B; /* 64 byte RX packets */ 40562306a36Sopenharmony_ci u64 rx_sz_127B; /* 65-127 byte RX packets */ 40662306a36Sopenharmony_ci u64 rx_sz_255B; /* 128-255 byte RX packets */ 40762306a36Sopenharmony_ci u64 rx_sz_511B; /* 256-511 byte RX packets */ 40862306a36Sopenharmony_ci u64 rx_sz_1023B; /* 512-1023 byte RX packets */ 40962306a36Sopenharmony_ci u64 rx_sz_1518B; /* 1024-1518 byte RX packets */ 41062306a36Sopenharmony_ci u64 rx_sz_max; /* 1519 byte to MTU RX packets */ 41162306a36Sopenharmony_ci u64 rx_ov_sz; /* truncated RX packets, size > MTU */ 41262306a36Sopenharmony_ci u64 rx_ov_rxf; /* frames dropped due to RX FIFO overflow */ 41362306a36Sopenharmony_ci u64 rx_ov_rrd; /* frames dropped due to RRD overflow */ 41462306a36Sopenharmony_ci u64 rx_align_err; /* alignment errors */ 41562306a36Sopenharmony_ci u64 rx_bc_byte_cnt; /* RX broadcast bytes, excluding FCS */ 41662306a36Sopenharmony_ci u64 rx_mc_byte_cnt; /* RX multicast bytes, excluding FCS */ 41762306a36Sopenharmony_ci u64 rx_err_addr; /* packets dropped due to address filtering */ 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci /* tx */ 42062306a36Sopenharmony_ci u64 tx_ok; /* good TX packets */ 42162306a36Sopenharmony_ci u64 tx_bcast; /* good TX broadcast packets */ 42262306a36Sopenharmony_ci u64 tx_mcast; /* good TX multicast packets */ 42362306a36Sopenharmony_ci u64 tx_pause; /* TX pause frames */ 42462306a36Sopenharmony_ci u64 tx_exc_defer; /* TX packets deferred excessively */ 42562306a36Sopenharmony_ci u64 tx_ctrl; /* TX control frames, excluding pause frames */ 42662306a36Sopenharmony_ci u64 tx_defer; /* TX packets deferred */ 42762306a36Sopenharmony_ci u64 tx_byte_cnt; /* bytes transmitted, FCS is NOT included */ 42862306a36Sopenharmony_ci u64 tx_sz_64B; /* 64 byte TX packets */ 42962306a36Sopenharmony_ci u64 tx_sz_127B; /* 65-127 byte TX packets */ 43062306a36Sopenharmony_ci u64 tx_sz_255B; /* 128-255 byte TX packets */ 43162306a36Sopenharmony_ci u64 tx_sz_511B; /* 256-511 byte TX packets */ 43262306a36Sopenharmony_ci u64 tx_sz_1023B; /* 512-1023 byte TX packets */ 43362306a36Sopenharmony_ci u64 tx_sz_1518B; /* 1024-1518 byte TX packets */ 43462306a36Sopenharmony_ci u64 tx_sz_max; /* 1519 byte to MTU TX packets */ 43562306a36Sopenharmony_ci u64 tx_single_col; /* packets TX after a single collision */ 43662306a36Sopenharmony_ci u64 tx_multi_col; /* packets TX after multiple collisions */ 43762306a36Sopenharmony_ci u64 tx_late_col; /* TX packets with late collisions */ 43862306a36Sopenharmony_ci u64 tx_abort_col; /* TX packets aborted w/excessive collisions */ 43962306a36Sopenharmony_ci u64 tx_underrun; /* TX packets aborted due to TX FIFO underrun 44062306a36Sopenharmony_ci * or TRD FIFO underrun 44162306a36Sopenharmony_ci */ 44262306a36Sopenharmony_ci u64 tx_trd_eop; /* reads beyond the EOP into the next frame 44362306a36Sopenharmony_ci * when TRD was not written timely 44462306a36Sopenharmony_ci */ 44562306a36Sopenharmony_ci u64 tx_len_err; /* TX packets where length != actual size */ 44662306a36Sopenharmony_ci u64 tx_trunc; /* TX packets truncated due to size > MTU */ 44762306a36Sopenharmony_ci u64 tx_bc_byte_cnt; /* broadcast bytes transmitted, excluding FCS */ 44862306a36Sopenharmony_ci u64 tx_mc_byte_cnt; /* multicast bytes transmitted, excluding FCS */ 44962306a36Sopenharmony_ci u64 update; 45062306a36Sopenharmony_ci}; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci/* maximum interrupt vectors for msix */ 45462306a36Sopenharmony_ci#define ALX_MAX_MSIX_INTRS 16 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci#define ALX_GET_FIELD(_data, _field) \ 45762306a36Sopenharmony_ci (((_data) >> _field ## _SHIFT) & _field ## _MASK) 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci#define ALX_SET_FIELD(_data, _field, _value) do { \ 46062306a36Sopenharmony_ci (_data) &= ~(_field ## _MASK << _field ## _SHIFT); \ 46162306a36Sopenharmony_ci (_data) |= ((_value) & _field ## _MASK) << _field ## _SHIFT;\ 46262306a36Sopenharmony_ci } while (0) 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_cistruct alx_hw { 46562306a36Sopenharmony_ci struct pci_dev *pdev; 46662306a36Sopenharmony_ci u8 __iomem *hw_addr; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci /* current & permanent mac addr */ 46962306a36Sopenharmony_ci u8 mac_addr[ETH_ALEN]; 47062306a36Sopenharmony_ci u8 perm_addr[ETH_ALEN]; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci u16 mtu; 47362306a36Sopenharmony_ci u16 imt; 47462306a36Sopenharmony_ci u8 dma_chnl; 47562306a36Sopenharmony_ci u8 max_dma_chnl; 47662306a36Sopenharmony_ci /* tpd threshold to trig INT */ 47762306a36Sopenharmony_ci u32 ith_tpd; 47862306a36Sopenharmony_ci u32 rx_ctrl; 47962306a36Sopenharmony_ci u32 mc_hash[2]; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci u32 smb_timer; 48262306a36Sopenharmony_ci /* SPEED_* + DUPLEX_*, SPEED_UNKNOWN if link is down */ 48362306a36Sopenharmony_ci int link_speed; 48462306a36Sopenharmony_ci u8 duplex; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci /* auto-neg advertisement or force mode config */ 48762306a36Sopenharmony_ci u8 flowctrl; 48862306a36Sopenharmony_ci u32 adv_cfg; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci spinlock_t mdio_lock; 49162306a36Sopenharmony_ci struct mdio_if_info mdio; 49262306a36Sopenharmony_ci u16 phy_id[2]; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci /* PHY link patch flag */ 49562306a36Sopenharmony_ci bool lnk_patch; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci /* cumulated stats from the hardware (registers are cleared on read) */ 49862306a36Sopenharmony_ci struct alx_hw_stats stats; 49962306a36Sopenharmony_ci}; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_cistatic inline int alx_hw_revision(struct alx_hw *hw) 50262306a36Sopenharmony_ci{ 50362306a36Sopenharmony_ci return hw->pdev->revision >> ALX_PCI_REVID_SHIFT; 50462306a36Sopenharmony_ci} 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic inline bool alx_hw_with_cr(struct alx_hw *hw) 50762306a36Sopenharmony_ci{ 50862306a36Sopenharmony_ci return hw->pdev->revision & 1; 50962306a36Sopenharmony_ci} 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_cistatic inline bool alx_hw_giga(struct alx_hw *hw) 51262306a36Sopenharmony_ci{ 51362306a36Sopenharmony_ci return hw->pdev->device & 1; 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic inline void alx_write_mem8(struct alx_hw *hw, u32 reg, u8 val) 51762306a36Sopenharmony_ci{ 51862306a36Sopenharmony_ci writeb(val, hw->hw_addr + reg); 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_cistatic inline void alx_write_mem16(struct alx_hw *hw, u32 reg, u16 val) 52262306a36Sopenharmony_ci{ 52362306a36Sopenharmony_ci writew(val, hw->hw_addr + reg); 52462306a36Sopenharmony_ci} 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cistatic inline u16 alx_read_mem16(struct alx_hw *hw, u32 reg) 52762306a36Sopenharmony_ci{ 52862306a36Sopenharmony_ci return readw(hw->hw_addr + reg); 52962306a36Sopenharmony_ci} 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_cistatic inline void alx_write_mem32(struct alx_hw *hw, u32 reg, u32 val) 53262306a36Sopenharmony_ci{ 53362306a36Sopenharmony_ci writel(val, hw->hw_addr + reg); 53462306a36Sopenharmony_ci} 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic inline u32 alx_read_mem32(struct alx_hw *hw, u32 reg) 53762306a36Sopenharmony_ci{ 53862306a36Sopenharmony_ci return readl(hw->hw_addr + reg); 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_cistatic inline void alx_post_write(struct alx_hw *hw) 54262306a36Sopenharmony_ci{ 54362306a36Sopenharmony_ci readl(hw->hw_addr); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ciint alx_get_perm_macaddr(struct alx_hw *hw, u8 *addr); 54762306a36Sopenharmony_civoid alx_reset_phy(struct alx_hw *hw); 54862306a36Sopenharmony_civoid alx_reset_pcie(struct alx_hw *hw); 54962306a36Sopenharmony_civoid alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en); 55062306a36Sopenharmony_ciint alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl); 55162306a36Sopenharmony_civoid alx_post_phy_link(struct alx_hw *hw); 55262306a36Sopenharmony_ciint alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data); 55362306a36Sopenharmony_ciint alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data); 55462306a36Sopenharmony_ciint alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata); 55562306a36Sopenharmony_ciint alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data); 55662306a36Sopenharmony_ciint alx_read_phy_link(struct alx_hw *hw); 55762306a36Sopenharmony_ciint alx_clear_phy_intr(struct alx_hw *hw); 55862306a36Sopenharmony_civoid alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc); 55962306a36Sopenharmony_civoid alx_start_mac(struct alx_hw *hw); 56062306a36Sopenharmony_ciint alx_reset_mac(struct alx_hw *hw); 56162306a36Sopenharmony_civoid alx_set_macaddr(struct alx_hw *hw, const u8 *addr); 56262306a36Sopenharmony_cibool alx_phy_configured(struct alx_hw *hw); 56362306a36Sopenharmony_civoid alx_configure_basic(struct alx_hw *hw); 56462306a36Sopenharmony_civoid alx_mask_msix(struct alx_hw *hw, int index, bool mask); 56562306a36Sopenharmony_civoid alx_disable_rss(struct alx_hw *hw); 56662306a36Sopenharmony_cibool alx_get_phy_info(struct alx_hw *hw); 56762306a36Sopenharmony_civoid alx_update_hw_stats(struct alx_hw *hw); 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_cistatic inline u32 alx_speed_to_ethadv(int speed, u8 duplex) 57062306a36Sopenharmony_ci{ 57162306a36Sopenharmony_ci if (speed == SPEED_1000 && duplex == DUPLEX_FULL) 57262306a36Sopenharmony_ci return ADVERTISED_1000baseT_Full; 57362306a36Sopenharmony_ci if (speed == SPEED_100 && duplex == DUPLEX_FULL) 57462306a36Sopenharmony_ci return ADVERTISED_100baseT_Full; 57562306a36Sopenharmony_ci if (speed == SPEED_100 && duplex== DUPLEX_HALF) 57662306a36Sopenharmony_ci return ADVERTISED_100baseT_Half; 57762306a36Sopenharmony_ci if (speed == SPEED_10 && duplex == DUPLEX_FULL) 57862306a36Sopenharmony_ci return ADVERTISED_10baseT_Full; 57962306a36Sopenharmony_ci if (speed == SPEED_10 && duplex == DUPLEX_HALF) 58062306a36Sopenharmony_ci return ADVERTISED_10baseT_Half; 58162306a36Sopenharmony_ci return 0; 58262306a36Sopenharmony_ci} 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci#endif 585