4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <hxge_impl.h>
28 #include <hxge_vmac.h>
30 hxge_status_t
hxge_vmac_init(p_hxge_t hxgep
);
31 hxge_status_t
hxge_tx_vmac_init(p_hxge_t hxgep
);
32 hxge_status_t
hxge_rx_vmac_init(p_hxge_t hxgep
);
33 hxge_status_t
hxge_tx_vmac_enable(p_hxge_t hxgep
);
34 hxge_status_t
hxge_tx_vmac_disable(p_hxge_t hxgep
);
35 hxge_status_t
hxge_rx_vmac_enable(p_hxge_t hxgep
);
36 hxge_status_t
hxge_rx_vmac_disable(p_hxge_t hxgep
);
37 hxge_status_t
hxge_tx_vmac_reset(p_hxge_t hxgep
);
38 hxge_status_t
hxge_rx_vmac_reset(p_hxge_t hxgep
);
39 uint_t
hxge_vmac_intr(caddr_t arg1
, caddr_t arg2
);
40 hxge_status_t
hxge_set_promisc(p_hxge_t hxgep
, boolean_t on
);
43 hxge_link_init(p_hxge_t hxgep
)
45 p_hxge_stats_t statsp
;
47 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "==> hxge_link_init>"));
49 statsp
= hxgep
->statsp
;
51 statsp
->mac_stats
.cap_10gfdx
= 1;
52 statsp
->mac_stats
.lp_cap_10gfdx
= 1;
55 * The driver doesn't control the link.
56 * It is always 10Gb full duplex.
58 statsp
->mac_stats
.link_duplex
= 2;
59 statsp
->mac_stats
.link_speed
= 10000;
61 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_link_init"));
66 hxge_vmac_init(p_hxge_t hxgep
)
68 hxge_status_t status
= HXGE_OK
;
70 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "==> hxge_vmac_init:"));
72 if ((status
= hxge_tx_vmac_reset(hxgep
)) != HXGE_OK
)
75 if ((status
= hxge_rx_vmac_reset(hxgep
)) != HXGE_OK
)
78 if ((status
= hxge_tx_vmac_enable(hxgep
)) != HXGE_OK
)
81 if ((status
= hxge_rx_vmac_enable(hxgep
)) != HXGE_OK
)
84 /* Clear the interrupt status registers */
85 (void) hpi_vmac_clear_rx_int_stat(hxgep
->hpi_handle
);
86 (void) hpi_vmac_clear_tx_int_stat(hxgep
->hpi_handle
);
89 * Take the masks off the overflow counters. Interrupt the system when
90 * any counts overflow. Don't interrupt the system for each frame.
91 * The current counts are retrieved when the "kstat" command is used.
93 (void) hpi_pfc_set_rx_int_stat_mask(hxgep
->hpi_handle
, 0, 1);
94 (void) hpi_pfc_set_tx_int_stat_mask(hxgep
->hpi_handle
, 0, 1);
96 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_vmac_init:"));
100 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
,
101 "hxge_vmac_init: failed to initialize VMAC>"));
107 /* Initialize the TxVMAC sub-block */
110 hxge_tx_vmac_init(p_hxge_t hxgep
)
113 hpi_handle_t handle
= hxgep
->hpi_handle
;
115 /* CFG_VMAC_TX_EN is done separately */
116 config
= CFG_VMAC_TX_CRC_INSERT
| CFG_VMAC_TX_PAD
;
118 if (hpi_vmac_tx_config(handle
, INIT
, config
,
119 hxgep
->vmac
.maxframesize
) != HPI_SUCCESS
)
122 hxgep
->vmac
.tx_config
= config
;
127 /* Initialize the RxVMAC sub-block */
130 hxge_rx_vmac_init(p_hxge_t hxgep
)
133 hpi_handle_t handle
= hxgep
->hpi_handle
;
134 uint16_t max_frame_length
= hxgep
->vmac
.maxframesize
;
137 * NOTE: CFG_VMAC_RX_ENABLE is done separately. Do not enable
138 * strip CRC. Bug ID 11451 -- enable strip CRC will cause
139 * rejection on minimum sized packets.
141 xconfig
= CFG_VMAC_RX_PASS_FLOW_CTRL_FR
;
143 if (hxgep
->filter
.all_phys_cnt
!= 0)
144 xconfig
|= CFG_VMAC_RX_PROMISCUOUS_MODE
;
146 if (hxgep
->filter
.all_multicast_cnt
!= 0)
147 xconfig
|= CFG_VMAC_RX_PROMIXCUOUS_GROUP
;
149 if (hxgep
->statsp
->port_stats
.lb_mode
!= hxge_lb_normal
)
150 xconfig
|= CFG_VMAC_RX_LOOP_BACK
;
152 if (hpi_vmac_rx_config(handle
, INIT
, xconfig
,
153 max_frame_length
) != HPI_SUCCESS
)
156 hxgep
->vmac
.rx_config
= xconfig
;
164 hxge_tx_vmac_enable(p_hxge_t hxgep
)
167 hxge_status_t status
= HXGE_OK
;
168 hpi_handle_t handle
= hxgep
->hpi_handle
;
170 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "==> hxge_tx_vmac_enable"));
172 rv
= hxge_tx_vmac_init(hxgep
);
177 hxgep
->msg_min
= ETHERMIN
;
179 rv
= hpi_vmac_tx_config(handle
, ENABLE
, CFG_VMAC_TX_EN
, 0);
181 status
= (rv
== HPI_SUCCESS
) ? HXGE_OK
: HXGE_ERROR
;
183 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_tx_vmac_enable"));
191 hxge_tx_vmac_disable(p_hxge_t hxgep
)
194 hxge_status_t status
= HXGE_OK
;
195 hpi_handle_t handle
= hxgep
->hpi_handle
;
197 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "==> hxge_tx_vmac_disable"));
199 rv
= hpi_vmac_tx_config(handle
, DISABLE
, CFG_VMAC_TX_EN
, 0);
201 status
= (rv
== HPI_SUCCESS
) ? HXGE_OK
: HXGE_ERROR
;
203 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_tx_vmac_disable"));
211 hxge_rx_vmac_enable(p_hxge_t hxgep
)
214 hxge_status_t status
= HXGE_OK
;
215 hpi_handle_t handle
= hxgep
->hpi_handle
;
217 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "==> hxge_rx_vmac_enable"));
220 * Because of hardware bug document with CR6770577, need
221 * reprogram max framesize when enabling/disabling RX
222 * vmac. Max framesize is programed here in
223 * hxge_rx_vmac_init().
225 rv
= hpi_vmac_rx_set_framesize(HXGE_DEV_HPI_HANDLE(hxgep
),
226 (uint16_t)hxgep
->vmac
.maxframesize
);
227 if (rv
!= HPI_SUCCESS
) {
228 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_rx_vmac_enable"));
233 * Wait for a period of time.
240 rv
= hpi_vmac_rx_config(handle
, ENABLE
, CFG_VMAC_RX_EN
, 0);
242 status
= (rv
== HPI_SUCCESS
) ? HXGE_OK
: HXGE_ERROR
;
244 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_rx_vmac_enable"));
251 hxge_rx_vmac_disable(p_hxge_t hxgep
)
254 hxge_status_t status
= HXGE_OK
;
255 hpi_handle_t handle
= hxgep
->hpi_handle
;
257 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "==> hxge_rx_vmac_disable"));
260 * Because of hardware bug document with CR6770577, need
261 * reprogram max framesize when enabling/disabling RX
262 * vmac. Max framesize is programed here in
263 * hxge_rx_vmac_init().
265 (void) hpi_vmac_rx_set_framesize(HXGE_DEV_HPI_HANDLE(hxgep
),
269 * Wait for 10us before doing disable.
273 rv
= hpi_vmac_rx_config(handle
, DISABLE
, CFG_VMAC_RX_EN
, 0);
275 status
= (rv
== HPI_SUCCESS
) ? HXGE_OK
: HXGE_ERROR
;
277 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_rx_vmac_disable"));
284 hxge_tx_vmac_reset(p_hxge_t hxgep
)
286 hpi_handle_t handle
= hxgep
->hpi_handle
;
288 (void) hpi_tx_vmac_reset(handle
);
296 hxge_rx_vmac_reset(p_hxge_t hxgep
)
298 hpi_handle_t handle
= hxgep
->hpi_handle
;
300 (void) hpi_vmac_rx_set_framesize(HXGE_DEV_HPI_HANDLE(hxgep
),
304 * Wait for 10us before doing reset.
308 (void) hpi_rx_vmac_reset(handle
);
315 hxge_vmac_intr(caddr_t arg1
, caddr_t arg2
)
317 p_hxge_t hxgep
= (p_hxge_t
)arg2
;
320 HXGE_DEBUG_MSG((hxgep
, INT_CTL
, "==> hxge_vmac_intr"));
322 handle
= HXGE_DEV_HPI_HANDLE(hxgep
);
324 hxge_save_cntrs(hxgep
);
326 /* Clear the interrupt status registers */
327 (void) hpi_vmac_clear_rx_int_stat(handle
);
328 (void) hpi_vmac_clear_tx_int_stat(handle
);
330 HXGE_DEBUG_MSG((hxgep
, INT_CTL
, "<== hxge_vmac_intr"));
331 return (DDI_INTR_CLAIMED
);
335 * Set promiscous mode
338 hxge_set_promisc(p_hxge_t hxgep
, boolean_t on
)
340 hxge_status_t status
= HXGE_OK
;
342 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "==> hxge_set_promisc: on %d", on
));
344 hxgep
->filter
.all_phys_cnt
= ((on
) ? 1 : 0);
346 RW_ENTER_WRITER(&hxgep
->filter_lock
);
347 if ((status
= hxge_rx_vmac_disable(hxgep
)) != HXGE_OK
)
349 if ((status
= hxge_rx_vmac_enable(hxgep
)) != HXGE_OK
)
351 RW_EXIT(&hxgep
->filter_lock
);
354 hxgep
->statsp
->mac_stats
.promisc
= B_TRUE
;
356 hxgep
->statsp
->mac_stats
.promisc
= B_FALSE
;
358 HXGE_DEBUG_MSG((hxgep
, MAC_CTL
, "<== hxge_set_promisc"));
362 RW_EXIT(&hxgep
->filter_lock
);
364 HXGE_ERROR_MSG((hxgep
, HXGE_ERR_CTL
, "hxge_set_promisc: "
365 "Unable to set promisc (%d)", on
));
370 hxge_save_cntrs(p_hxge_t hxgep
)
372 p_hxge_stats_t statsp
;
375 vmac_tx_frame_cnt_t tx_frame_cnt
;
376 vmac_tx_byte_cnt_t tx_byte_cnt
;
377 vmac_rx_frame_cnt_t rx_frame_cnt
;
378 vmac_rx_byte_cnt_t rx_byte_cnt
;
379 vmac_rx_drop_fr_cnt_t rx_drop_fr_cnt
;
380 vmac_rx_drop_byte_cnt_t rx_drop_byte_cnt
;
381 vmac_rx_crc_cnt_t rx_crc_cnt
;
382 vmac_rx_pause_cnt_t rx_pause_cnt
;
383 vmac_rx_bcast_fr_cnt_t rx_bcast_fr_cnt
;
384 vmac_rx_mcast_fr_cnt_t rx_mcast_fr_cnt
;
386 HXGE_DEBUG_MSG((hxgep
, INT_CTL
, "==> hxge_save_cntrs"));
388 statsp
= (p_hxge_stats_t
)hxgep
->statsp
;
389 handle
= hxgep
->hpi_handle
;
391 HXGE_REG_RD64(handle
, VMAC_TX_FRAME_CNT
, &tx_frame_cnt
.value
);
392 HXGE_REG_RD64(handle
, VMAC_TX_BYTE_CNT
, &tx_byte_cnt
.value
);
393 HXGE_REG_RD64(handle
, VMAC_RX_FRAME_CNT
, &rx_frame_cnt
.value
);
394 HXGE_REG_RD64(handle
, VMAC_RX_BYTE_CNT
, &rx_byte_cnt
.value
);
395 HXGE_REG_RD64(handle
, VMAC_RX_DROP_FR_CNT
, &rx_drop_fr_cnt
.value
);
396 HXGE_REG_RD64(handle
, VMAC_RX_DROP_BYTE_CNT
, &rx_drop_byte_cnt
.value
);
397 HXGE_REG_RD64(handle
, VMAC_RX_CRC_CNT
, &rx_crc_cnt
.value
);
398 HXGE_REG_RD64(handle
, VMAC_RX_PAUSE_CNT
, &rx_pause_cnt
.value
);
399 HXGE_REG_RD64(handle
, VMAC_RX_BCAST_FR_CNT
, &rx_bcast_fr_cnt
.value
);
400 HXGE_REG_RD64(handle
, VMAC_RX_MCAST_FR_CNT
, &rx_mcast_fr_cnt
.value
);
402 statsp
->vmac_stats
.tx_frame_cnt
+= tx_frame_cnt
.bits
.tx_frame_cnt
;
403 statsp
->vmac_stats
.tx_byte_cnt
+= tx_byte_cnt
.bits
.tx_byte_cnt
;
404 statsp
->vmac_stats
.rx_frame_cnt
+= rx_frame_cnt
.bits
.rx_frame_cnt
;
405 statsp
->vmac_stats
.rx_byte_cnt
+= rx_byte_cnt
.bits
.rx_byte_cnt
;
406 statsp
->vmac_stats
.rx_drop_frame_cnt
+=
407 rx_drop_fr_cnt
.bits
.rx_drop_frame_cnt
;
408 statsp
->vmac_stats
.rx_drop_byte_cnt
+=
409 rx_drop_byte_cnt
.bits
.rx_drop_byte_cnt
;
410 statsp
->vmac_stats
.rx_crc_cnt
+= rx_crc_cnt
.bits
.rx_crc_cnt
;
411 statsp
->vmac_stats
.rx_pause_cnt
+= rx_pause_cnt
.bits
.rx_pause_cnt
;
412 statsp
->vmac_stats
.rx_bcast_fr_cnt
+=
413 rx_bcast_fr_cnt
.bits
.rx_bcast_fr_cnt
;
414 statsp
->vmac_stats
.rx_mcast_fr_cnt
+=
415 rx_mcast_fr_cnt
.bits
.rx_mcast_fr_cnt
;
417 hxge_save_cntrs_exit
:
418 HXGE_DEBUG_MSG((hxgep
, INT_CTL
, "<== hxge_save_cntrs"));
422 hxge_vmac_set_framesize(p_hxge_t hxgep
)
426 HXGE_DEBUG_MSG((hxgep
, NDD_CTL
, "==> hxge_vmac_set_framesize"));
428 RW_ENTER_WRITER(&hxgep
->filter_lock
);
429 (void) hxge_rx_vmac_disable(hxgep
);
430 (void) hxge_tx_vmac_disable(hxgep
);
433 * Apply the new jumbo parameter here which is contained in hxgep
434 * data structure (hxgep->vmac.maxframesize);
435 * The order of the following two calls is important.
437 (void) hxge_tx_vmac_enable(hxgep
);
438 (void) hxge_rx_vmac_enable(hxgep
);
439 RW_EXIT(&hxgep
->filter_lock
);
441 HXGE_DEBUG_MSG((hxgep
, NDD_CTL
, "<== hxge_vmac_set_framesize"));