1a23fd118Syl /*
2a23fd118Syl * CDDL HEADER START
3a23fd118Syl *
4a23fd118Syl * The contents of this file are subject to the terms of the
5a23fd118Syl * Common Development and Distribution License (the "License").
6a23fd118Syl * You may not use this file except in compliance with the License.
7a23fd118Syl *
8a23fd118Syl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a23fd118Syl * or http://www.opensolaris.org/os/licensing.
10a23fd118Syl * See the License for the specific language governing permissions
11a23fd118Syl * and limitations under the License.
12a23fd118Syl *
13a23fd118Syl * When distributing Covered Code, include this CDDL HEADER in each
14a23fd118Syl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a23fd118Syl * If applicable, add the following below this CDDL HEADER, with the
16a23fd118Syl * fields enclosed by brackets "[]" replaced with your own identifying
17a23fd118Syl * information: Portions Copyright [yyyy] [name of copyright owner]
18a23fd118Syl *
19a23fd118Syl * CDDL HEADER END
20a23fd118Syl */
21a23fd118Syl
22a23fd118Syl /*
237eced415Sxw * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24a23fd118Syl * Use is subject to license terms.
25a23fd118Syl */
26a23fd118Syl
27a23fd118Syl /*
28a23fd118Syl * Copyright (c) 2002-2005 Neterion, Inc.
29a23fd118Syl * All right Reserved.
30a23fd118Syl *
31a23fd118Syl * FileName : xge.c
32a23fd118Syl *
33a23fd118Syl * Description: Xge main Solaris specific initialization & routines
34a23fd118Syl * for upper layer driver
35a23fd118Syl *
36a23fd118Syl */
37a23fd118Syl #include "xgell.h"
38a23fd118Syl
39a23fd118Syl static int xge_attach(dev_info_t *dev_info, ddi_attach_cmd_t cmd);
40a23fd118Syl static int xge_detach(dev_info_t *dev_info, ddi_detach_cmd_t cmd);
4119397407SSherry Moore static int xge_quiesce(dev_info_t *dev_info);
42a23fd118Syl
43a23fd118Syl DDI_DEFINE_STREAM_OPS(xge_ops, nulldev, nulldev, xge_attach, xge_detach,
4419397407SSherry Moore nodev, NULL, D_MP, NULL, xge_quiesce);
45a23fd118Syl
46a23fd118Syl /* Standard Module linkage initialization for a Streams driver */
47a23fd118Syl extern struct mod_ops mod_driverops;
48a23fd118Syl
49a23fd118Syl static struct modldrv modldrv = {
50a23fd118Syl &mod_driverops, /* Type of module. This one is a driver */
51a23fd118Syl XGELL_DESC, /* short description */
52a23fd118Syl &xge_ops /* driver specific ops */
53a23fd118Syl };
54a23fd118Syl
55a23fd118Syl static struct modlinkage modlinkage = {
56a23fd118Syl MODREV_1, {(void *)&modldrv, NULL}
57a23fd118Syl };
58a23fd118Syl
59a23fd118Syl /* Xge device attributes */
60a23fd118Syl ddi_device_acc_attr_t xge_dev_attr = {
61a23fd118Syl DDI_DEVICE_ATTR_V0,
62a23fd118Syl DDI_NEVERSWAP_ACC,
63a23fd118Syl DDI_STRICTORDER_ACC
64a23fd118Syl };
65a23fd118Syl ddi_device_acc_attr_t *p_xge_dev_attr = &xge_dev_attr;
66a23fd118Syl
67a23fd118Syl /*
68a23fd118Syl * xgell_callback_crit_err
69a23fd118Syl *
70a23fd118Syl * This function called by HAL on Serious Error event. XGE_HAL_EVENT_SERR.
71a23fd118Syl * Upper layer must analyze it based on %type.
72a23fd118Syl */
73a23fd118Syl static void
xge_callback_crit_err(void * userdata,xge_hal_event_e type,u64 serr_data)74a23fd118Syl xge_callback_crit_err(void *userdata, xge_hal_event_e type, u64 serr_data)
75a23fd118Syl {
76a23fd118Syl (void) xgell_onerr_reset(userdata);
77a23fd118Syl }
78a23fd118Syl
797eced415Sxw /*
807eced415Sxw * xge_xpak_alarm_log
817eced415Sxw * This function called by HAL on XPAK alarms. Upper layer must log the msg
827eced415Sxw * based on the xpak alarm type
837eced415Sxw */
847eced415Sxw static void
xge_xpak_alarm_log(void * userdata,xge_hal_xpak_alarm_type_e type)857eced415Sxw xge_xpak_alarm_log(void *userdata, xge_hal_xpak_alarm_type_e type)
867eced415Sxw {
877eced415Sxw switch (type) {
887eced415Sxw case XGE_HAL_XPAK_ALARM_EXCESS_TEMP:
897eced415Sxw xge_debug_osdep(XGE_ERR, "%s", "Take Xframe NIC out of "
907eced415Sxw "service. Excessive temperatures may result in "
917eced415Sxw "premature transceiver failure \n");
927eced415Sxw
937eced415Sxw break;
947eced415Sxw case XGE_HAL_XPAK_ALARM_EXCESS_BIAS_CURRENT:
957eced415Sxw xge_debug_osdep(XGE_ERR, "%s", "Take Xframe NIC out of "
967eced415Sxw "service Excessive bias currents may indicate "
977eced415Sxw "imminent laser diode failure \n");
987eced415Sxw
997eced415Sxw break;
1007eced415Sxw case XGE_HAL_XPAK_ALARM_EXCESS_LASER_OUTPUT:
1017eced415Sxw xge_debug_osdep(XGE_ERR, "%s", "Take Xframe NIC out of "
1027eced415Sxw "service Excessive laser output power may saturate "
1037eced415Sxw "far-end receiver\n");
1047eced415Sxw
1057eced415Sxw break;
1067eced415Sxw default:
1077eced415Sxw xge_debug_osdep(XGE_ERR, "%s", "Undefined Xpak Alarm");
1087eced415Sxw break;
1097eced415Sxw }
1107eced415Sxw
1117eced415Sxw }
1127eced415Sxw
113a23fd118Syl /*
114a23fd118Syl * xge_driver_init_hal
115a23fd118Syl *
116a23fd118Syl * To initialize HAL portion of driver.
117a23fd118Syl */
118a23fd118Syl static xge_hal_status_e
xge_driver_init_hal(void)119a23fd118Syl xge_driver_init_hal(void)
120a23fd118Syl {
121a23fd118Syl static xge_hal_driver_config_t driver_config;
122a23fd118Syl xge_hal_uld_cbs_t uld_callbacks;
123a23fd118Syl
124a23fd118Syl driver_config.queue_size_initial = 1;
125a23fd118Syl driver_config.queue_size_max = 4;
126a23fd118Syl
127a23fd118Syl uld_callbacks.link_up = xgell_callback_link_up;
128a23fd118Syl uld_callbacks.link_down = xgell_callback_link_down;
129a23fd118Syl uld_callbacks.crit_err = xge_callback_crit_err;
130*da14cebeSEric Cheng uld_callbacks.event = NULL;
131*da14cebeSEric Cheng uld_callbacks.event_queued = NULL;
132a23fd118Syl uld_callbacks.before_device_poll = NULL;
133a23fd118Syl uld_callbacks.after_device_poll = NULL;
134a23fd118Syl uld_callbacks.sched_timer = NULL;
1357eced415Sxw uld_callbacks.xpak_alarm_log = xge_xpak_alarm_log;
136a23fd118Syl
137a23fd118Syl return (xge_hal_driver_initialize(&driver_config, &uld_callbacks));
138a23fd118Syl
139a23fd118Syl }
140a23fd118Syl
141a23fd118Syl /*
142a23fd118Syl * _init
143a23fd118Syl *
144a23fd118Syl * Solaris standard _init function for a device driver
145a23fd118Syl */
146a23fd118Syl int
_init(void)147a23fd118Syl _init(void)
148a23fd118Syl {
149a23fd118Syl int ret = 0;
150a23fd118Syl xge_hal_status_e status;
151a23fd118Syl
152a23fd118Syl status = xge_driver_init_hal();
153a23fd118Syl if (status != XGE_HAL_OK) {
154a23fd118Syl xge_debug_osdep(XGE_ERR, "can't initialize the driver (%d)",
155a23fd118Syl status);
156a23fd118Syl return (EINVAL);
157a23fd118Syl }
158a23fd118Syl
159a23fd118Syl xge_hal_driver_debug_module_mask_set(0xffffffff);
160a23fd118Syl xge_hal_driver_debug_level_set(XGE_TRACE);
161a23fd118Syl
162a23fd118Syl mac_init_ops(&xge_ops, "xge");
163a23fd118Syl if ((ret = mod_install(&modlinkage)) != 0) {
164a23fd118Syl xge_hal_driver_terminate();
165a23fd118Syl mac_fini_ops(&xge_ops);
166a23fd118Syl xge_debug_osdep(XGE_ERR, "%s",
167a23fd118Syl "Unable to install the driver");
168a23fd118Syl return (ret);
169a23fd118Syl }
170a23fd118Syl
171a23fd118Syl return (0);
172a23fd118Syl }
173a23fd118Syl
174a23fd118Syl /*
175a23fd118Syl * _fini
176a23fd118Syl *
177a23fd118Syl * Solaris standard _fini function for device driver
178a23fd118Syl */
179a23fd118Syl int
_fini(void)180a23fd118Syl _fini(void)
181a23fd118Syl {
182a23fd118Syl int ret;
183a23fd118Syl
184a23fd118Syl ret = mod_remove(&modlinkage);
185a23fd118Syl if (ret == 0) {
186a23fd118Syl xge_hal_driver_terminate();
187a23fd118Syl mac_fini_ops(&xge_ops);
188a23fd118Syl }
189a23fd118Syl
190a23fd118Syl return (ret);
191a23fd118Syl }
192a23fd118Syl
193a23fd118Syl /*
194a23fd118Syl * _info
195a23fd118Syl *
196a23fd118Syl * Solaris standard _info function for device driver
197a23fd118Syl */
198a23fd118Syl int
_info(struct modinfo * pModinfo)199a23fd118Syl _info(struct modinfo *pModinfo)
200a23fd118Syl {
201a23fd118Syl return (mod_info(&modlinkage, pModinfo));
202a23fd118Syl }
203a23fd118Syl
204a23fd118Syl /*
205a23fd118Syl * xge_isr
206a23fd118Syl * @arg: pointer to device private strucutre(hldev)
207a23fd118Syl *
208a23fd118Syl * This is the ISR scheduled by the OS to indicate to the
209a23fd118Syl * driver that the receive/transmit operation is completed.
210a23fd118Syl */
211*da14cebeSEric Cheng /* ARGSUSED */
212a23fd118Syl static uint_t
xge_isr(caddr_t arg0,caddr_t arg1)2137eced415Sxw xge_isr(caddr_t arg0, caddr_t arg1)
214a23fd118Syl {
215a23fd118Syl xge_hal_status_e status;
2167eced415Sxw xge_hal_device_t *hldev = (xge_hal_device_t *)arg0;
217a23fd118Syl xgelldev_t *lldev = xge_hal_device_private(hldev);
218a23fd118Syl
219a23fd118Syl if (!lldev->is_initialized) {
2207eced415Sxw return (DDI_INTR_UNCLAIMED);
221a23fd118Syl }
222a23fd118Syl
223a23fd118Syl status = xge_hal_device_handle_irq(hldev);
224a23fd118Syl
225a23fd118Syl return ((status == XGE_HAL_ERR_WRONG_IRQ) ?
226a23fd118Syl DDI_INTR_UNCLAIMED : DDI_INTR_CLAIMED);
227a23fd118Syl }
228a23fd118Syl
2297eced415Sxw /*
2307eced415Sxw * Interrupt handler for transmit when MSI-X interrupt mechasnism is used
2317eced415Sxw */
2327eced415Sxw /* ARGSUSED */
2337eced415Sxw static uint_t
xge_fifo_msix_isr(caddr_t arg0,caddr_t arg1)2347eced415Sxw xge_fifo_msix_isr(caddr_t arg0, caddr_t arg1)
2357eced415Sxw {
2367eced415Sxw int got_tx;
2377eced415Sxw xge_hal_channel_t *channel = (xge_hal_channel_t *)arg0;
2387eced415Sxw xgelldev_t *lldev = xge_hal_device_private(channel->devh);
2397eced415Sxw
2407eced415Sxw if (!lldev->is_initialized) {
2417eced415Sxw return (DDI_INTR_UNCLAIMED);
2427eced415Sxw }
2437eced415Sxw (void) xge_hal_device_poll_tx_channel(channel, &got_tx);
2447eced415Sxw
2457eced415Sxw return (DDI_INTR_CLAIMED);
2467eced415Sxw }
2477eced415Sxw
2487eced415Sxw /*
2497eced415Sxw * Interrupt handler for receive when MSI-X interrupt mechasnism is used
2507eced415Sxw */
2517eced415Sxw /* ARGSUSED */
2527eced415Sxw static uint_t
xge_ring_msix_isr(caddr_t arg0,caddr_t arg1)2537eced415Sxw xge_ring_msix_isr(caddr_t arg0, caddr_t arg1)
2547eced415Sxw {
2557eced415Sxw int got_rx;
2567eced415Sxw xge_hal_channel_t *channel = (xge_hal_channel_t *)arg0;
2577eced415Sxw xgelldev_t *lldev = xge_hal_device_private(channel->devh);
2587eced415Sxw
2597eced415Sxw if (!lldev->is_initialized) {
2607eced415Sxw return (DDI_INTR_UNCLAIMED);
2617eced415Sxw }
2627eced415Sxw (void) xge_hal_device_poll_rx_channel(channel, &got_rx);
2637eced415Sxw
2647eced415Sxw return (DDI_INTR_CLAIMED);
2657eced415Sxw }
2667eced415Sxw
2677eced415Sxw /*
2687eced415Sxw * Configure single ring
2697eced415Sxw */
2707eced415Sxw static void
xge_ring_config(dev_info_t * dev_info,xge_hal_device_config_t * device_config,int index)271*da14cebeSEric Cheng xge_ring_config(dev_info_t *dev_info, xge_hal_device_config_t *device_config,
272*da14cebeSEric Cheng int index)
2737eced415Sxw {
2747eced415Sxw char msg[MSG_SIZE];
2757eced415Sxw
276*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_configured", index);
277*da14cebeSEric Cheng device_config->ring.queue[index].configured =
2787eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS,
279*da14cebeSEric Cheng msg, index < XGELL_RX_RING_NUM_MAX ? 1 : 0);
2807eced415Sxw
2817eced415Sxw /* no point to configure it further if unconfigured */
282*da14cebeSEric Cheng if (!device_config->ring.queue[index].configured)
2837eced415Sxw return;
2847eced415Sxw
2857eced415Sxw #if defined(__sparc)
286*da14cebeSEric Cheng device_config->ring.queue[index].no_snoop_bits = 1;
2877eced415Sxw #endif
2887eced415Sxw
289*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_max", index);
290*da14cebeSEric Cheng device_config->ring.queue[index].max =
2917eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
2927eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
2937eced415Sxw XGE_HAL_DEFAULT_USE_HARDCODE);
2947eced415Sxw
295*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_initial", index);
296*da14cebeSEric Cheng device_config->ring.queue[index].initial =
2977eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
2987eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
2997eced415Sxw XGE_HAL_DEFAULT_USE_HARDCODE);
3007eced415Sxw
301*da14cebeSEric Cheng if (device_config->ring.queue[index].initial ==
3027eced415Sxw XGE_HAL_DEFAULT_USE_HARDCODE) {
303*da14cebeSEric Cheng device_config->ring.queue[index].initial =
304*da14cebeSEric Cheng device_config->ring.queue[index].max =
305*da14cebeSEric Cheng XGE_HAL_DEFAULT_RING_QUEUE_BLOCKS;
3067eced415Sxw }
3077eced415Sxw
308*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_buffer_mode", index);
309*da14cebeSEric Cheng device_config->ring.queue[index].buffer_mode =
3107eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3117eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3127eced415Sxw XGE_HAL_RING_QUEUE_BUFFER_MODE_DEFAULT);
3137eced415Sxw
314*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_dram_size_mb", index);
315*da14cebeSEric Cheng device_config->ring.queue[index].dram_size_mb =
3167eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3177eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3187eced415Sxw XGE_HAL_DEFAULT_USE_HARDCODE);
3197eced415Sxw
3207eced415Sxw (void) xge_os_snprintf(msg, MSG_SIZE,
321*da14cebeSEric Cheng "ring%d_backoff_interval_us", index);
322*da14cebeSEric Cheng device_config->ring.queue[index].backoff_interval_us =
3237eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3247eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3257eced415Sxw XGE_HAL_DEFAULT_BACKOFF_INTERVAL_US);
3267eced415Sxw
327*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_max_frm_len", index);
328*da14cebeSEric Cheng device_config->ring.queue[index].max_frm_len =
3297eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3307eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3317eced415Sxw XGE_HAL_RING_USE_MTU);
3327eced415Sxw
3337eced415Sxw
334*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_priority", index);
335*da14cebeSEric Cheng device_config->ring.queue[index].priority =
3367eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3377eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3387eced415Sxw XGE_HAL_DEFAULT_RING_PRIORITY);
3397eced415Sxw
340*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_urange_a", index);
341*da14cebeSEric Cheng device_config->ring.queue[index].rti.urange_a =
3427eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3437eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3447eced415Sxw XGE_HAL_DEFAULT_RX_URANGE_A);
3457eced415Sxw
346*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_ufc_a", index);
347*da14cebeSEric Cheng device_config->ring.queue[index].rti.ufc_a =
3487eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3497eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3507eced415Sxw XGE_HAL_DEFAULT_RX_UFC_A);
3517eced415Sxw
352*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_urange_b", index);
353*da14cebeSEric Cheng device_config->ring.queue[index].rti.urange_b =
3547eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3557eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3567eced415Sxw XGE_HAL_DEFAULT_RX_URANGE_B);
3577eced415Sxw
358*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_ufc_b", index);
359*da14cebeSEric Cheng device_config->ring.queue[index].rti.ufc_b =
3607eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3617eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3627eced415Sxw device_config->mtu > XGE_HAL_DEFAULT_MTU ?
3637eced415Sxw XGE_HAL_DEFAULT_RX_UFC_B_J:
3647eced415Sxw XGE_HAL_DEFAULT_RX_UFC_B_N);
3657eced415Sxw
366*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_urange_c", index);
367*da14cebeSEric Cheng device_config->ring.queue[index].rti.urange_c =
3687eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3697eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3707eced415Sxw XGE_HAL_DEFAULT_RX_URANGE_C);
3717eced415Sxw
372*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_ufc_c", index);
373*da14cebeSEric Cheng device_config->ring.queue[index].rti.ufc_c =
3747eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3757eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3767eced415Sxw device_config->mtu > XGE_HAL_DEFAULT_MTU ?
3777eced415Sxw XGE_HAL_DEFAULT_RX_UFC_C_J:
3787eced415Sxw XGE_HAL_DEFAULT_RX_UFC_C_N);
3797eced415Sxw
380*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_ufc_d", index);
381*da14cebeSEric Cheng device_config->ring.queue[index].rti.ufc_d =
3827eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3837eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3847eced415Sxw XGE_HAL_DEFAULT_RX_UFC_D);
3857eced415Sxw
386*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_timer_val", index);
387*da14cebeSEric Cheng device_config->ring.queue[index].rti.timer_val_us =
3887eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3897eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3907eced415Sxw XGE_HAL_DEFAULT_RX_TIMER_VAL);
3917eced415Sxw
392*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_timer_ac_en", index);
393*da14cebeSEric Cheng device_config->ring.queue[index].rti.timer_ac_en =
3947eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
3957eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
3967eced415Sxw XGE_HAL_DEFAULT_RX_TIMER_AC_EN);
3977eced415Sxw
398*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "ring%d_indicate_max_pkts",
399*da14cebeSEric Cheng index);
400*da14cebeSEric Cheng device_config->ring.queue[index].indicate_max_pkts =
4017eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY,
4027eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
4037eced415Sxw (device_config->bimodal_interrupts ?
4047eced415Sxw XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_B :
4057eced415Sxw XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_N));
4067eced415Sxw
407*da14cebeSEric Cheng /*
408*da14cebeSEric Cheng * Enable RTH steering if needed HERE!!!!
409*da14cebeSEric Cheng */
410*da14cebeSEric Cheng if (device_config->rth_en == XGE_HAL_RTH_ENABLE)
411*da14cebeSEric Cheng device_config->ring.queue[index].rth_en = 1;
4127eced415Sxw }
4137eced415Sxw
4147eced415Sxw /*
4157eced415Sxw * Configure single fifo
4167eced415Sxw */
4177eced415Sxw static void
xge_fifo_config(dev_info_t * dev_info,xge_hal_device_config_t * device_config,int index)418*da14cebeSEric Cheng xge_fifo_config(dev_info_t *dev_info, xge_hal_device_config_t *device_config,
419*da14cebeSEric Cheng int index)
4207eced415Sxw {
4217eced415Sxw char msg[MSG_SIZE];
4227eced415Sxw
423*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_configured", index);
424*da14cebeSEric Cheng device_config->fifo.queue[index].configured =
4257eced415Sxw ddi_prop_get_int(DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS,
426*da14cebeSEric Cheng msg, index < XGELL_TX_RING_NUM_MAX ? 1 : 0);
4277eced415Sxw
4287eced415Sxw /* no point to configure it further */
429*da14cebeSEric Cheng if (!device_config->fifo.queue[index].configured)
4307eced415Sxw return;
4317eced415Sxw
4327eced415Sxw #if defined(__sparc)
433*da14cebeSEric Cheng device_config->fifo.queue[index].no_snoop_bits = 1;
4347eced415Sxw #endif
4357eced415Sxw
436*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_max", index);
437*da14cebeSEric Cheng device_config->fifo.queue[index].max = ddi_prop_get_int(DDI_DEV_T_ANY,
4387eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
4397eced415Sxw XGE_HAL_DEFAULT_USE_HARDCODE);
4407eced415Sxw
441*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_initial", index);
442*da14cebeSEric Cheng device_config->fifo.queue[index].initial =
443*da14cebeSEric Cheng ddi_prop_get_int(DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
4447eced415Sxw XGE_HAL_DEFAULT_USE_HARDCODE);
4457eced415Sxw
446*da14cebeSEric Cheng #if 0
447*da14cebeSEric Cheng if (device_config->fifo.queue[index].initial ==
4487eced415Sxw XGE_HAL_DEFAULT_USE_HARDCODE) {
4497eced415Sxw if (device_config->mtu > XGE_HAL_DEFAULT_MTU) {
450*da14cebeSEric Cheng device_config->fifo.queue[index].initial =
451*da14cebeSEric Cheng device_config->fifo.queue[index].max =
4527eced415Sxw XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_J;
4537eced415Sxw } else {
454*da14cebeSEric Cheng device_config->fifo.queue[index].initial =
455*da14cebeSEric Cheng device_config->fifo.queue[index].max =
4567eced415Sxw XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_N;
4577eced415Sxw }
4587eced415Sxw }
459*da14cebeSEric Cheng #else
460*da14cebeSEric Cheng if (device_config->fifo.queue[index].initial ==
461*da14cebeSEric Cheng XGE_HAL_DEFAULT_USE_HARDCODE) {
462*da14cebeSEric Cheng device_config->fifo.queue[index].max =
463*da14cebeSEric Cheng device_config->fifo.queue[index].initial =
464*da14cebeSEric Cheng XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_A;
465*da14cebeSEric Cheng }
466*da14cebeSEric Cheng #endif
4677eced415Sxw
468*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_intr", index);
469*da14cebeSEric Cheng device_config->fifo.queue[index].intr = ddi_prop_get_int(DDI_DEV_T_ANY,
4707eced415Sxw dev_info, DDI_PROP_DONTPASS, msg,
4717eced415Sxw XGE_HAL_DEFAULT_FIFO_QUEUE_INTR);
4727eced415Sxw
4737eced415Sxw /*
4747eced415Sxw * TTI 0 configuration
4757eced415Sxw */
476*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_enable", index);
477*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].enabled = ddi_prop_get_int(
4787eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg, 1);
4797eced415Sxw
480*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_urange_a", index);
481*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].urange_a = ddi_prop_get_int(
4827eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
4837eced415Sxw XGE_HAL_DEFAULT_TX_URANGE_A);
4847eced415Sxw
485*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_ufc_a", index);
486*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].ufc_a = ddi_prop_get_int(
4877eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
4887eced415Sxw XGE_HAL_DEFAULT_TX_UFC_A);
4897eced415Sxw
490*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_urange_b", index);
491*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].urange_b = ddi_prop_get_int(
4927eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
4937eced415Sxw XGE_HAL_DEFAULT_TX_URANGE_B);
4947eced415Sxw
495*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_ufc_b", index);
496*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].ufc_b = ddi_prop_get_int(
4977eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
4987eced415Sxw XGE_HAL_DEFAULT_TX_UFC_B);
4997eced415Sxw
500*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_urange_c", index);
501*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].urange_c = ddi_prop_get_int(
5027eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
5037eced415Sxw XGE_HAL_DEFAULT_TX_URANGE_C);
5047eced415Sxw
505*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_ufc_c", index);
506*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].ufc_c = ddi_prop_get_int(
5077eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
5087eced415Sxw XGE_HAL_DEFAULT_TX_UFC_C);
5097eced415Sxw
510*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_ufc_d", index);
511*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].ufc_d = ddi_prop_get_int(
5127eced415Sxw DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
5137eced415Sxw XGE_HAL_DEFAULT_TX_UFC_D);
5147eced415Sxw
515*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_timer_ac_en", index);
516*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].timer_ac_en =
517*da14cebeSEric Cheng ddi_prop_get_int(DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
5187eced415Sxw XGE_HAL_DEFAULT_TX_TIMER_AC_EN);
5197eced415Sxw
520*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_timer_val", index);
521*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].timer_val_us =
522*da14cebeSEric Cheng ddi_prop_get_int(DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
5237eced415Sxw XGE_HAL_DEFAULT_TX_TIMER_VAL);
5247eced415Sxw
525*da14cebeSEric Cheng (void) xge_os_snprintf(msg, MSG_SIZE, "fifo%d_tti_timer_ci_en", index);
526*da14cebeSEric Cheng device_config->fifo.queue[index].tti[index].timer_ci_en =
527*da14cebeSEric Cheng ddi_prop_get_int(DDI_DEV_T_ANY, dev_info, DDI_PROP_DONTPASS, msg,
5287eced415Sxw XGE_HAL_DEFAULT_TX_TIMER_CI_EN);
5297eced415Sxw }
5307eced415Sxw
531a23fd118Syl /*
532a23fd118Syl * xge_configuration_init
533a23fd118Syl * @device_config: pointer to xge_hal_device_config_t
534a23fd118Syl *
535a23fd118Syl * This function will lookup properties from .conf file to init
536a23fd118Syl * the configuration data structure. If a property is not in .conf
537a23fd118Syl * file, the default value should be set.
538a23fd118Syl */
539a23fd118Syl static void
xge_configuration_init(dev_info_t * dev_info,xge_hal_device_config_t * device_config,xgell_config_t * xgell_config)540a23fd118Syl xge_configuration_init(dev_info_t *dev_info,
541*da14cebeSEric Cheng xge_hal_device_config_t *device_config, xgell_config_t *xgell_config)
542a23fd118Syl {
5437eced415Sxw int i, rings_configured = 0, fifos_configured = 0;
5447eced415Sxw
545*da14cebeSEric Cheng /*
546*da14cebeSEric Cheng * Initialize link layer configuration first
547*da14cebeSEric Cheng */
548*da14cebeSEric Cheng xgell_config->rx_dma_lowat = ddi_prop_get_int(DDI_DEV_T_ANY, dev_info,
549*da14cebeSEric Cheng DDI_PROP_DONTPASS, "rx_dma_lowat", XGELL_RX_DMA_LOWAT);
550*da14cebeSEric Cheng xgell_config->rx_pkt_burst = ddi_prop_get_int(DDI_DEV_T_ANY,
551