xref: /openbsd-src/sys/dev/pci/igc_hw.h (revision 8f0f8a75b873b7983a96e904a7ea1a909d7030e1)
1*8f0f8a75Sjsg /*	$OpenBSD: igc_hw.h,v 1.3 2024/05/13 01:22:47 jsg Exp $	*/
283306792Spatrick /*-
383306792Spatrick  * Copyright 2021 Intel Corp
483306792Spatrick  * Copyright 2021 Rubicon Communications, LLC (Netgate)
583306792Spatrick  * SPDX-License-Identifier: BSD-3-Clause
683306792Spatrick  *
783306792Spatrick  * $FreeBSD$
883306792Spatrick  */
983306792Spatrick 
1083306792Spatrick #ifndef _IGC_HW_H_
1183306792Spatrick #define _IGC_HW_H_
1283306792Spatrick 
1383306792Spatrick #include "bpfilter.h"
1483306792Spatrick #include "vlan.h"
1583306792Spatrick 
1683306792Spatrick #include <sys/param.h>
1783306792Spatrick #include <sys/systm.h>
1883306792Spatrick #include <sys/sockio.h>
1983306792Spatrick #include <sys/mbuf.h>
2083306792Spatrick #include <sys/malloc.h>
2183306792Spatrick #include <sys/kernel.h>
2283306792Spatrick #include <sys/socket.h>
2383306792Spatrick #include <sys/device.h>
2483306792Spatrick #include <sys/endian.h>
2583306792Spatrick #include <sys/intrmap.h>
2683306792Spatrick 
2783306792Spatrick #include <net/if.h>
2883306792Spatrick #include <net/if_media.h>
2983306792Spatrick #include <net/toeplitz.h>
3083306792Spatrick 
3183306792Spatrick #include <netinet/in.h>
3283306792Spatrick #include <netinet/if_ether.h>
3383306792Spatrick 
3483306792Spatrick #if NBPFILTER > 0
3583306792Spatrick #include <net/bpf.h>
3683306792Spatrick #endif
3783306792Spatrick 
3883306792Spatrick #include <machine/bus.h>
3983306792Spatrick #include <machine/intr.h>
4083306792Spatrick 
4183306792Spatrick #include <dev/pci/pcivar.h>
4283306792Spatrick #include <dev/pci/pcireg.h>
4383306792Spatrick #include <dev/pci/pcidevs.h>
4483306792Spatrick 
4583306792Spatrick #include <dev/pci/igc_base.h>
4683306792Spatrick #include <dev/pci/igc_defines.h>
4783306792Spatrick #include <dev/pci/igc_i225.h>
4883306792Spatrick #include <dev/pci/igc_mac.h>
4983306792Spatrick #include <dev/pci/igc_nvm.h>
5083306792Spatrick #include <dev/pci/igc_phy.h>
5183306792Spatrick #include <dev/pci/igc_regs.h>
5283306792Spatrick 
5383306792Spatrick struct igc_hw;
5483306792Spatrick 
5583306792Spatrick #define IGC_FUNC_1	1
5683306792Spatrick 
5783306792Spatrick #define IGC_ALT_MAC_ADDRESS_OFFSET_LAN0	0
5883306792Spatrick #define IGC_ALT_MAC_ADDRESS_OFFSET_LAN1	3
5983306792Spatrick 
6083306792Spatrick enum igc_mac_type {
6183306792Spatrick 	igc_undefined = 0,
6283306792Spatrick 	igc_i225,
6383306792Spatrick 	igc_num_macs	/* List is 1-based, so subtract 1 for TRUE count. */
6483306792Spatrick };
6583306792Spatrick 
6683306792Spatrick enum igc_media_type {
6783306792Spatrick 	igc_media_type_unknown = 0,
6883306792Spatrick 	igc_media_type_copper = 1,
6983306792Spatrick 	igc_num_media_types
7083306792Spatrick };
7183306792Spatrick 
7283306792Spatrick enum igc_nvm_type {
7383306792Spatrick 	igc_nvm_unknown = 0,
7483306792Spatrick 	igc_nvm_eeprom_spi,
7583306792Spatrick 	igc_nvm_flash_hw,
7683306792Spatrick 	igc_nvm_invm
7783306792Spatrick };
7883306792Spatrick 
7983306792Spatrick enum igc_phy_type {
8083306792Spatrick 	igc_phy_unknown = 0,
8183306792Spatrick 	igc_phy_none,
8283306792Spatrick 	igc_phy_i225
8383306792Spatrick };
8483306792Spatrick 
8583306792Spatrick enum igc_bus_type {
8683306792Spatrick 	igc_bus_type_unknown = 0,
8783306792Spatrick 	igc_bus_type_pci,
8883306792Spatrick 	igc_bus_type_pcix,
8983306792Spatrick 	igc_bus_type_pci_express,
9083306792Spatrick 	igc_bus_type_reserved
9183306792Spatrick };
9283306792Spatrick 
9383306792Spatrick enum igc_bus_speed {
9483306792Spatrick 	igc_bus_speed_unknown = 0,
9583306792Spatrick 	igc_bus_speed_33,
9683306792Spatrick 	igc_bus_speed_66,
9783306792Spatrick 	igc_bus_speed_100,
9883306792Spatrick 	igc_bus_speed_120,
9983306792Spatrick 	igc_bus_speed_133,
10083306792Spatrick 	igc_bus_speed_2500,
10183306792Spatrick 	igc_bus_speed_5000,
10283306792Spatrick 	igc_bus_speed_reserved
10383306792Spatrick };
10483306792Spatrick 
10583306792Spatrick enum igc_bus_width {
10683306792Spatrick 	igc_bus_width_unknown = 0,
10783306792Spatrick 	igc_bus_width_pcie_x1,
10883306792Spatrick 	igc_bus_width_pcie_x2,
10983306792Spatrick 	igc_bus_width_pcie_x4 = 4,
11083306792Spatrick 	igc_bus_width_pcie_x8 = 8,
11183306792Spatrick 	igc_bus_width_32,
11283306792Spatrick 	igc_bus_width_64,
11383306792Spatrick 	igc_bus_width_reserved
11483306792Spatrick };
11583306792Spatrick 
11683306792Spatrick enum igc_fc_mode {
11783306792Spatrick 	igc_fc_none = 0,
11883306792Spatrick 	igc_fc_rx_pause,
11983306792Spatrick 	igc_fc_tx_pause,
12083306792Spatrick 	igc_fc_full,
12183306792Spatrick 	igc_fc_default = 0xFF
12283306792Spatrick };
12383306792Spatrick 
12483306792Spatrick enum igc_ms_type {
12583306792Spatrick 	igc_ms_hw_default = 0,
12683306792Spatrick 	igc_ms_force_master,
12783306792Spatrick 	igc_ms_force_slave,
12883306792Spatrick 	igc_ms_auto
12983306792Spatrick };
13083306792Spatrick 
13183306792Spatrick enum igc_smart_speed {
13283306792Spatrick 	igc_smart_speed_default = 0,
13383306792Spatrick 	igc_smart_speed_on,
13483306792Spatrick 	igc_smart_speed_off
13583306792Spatrick };
13683306792Spatrick 
13783306792Spatrick /* Receive Descriptor */
13883306792Spatrick struct igc_rx_desc {
13983306792Spatrick 	uint64_t buffer_addr;	/* Address of the descriptor's data buffer */
14083306792Spatrick 	uint64_t length;	/* Length of data DMAed into data buffer */
14183306792Spatrick 	uint16_t csum;		/* Packet checksum */
14283306792Spatrick 	uint8_t  status;	/* Descriptor status */
14383306792Spatrick 	uint8_t  errors;	/* Descriptor errors */
14483306792Spatrick 	uint16_t special;
14583306792Spatrick };
14683306792Spatrick 
14783306792Spatrick /* Receive Descriptor - Extended */
14883306792Spatrick union igc_rx_desc_extended {
14983306792Spatrick 	struct {
15083306792Spatrick 		uint64_t buffer_addr;
15183306792Spatrick 		uint64_t reserved;
15283306792Spatrick 	} read;
15383306792Spatrick 	struct {
15483306792Spatrick 		struct {
15583306792Spatrick 			uint32_t mrq;	/* Multiple Rx queues */
15683306792Spatrick 			union {
15783306792Spatrick 				uint32_t rss;	/* RSS hash */
15883306792Spatrick 				struct {
15983306792Spatrick 					uint16_t ip_id;	/* IP id */
16083306792Spatrick 					uint16_t csum;	/* Packet checksum */
16183306792Spatrick 				} csum_ip;
16283306792Spatrick 			} hi_dword;
16383306792Spatrick 		} lower;
16483306792Spatrick 		struct {
16583306792Spatrick 			uint32_t status_error;	/* ext status/error */
16683306792Spatrick 			uint16_t length;
16783306792Spatrick 			uint16_t vlan;	/* VLAN tag */
16883306792Spatrick 		} upper;
16983306792Spatrick 	} wb;	/* writeback */
17083306792Spatrick };
17183306792Spatrick 
17283306792Spatrick /* Transmit Descriptor */
17383306792Spatrick struct igc_tx_desc {
17483306792Spatrick 	uint64_t buffer_addr;	/* Address of the descriptor's data buffer */
17583306792Spatrick 	union {
17683306792Spatrick 		uint32_t data;
17783306792Spatrick 		struct {
17883306792Spatrick 			uint16_t length;	/* Data buffer length */
17983306792Spatrick 			uint8_t cso;	/* Checksum offset */
18083306792Spatrick 			uint8_t cmd;	/* Descriptor control */
18183306792Spatrick 		} flags;
18283306792Spatrick 	} lower;
18383306792Spatrick 	union {
18483306792Spatrick 		uint32_t data;
18583306792Spatrick 		struct {
18683306792Spatrick 			uint8_t status;	/* Descriptor status */
18783306792Spatrick 			uint8_t css;	/* Checksum start */
18883306792Spatrick 			uint16_t special;
18983306792Spatrick 		} fields;
19083306792Spatrick 	} upper;
19183306792Spatrick };
19283306792Spatrick 
19383306792Spatrick /* Function pointers for the MAC. */
19483306792Spatrick struct igc_mac_operations {
19583306792Spatrick 	int	(*init_params)(struct igc_hw *);
19683306792Spatrick 	int	(*check_for_link)(struct igc_hw *);
19783306792Spatrick 	void	(*clear_hw_cntrs)(struct igc_hw *);
19883306792Spatrick 	void	(*clear_vfta)(struct igc_hw *);
19983306792Spatrick 	int	(*get_bus_info)(struct igc_hw *);
20083306792Spatrick 	void	(*set_lan_id)(struct igc_hw *);
20183306792Spatrick 	int	(*get_link_up_info)(struct igc_hw *, uint16_t *, uint16_t *);
20283306792Spatrick 	void	(*update_mc_addr_list)(struct igc_hw *, uint8_t *, uint32_t);
20383306792Spatrick 	int	(*reset_hw)(struct igc_hw *);
20483306792Spatrick 	int	(*init_hw)(struct igc_hw *);
20583306792Spatrick 	int	(*setup_link)(struct igc_hw *);
20683306792Spatrick 	int	(*setup_physical_interface)(struct igc_hw *);
20783306792Spatrick 	void	(*write_vfta)(struct igc_hw *, uint32_t, uint32_t);
20883306792Spatrick 	void	(*config_collision_dist)(struct igc_hw *);
20983306792Spatrick 	int	(*rar_set)(struct igc_hw *, uint8_t *, uint32_t);
21083306792Spatrick 	int	(*read_mac_addr)(struct igc_hw *);
21183306792Spatrick 	int	(*validate_mdi_setting)(struct igc_hw *);
21283306792Spatrick 	int	(*acquire_swfw_sync)(struct igc_hw *, uint16_t);
21383306792Spatrick 	void	(*release_swfw_sync)(struct igc_hw *, uint16_t);
21483306792Spatrick };
21583306792Spatrick 
21683306792Spatrick /* When to use various PHY register access functions:
21783306792Spatrick  *
21883306792Spatrick  *                 Func   Caller
21983306792Spatrick  *   Function      Does   Does    When to use
22083306792Spatrick  *   ~~~~~~~~~~~~  ~~~~~  ~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22183306792Spatrick  *   X_reg         L,P,A  n/a     for simple PHY reg accesses
22283306792Spatrick  *   X_reg_locked  P,A    L       for multiple accesses of different regs
22383306792Spatrick  *                                on different pages
22483306792Spatrick  *   X_reg_page    A      L,P     for multiple accesses of different regs
22583306792Spatrick  *                                on the same page
22683306792Spatrick  *
22783306792Spatrick  * Where X=[read|write], L=locking, P=sets page, A=register access
22883306792Spatrick  *
22983306792Spatrick  */
23083306792Spatrick struct igc_phy_operations {
23183306792Spatrick 	int	(*init_params)(struct igc_hw *);
23283306792Spatrick 	int	(*acquire)(struct igc_hw *);
23383306792Spatrick 	int	(*check_reset_block)(struct igc_hw *);
23483306792Spatrick 	int	(*force_speed_duplex)(struct igc_hw *);
23583306792Spatrick 	int	(*get_info)(struct igc_hw *);
23683306792Spatrick 	int	(*set_page)(struct igc_hw *, uint16_t);
23783306792Spatrick 	int	(*read_reg)(struct igc_hw *, uint32_t, uint16_t *);
23883306792Spatrick 	int	(*read_reg_locked)(struct igc_hw *, uint32_t, uint16_t *);
23983306792Spatrick 	int	(*read_reg_page)(struct igc_hw *, uint32_t, uint16_t *);
24083306792Spatrick 	void	(*release)(struct igc_hw *);
24183306792Spatrick 	int	(*reset)(struct igc_hw *);
24283306792Spatrick 	int	(*set_d0_lplu_state)(struct igc_hw *, bool);
24383306792Spatrick 	int	(*set_d3_lplu_state)(struct igc_hw *, bool);
24483306792Spatrick 	int	(*write_reg)(struct igc_hw *, uint32_t, uint16_t);
24583306792Spatrick 	int	(*write_reg_locked)(struct igc_hw *, uint32_t, uint16_t);
24683306792Spatrick 	int	(*write_reg_page)(struct igc_hw *, uint32_t, uint16_t);
24783306792Spatrick 	void	(*power_up)(struct igc_hw *);
24883306792Spatrick 	void	(*power_down)(struct igc_hw *);
24983306792Spatrick };
25083306792Spatrick 
25183306792Spatrick /* Function pointers for the NVM. */
25283306792Spatrick struct igc_nvm_operations {
25383306792Spatrick 	int	(*init_params)(struct igc_hw *);
25483306792Spatrick 	int	(*acquire)(struct igc_hw *);
25583306792Spatrick 	int	(*read)(struct igc_hw *, uint16_t, uint16_t, uint16_t *);
25683306792Spatrick 	void	(*release)(struct igc_hw *);
25783306792Spatrick 	void	(*reload)(struct igc_hw *);
25883306792Spatrick 	int	(*update)(struct igc_hw *);
25983306792Spatrick 	int	(*validate)(struct igc_hw *);
26083306792Spatrick 	int	(*write)(struct igc_hw *, uint16_t, uint16_t, uint16_t *);
26183306792Spatrick };
26283306792Spatrick 
26383306792Spatrick struct igc_mac_info {
26483306792Spatrick 	struct igc_mac_operations	ops;
26583306792Spatrick 	uint8_t				addr[ETHER_ADDR_LEN];
26683306792Spatrick 	uint8_t				perm_addr[ETHER_ADDR_LEN];
26783306792Spatrick 
26883306792Spatrick 	enum igc_mac_type		type;
26983306792Spatrick 
27083306792Spatrick 	uint32_t			mc_filter_type;
27183306792Spatrick 
27283306792Spatrick 	uint16_t			current_ifs_val;
27383306792Spatrick 	uint16_t			ifs_max_val;
27483306792Spatrick 	uint16_t			ifs_min_val;
27583306792Spatrick 	uint16_t			ifs_ratio;
27683306792Spatrick 	uint16_t			ifs_step_size;
27783306792Spatrick 	uint16_t			mta_reg_count;
27883306792Spatrick 	uint16_t			uta_reg_count;
27983306792Spatrick 
28083306792Spatrick 	/* Maximum size of the MTA register table in all supported adapters */
28183306792Spatrick #define MAX_MTA_REG	128
28283306792Spatrick 	uint32_t			mta_shadow[MAX_MTA_REG];
28383306792Spatrick 	uint16_t			rar_entry_count;
28483306792Spatrick 
28583306792Spatrick 	uint8_t				forced_speed_duplex;
28683306792Spatrick 
28783306792Spatrick 	bool				asf_firmware_present;
28883306792Spatrick 	bool				autoneg;
28983306792Spatrick 	bool				get_link_status;
29083306792Spatrick 	uint32_t			max_frame_size;
29183306792Spatrick };
29283306792Spatrick 
29383306792Spatrick struct igc_phy_info {
29483306792Spatrick 	struct igc_phy_operations	ops;
29583306792Spatrick 	enum igc_phy_type		type;
29683306792Spatrick 
29783306792Spatrick 	enum igc_smart_speed		smart_speed;
29883306792Spatrick 
29983306792Spatrick 	uint32_t			addr;
30083306792Spatrick 	uint32_t			id;
30183306792Spatrick 	uint32_t			reset_delay_us;	/* in usec */
30283306792Spatrick 	uint32_t			revision;
30383306792Spatrick 
30483306792Spatrick 	enum igc_media_type		media_type;
30583306792Spatrick 
30683306792Spatrick 	uint16_t			autoneg_advertised;
30783306792Spatrick 	uint16_t			autoneg_mask;
30883306792Spatrick 
30983306792Spatrick 	uint8_t				mdix;
31083306792Spatrick 
31183306792Spatrick 	bool				polarity_correction;
31283306792Spatrick 	bool				speed_downgraded;
31383306792Spatrick 	bool				autoneg_wait_to_complete;
31483306792Spatrick };
31583306792Spatrick 
31683306792Spatrick struct igc_nvm_info {
31783306792Spatrick 	struct igc_nvm_operations	ops;
31883306792Spatrick 	enum igc_nvm_type		type;
31983306792Spatrick 
32083306792Spatrick 	uint16_t			word_size;
32183306792Spatrick 	uint16_t			delay_usec;
32283306792Spatrick 	uint16_t			address_bits;
32383306792Spatrick 	uint16_t			opcode_bits;
32483306792Spatrick 	uint16_t			page_size;
32583306792Spatrick };
32683306792Spatrick 
32783306792Spatrick struct igc_bus_info {
32883306792Spatrick 	enum igc_bus_type	type;
32983306792Spatrick 	enum igc_bus_speed	speed;
33083306792Spatrick 	enum igc_bus_width	width;
33183306792Spatrick 
33283306792Spatrick 	uint16_t		func;
33383306792Spatrick 	uint16_t		pci_cmd_word;
33483306792Spatrick };
33583306792Spatrick 
33683306792Spatrick struct igc_fc_info {
33783306792Spatrick 	uint32_t	high_water;
33883306792Spatrick 	uint32_t	low_water;
33983306792Spatrick 	uint16_t	pause_time;
34083306792Spatrick 	uint16_t	refresh_time;
34183306792Spatrick 	bool		send_xon;
34283306792Spatrick 	bool		strict_ieee;
34383306792Spatrick 	enum		igc_fc_mode current_mode;
34483306792Spatrick 	enum		igc_fc_mode requested_mode;
34583306792Spatrick };
34683306792Spatrick 
34783306792Spatrick struct igc_dev_spec_i225 {
34883306792Spatrick 	bool		eee_disable;
34983306792Spatrick 	bool		clear_semaphore_once;
35083306792Spatrick 	uint32_t	mtu;
35183306792Spatrick };
35283306792Spatrick 
35383306792Spatrick struct igc_hw {
35483306792Spatrick 	void			*back;
35583306792Spatrick 
35683306792Spatrick 	uint8_t			*hw_addr;
35783306792Spatrick 
35883306792Spatrick 	struct igc_mac_info	mac;
35983306792Spatrick 	struct igc_fc_info	fc;
36083306792Spatrick 	struct igc_phy_info	phy;
36183306792Spatrick 	struct igc_nvm_info	nvm;
36283306792Spatrick 	struct igc_bus_info	bus;
36383306792Spatrick 
36483306792Spatrick 	union {
36583306792Spatrick 		struct igc_dev_spec_i225 _i225;
36683306792Spatrick 	} dev_spec;
36783306792Spatrick 
36883306792Spatrick 	uint16_t		device_id;
36983306792Spatrick };
37083306792Spatrick 
37183306792Spatrick #endif	/* _IGC_HW_H_ */
372