2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2002-2007 Neterion, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <dev/nxge/include/xgehal.h>
35 #include <dev/nxge/xge-osdep.h>
37 /* Printing description, Copyright */
38 #define XGE_DRIVER_VERSION \
39 XGELL_VERSION_MAJOR"."XGELL_VERSION_MINOR"." \
40 XGELL_VERSION_FIX"."XGELL_VERSION_BUILD
41 #define XGE_COPYRIGHT "Copyright(c) 2002-2007 Neterion Inc."
44 #define xge_trace(trace, fmt, args...) xge_debug_ll(trace, fmt, ## args);
46 #define XGE_ALIGN_TO(buffer_length, to) { \
47 if((buffer_length % to) != 0) { \
48 buffer_length += (to - (buffer_length % to)); \
52 #define XGE_EXIT_ON_ERR(text, label, return_value) { \
53 xge_trace(XGE_ERR, "%s (Status: %d)", text, return_value); \
54 status = return_value; \
58 #define XGE_SET_BUFFER_MODE_IN_RINGS(mode) { \
59 for(index = 0; index < XGE_RING_COUNT; index++) \
60 ring_config->queue[index].buffer_mode = mode; \
63 #define XGE_DEFAULT_USER_HARDCODED -1
64 #define XGE_MAX_SEGS 100 /* Maximum number of segments */
65 #define XGE_TX_LEVEL_LOW 16
66 #define XGE_FIFO_COUNT XGE_HAL_MIN_FIFO_NUM
67 #define XGE_RING_COUNT XGE_HAL_MIN_RING_NUM
68 #define XGE_BUFFER_SIZE 20
69 #define XGE_LRO_DEFAULT_ENTRIES 12
70 #define XGE_BAUDRATE 1000000000
72 /* Default values to configuration parameters */
73 #define XGE_DEFAULT_ENABLED_TSO 1
74 #define XGE_DEFAULT_ENABLED_LRO 1
75 #define XGE_DEFAULT_ENABLED_MSI 1
76 #define XGE_DEFAULT_BUFFER_MODE 1
77 #define XGE_DEFAULT_INITIAL_MTU 1500
78 #define XGE_DEFAULT_LATENCY_TIMER -1
79 #define XGE_DEFAULT_MAX_SPLITS_TRANS -1
80 #define XGE_DEFAULT_MMRB_COUNT -1
81 #define XGE_DEFAULT_SHARED_SPLITS 0
82 #define XGE_DEFAULT_ISR_POLLING_CNT 8
83 #define XGE_DEFAULT_STATS_REFRESH_TIME_SEC 4
84 #define XGE_DEFAULT_MAC_RMAC_BCAST_EN 1
85 #define XGE_DEFAULT_MAC_TMAC_UTIL_PERIOD 5
86 #define XGE_DEFAULT_MAC_RMAC_UTIL_PERIOD 5
87 #define XGE_DEFAULT_MAC_RMAC_PAUSE_GEN_EN 1
88 #define XGE_DEFAULT_MAC_RMAC_PAUSE_RCV_EN 1
89 #define XGE_DEFAULT_MAC_RMAC_PAUSE_TIME 65535
90 #define XGE_DEFAULT_MAC_MC_PAUSE_THRESHOLD_Q0Q3 187
91 #define XGE_DEFAULT_MAC_MC_PAUSE_THRESHOLD_Q4Q7 187
92 #define XGE_DEFAULT_FIFO_MEMBLOCK_SIZE PAGE_SIZE
93 #define XGE_DEFAULT_FIFO_RESERVE_THRESHOLD 0
94 #define XGE_DEFAULT_FIFO_MAX_FRAGS 64
95 #define XGE_DEFAULT_FIFO_QUEUE_INTR 0
96 #define XGE_DEFAULT_FIFO_QUEUE_MAX 2048
97 #define XGE_DEFAULT_FIFO_QUEUE_INITIAL 2048
98 #define XGE_DEFAULT_FIFO_QUEUE_TTI_URANGE_A 5
99 #define XGE_DEFAULT_FIFO_QUEUE_TTI_URANGE_B 10
100 #define XGE_DEFAULT_FIFO_QUEUE_TTI_URANGE_C 20
101 #define XGE_DEFAULT_FIFO_QUEUE_TTI_UFC_A 15
102 #define XGE_DEFAULT_FIFO_QUEUE_TTI_UFC_B 30
103 #define XGE_DEFAULT_FIFO_QUEUE_TTI_UFC_C 45
104 #define XGE_DEFAULT_FIFO_QUEUE_TTI_UFC_D 60
105 #define XGE_DEFAULT_FIFO_QUEUE_TTI_TIMER_CI_EN 1
106 #define XGE_DEFAULT_FIFO_QUEUE_TTI_TIMER_AC_EN 1
107 #define XGE_DEFAULT_FIFO_QUEUE_TTI_TIMER_VAL_US 8000
108 #define XGE_DEFAULT_FIFO_ALIGNMENT_SIZE sizeof(u64)
109 #define XGE_DEFAULT_RING_MEMBLOCK_SIZE PAGE_SIZE
110 #define XGE_DEFAULT_RING_STRIP_VLAN_TAG 1
111 #define XGE_DEFAULT_RING_QUEUE_MAX 16
112 #define XGE_DEFAULT_RING_QUEUE_INITIAL 16
113 #define XGE_DEFAULT_RING_QUEUE_DRAM_SIZE_MB 32
114 #define XGE_DEFAULT_RING_QUEUE_INDICATE_MAX_PKTS 16
115 #define XGE_DEFAULT_RING_QUEUE_BACKOFF_INTERVAL_US 1000
116 #define XGE_DEFAULT_RING_QUEUE_RTI_URANGE_A 5
117 #define XGE_DEFAULT_RING_QUEUE_RTI_URANGE_B 10
118 #define XGE_DEFAULT_RING_QUEUE_RTI_URANGE_C 50
119 #define XGE_DEFAULT_RING_QUEUE_RTI_UFC_A 1
120 #define XGE_DEFAULT_RING_QUEUE_RTI_UFC_B 8
121 #define XGE_DEFAULT_RING_QUEUE_RTI_UFC_C 16
122 #define XGE_DEFAULT_RING_QUEUE_RTI_UFC_D 32
123 #define XGE_DEFAULT_RING_QUEUE_RTI_TIMER_AC_EN 1
124 #define XGE_DEFAULT_RING_QUEUE_RTI_TIMER_VAL_US 250
126 #define XGE_DRV_STATS(param) (lldev->driver_stats.param++)
128 #define XGE_SAVE_PARAM(to, what, value) to.what = value;
130 #define XGE_GET_PARAM(str_kenv, to, param, hardcode) { \
131 static int param##__LINE__; \
132 if(testenv(str_kenv) == 1) { \
133 getenv_int(str_kenv, ¶m##__LINE__); \
136 param##__LINE__ = hardcode; \
138 XGE_SAVE_PARAM(to, param, param##__LINE__); \
141 #define XGE_GET_PARAM_MAC(str_kenv, param, hardcode) \
142 XGE_GET_PARAM(str_kenv, ((*dconfig).mac), param, hardcode);
144 #define XGE_GET_PARAM_FIFO(str_kenv, param, hardcode) \
145 XGE_GET_PARAM(str_kenv, ((*dconfig).fifo), param, hardcode);
147 #define XGE_GET_PARAM_FIFO_QUEUE(str_kenv, param, qindex, hardcode) \
148 XGE_GET_PARAM(str_kenv, ((*dconfig).fifo.queue[qindex]), param, \
151 #define XGE_GET_PARAM_FIFO_QUEUE_TTI(str_kenv, param, qindex, tindex, hardcode)\
152 XGE_GET_PARAM(str_kenv, ((*dconfig).fifo.queue[qindex].tti[tindex]), \
155 #define XGE_GET_PARAM_RING(str_kenv, param, hardcode) \
156 XGE_GET_PARAM(str_kenv, ((*dconfig).ring), param, hardcode);
158 #define XGE_GET_PARAM_RING_QUEUE(str_kenv, param, qindex, hardcode) \
159 XGE_GET_PARAM(str_kenv, ((*dconfig).ring.queue[qindex]), param, \
162 #define XGE_GET_PARAM_RING_QUEUE_RTI(str_kenv, param, qindex, hardcode) \
163 XGE_GET_PARAM(str_kenv, ((*dconfig).ring.queue[qindex].rti), param, \
166 /* Values to identify the requests from getinfo tool in ioctl */
167 #define XGE_QUERY_STATS 1
168 #define XGE_QUERY_PCICONF 2
169 #define XGE_QUERY_DEVSTATS 3
170 #define XGE_QUERY_DEVCONF 4
171 #define XGE_READ_VERSION 5
172 #define XGE_QUERY_SWSTATS 6
173 #define XGE_QUERY_DRIVERSTATS 7
174 #define XGE_SET_BUFFER_MODE_1 8
175 #define XGE_SET_BUFFER_MODE_2 9
176 #define XGE_SET_BUFFER_MODE_5 10
177 #define XGE_QUERY_BUFFER_MODE 11
179 #define XGE_OFFSET_OF_LAST_REG 0x3180
181 #define VENDOR_ID_AMD 0x1022
182 #define DEVICE_ID_8131_PCI_BRIDGE 0x7450
184 typedef struct mbuf *mbuf_t;
186 typedef enum xge_lables {
189 xge_free_terminate_hal_driver = 2,
190 xge_free_hal_device = 3,
191 xge_free_pci_info = 4,
193 xge_free_bar0_resource = 6,
195 xge_free_bar1_resource = 8,
196 xge_free_irq_resource = 9,
197 xge_free_terminate_hal_device = 10,
198 xge_free_media_interface = 11,
201 typedef enum xge_option {
206 typedef enum xge_event_e {
207 XGE_LL_EVENT_TRY_XMIT_AGAIN = XGE_LL_EVENT_BASE + 1,
208 XGE_LL_EVENT_DEVICE_RESETTING = XGE_LL_EVENT_BASE + 2
211 typedef struct xge_msi_info {
212 u16 msi_control; /* MSI control 0x42 */
213 u32 msi_lower_address; /* MSI lower address 0x44 */
214 u32 msi_higher_address; /* MSI higher address 0x48 */
215 u16 msi_data; /* MSI data */
218 typedef struct xge_driver_stats_t {
252 u64 lro_session_exceeded;
254 } xge_driver_stats_t;
256 typedef struct xge_lro_entry_t {
257 SLIST_ENTRY(xge_lro_entry_t) next;
260 struct ip *lro_header_ip;
277 SLIST_HEAD(lro_head, xge_lro_entry_t);
279 /* Adapter structure */
280 typedef struct xge_lldev_t {
281 device_t device; /* Device */
282 struct ifnet *ifnetp; /* Interface ifnet structure */
283 struct resource *irq; /* Resource structure for IRQ */
284 void *irqhandle; /* IRQ handle */
285 xge_pci_info_t *pdev; /* PCI info */
286 xge_hal_device_t *devh; /* HAL: Device Handle */
287 struct mtx mtx_drv; /* Mutex - Driver */
288 struct mtx mtx_tx[XGE_FIFO_COUNT];
290 char mtx_name_drv[16];/*Mutex Name - Driver */
291 char mtx_name_tx[16][XGE_FIFO_COUNT];
292 /* Mutex Name - Tx */
293 struct callout timer; /* Timer for polling */
294 struct ifmedia media; /* In-kernel representation of a */
295 /* single supported media type */
296 xge_hal_channel_h fifo_channel[XGE_FIFO_COUNT];
298 xge_hal_channel_h ring_channel[XGE_RING_COUNT];
300 bus_dma_tag_t dma_tag_tx; /* Tag for dtr dma mapping (Tx) */
301 bus_dma_tag_t dma_tag_rx; /* Tag for dtr dma mapping (Rx) */
302 bus_dmamap_t extra_dma_map; /* Extra DMA map for Rx */
303 xge_msi_info_t msi_info; /* MSI info */
304 xge_driver_stats_t driver_stats; /* Driver statistics */
305 int initialized; /* Flag: Initialized or not */
306 int all_multicast; /* All multicast flag */
307 int macaddr_count; /* Multicast address count */
308 int in_detach; /* To avoid ioctl during detach */
309 int buffer_mode; /* Buffer Mode */
310 int rxd_mbuf_cnt; /* Number of buffers used */
311 int rxd_mbuf_len[5];/* Buffer lengths */
312 int enabled_tso; /* Flag: TSO Enabled */
313 int enabled_lro; /* Flag: LRO Enabled */
314 int enabled_msi; /* Flag: MSI Enabled */
315 int mtu; /* Interface MTU */
316 int lro_num; /* Number of LRO sessions */
317 struct lro_head lro_active; /* Active LRO sessions */
318 struct lro_head lro_free; /* Free LRO sessions */
321 /* Rx descriptor private structure */
322 typedef struct xge_rx_priv_t {
324 xge_dma_mbuf_t dmainfo[5];
327 /* Tx descriptor private structure */
328 typedef struct xge_tx_priv_t {
330 bus_dmamap_t dma_map;
334 typedef struct xge_register_t {
340 void xge_init_params(xge_hal_device_config_t *, device_t);
341 void xge_init(void *);
342 void xge_device_init(xge_lldev_t *, xge_hal_channel_reopen_e);
343 void xge_device_stop(xge_lldev_t *, xge_hal_channel_reopen_e);
344 void xge_stop(xge_lldev_t *);
345 void xge_resources_free(device_t, xge_lables_e);
346 void xge_callback_link_up(void *);
347 void xge_callback_link_down(void *);
348 void xge_callback_crit_err(void *, xge_hal_event_e, u64);
349 void xge_callback_event(xge_queue_item_t *);
350 int xge_ifmedia_change(struct ifnet *);
351 void xge_ifmedia_status(struct ifnet *, struct ifmediareq *);
352 int xge_ioctl(struct ifnet *, unsigned long, caddr_t);
353 int xge_ioctl_stats(xge_lldev_t *, struct ifreq *);
354 int xge_ioctl_registers(xge_lldev_t *, struct ifreq *);
355 void xge_timer(void *);
356 int xge_isr_filter(void *);
357 void xge_isr_line(void *);
358 void xge_isr_msi(void *);
359 void xge_enable_msi(xge_lldev_t *);
360 int xge_rx_open(int, xge_lldev_t *, xge_hal_channel_reopen_e);
361 int xge_tx_open(xge_lldev_t *, xge_hal_channel_reopen_e);
362 void xge_channel_close(xge_lldev_t *, xge_hal_channel_reopen_e);
363 int xge_channel_open(xge_lldev_t *, xge_hal_channel_reopen_e);
364 xge_hal_status_e xge_rx_compl(xge_hal_channel_h, xge_hal_dtr_h, u8, void *);
365 xge_hal_status_e xge_tx_compl(xge_hal_channel_h, xge_hal_dtr_h, u8, void *);
366 xge_hal_status_e xge_tx_initial_replenish(xge_hal_channel_h, xge_hal_dtr_h,
367 int, void *, xge_hal_channel_reopen_e);
368 xge_hal_status_e xge_rx_initial_replenish(xge_hal_channel_h, xge_hal_dtr_h,
369 int, void *, xge_hal_channel_reopen_e);
370 void xge_rx_term(xge_hal_channel_h, xge_hal_dtr_h, xge_hal_dtr_state_e,
371 void *, xge_hal_channel_reopen_e);
372 void xge_tx_term(xge_hal_channel_h, xge_hal_dtr_h, xge_hal_dtr_state_e,
373 void *, xge_hal_channel_reopen_e);
374 void xge_set_mbuf_cflags(mbuf_t);
375 void xge_send(struct ifnet *);
376 static void inline xge_send_locked(struct ifnet *, int);
377 int xge_get_buf(xge_hal_dtr_h, xge_rx_priv_t *, xge_lldev_t *, int);
378 int xge_ring_dtr_get(mbuf_t, xge_hal_channel_h, xge_hal_dtr_h, xge_lldev_t *,
380 int xge_get_buf_3b_5b(xge_hal_dtr_h, xge_rx_priv_t *, xge_lldev_t *);
381 void dmamap_cb(void *, bus_dma_segment_t *, int, int);
382 void xge_reset(xge_lldev_t *);
383 void xge_setmulti(xge_lldev_t *);
384 void xge_enable_promisc(xge_lldev_t *);
385 void xge_disable_promisc(xge_lldev_t *);
386 int xge_change_mtu(xge_lldev_t *, int);
387 void xge_buffer_mode_init(xge_lldev_t *, int);
388 void xge_initialize(device_t, xge_hal_channel_reopen_e);
389 void xge_terminate(device_t, xge_hal_channel_reopen_e);
390 int xge_probe(device_t);
391 int xge_driver_initialize(void);
392 void xge_media_init(device_t);
393 void xge_pci_space_save(device_t);
394 void xge_pci_space_restore(device_t);
395 void xge_msi_info_save(xge_lldev_t *);
396 void xge_msi_info_restore(xge_lldev_t *);
397 int xge_attach(device_t);
398 int xge_interface_setup(device_t);
399 int xge_detach(device_t);
400 int xge_shutdown(device_t);
401 void xge_mutex_init(xge_lldev_t *);
402 void xge_mutex_destroy(xge_lldev_t *);
403 void xge_print_info(xge_lldev_t *);
404 void xge_lro_flush_sessions(xge_lldev_t *);
405 void xge_rx_buffer_sizes_set(xge_lldev_t *, int, int);
406 void xge_accumulate_large_rx(xge_lldev_t *, struct mbuf *, int,
408 xge_hal_status_e xge_create_dma_tags(device_t);
409 void xge_add_sysctl_handlers(xge_lldev_t *);
410 void xge_confirm_changes(xge_lldev_t *, xge_option_e);
411 static int xge_lro_accumulate(xge_lldev_t *, struct mbuf *);
412 static void xge_lro_flush(xge_lldev_t *, xge_lro_entry_t *);