bmake-ify mr_sas
[unleashed.git] / kernel / drivers / net / hxge / hxge_vmac.c
blobc70815d2728132249f332099ca61b2ae41f20a3a
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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);
42 hxge_status_t
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"));
62 return (HXGE_OK);
65 hxge_status_t
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)
73 goto fail;
75 if ((status = hxge_rx_vmac_reset(hxgep)) != HXGE_OK)
76 goto fail;
78 if ((status = hxge_tx_vmac_enable(hxgep)) != HXGE_OK)
79 goto fail;
81 if ((status = hxge_rx_vmac_enable(hxgep)) != HXGE_OK)
82 goto fail;
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:"));
98 return (HXGE_OK);
99 fail:
100 HXGE_DEBUG_MSG((hxgep, MAC_CTL,
101 "hxge_vmac_init: failed to initialize VMAC>"));
103 return (status);
107 /* Initialize the TxVMAC sub-block */
109 hxge_status_t
110 hxge_tx_vmac_init(p_hxge_t hxgep)
112 uint64_t config;
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)
120 return (HXGE_ERROR);
122 hxgep->vmac.tx_config = config;
124 return (HXGE_OK);
127 /* Initialize the RxVMAC sub-block */
129 hxge_status_t
130 hxge_rx_vmac_init(p_hxge_t hxgep)
132 uint64_t xconfig;
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)
154 return (HXGE_ERROR);
156 hxgep->vmac.rx_config = xconfig;
158 return (HXGE_OK);
161 /* Enable TxVMAC */
163 hxge_status_t
164 hxge_tx_vmac_enable(p_hxge_t hxgep)
166 hpi_status_t rv;
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);
173 if (rv != HXGE_OK)
174 return (rv);
176 /* Based on speed */
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"));
185 return (status);
188 /* Disable TxVMAC */
190 hxge_status_t
191 hxge_tx_vmac_disable(p_hxge_t hxgep)
193 hpi_status_t rv;
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"));
205 return (status);
208 /* Enable RxVMAC */
210 hxge_status_t
211 hxge_rx_vmac_enable(p_hxge_t hxgep)
213 hpi_status_t rv;
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"));
229 return (HXGE_ERROR);
233 * Wait for a period of time.
235 HXGE_DELAY(10);
238 * Enable the vmac.
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"));
245 return (status);
248 /* Disable RxVMAC */
250 hxge_status_t
251 hxge_rx_vmac_disable(p_hxge_t hxgep)
253 hpi_status_t rv;
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),
266 (uint16_t)0);
269 * Wait for 10us before doing disable.
271 HXGE_DELAY(10);
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"));
278 return (status);
281 /* Reset TxVMAC */
283 hxge_status_t
284 hxge_tx_vmac_reset(p_hxge_t hxgep)
286 hpi_handle_t handle = hxgep->hpi_handle;
288 (void) hpi_tx_vmac_reset(handle);
290 return (HXGE_OK);
293 /* Reset RxVMAC */
295 hxge_status_t
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),
301 (uint16_t)0);
304 * Wait for 10us before doing reset.
306 HXGE_DELAY(10);
308 (void) hpi_rx_vmac_reset(handle);
310 return (HXGE_OK);
313 /*ARGSUSED*/
314 uint_t
315 hxge_vmac_intr(caddr_t arg1, caddr_t arg2)
317 p_hxge_t hxgep = (p_hxge_t)arg2;
318 hpi_handle_t handle;
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
337 hxge_status_t
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)
348 goto fail;
349 if ((status = hxge_rx_vmac_enable(hxgep)) != HXGE_OK)
350 goto fail;
351 RW_EXIT(&hxgep->filter_lock);
353 if (on)
354 hxgep->statsp->mac_stats.promisc = B_TRUE;
355 else
356 hxgep->statsp->mac_stats.promisc = B_FALSE;
358 HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_set_promisc"));
359 return (HXGE_OK);
361 fail:
362 RW_EXIT(&hxgep->filter_lock);
364 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "hxge_set_promisc: "
365 "Unable to set promisc (%d)", on));
366 return (status);
369 void
370 hxge_save_cntrs(p_hxge_t hxgep)
372 p_hxge_stats_t statsp;
373 hpi_handle_t handle;
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)
424 int status = 0;
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"));
442 return (status);