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