diff options
Diffstat (limited to 'sys/dev/pci/igc_hw.h')
-rw-r--r-- | sys/dev/pci/igc_hw.h | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/sys/dev/pci/igc_hw.h b/sys/dev/pci/igc_hw.h new file mode 100644 index 00000000000..4224afb4945 --- /dev/null +++ b/sys/dev/pci/igc_hw.h @@ -0,0 +1,394 @@ +/* $OpenBSD: igc_hw.h,v 1.1 2021/10/31 14:52:57 patrick Exp $ */ +/*- + * Copyright 2021 Intel Corp + * Copyright 2021 Rubicon Communications, LLC (Netgate) + * SPDX-License-Identifier: BSD-3-Clause + * + * $FreeBSD$ + */ + +#ifndef _IGC_HW_H_ +#define _IGC_HW_H_ + +#include "bpfilter.h" +#include "vlan.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/sockio.h> +#include <sys/mbuf.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/socket.h> +#include <sys/device.h> +#include <sys/endian.h> +#include <sys/intrmap.h> + +#include <net/if.h> +#include <net/if_media.h> +#include <net/toeplitz.h> + +#include <netinet/in.h> +#include <netinet/if_ether.h> + +#if NBPFILTER > 0 +#include <net/bpf.h> +#endif + +#include <machine/bus.h> +#include <machine/intr.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> + +#include <dev/pci/igc_base.h> +#include <dev/pci/igc_defines.h> +#include <dev/pci/igc_i225.h> +#include <dev/pci/igc_mac.h> +#include <dev/pci/igc_nvm.h> +#include <dev/pci/igc_phy.h> +#include <dev/pci/igc_regs.h> + +#if 0 +/* Enable/disable debugging statements in shared code */ +#define DBG 0 + +#define DEBUGOUT(...) \ + do { if (DBG) printf(__VA_ARGS__); } while (0) +#define DEBUGOUT1(...) DEBUGOUT(__VA_ARGS__) +#define DEBUGOUT2(...) DEBUGOUT(__VA_ARGS__) +#define DEBUGOUT3(...) DEBUGOUT(__VA_ARGS__) +#define DEBUGOUT7(...) DEBUGOUT(__VA_ARGS__) +#define DEBUGFUNC(F) DEBUGOUT(F "\n") +#endif + +struct igc_hw; + +#define IGC_FUNC_1 1 + +#define IGC_ALT_MAC_ADDRESS_OFFSET_LAN0 0 +#define IGC_ALT_MAC_ADDRESS_OFFSET_LAN1 3 + +enum igc_mac_type { + igc_undefined = 0, + igc_i225, + igc_num_macs /* List is 1-based, so subtract 1 for TRUE count. */ +}; + +enum igc_media_type { + igc_media_type_unknown = 0, + igc_media_type_copper = 1, + igc_num_media_types +}; + +enum igc_nvm_type { + igc_nvm_unknown = 0, + igc_nvm_eeprom_spi, + igc_nvm_flash_hw, + igc_nvm_invm +}; + +enum igc_phy_type { + igc_phy_unknown = 0, + igc_phy_none, + igc_phy_i225 +}; + +enum igc_bus_type { + igc_bus_type_unknown = 0, + igc_bus_type_pci, + igc_bus_type_pcix, + igc_bus_type_pci_express, + igc_bus_type_reserved +}; + +enum igc_bus_speed { + igc_bus_speed_unknown = 0, + igc_bus_speed_33, + igc_bus_speed_66, + igc_bus_speed_100, + igc_bus_speed_120, + igc_bus_speed_133, + igc_bus_speed_2500, + igc_bus_speed_5000, + igc_bus_speed_reserved +}; + +enum igc_bus_width { + igc_bus_width_unknown = 0, + igc_bus_width_pcie_x1, + igc_bus_width_pcie_x2, + igc_bus_width_pcie_x4 = 4, + igc_bus_width_pcie_x8 = 8, + igc_bus_width_32, + igc_bus_width_64, + igc_bus_width_reserved +}; + +enum igc_fc_mode { + igc_fc_none = 0, + igc_fc_rx_pause, + igc_fc_tx_pause, + igc_fc_full, + igc_fc_default = 0xFF +}; + +enum igc_ms_type { + igc_ms_hw_default = 0, + igc_ms_force_master, + igc_ms_force_slave, + igc_ms_auto +}; + +enum igc_smart_speed { + igc_smart_speed_default = 0, + igc_smart_speed_on, + igc_smart_speed_off +}; + +/* Receive Descriptor */ +struct igc_rx_desc { + uint64_t buffer_addr; /* Address of the descriptor's data buffer */ + uint64_t length; /* Length of data DMAed into data buffer */ + uint16_t csum; /* Packet checksum */ + uint8_t status; /* Descriptor status */ + uint8_t errors; /* Descriptor errors */ + uint16_t special; +}; + +/* Receive Descriptor - Extended */ +union igc_rx_desc_extended { + struct { + uint64_t buffer_addr; + uint64_t reserved; + } read; + struct { + struct { + uint32_t mrq; /* Multiple Rx queues */ + union { + uint32_t rss; /* RSS hash */ + struct { + uint16_t ip_id; /* IP id */ + uint16_t csum; /* Packet checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + uint32_t status_error; /* ext status/error */ + uint16_t length; + uint16_t vlan; /* VLAN tag */ + } upper; + } wb; /* writeback */ +}; + +/* Transmit Descriptor */ +struct igc_tx_desc { + uint64_t buffer_addr; /* Address of the descriptor's data buffer */ + union { + uint32_t data; + struct { + uint16_t length; /* Data buffer length */ + uint8_t cso; /* Checksum offset */ + uint8_t cmd; /* Descriptor control */ + } flags; + } lower; + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t css; /* Checksum start */ + uint16_t special; + } fields; + } upper; +}; + +/* Function pointers for the MAC. */ +struct igc_mac_operations { + int (*init_params)(struct igc_hw *); + int (*check_for_link)(struct igc_hw *); + void (*clear_hw_cntrs)(struct igc_hw *); + void (*clear_vfta)(struct igc_hw *); + int (*get_bus_info)(struct igc_hw *); + void (*set_lan_id)(struct igc_hw *); + int (*get_link_up_info)(struct igc_hw *, uint16_t *, uint16_t *); + void (*update_mc_addr_list)(struct igc_hw *, uint8_t *, uint32_t); + int (*reset_hw)(struct igc_hw *); + int (*init_hw)(struct igc_hw *); + int (*setup_link)(struct igc_hw *); + int (*setup_physical_interface)(struct igc_hw *); + void (*write_vfta)(struct igc_hw *, uint32_t, uint32_t); + void (*config_collision_dist)(struct igc_hw *); + int (*rar_set)(struct igc_hw *, uint8_t *, uint32_t); + int (*read_mac_addr)(struct igc_hw *); + int (*validate_mdi_setting)(struct igc_hw *); + int (*acquire_swfw_sync)(struct igc_hw *, uint16_t); + void (*release_swfw_sync)(struct igc_hw *, uint16_t); +}; + +/* When to use various PHY register access functions: + * + * Func Caller + * Function Does Does When to use + * ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * X_reg L,P,A n/a for simple PHY reg accesses + * X_reg_locked P,A L for multiple accesses of different regs + * on different pages + * X_reg_page A L,P for multiple accesses of different regs + * on the same page + * + * Where X=[read|write], L=locking, P=sets page, A=register access + * + */ +struct igc_phy_operations { + int (*init_params)(struct igc_hw *); + int (*acquire)(struct igc_hw *); + int (*check_reset_block)(struct igc_hw *); + int (*commit)(struct igc_hw *); + int (*force_speed_duplex)(struct igc_hw *); + int (*get_info)(struct igc_hw *); + int (*set_page)(struct igc_hw *, uint16_t); + int (*read_reg)(struct igc_hw *, uint32_t, uint16_t *); + int (*read_reg_locked)(struct igc_hw *, uint32_t, uint16_t *); + int (*read_reg_page)(struct igc_hw *, uint32_t, uint16_t *); + void (*release)(struct igc_hw *); + int (*reset)(struct igc_hw *); + int (*set_d0_lplu_state)(struct igc_hw *, bool); + int (*set_d3_lplu_state)(struct igc_hw *, bool); + int (*write_reg)(struct igc_hw *, uint32_t, uint16_t); + int (*write_reg_locked)(struct igc_hw *, uint32_t, uint16_t); + int (*write_reg_page)(struct igc_hw *, uint32_t, uint16_t); + void (*power_up)(struct igc_hw *); + void (*power_down)(struct igc_hw *); +}; + +/* Function pointers for the NVM. */ +struct igc_nvm_operations { + int (*init_params)(struct igc_hw *); + int (*acquire)(struct igc_hw *); + int (*read)(struct igc_hw *, uint16_t, uint16_t, uint16_t *); + void (*release)(struct igc_hw *); + void (*reload)(struct igc_hw *); + int (*update)(struct igc_hw *); + int (*validate)(struct igc_hw *); + int (*write)(struct igc_hw *, uint16_t, uint16_t, uint16_t *); +}; + +struct igc_info { + int (*get_invariants)(struct igc_hw *hw); + struct igc_mac_operations *mac_ops; + const struct igc_phy_operations *phy_ops; + struct igc_nvm_operations *nvm_ops; +}; + +extern const struct igc_info igc_i225_info; + +struct igc_mac_info { + struct igc_mac_operations ops; + uint8_t addr[ETHER_ADDR_LEN]; + uint8_t perm_addr[ETHER_ADDR_LEN]; + + enum igc_mac_type type; + + uint32_t mc_filter_type; + + uint16_t current_ifs_val; + uint16_t ifs_max_val; + uint16_t ifs_min_val; + uint16_t ifs_ratio; + uint16_t ifs_step_size; + uint16_t mta_reg_count; + uint16_t uta_reg_count; + + /* Maximum size of the MTA register table in all supported adapters */ +#define MAX_MTA_REG 128 + uint32_t mta_shadow[MAX_MTA_REG]; + uint16_t rar_entry_count; + + uint8_t forced_speed_duplex; + + bool asf_firmware_present; + bool autoneg; + bool get_link_status; + uint32_t max_frame_size; +}; + +struct igc_phy_info { + struct igc_phy_operations ops; + enum igc_phy_type type; + + enum igc_smart_speed smart_speed; + + uint32_t addr; + uint32_t id; + uint32_t reset_delay_us; /* in usec */ + uint32_t revision; + + enum igc_media_type media_type; + + uint16_t autoneg_advertised; + uint16_t autoneg_mask; + + uint8_t mdix; + + bool polarity_correction; + bool speed_downgraded; + bool autoneg_wait_to_complete; +}; + +struct igc_nvm_info { + struct igc_nvm_operations ops; + enum igc_nvm_type type; + + uint16_t word_size; + uint16_t delay_usec; + uint16_t address_bits; + uint16_t opcode_bits; + uint16_t page_size; +}; + +struct igc_bus_info { + enum igc_bus_type type; + enum igc_bus_speed speed; + enum igc_bus_width width; + + uint16_t func; + uint16_t pci_cmd_word; +}; + +struct igc_fc_info { + uint32_t high_water; + uint32_t low_water; + uint16_t pause_time; + uint16_t refresh_time; + bool send_xon; + bool strict_ieee; + enum igc_fc_mode current_mode; + enum igc_fc_mode requested_mode; +}; + +struct igc_dev_spec_i225 { + bool eee_disable; + bool clear_semaphore_once; + uint32_t mtu; +}; + +struct igc_hw { + void *back; + + uint8_t *hw_addr; + + struct igc_mac_info mac; + struct igc_fc_info fc; + struct igc_phy_info phy; + struct igc_nvm_info nvm; + struct igc_bus_info bus; + + union { + struct igc_dev_spec_i225 _i225; + } dev_spec; + + uint16_t device_id; +}; + +#endif /* _IGC_HW_H_ */ |