|
root / base / usr / src / uts / common / io / igc / igc_osdep.h
igc_osdep.h C 203 lines 6.3 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2024 Oxide Computer Company
 */

#ifndef _IGC_OSDEP_H
#define	_IGC_OSDEP_H

/*
 * Definitions that are required for the igc core code.
 */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * The common code requires the following headers.
 */
#include <sys/stdbool.h>
#include <sys/sunddi.h>

/*
 * It requires the following due to what we have declared.
 */
#include <sys/types.h>
#include <sys/ddi.h>
#include <sys/bitext.h>

/*
 * We redeclare the forward struct igc_hw here because this is required to be
 * included for igc_hw.h.
 */
struct igc_hw;

/*
 * The following typedefs allow for the types in the core code to be defined in
 * terms of types that we actually use.
 */
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int32_t s32;
typedef uint16_t __le16;
typedef uint32_t __le32;
typedef uint64_t __le64;

/*
 * Register read and write APIs. While these are in all caps because they are
 * conventionally macros, we implement them as functions in igc_osdep.c.
 */
extern uint32_t IGC_READ_REG(struct igc_hw *, uint32_t);
extern void IGC_WRITE_REG(struct igc_hw *, uint32_t, uint32_t);
extern void IGC_WRITE_REG_ARRAY(struct igc_hw *, uint32_t, uint32_t, uint32_t);

/*
 * This is the implementation of a flush command which forces certain PCIe
 * transaction ordering to complete.
 */
#define	IGC_WRITE_FLUSH(hw)	IGC_READ_REG(hw, IGC_STATUS)

/*
 * Delay variants. The semantics in the common code and Linux use non-sleeping
 * delay variants. It's not really clear that we should be spinning for
 * miliseconds, but for now, that's what we end up doing.
 */
#define	usec_delay(x)		drv_usecwait(x)
#define	usec_delay_irq(x)	drv_usecwait(x)
#define	msec_delay(x)		drv_usecwait((x) * 1000)
#define	msec_delay_irq(x)	drv_usecwait((x) * 1000)

/*
 * Debugging macros that the common code expects to exist. Because of how these
 * are used, we need to define something lest we generate empty body warnings.
 */
extern void igc_core_log(struct igc_hw *, const char *, ...);
#define	DEBUGOUT(str)		igc_core_log(hw, str)
#define	DEBUGOUT1(str, d1)	igc_core_log(hw, str, d1)
#define	DEBUGOUT2(str, d1, d2)	igc_core_log(hw, str, d1, d2)
#define	DEBUGFUNC(str)		igc_core_log(hw, str)

/*
 * The following defines registers or register values that should be defined by
 * the core code, but are not right now. As such, we define them here to
 * minimize the diffs that are required in the core code.
 */

/*
 * Used in the IGC_EECD register to indicate that a flash device is present.
 */
#define	IGC_EECD_EE_DET		(1 << 19)

/*
 * Starting positions of the IVAR queue regions.
 */
#define	IGC_IVAR_RX0_START	0
#define	IGC_IVAR_TX0_START	8
#define	IGC_IVAR_RX1_START	16
#define	IGC_IVAR_TX1_START	24
#define	IGC_IVAR_ENT_LEN	8

/*
 * The I225 has the exact same LED controls that the other parts have. There are
 * three LEDs defined in the IC which are initialized by firmware and controlled
 * through the classic LEDCTL register just like igb/e1000g. While the register
 * is in igc_regs.h, the actual values for the modes in igc_defines.h do not
 * match the I225 Ethernet Controller Datasheet. They match older parts without
 * 2.5 GbE support. See I225/6 Datasheet v2.6.7 Section 3.4 'Configurable LED
 * Outputs'.
 */
typedef enum {
	I225_LED_M_ON	= 0,
	I225_LED_M_OFF,
	I225_LED_M_LINK_UP,
	I225_LED_M_FILTER_ACT,
	I225_LED_M_LINK_ACT,
	I225_LED_M_LINK_10,
	I225_LED_M_LINK_100,
	I225_LED_M_LINK_1000,
	I225_LED_M_LINK_2500,
	I225_LED_M_SDP,
	I225_LED_M_PAUSE,
	I225_LED_M_ACT,
	I225_LED_M_LINK_10_100,
	I225_LED_M_LINK_100_1000,
	I225_LED_M_LINK_1000_2500,
	I225_LED_M_LINK_100_2500,
} i225_led_mode_t;

/*
 * The LED registers are organized into three groups that repeat. Register
 * manipulation functions are defined in igc.c. The following are constants for
 * the various registers.
 */
#define	IGC_I225_NLEDS			3
#define	IGC_LEDCTL_GLOB_BLINK_200MS	0
#define	IGC_LEDCTL_GLOB_BLINK_83MS	1

/*
 * IEEE MMD Status register 7.33 access. These definitions are done in the style
 * of igc_defines.h, where this phy is missing. We should eventually update the
 * mii layer headers to know about this. See IEEE Table 45-386 'MultiGBASE-T AN
 * status 1 register'.
 */
#define	ANEG_MULTIGBT_AN_STS1		0x0021 /* MULTI GBT Status 1 register */
#define	MMD_AN_STS1_LP_40T_FRT		(1 << 0)
#define	MMD_AN_STS1_LP_10T_FRT		(1 << 1)
#define	MMD_AN_STS1_LP_25T_FRT		(1 << 2)
#define	MMD_AN_STS1_LP_2P5T_FRT		(1 << 3)
#define	MMD_AN_STS1_LP_5T_FRT		(1 << 4)
#define	MMD_AN_STS1_LP_2P5T_CAP		(1 << 5)
#define	MMD_AN_STS1_LP_5T_CAP		(1 << 6)
#define	MMD_AN_STS1_LP_25T_CAP		(1 << 7)
#define	MMD_AN_STS1_LP_40T_CAP		(1 << 8)
#define	MMD_AN_STS1_LP_10T_PMA		(1 << 9)
#define	MMD_AN_STS1_LP_LOOP_TIME	(1 << 10)
#define	MMD_AN_STS1_LP_10T_CAP		(1 << 11)
#define	MMD_AN_STS1_LP_REM_STS		(1 << 12)
#define	MMD_AN_STS1_LP_LOC_STS		(1 << 13)
#define	MMD_AN_STS1_LP_MSC_RES		(1 << 14)
#define	MMD_AN_STS1_LP_MSC_FLT		(1 << 15)

/*
 * Reserved bits in the RXDCTL register that must be preserved. The I210
 * datasheet indicates that it leverages bits 24:21 and then 31:27. There are
 * other reserved portions by they are explicitly write 0.
 */
#define	IGC_RXDCTL_PRESERVE	0xf9e00000

/*
 * Missing setters for the various prefetch, host, and write-back thresholds.
 */
#define	IGC_RXDCTL_SET_PTHRESH(r, v)	bitset32(r, 4, 0, v)
#define	IGC_RXDCTL_SET_HTHRESH(r, v)	bitset32(r, 12, 8, v)
#define	IGC_RXDCTL_SET_WTHRESH(r, v)	bitset32(r, 20, 16, v)

/*
 * Missing setters for the tx varaint. We assume that this uses the shorter I210
 * 5-bit range as opposed to the I217 6-bit range. Given we don't set anything
 * much higher than this, this is the best we can do. In general this is more
 * I210-like than I217-like.
 */
#define	IGC_TXDCTL_SET_PTHRESH(r, v)	bitset32(r, 4, 0, v)
#define	IGC_TXDCTL_SET_HTHRESH(r, v)	bitset32(r, 13, 8, v)
#define	IGC_TXDCTL_SET_WTHRESH(r, v)	bitset32(r, 20, 16, v)

#ifdef __cplusplus
}
#endif

#endif /* _IGC_OSDEP_H */