8866 bnxe MAC_CAPAB_TRANSCEIVER support
[unleashed.git] / usr / src / uts / common / io / bnxe / bnxe_gld.c
blob679ec3d5a9e5703cfa0a24a35ebd1bd19186a40d
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 2014 QLogic Corporation
24 * The contents of this file are subject to the terms of the
25 * QLogic End User License (the "License").
26 * You may not use this file except in compliance with the License.
28 * You can obtain a copy of the License at
29 * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
30 * QLogic_End_User_Software_License.txt
31 * See the License for the specific language governing permissions
32 * and limitations under the License.
36 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
37 * Copyright (c) 2017, Joyent, Inc.
40 #include "bnxe.h"
42 #include <sys/mac.h>
43 #include <sys/mac_ether.h>
44 #include <sys/dlpi.h>
46 #if !(defined(__S11) || defined(__S12))
47 #define mri_driver mr_driver
48 #define mri_start mr_start
49 #define mri_stop mr_stop
50 #define mri_intr mr_intr
51 #define mri_poll mr_poll
52 #define mri_tx mr_send
53 #define mgi_driver mrg_driver
54 #define mgi_start mrg_start
55 #define mgi_stop mrg_stop
56 #define mgi_count mrg_count
57 #define mgi_addmac mrg_addmac
58 #define mgi_remmac mrg_addmac
59 #define mr_gaddring mr_gadd_ring
60 #define mr_gremring mr_grem_ring
61 #endif /* not __S11 or __S12 */
64 * Reconfiguring the network devices parameters require net_config
65 * privilege starting Solaris 10. Only root user is allowed to
66 * update device parameter in Solaris 9 and earlier version. Following
67 * declaration allows single binary image to run on all OS versions.
69 extern int secpolicy_net_config(const cred_t *, boolean_t);
70 extern int drv_priv(cred_t *);
71 #pragma weak secpolicy_net_config
72 #pragma weak drv_priv
74 #ifdef MC_SETPROP
76 char * bnxeLink_priv_props[] =
78 "_adv_2500fdx_cap",
79 "_en_2500fdx_cap",
80 "_adv_txpause_cap",
81 "_en_txpause_cap",
82 "_txpause",
83 "_adv_rxpause_cap",
84 "_en_rxpause_cap",
85 "_rxpause",
86 "_autoneg_flow",
87 "_checksum",
88 "_num_rings",
89 "_rx_descs",
90 "_rx_free_reclaim",
91 "_rx_copy_threshold",
92 "_tx_descs",
93 "_tx_free_reclaim",
94 "_tx_copy_threshold",
95 "_tx_ring_policy",
96 "_interrupt_coalesce",
97 "_rx_interrupt_coalesce_usec",
98 "_tx_interrupt_coalesce_usec",
99 "_disable_msix",
100 "_l2_fw_flow_ctrl",
101 "_autogreeen_enable",
102 "_lso_enable",
103 "_log_enable",
104 "_fcoe_enable",
105 NULL
108 #endif /* MC_SETPROP */
111 static int BnxeMacStats(void * pArg,
112 uint_t stat,
113 uint64_t * pVal)
115 um_device_t * pUM = (um_device_t *)pArg;
116 lm_device_t * pLM;
117 b10_l2_chip_statistics_t b10_l2_stats;
118 int idx, rc = 0;
120 if ((pUM == NULL) || (pVal == NULL))
122 return EINVAL;
125 pLM = &pUM->lm_dev;
127 BNXE_LOCK_ENTER_GLD(pUM);
129 if (!pUM->plumbed)
131 BNXE_LOCK_EXIT_GLD(pUM);
132 return EAGAIN;
135 *pVal = 0;
137 switch (stat)
139 case MAC_STAT_IFSPEED:
140 *pVal = (pUM->props.link_speed * 1000000ULL);
141 break;
143 case MAC_STAT_MULTIRCV:
144 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
145 L2_CHIP_STATISTICS_VER_NUM_1);
146 *pVal = b10_l2_stats.IfHCInMulticastPkts;
147 break;
149 case MAC_STAT_BRDCSTRCV:
150 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
151 L2_CHIP_STATISTICS_VER_NUM_1);
152 *pVal = b10_l2_stats.IfHCInBroadcastPkts;
153 break;
155 case MAC_STAT_MULTIXMT:
156 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
157 L2_CHIP_STATISTICS_VER_NUM_1);
158 *pVal = b10_l2_stats.IfHCOutMulticastPkts;
159 break;
161 case MAC_STAT_BRDCSTXMT:
162 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
163 L2_CHIP_STATISTICS_VER_NUM_1);
164 *pVal = b10_l2_stats.IfHCOutBroadcastPkts;
165 break;
167 case MAC_STAT_NORCVBUF:
168 lm_get_stats(pLM, LM_STATS_RCV_NO_BUFFER_DROP, (u64_t *)pVal);
169 break;
171 case MAC_STAT_NOXMTBUF:
172 *pVal = 0;
173 LM_FOREACH_TSS_IDX(pLM, idx)
175 *pVal += pUM->txq[idx].txRecycle;
177 break;
179 case MAC_STAT_IERRORS:
180 case ETHER_STAT_MACRCV_ERRORS:
181 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
182 L2_CHIP_STATISTICS_VER_NUM_1);
183 *pVal = b10_l2_stats.IfInErrors;
184 break;
186 case MAC_STAT_OERRORS:
187 /* XXX not available */
188 break;
190 case MAC_STAT_COLLISIONS:
191 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
192 L2_CHIP_STATISTICS_VER_NUM_1);
193 *pVal = b10_l2_stats.EtherStatsCollisions;
194 break;
196 case MAC_STAT_RBYTES:
197 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
198 L2_CHIP_STATISTICS_VER_NUM_1);
199 *pVal = b10_l2_stats.IfHCInOctets;
200 break;
202 case MAC_STAT_IPACKETS:
203 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
204 L2_CHIP_STATISTICS_VER_NUM_1);
205 *pVal = b10_l2_stats.IfHCInPkts;
206 break;
208 case MAC_STAT_OBYTES:
209 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
210 L2_CHIP_STATISTICS_VER_NUM_1);
211 *pVal = b10_l2_stats.IfHCOutOctets;
212 break;
214 case MAC_STAT_OPACKETS:
215 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
216 L2_CHIP_STATISTICS_VER_NUM_1);
217 *pVal = b10_l2_stats.IfHCOutPkts;
218 break;
220 case ETHER_STAT_ALIGN_ERRORS:
221 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
222 L2_CHIP_STATISTICS_VER_NUM_1);
223 *pVal = b10_l2_stats.Dot3StatsAlignmentErrors;
224 break;
226 case ETHER_STAT_FCS_ERRORS:
227 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
228 L2_CHIP_STATISTICS_VER_NUM_1);
229 *pVal = b10_l2_stats.Dot3StatsFCSErrors;
230 break;
232 case ETHER_STAT_FIRST_COLLISIONS:
233 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
234 L2_CHIP_STATISTICS_VER_NUM_1);
235 *pVal = b10_l2_stats.Dot3StatsSingleCollisionFrames;
236 break;
238 case ETHER_STAT_MULTI_COLLISIONS:
239 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
240 L2_CHIP_STATISTICS_VER_NUM_1);
241 *pVal = b10_l2_stats.Dot3StatsMultipleCollisionFrames;
242 break;
244 case ETHER_STAT_DEFER_XMTS:
245 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
246 L2_CHIP_STATISTICS_VER_NUM_1);
247 *pVal = b10_l2_stats.Dot3StatsDeferredTransmissions;
248 break;
250 case ETHER_STAT_TX_LATE_COLLISIONS:
251 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
252 L2_CHIP_STATISTICS_VER_NUM_1);
253 *pVal = b10_l2_stats.Dot3StatsLateCollisions;
254 break;
256 case ETHER_STAT_EX_COLLISIONS:
257 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
258 L2_CHIP_STATISTICS_VER_NUM_1);
259 *pVal = b10_l2_stats.Dot3StatsExcessiveCollisions;
260 break;
262 case ETHER_STAT_MACXMT_ERRORS:
263 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
264 L2_CHIP_STATISTICS_VER_NUM_1);
265 *pVal = b10_l2_stats.Dot3StatsInternalMacTransmitErrors;
266 break;
268 case ETHER_STAT_CARRIER_ERRORS:
269 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
270 L2_CHIP_STATISTICS_VER_NUM_1);
271 *pVal = b10_l2_stats.Dot3StatsCarrierSenseErrors;
272 break;
274 case ETHER_STAT_TOOLONG_ERRORS:
275 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
276 L2_CHIP_STATISTICS_VER_NUM_1);
277 *pVal = b10_l2_stats.EtherStatsOverrsizePkts;
278 break;
280 #if (MAC_VERSION > 1)
281 case ETHER_STAT_TOOSHORT_ERRORS:
282 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
283 L2_CHIP_STATISTICS_VER_NUM_1);
284 *pVal = b10_l2_stats.EtherStatsUndersizePkts;
285 break;
286 #endif
288 case ETHER_STAT_XCVR_ADDR:
289 *pVal = pLM->vars.phy_addr;
290 break;
292 case ETHER_STAT_XCVR_ID:
293 *pVal = 0;
294 break;
296 case ETHER_STAT_XCVR_INUSE:
297 switch (pUM->props.link_speed)
299 case 0: /* no speed then status is down */
300 *pVal = XCVR_NONE;
301 break;
303 case 1000:
304 *pVal = XCVR_1000X;
305 break;
307 case 100:
308 *pVal = XCVR_100X;
309 break;
311 case 10:
312 *pVal = XCVR_10;
313 break;
315 default:
316 /* catches 2500/10000 */
317 *pVal = XCVR_UNDEFINED;
319 break;
321 #if (MAC_VERSION > 1)
322 case ETHER_STAT_CAP_10GFDX:
323 *pVal = 1;
324 break;
325 #endif
327 case ETHER_STAT_CAP_1000FDX:
328 *pVal = 1;
329 break;
331 #if 0
332 case ETHER_STAT_CAP_1000HDX:
333 //*pVal = linkconf->param_1000hdx;
334 *pVal = 0;
335 break;
336 #endif
338 case ETHER_STAT_CAP_100FDX:
339 //*pVal = linkconf->param_100fdx;
340 *pVal = 1;
341 break;
343 case ETHER_STAT_CAP_100HDX:
344 //*pVal = linkconf->param_100hdx;
345 *pVal = 1;
346 break;
348 case ETHER_STAT_CAP_10FDX:
349 //*pVal = linkconf->param_10fdx;
350 *pVal = 1;
351 break;
353 case ETHER_STAT_CAP_10HDX:
354 //*pVal = linkconf->param_10hdx;
355 *pVal = 1;
356 break;
358 case ETHER_STAT_CAP_ASMPAUSE:
359 *pVal = 1;
360 break;
362 case ETHER_STAT_CAP_PAUSE:
363 *pVal = 1;
364 break;
366 case ETHER_STAT_CAP_AUTONEG:
367 *pVal = 1;
368 break;
370 #if (MAC_VERSION > 1)
371 case ETHER_STAT_CAP_REMFAULT:
372 *pVal = 1;
373 break;
374 #endif
376 #if (MAC_VERSION > 1)
377 case ETHER_STAT_ADV_CAP_10GFDX:
378 *pVal = pUM->curcfg.lnkcfg.param_10000fdx;
379 break;
380 #endif
382 case ETHER_STAT_ADV_CAP_1000FDX:
383 *pVal = pUM->curcfg.lnkcfg.param_1000fdx;
384 break;
386 #if 0
387 case ETHER_STAT_ADV_CAP_1000HDX:
388 //*pVal = pUM->curcfg.lnkcfg.param_1000hdx;
389 *pVal = 0;
390 break;
391 #endif
393 case ETHER_STAT_ADV_CAP_100FDX:
394 *pVal = pUM->curcfg.lnkcfg.param_100fdx;
395 break;
397 case ETHER_STAT_ADV_CAP_100HDX:
398 *pVal = pUM->curcfg.lnkcfg.param_100hdx;
399 break;
401 case ETHER_STAT_ADV_CAP_10FDX:
402 *pVal = pUM->curcfg.lnkcfg.param_10fdx;
403 break;
405 case ETHER_STAT_ADV_CAP_10HDX:
406 *pVal = pUM->curcfg.lnkcfg.param_10hdx;
407 break;
409 case ETHER_STAT_ADV_CAP_ASMPAUSE:
410 *pVal = 1;
411 break;
413 case ETHER_STAT_ADV_CAP_PAUSE:
414 *pVal = 1;
415 break;
417 case ETHER_STAT_ADV_CAP_AUTONEG:
418 *pVal = pUM->curcfg.lnkcfg.link_autoneg;
419 break;
421 #if (MAC_VERSION > 1)
422 case ETHER_STAT_ADV_REMFAULT:
423 *pVal = 1;
424 break;
425 #endif
427 #if 0 /* LP caps not supported */
428 #if (MAC_VERSION > 1)
429 case ETHER_STAT_LP_CAP_10GFDX:
430 *pVal = pUM->remote.param_10000fdx;
431 break;
432 #endif
434 case ETHER_STAT_LP_CAP_1000FDX:
435 *pVal = pUM->remote.param_1000fdx;
436 break;
438 #if 0
439 case ETHER_STAT_LP_CAP_1000HDX:
440 //*pVal = pUM->remote.param_1000hdx;
441 *pVal = 0;
442 break;
443 #endif
445 case ETHER_STAT_LP_CAP_100FDX:
446 *pVal = pUM->remote.param_100fdx;
447 break;
449 case ETHER_STAT_LP_CAP_100HDX:
450 *pVal = pUM->remote.param_100hdx;
451 break;
453 case ETHER_STAT_LP_CAP_10FDX:
454 *pVal = pUM->remote.param_10fdx;
455 break;
457 case ETHER_STAT_LP_CAP_10HDX:
458 *pVal = pUM->remote.param_10hdx;
459 break;
461 #if 0
462 case ETHER_STAT_LP_CAP_ASMPAUSE:
463 /* XXX implement LP_ASYM_PAUSE stat */
464 break;
466 case ETHER_STAT_LP_CAP_PAUSE:
467 /* XXX implement LP_PAUSE stat */
468 break;
469 #endif
471 case ETHER_STAT_LP_CAP_AUTONEG:
472 *pVal = pUM->remote.link_autoneg;
473 break;
475 case ETHER_STAT_LP_REMFAULT:
476 /* XXX implement LP_REMFAULT stat */
477 break;
478 #endif /* LP caps not supported */
480 #if 0
481 case ETHER_STAT_LINK_ASMPAUSE:
482 /* XXX implement ASMPAUSE stat */
483 break;
485 case ETHER_STAT_LINK_PAUSE:
486 /* XXX implement PAUSE stat */
487 break;
488 #endif
490 case ETHER_STAT_LINK_AUTONEG:
491 *pVal = pUM->curcfg.lnkcfg.link_autoneg;
492 break;
494 case ETHER_STAT_LINK_DUPLEX:
495 *pVal = (pUM->props.link_duplex == B_TRUE) ?
496 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
497 break;
499 default:
500 rc = ENOTSUP;
503 BNXE_LOCK_EXIT_GLD(pUM);
505 return rc;
511 * This routine is called by GLD to enable device for packet reception and
512 * enable interrupts.
514 static int BnxeMacStart(void * pArg)
516 um_device_t * pUM = (um_device_t *)pArg;
518 BNXE_LOCK_ENTER_GLD(pUM);
520 if (pUM->plumbed)
522 /* already started */
523 BNXE_LOCK_EXIT_GLD(pUM);
524 return EAGAIN;
527 /* Always report the initial link state as unknown. */
528 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
530 if (BnxeHwStartL2(pUM))
532 BNXE_LOCK_EXIT_GLD(pUM);
533 return EIO;
536 atomic_swap_32(&pUM->plumbed, B_TRUE);
538 mutex_enter(&bnxeLoaderMutex);
539 bnxeNumPlumbed++;
540 mutex_exit(&bnxeLoaderMutex);
542 BNXE_LOCK_EXIT_GLD(pUM);
544 return 0;
549 * This routine stops packet reception by clearing RX MASK register. Also
550 * interrupts are disabled for this device.
552 static void BnxeMacStop(void * pArg)
554 um_device_t * pUM = (um_device_t *)pArg;
556 BNXE_LOCK_ENTER_GLD(pUM);
558 if (pUM->plumbed)
560 atomic_swap_32(&pUM->plumbed, B_FALSE);
562 BnxeHwStopL2(pUM);
564 /* Report the link state back to unknown. */
565 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
567 mutex_enter(&bnxeLoaderMutex);
568 bnxeNumPlumbed--;
569 mutex_exit(&bnxeLoaderMutex);
572 BNXE_LOCK_EXIT_GLD(pUM);
575 /* (flag) TRUE = on, FALSE = off */
576 static int BnxeMacPromiscuous(void * pArg,
577 boolean_t flag)
579 um_device_t * pUM = (um_device_t *)pArg;
581 BNXE_LOCK_ENTER_GLD(pUM);
583 if (!pUM->plumbed)
585 BNXE_LOCK_EXIT_GLD(pUM);
586 return EAGAIN;
589 if (flag)
591 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] |=
592 LM_RX_MASK_PROMISCUOUS_MODE;
594 else
596 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] &=
597 ~LM_RX_MASK_PROMISCUOUS_MODE;
600 BNXE_LOCK_ENTER_HWINIT(pUM);
602 if (BnxeRxMask(pUM, LM_CLI_IDX_NDIS,
603 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS]) < 0)
605 BNXE_LOCK_EXIT_HWINIT(pUM);
606 BNXE_LOCK_EXIT_GLD(pUM);
607 return ECANCELED;
610 BNXE_LOCK_EXIT_HWINIT(pUM);
612 BNXE_LOCK_EXIT_GLD(pUM);
614 return 0;
619 * This function is used to enable or disable multicast packet reception for
620 * particular multicast addresses.
621 * (flag) TRUE = add, FALSE = remove
623 static int BnxeMacMulticast(void * pArg,
624 boolean_t flag,
625 const uint8_t * pMcastAddr)
627 um_device_t * pUM = (um_device_t *)pArg;
628 int rc;
630 BNXE_LOCK_ENTER_GLD(pUM);
632 if (!pUM->plumbed)
634 BNXE_LOCK_EXIT_GLD(pUM);
635 return EAGAIN;
638 BNXE_LOCK_ENTER_HWINIT(pUM);
639 rc = BnxeMulticast(pUM, LM_CLI_IDX_NDIS, flag, pMcastAddr, B_TRUE);
640 BNXE_LOCK_EXIT_HWINIT(pUM);
642 BNXE_LOCK_EXIT_GLD(pUM);
644 return rc;
648 #ifdef BNXE_RINGS
650 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
651 static int BnxeRxRingGroupAddMac(void * groupHandle,
652 const uint8_t * pMacAddr,
653 uint64_t flags)
654 #else
655 static int BnxeRxRingGroupAddMac(void * groupHandle,
656 const uint8_t * pMacAddr)
657 #endif
659 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle;
660 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM;
661 //u32_t idx = pRxQGroup->idx;
662 int rc;
664 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
665 _NOTE(ARGUNUSED(flags))
666 #endif
668 BNXE_LOCK_ENTER_GLD(pUM);
670 if (!pUM->plumbed)
672 BNXE_LOCK_EXIT_GLD(pUM);
673 return ECANCELED;
676 /* Validate MAC address */
677 if (IS_ETH_MULTICAST(pMacAddr))
679 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address.");
680 BNXE_LOCK_EXIT_GLD(pUM);
681 return EINVAL;
684 if (pUM->ucastTableLen == LM_MAX_UC_TABLE_SIZE)
686 BNXE_LOCK_EXIT_GLD(pUM);
687 return ENOMEM;
690 BNXE_LOCK_ENTER_HWINIT(pUM);
692 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr);
694 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE,
695 pUM->lm_dev.params.mac_addr);
697 BNXE_LOCK_EXIT_HWINIT(pUM);
699 if (rc < 0)
701 BNXE_LOCK_EXIT_GLD(pUM);
702 return ECANCELED;
705 pUM->ucastTableLen++;
707 BNXE_LOCK_EXIT_GLD(pUM);
708 return 0;
712 static int BnxeRxRingGroupRemMac(void * groupHandle,
713 const uint8_t * pMacAddr)
715 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle;
716 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM;
717 //u32_t idx = pRxQGroup->idx;
718 int rc;
720 BNXE_LOCK_ENTER_GLD(pUM);
722 if (!pUM->plumbed)
724 BNXE_LOCK_EXIT_GLD(pUM);
725 return ECANCELED;
728 if (pUM->ucastTableLen == 0)
730 BNXE_LOCK_EXIT_GLD(pUM);
731 return EINVAL;
734 BNXE_LOCK_ENTER_HWINIT(pUM);
736 if (!IS_ETH_ADDRESS_EQUAL(pMacAddr, pUM->lm_dev.params.mac_addr))
738 BnxeLogWarn(pUM, "Deleting MAC address that doesn't match default");
739 /* XXX */
742 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_FALSE,
743 pUM->lm_dev.params.mac_addr);
745 memset(pUM->lm_dev.params.mac_addr, 0, sizeof(pUM->lm_dev.params.mac_addr));
747 BNXE_LOCK_EXIT_HWINIT(pUM);
749 if (rc < 0)
751 BNXE_LOCK_EXIT_GLD(pUM);
752 return ECANCELED;
755 pUM->ucastTableLen--;
757 BNXE_LOCK_EXIT_GLD(pUM);
758 return 0;
762 static mblk_t * BnxeTxRingSend(void * ringHandle,
763 mblk_t * pMblk)
765 TxQueue * pTxQ = (TxQueue *)ringHandle;
766 um_device_t * pUM = (um_device_t *)pTxQ->pUM;
767 u32_t idx = pTxQ->idx;
768 mblk_t * pNextMblk;
769 int rc;
771 while (pMblk)
773 pNextMblk = pMblk->b_next;
774 pMblk->b_next = NULL;
776 rc = BnxeTxSendMblk(pUM, idx, pMblk, 0, 0);
778 if (rc == BNXE_TX_GOODXMIT)
780 pMblk = pNextMblk;
781 continue;
783 else if (rc == BNXE_TX_DEFERPKT)
785 pMblk = pNextMblk;
787 else
789 pMblk->b_next = pNextMblk;
792 break;
795 return pMblk;
798 #endif /* BNXE_RINGS */
801 static int BnxeMacUnicast(void * pArg,
802 const uint8_t * pMacAddr)
804 um_device_t * pUM = (um_device_t *)pArg;
805 int rc;
807 BNXE_LOCK_ENTER_GLD(pUM);
809 if (!pUM->plumbed)
811 memcpy(pUM->gldMac, pMacAddr, ETHERNET_ADDRESS_SIZE);
812 BNXE_LOCK_EXIT_GLD(pUM);
813 return 0;
816 /* Validate MAC address */
817 if (IS_ETH_MULTICAST(pMacAddr))
819 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address.");
820 BNXE_LOCK_EXIT_GLD(pUM);
821 return EINVAL;
824 BNXE_LOCK_ENTER_HWINIT(pUM);
826 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr);
828 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE,
829 pUM->lm_dev.params.mac_addr);
831 BNXE_LOCK_EXIT_HWINIT(pUM);
833 if (rc < 0)
835 BNXE_LOCK_EXIT_GLD(pUM);
836 return EAGAIN;
839 BNXE_LOCK_EXIT_GLD(pUM);
840 return 0;
844 static mblk_t * BnxeMacTx(void * pArg,
845 mblk_t * pMblk)
847 um_device_t * pUM = (um_device_t *)pArg;
848 mblk_t * pNextMblk;
849 int ring, rc;
851 BNXE_LOCK_ENTER_GLDTX(pUM, RW_READER);
853 if (!pUM->plumbed)
855 freemsgchain(pMblk);
856 BNXE_LOCK_EXIT_GLDTX(pUM);
858 return NULL;
861 while (pMblk)
863 ring = BnxeRouteTxRing(pUM, pMblk);
865 pNextMblk = pMblk->b_next;
866 pMblk->b_next = NULL;
868 //rc = BnxeTxSendMblk(pUM, NDIS_CID(&pUM->lm_dev), pMblk, 0, 0);
869 rc = BnxeTxSendMblk(pUM, ring, pMblk, 0, 0);
871 if (rc == BNXE_TX_GOODXMIT)
873 pMblk = pNextMblk;
874 continue;
876 else if (rc == BNXE_TX_DEFERPKT)
878 pMblk = pNextMblk;
880 else
882 pMblk->b_next = pNextMblk;
885 break;
888 BNXE_LOCK_EXIT_GLDTX(pUM);
890 return pMblk;
894 #ifdef MC_RESOURCES
896 static void BnxeBlank(void * pArg,
897 time_t tick_cnt,
898 uint_t pkt_cnt)
900 um_device_t * pUM = (um_device_t *)pArg;
902 if (!pUM->plumbed)
904 return;
907 /* XXX
908 * Need to dynamically reconfigure the hw with new interrupt
909 * coalescing params...
914 static void BnxeMacResources(void * pArg)
916 um_device_t * pUM = (um_device_t *)pArg;
917 mac_rx_fifo_t mrf;
918 int idx;
920 mrf.mrf_type = MAC_RX_FIFO;
921 mrf.mrf_blank = BnxeBlank;
922 mrf.mrf_arg = (void *)pUM;
923 mrf.mrf_normal_blank_time = 25;
924 mrf.mrf_normal_pkt_count = 8;
926 LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
928 pUM->macRxResourceHandles[idx] =
929 mac_resource_add(pUM->pMac, (mac_resource_t *)&mrf);
933 #endif /* MC_RESOURCES */
936 static boolean_t BnxeReadReg(um_device_t * pUM,
937 struct bnxe_reg_data * pData)
939 if (pData->offset & 0x3)
941 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXEREG ioctl");
942 return B_FALSE;
945 LM_BAR_RD32_OFFSET(&pUM->lm_dev, 0, pData->offset, &pData->value);
947 return B_TRUE;
951 static boolean_t BnxeWriteReg(um_device_t * pUM,
952 struct bnxe_reg_data * pData)
954 if (pData->offset & 0x3)
956 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXEREG ioctl");
957 return B_FALSE;
960 LM_BAR_WR32_OFFSET(&pUM->lm_dev, 0, pData->offset, pData->value);
962 return B_TRUE;
966 static boolean_t BnxeReadNvm(um_device_t * pUM,
967 struct bnxe_nvram_data * pData)
969 if (pData->offset & 0x3)
971 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXENVRM ioctl");
972 return B_FALSE;
975 if (lm_nvram_read(&pUM->lm_dev,
976 pData->offset,
977 pData->value,
978 (pData->num_of_u32 * sizeof(u32_t))) !=
979 LM_STATUS_SUCCESS)
981 return B_FALSE;
984 return B_TRUE;
988 static boolean_t BnxeWriteNvm(um_device_t * pUM,
989 struct bnxe_nvram_data * pData)
991 if (pData->offset & 0x3)
993 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXENVRM ioctl");
994 return B_FALSE;
997 if (lm_nvram_write(&pUM->lm_dev,
998 pData->offset,
999 pData->value,
1000 (pData->num_of_u32 * sizeof(u32_t))) !=
1001 LM_STATUS_SUCCESS)
1003 return B_FALSE;
1006 return B_TRUE;
1010 static boolean_t BnxeReadPciCfg(um_device_t * pUM,
1011 struct bnxe_reg_data * pData)
1013 pData->value = pci_config_get32(pUM->pPciCfg, (off_t)pData->offset);
1014 return B_TRUE;
1017 typedef enum {
1018 STATS_SHOW_TYPE_NUM,
1019 STATS_SHOW_TYPE_STR,
1020 STATS_SHOW_TYPE_CNT,
1021 STATS_SHOW_TYPE_MAX
1022 } stats_show_type_t;
1024 typedef union _b10_stats_show_data_t
1026 u32_t op; /* ioctl sub-commond */
1028 struct
1030 u32_t num; /* return number of stats */
1031 u32_t len; /* length of each string item */
1032 } desc;
1034 /* variable length... */
1035 char str[1]; /* holds names of desc.num stats, each desc.len in length */
1037 struct
1039 b10_l2_chip_statistics_v2_t l2_chip_stats;
1040 b10_l4_chip_statistics_t l4_chip_stats;
1041 b10_l2_driver_statistics_t l2_drv_stats;
1042 b10_l4_driver_statistics_t l4_drv_stats;
1043 } cnt;
1044 } b10_stats_show_data_t;
1047 static boolean_t BnxeStatsShow(um_device_t * pUM,
1048 b10_stats_show_data_t * pStats,
1049 u32_t statsLen)
1051 stats_show_type_t op;
1052 const size_t stats_size = sizeof(pStats->cnt);
1055 * All stats names MUST conform to STATS_STR_LEN length!!!
1058 #define STATS_STR_LEN 39
1060 /* XXX
1061 * Note: these strings must be updated whenever any of
1062 * b10_l2_chip_statistics_t, b10_l4_chip_statistics_t,
1063 * b10_l2_driver_statistics_t or b10_l4_driver_statistics_t
1064 * are changed, or additional statistics are required.
1067 const char p_stat_str[] =
1069 // b10_l2_chip_statistics_t
1071 "l2_chip_stats_ver_num\0 "
1072 "IfHCInOctets\0 "
1073 "IfHCInBadOctets\0 "
1074 "IfHCOutOctets\0 "
1075 "IfHCOutBadOctets\0 "
1076 "IfHCOutPkts\0 "
1077 "IfHCInPkts\0 "
1078 "IfHCInUcastPkts\0 "
1079 "IfHCInMulticastPkts\0 "
1080 "IfHCInBroadcastPkts\0 "
1081 "IfHCOutUcastPkts\0 "
1082 "IfHCOutMulticastPkts\0 "
1083 "IfHCOutBroadcastPkts\0 "
1084 "IfHCInUcastOctets\0 "
1085 "IfHCInMulticastOctets\0 "
1086 "IfHCInBroadcastOctets\0 "
1087 "IfHCOutUcastOctets\0 "
1088 "IfHCOutMulticastOctets\0 "
1089 "IfHCOutBroadcastOctets\0 "
1090 "IfHCOutDiscards\0 "
1091 "IfHCInFalseCarrierErrors\0 "
1092 "Dot3StatsInternalMacTransmitErrors\0 "
1093 "Dot3StatsCarrierSenseErrors\0 "
1094 "Dot3StatsFCSErrors\0 "
1095 "Dot3StatsAlignmentErrors\0 "
1096 "Dot3StatsSingleCollisionFrames\0 "
1097 "Dot3StatsMultipleCollisionFrames\0 "
1098 "Dot3StatsDeferredTransmissions\0 "
1099 "Dot3StatsExcessiveCollisions\0 "
1100 "Dot3StatsLateCollisions\0 "
1101 "EtherStatsCollisions\0 "
1102 "EtherStatsFragments\0 "
1103 "EtherStatsJabbers\0 "
1104 "EtherStatsUndersizePkts\0 "
1105 "EtherStatsOverrsizePkts\0 "
1106 "EtherStatsPktsTx64Octets\0 "
1107 "EtherStatsPktsTx65Octetsto127Octets\0 "
1108 "EtherStatsPktsTx128Octetsto255Octets\0 "
1109 "EtherStatsPktsTx256Octetsto511Octets\0 "
1110 "EtherStatsPktsTx512Octetsto1023Octets\0 "
1111 "EtherStatsPktsTx1024Octetsto1522Octets\0"
1112 "EtherStatsPktsTxOver1522Octets\0 "
1113 "XonPauseFramesReceived\0 "
1114 "XoffPauseFramesReceived\0 "
1115 "OutXonSent\0 "
1116 "OutXoffSent\0 "
1117 "FlowControlDone\0 "
1118 "MacControlFramesReceived\0 "
1119 "XoffStateEntered\0 "
1120 "IfInFramesL2FilterDiscards\0 "
1121 "IfInTTL0Discards\0 "
1122 "IfInxxOverflowDiscards\0 "
1123 "IfInMBUFDiscards\0 "
1124 "IfInErrors\0 "
1125 "IfInErrorsOctets\0 "
1126 "IfInNoBrbBuffer\0 "
1128 "Nig_brb_packet\0 "
1129 "Nig_brb_truncate\0 "
1130 "Nig_flow_ctrl_discard\0 "
1131 "Nig_flow_ctrl_octets\0 "
1132 "Nig_flow_ctrl_packet\0 "
1133 "Nig_mng_discard\0 "
1134 "Nig_mng_octet_inp\0 "
1135 "Nig_mng_octet_out\0 "
1136 "Nig_mng_packet_inp\0 "
1137 "Nig_mng_packet_out\0 "
1138 "Nig_pbf_octets\0 "
1139 "Nig_pbf_packet\0 "
1140 "Nig_safc_inp\0 "
1142 "Tx_Lpi_Count\0 " // This counter counts the number of timers the debounced version of EEE link idle is asserted
1144 // b10_l4_chip_statistics_t
1146 "l4_chip_stats_ver_num\0 "
1147 "NoTxCqes\0 "
1148 "InTCP4Segments\0 "
1149 "OutTCP4Segments\0 "
1150 "RetransmittedTCP4Segments\0 "
1151 "InTCP4Errors\0 "
1152 "InIP4Receives\0 "
1153 "InIP4HeaderErrors\0 "
1154 "InIP4Discards\0 "
1155 "InIP4Delivers\0 "
1156 "InIP4Octets\0 "
1157 "OutIP4Octets\0 "
1158 "InIP4TruncatedPackets\0 "
1159 "InTCP6Segments\0 "
1160 "OutTCP6Segments\0 "
1161 "RetransmittedTCP6Segments\0 "
1162 "InTCP6Errors\0 "
1163 "InIP6Receives\0 "
1164 "InIP6HeaderErrors\0 "
1165 "InIP6Discards\0 "
1166 "InIP6Delivers\0 "
1167 "InIP6Octets\0 "
1168 "OutIP6Octets\0 "
1169 "InIP6TruncatedPackets\0 "
1171 // b10_l2_driver_statistics_t
1173 "l2_driver_stats_ver_num\0 "
1174 "RxIPv4FragCount\0 "
1175 "RxIpCsErrorCount\0 "
1176 "RxTcpCsErrorCount\0 "
1177 "RxLlcSnapCount\0 "
1178 "RxPhyErrorCount\0 "
1179 "RxIpv6ExtCount\0 "
1180 "TxNoL2Bd\0 "
1181 "TxNoSqWqe\0 "
1182 "TxL2AssemblyBufUse\0 "
1184 // b10_l4_driver_statistics_t
1186 "l4_driver_stats_ver_num\0 "
1187 "CurrentlyIpv4Established\0 "
1188 "OutIpv4Resets\0 "
1189 "OutIpv4Fin\0 "
1190 "InIpv4Reset\0 "
1191 "InIpv4Fin\0 "
1192 "CurrentlyIpv6Established\0 "
1193 "OutIpv6Resets\0 "
1194 "OutIpv6Fin\0 "
1195 "InIpv6Reset\0 "
1196 "InIpv6Fin\0 "
1197 "RxIndicateReturnPendingCnt\0 "
1198 "RxIndicateReturnDoneCnt\0 "
1199 "RxActiveGenBufCnt\0 "
1200 "TxNoL4Bd\0 "
1201 "TxL4AssemblyBufUse\0 "
1205 ASSERT_STATIC((sizeof(p_stat_str) / STATS_STR_LEN) ==
1206 (stats_size / sizeof(u64_t)));
1208 op = *((stats_show_type_t *)pStats);
1210 switch (op)
1212 case STATS_SHOW_TYPE_NUM:
1214 if (statsLen < sizeof(pStats->desc))
1216 return B_FALSE;
1219 pStats->desc.num = (stats_size / sizeof(u64_t));
1220 pStats->desc.len = STATS_STR_LEN;
1222 return B_TRUE;
1224 case STATS_SHOW_TYPE_STR:
1226 if (statsLen != sizeof(p_stat_str))
1228 return B_FALSE;
1231 memcpy(pStats->str, p_stat_str, sizeof(p_stat_str));
1233 return B_TRUE;
1235 case STATS_SHOW_TYPE_CNT:
1237 if (statsLen != stats_size)
1239 return B_FALSE;
1242 lm_stats_get_l2_chip_stats(&pUM->lm_dev,
1243 &pStats->cnt.l2_chip_stats,
1244 L2_CHIP_STATISTICS_VER_NUM_2);
1246 lm_stats_get_l4_chip_stats(&pUM->lm_dev,
1247 &pStats->cnt.l4_chip_stats);
1249 lm_stats_get_l2_driver_stats(&pUM->lm_dev
1250 ,&pStats->cnt.l2_drv_stats);
1252 lm_stats_get_l4_driver_stats(&pUM->lm_dev,
1253 &pStats->cnt.l4_drv_stats);
1255 return B_TRUE;
1257 default:
1259 return B_FALSE;
1263 static void BnxeMacIoctl(void * pArg,
1264 queue_t * pQ,
1265 mblk_t * pMblk)
1267 um_device_t * pUM = (um_device_t *)pArg;
1268 struct iocblk * pIoctl;
1269 int rc;
1271 if ((pQ == NULL) || (pMblk == NULL))
1273 return;
1276 if (pMblk->b_datap->db_type != M_IOCTL)
1278 miocnak(pQ, pMblk, 0, EINVAL);
1279 return;
1282 pIoctl = (struct iocblk *)pMblk->b_rptr;
1284 BNXE_LOCK_ENTER_GLD(pUM);
1286 switch (pIoctl->ioc_cmd)
1288 case GIOCBNXELLDP:
1290 if ((pIoctl->ioc_count != sizeof(b10_lldp_params_get_t)) ||
1291 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1292 (miocpullup(pMblk, sizeof(b10_lldp_params_get_t)) < 0))
1294 miocnak(pQ, pMblk, 0, EINVAL);
1295 break;
1298 if (((b10_lldp_params_get_t *)pMblk->b_cont->b_rptr)->ver_num !=
1299 LLDP_PARAMS_VER_NUM)
1301 miocnak(pQ, pMblk, 0, EINVAL);
1302 break;
1305 if (lm_dcbx_lldp_read_params(&pUM->lm_dev,
1306 (b10_lldp_params_get_t *)pMblk->b_cont->b_rptr) !=
1307 LM_STATUS_SUCCESS)
1309 miocnak(pQ, pMblk, 0,
1310 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL);
1311 break;
1314 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1315 break;
1317 case GIOCBNXEDCBX:
1319 if ((pIoctl->ioc_count != sizeof(b10_dcbx_params_get_t)) ||
1320 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1321 (miocpullup(pMblk, sizeof(b10_dcbx_params_get_t)) < 0))
1323 miocnak(pQ, pMblk, 0, EINVAL);
1324 break;
1327 if (((b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr)->ver_num !=
1328 DCBX_PARAMS_VER_NUM)
1330 miocnak(pQ, pMblk, 0, EINVAL);
1331 break;
1334 if (lm_dcbx_read_params(&pUM->lm_dev,
1335 (b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr) !=
1336 LM_STATUS_SUCCESS)
1338 miocnak(pQ, pMblk, 0,
1339 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL);
1340 break;
1343 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1344 break;
1346 case SIOCBNXEDCBX:
1348 /* XXX */
1349 miocnak(pQ, pMblk, 0, EINVAL);
1350 break;
1352 case GIOCBNXEREG:
1354 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) ||
1355 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1356 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0))
1358 miocnak(pQ, pMblk, 0, EINVAL);
1359 break;
1362 if (!BnxeReadReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1364 miocnak(pQ, pMblk, 0, EINVAL);
1366 else
1368 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1371 break;
1373 case SIOCBNXEREG:
1375 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) ||
1376 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1377 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0))
1379 miocnak(pQ, pMblk, 0, EINVAL);
1380 break;
1383 if (!BnxeWriteReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1385 miocnak(pQ, pMblk, 0, EINVAL);
1387 else
1389 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1392 break;
1394 case GIOCBNXENVRM:
1396 if ((pIoctl->ioc_count < sizeof(struct bnxe_nvram_data)) ||
1397 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1398 (miocpullup(pMblk, pIoctl->ioc_count) < 0))
1400 miocnak(pQ, pMblk, 0, EINVAL);
1401 break;
1404 if (!BnxeReadNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr))
1406 miocnak(pQ, pMblk, 0, EINVAL);
1408 else
1410 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1413 break;
1415 case SIOCBNXENVRM:
1417 if ((pIoctl->ioc_count < sizeof(struct bnxe_nvram_data)) ||
1418 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1419 (miocpullup(pMblk, pIoctl->ioc_count) < 0))
1421 miocnak(pQ, pMblk, 0, EINVAL);
1422 break;
1425 if (!BnxeWriteNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr))
1427 miocnak(pQ, pMblk, 0, EINVAL);
1429 else
1431 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1434 break;
1436 case GIOCBNXEPCI:
1438 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) ||
1439 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1440 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0))
1442 miocnak(pQ, pMblk, 0, EINVAL);
1443 break;
1446 if (!BnxeReadPciCfg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1448 miocnak(pQ, pMblk, 0, EINVAL);
1450 else
1452 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1455 break;
1457 case GIOCBNXESTATS:
1459 /* min size = sizeof(op) in b10_stats_show_data_t */
1460 if ((pIoctl->ioc_count < sizeof(u32_t)) ||
1461 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1462 (miocpullup(pMblk, pIoctl->ioc_count) < 0))
1464 miocnak(pQ, pMblk, 0, EINVAL);
1465 break;
1468 if (!BnxeStatsShow(pUM,
1469 (b10_stats_show_data_t *)pMblk->b_cont->b_rptr,
1470 pIoctl->ioc_count))
1472 miocnak(pQ, pMblk, 0, EINVAL);
1474 else
1476 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1479 break;
1481 default:
1483 miocnak(pQ, pMblk, 0, EINVAL);
1484 break;
1487 BNXE_LOCK_EXIT_GLD(pUM);
1491 #ifdef BNXE_RINGS
1493 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1494 static mblk_t * BnxeRxRingPoll(void * ringHandle,
1495 int numBytes,
1496 int numPkts)
1497 #else
1498 static mblk_t * BnxeRxRingPoll(void * ringHandle,
1499 int numBytes)
1500 #endif
1502 RxQueue * pRxQ = (RxQueue *)ringHandle;
1503 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1504 u32_t idx = pRxQ->idx;
1505 mblk_t * pMblk = NULL;
1506 boolean_t pktsRxed = 0;
1507 boolean_t pktsTxed = 0;
1509 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1510 _NOTE(ARGUNUSED(numPkts))
1511 #endif
1513 if (numBytes <= 0)
1515 return NULL;
1518 if (pRxQ->inPollMode == B_FALSE)
1520 BnxeLogWarn(pUM, "Polling on ring %d when NOT in poll mode!", idx);
1521 return NULL;
1524 BNXE_LOCK_ENTER_INTR(pUM, idx);
1526 pRxQ->pollCnt++;
1528 BnxePollRxRing(pUM, idx, &pktsRxed, &pktsTxed);
1530 if (pktsTxed) BnxeTxRingProcess(pUM, idx);
1531 if (pktsRxed) pMblk = BnxeRxRingProcess(pUM, idx, TRUE, numBytes);
1534 * This is here for the off chance that all rings are in polling
1535 * mode and the default interrupt hasn't fired recently to handle
1536 * the sq.
1538 lm_sq_post_pending(&pUM->lm_dev);
1540 BNXE_LOCK_EXIT_INTR(pUM, idx);
1542 return pMblk;
1546 static int BnxeRxRingStart(mac_ring_driver_t ringHandle
1547 #if defined(__S11) || defined(__S12)
1548 , uint64_t genNumber
1549 #endif
1552 RxQueue * pRxQ = (RxQueue *)ringHandle;
1553 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1554 u32_t idx = pRxQ->idx;
1556 BnxeLogDbg(pUM, "Starting Rx Ring %d", idx);
1558 BNXE_LOCK_ENTER_RX(pUM, idx);
1559 #if defined(__S11) || defined(__S12)
1560 pRxQ->genNumber = genNumber;
1561 #endif
1562 pRxQ->inPollMode = B_FALSE;
1563 pRxQ->intrDisableCnt = 0;
1564 pRxQ->intrEnableCnt = 0;
1565 pRxQ->pollCnt = 0;
1566 BNXE_LOCK_EXIT_RX(pUM, idx);
1568 return 0;
1572 #if defined(__S11) || defined(__S12)
1574 static int BnxeRingStat(mac_ring_driver_t ringHandle,
1575 uint_t stat,
1576 uint64_t * val)
1578 RxQueue * pRxQ = (RxQueue *)ringHandle;
1579 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1581 switch (stat)
1583 case MAC_STAT_OERRORS:
1584 case MAC_STAT_OBYTES:
1585 case MAC_STAT_OPACKETS:
1586 case MAC_STAT_IERRORS:
1587 case MAC_STAT_RBYTES: /* MAC_STAT_IBYTES */
1588 case MAC_STAT_IPACKETS:
1589 default:
1590 return ENOTSUP;
1593 return 0;
1596 #endif /* __S11 or __S12 */
1599 #if defined(__S11) || defined(__S12)
1600 static int BnxeRxRingIntrEnable(mac_ring_driver_t ringHandle)
1601 #else
1602 static int BnxeRxRingIntrEnable(mac_intr_handle_t ringHandle)
1603 #endif
1605 RxQueue * pRxQ = (RxQueue *)ringHandle;
1606 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1608 BnxeLogDbg(pUM, "Enabling Interrupt for Rx Ring %d", pRxQ->idx);
1610 /* polling not allowed on LM_NON_RSS_SB when overlapped with FCoE */
1611 if ((pRxQ->idx == LM_NON_RSS_SB(&pUM->lm_dev)) &&
1612 CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE) &&
1613 (pUM->rssIntr.intrCount == LM_MAX_RSS_CHAINS(&pUM->lm_dev)))
1615 return 0; /* ok, already enabled */
1618 BnxeIntrIguSbEnable(pUM, pRxQ->idx, B_FALSE);
1620 return 0;
1624 #if defined(__S11) || defined(__S12)
1625 static int BnxeRxRingIntrDisable(mac_ring_driver_t ringHandle)
1626 #else
1627 static int BnxeRxRingIntrDisable(mac_intr_handle_t ringHandle)
1628 #endif
1630 RxQueue * pRxQ = (RxQueue *)ringHandle;
1631 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1633 BnxeLogDbg(pUM, "Disabling Interrupt for Rx Ring %d", pRxQ->idx);
1635 /* polling not allowed on LM_NON_RSS_SB when overlapped with FCoE */
1636 if ((pRxQ->idx == LM_NON_RSS_SB(&pUM->lm_dev)) &&
1637 CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE) &&
1638 (pUM->rssIntr.intrCount == LM_MAX_RSS_CHAINS(&pUM->lm_dev)))
1640 return -1; /* NO, keep enabled! */
1643 BnxeIntrIguSbDisable(pUM, pRxQ->idx, B_FALSE);
1645 return 0;
1649 /* callback function for MAC layer to register rings */
1650 static void BnxeFillRing(void * arg,
1651 mac_ring_type_t ringType,
1652 const int ringGroupIndex,
1653 const int ringIndex,
1654 mac_ring_info_t * pRingInfo,
1655 mac_ring_handle_t ringHandle)
1657 um_device_t * pUM = (um_device_t *)arg;
1658 RxQueue * pRxQ;
1659 TxQueue * pTxQ;
1661 switch (ringType)
1663 case MAC_RING_TYPE_RX:
1665 BnxeLogInfo(pUM, "Initializing Rx Ring %d (Ring Group %d)",
1666 ringIndex, ringGroupIndex);
1668 ASSERT(ringGroupIndex == 0);
1669 ASSERT(ringIndex < pUM->devParams.numRings);
1671 pRxQ = &pUM->rxq[ringIndex];
1672 pRxQ->ringHandle = ringHandle;
1674 pRingInfo->mri_driver = (mac_ring_driver_t)pRxQ;
1675 pRingInfo->mri_start = BnxeRxRingStart;
1676 pRingInfo->mri_stop = NULL;
1677 #if defined(__S11) || defined(__S12)
1678 pRingInfo->mri_stat = BnxeRingStat;
1679 #endif
1680 pRingInfo->mri_poll = BnxeRxRingPoll;
1682 #if !(defined(__S11) || defined(__S12))
1683 pRingInfo->mri_intr.mi_handle = (mac_intr_handle_t)pRxQ;
1684 #endif
1685 pRingInfo->mri_intr.mi_enable = (mac_intr_enable_t)BnxeRxRingIntrEnable;
1686 pRingInfo->mri_intr.mi_disable = (mac_intr_disable_t)BnxeRxRingIntrDisable;
1688 break;
1690 case MAC_RING_TYPE_TX:
1692 BnxeLogInfo(pUM, "Initializing Tx Ring %d (Ring Group %d)",
1693 ringIndex, ringGroupIndex);
1695 ASSERT(ringGroupIndex == 0);
1696 ASSERT(ringIndex < pUM->devParams.numRings);
1698 pTxQ = &pUM->txq[ringIndex];
1699 pTxQ->ringHandle = ringHandle;
1701 pRingInfo->mri_driver = (mac_ring_driver_t)pTxQ;
1702 pRingInfo->mri_start = NULL;
1703 pRingInfo->mri_stop = NULL;
1704 #if defined(__S11) || defined(__S12)
1705 pRingInfo->mri_stat = BnxeRingStat;
1706 #endif
1707 pRingInfo->mri_tx = (mac_ring_send_t)BnxeTxRingSend;
1709 break;
1711 default:
1712 break;
1717 /* callback function for MAC layer to register groups */
1718 static void BnxeFillGroup(void * arg,
1719 mac_ring_type_t ringType,
1720 const int ringGroupIndex,
1721 mac_group_info_t * pGroupInfo,
1722 mac_group_handle_t groupHandle)
1724 um_device_t * pUM = (um_device_t *)arg;
1725 RxQueueGroup * pRxQGroup;
1727 switch (ringType)
1729 case MAC_RING_TYPE_RX:
1731 BnxeLogInfo(pUM, "Initializing Rx Group %d", ringGroupIndex);
1733 pRxQGroup = &pUM->rxqGroup[ringGroupIndex];
1734 pRxQGroup->groupHandle = groupHandle;
1736 pGroupInfo->mgi_driver = (mac_group_driver_t)pRxQGroup;
1737 pGroupInfo->mgi_start = NULL;
1738 pGroupInfo->mgi_stop = NULL;
1739 pGroupInfo->mgi_addmac = BnxeRxRingGroupAddMac;
1740 pGroupInfo->mgi_remmac = BnxeRxRingGroupRemMac;
1741 pGroupInfo->mgi_count = (pUM->devParams.numRings /
1742 USER_OPTION_RX_RING_GROUPS_DEFAULT);
1743 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1744 pGroupInfo->mgi_flags = MAC_GROUP_DEFAULT;
1745 #endif
1747 break;
1749 case MAC_RING_TYPE_TX:
1750 default:
1751 break;
1755 #endif /* BNXE_RINGS */
1758 static boolean_t BnxeMacGetCapability(void * pArg,
1759 mac_capab_t capability,
1760 void * pCapabilityData)
1762 um_device_t * pUM = (um_device_t *)pArg;
1763 mac_capab_lso_t * pCapLSO;
1764 mac_capab_rings_t * pCapRings;
1766 switch (capability)
1768 case MAC_CAPAB_HCKSUM:
1770 *((u32_t *)pCapabilityData) = 0;
1772 if (pUM->devParams.enabled_oflds &
1773 (LM_OFFLOAD_TX_IP_CKSUM | LM_OFFLOAD_RX_IP_CKSUM))
1775 *((u32_t *)pCapabilityData) |= HCKSUM_IPHDRCKSUM;
1778 if (pUM->devParams.enabled_oflds &
1779 (LM_OFFLOAD_TX_TCP_CKSUM | LM_OFFLOAD_TX_UDP_CKSUM |
1780 LM_OFFLOAD_RX_TCP_CKSUM | LM_OFFLOAD_RX_UDP_CKSUM))
1782 *((u32_t *)pCapabilityData) |= HCKSUM_INET_PARTIAL;
1785 break;
1787 case MAC_CAPAB_LSO:
1789 pCapLSO = (mac_capab_lso_t *)pCapabilityData;
1791 if (pUM->devParams.lsoEnable)
1793 pCapLSO->lso_flags = LSO_TX_BASIC_TCP_IPV4;
1794 pCapLSO->lso_basic_tcp_ipv4.lso_max = BNXE_LSO_MAXLEN;
1795 break;
1798 return B_FALSE;
1800 #ifdef BNXE_RINGS
1802 case MAC_CAPAB_RINGS:
1804 if (!pUM->devParams.numRings)
1806 return B_FALSE;
1809 pCapRings = (mac_capab_rings_t *)pCapabilityData;
1811 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1812 pCapRings->mr_version = MAC_RINGS_VERSION_1;
1813 pCapRings->mr_flags = MAC_RINGS_FLAGS_NONE;
1814 #endif
1815 pCapRings->mr_group_type = MAC_GROUP_TYPE_STATIC;
1816 pCapRings->mr_rnum = pUM->devParams.numRings;
1817 pCapRings->mr_rget = BnxeFillRing;
1818 pCapRings->mr_gaddring = NULL;
1819 pCapRings->mr_gremring = NULL;
1820 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1821 pCapRings->mr_ggetringtc = NULL;
1822 #endif
1824 switch (pCapRings->mr_type)
1826 case MAC_RING_TYPE_RX:
1828 pCapRings->mr_gnum = USER_OPTION_RX_RING_GROUPS_DEFAULT;
1829 pCapRings->mr_gget = BnxeFillGroup;
1830 break;
1832 case MAC_RING_TYPE_TX:
1834 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1835 pCapRings->mr_gnum = 1;
1836 #else
1837 pCapRings->mr_gnum = 0;
1838 #endif
1839 pCapRings->mr_gget = NULL;
1840 break;
1842 default:
1844 return B_FALSE;
1847 break;
1849 #endif /* BNXE_RINGS */
1851 #if !(defined(__S11) || defined(__S12))
1853 case MAC_CAPAB_POLL:
1856 * There's nothing for us to fill in, simply returning B_TRUE stating
1857 * that we support polling is sufficient.
1859 break;
1861 #endif /* not __S11 or __S12 */
1863 #if defined(ILLUMOS)
1864 case MAC_CAPAB_TRANSCEIVER:
1865 return bnxe_fill_transceiver(pUM, pCapabilityData);
1866 #endif
1868 default:
1870 return B_FALSE;
1873 return B_TRUE;
1877 #ifdef MC_SETPROP
1879 static int BnxeSetPrivateProperty(um_device_t * pUM,
1880 const char * pr_name,
1881 uint_t pr_valsize,
1882 const void * pr_val)
1884 int err = 0;
1885 long result;
1887 if (strcmp(pr_name, "_en_2500fdx_cap") == 0)
1889 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1891 return EINVAL;
1894 if ((result > 1) || (result < 0))
1896 return EINVAL;
1899 pUM->hwinit.lnkcfg.param_2500fdx = (uint32_t)result;
1900 pUM->curcfg.lnkcfg.param_2500fdx = (uint32_t)result;
1901 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1903 else if (strcmp(pr_name, "_en_txpause_cap") == 0)
1905 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1907 return EINVAL;
1910 if ((result > 1) || (result < 0))
1912 return EINVAL;
1915 pUM->hwinit.lnkcfg.param_txpause = (uint32_t)result;
1916 pUM->curcfg.lnkcfg.param_txpause = (uint32_t)result;
1917 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1919 else if (strcmp(pr_name, "_en_rxpause_cap") == 0)
1921 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1923 return EINVAL;
1926 if ((result > 1) || (result < 0))
1928 return EINVAL;
1931 pUM->hwinit.lnkcfg.param_rxpause = (uint32_t)result;
1932 pUM->curcfg.lnkcfg.param_rxpause = (uint32_t)result;
1933 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1935 else if (strcmp(pr_name, "_autoneg_flow") == 0)
1937 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1939 return EINVAL;
1942 if ((result > 1) || (result < 0))
1944 return EINVAL;
1947 pUM->hwinit.flow_autoneg = (uint32_t)result;
1948 pUM->curcfg.flow_autoneg = (uint32_t)result;
1949 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1951 else if (strcmp(pr_name, "_checksum") == 0)
1953 if (pUM->plumbed)
1955 return EBUSY;
1958 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1960 return EINVAL;
1963 switch (result)
1965 case USER_OPTION_CKSUM_NONE:
1967 pUM->devParams.enabled_oflds = LM_OFFLOAD_NONE;
1968 break;
1970 case USER_OPTION_CKSUM_L3:
1972 pUM->devParams.enabled_oflds = (LM_OFFLOAD_TX_IP_CKSUM |
1973 LM_OFFLOAD_RX_IP_CKSUM);
1974 break;
1976 case USER_OPTION_CKSUM_L3_L4:
1978 pUM->devParams.enabled_oflds = (LM_OFFLOAD_TX_IP_CKSUM |
1979 LM_OFFLOAD_RX_IP_CKSUM |
1980 LM_OFFLOAD_TX_TCP_CKSUM |
1981 LM_OFFLOAD_RX_TCP_CKSUM |
1982 LM_OFFLOAD_TX_UDP_CKSUM |
1983 LM_OFFLOAD_RX_UDP_CKSUM);
1984 break;
1986 default:
1988 return EINVAL;
1991 pUM->devParams.checksum = (uint32_t)result;
1993 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
1995 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1997 return EINVAL;
2000 switch (result)
2002 case BNXE_ROUTE_RING_NONE:
2003 case BNXE_ROUTE_RING_TCPUDP:
2004 case BNXE_ROUTE_RING_DEST_MAC:
2005 case BNXE_ROUTE_RING_MSG_PRIO:
2007 break;
2009 default:
2011 return EINVAL;
2014 pUM->devParams.routeTxRingPolicy = (uint32_t)result;
2016 else if (strcmp(pr_name, "_num_rings") == 0)
2018 if (pUM->plumbed)
2020 return EBUSY;
2023 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2025 return EINVAL;
2028 if ((result < USER_OPTION_NUM_RINGS_MIN) ||
2029 (result > USER_OPTION_NUM_RINGS_MAX))
2031 return EINVAL;
2034 pUM->devParams.numRings = (uint32_t)result;
2036 else if (strcmp(pr_name, "_rx_descs") == 0)
2038 if (pUM->plumbed)
2040 return EBUSY;
2043 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2045 return EINVAL;
2048 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2050 return EINVAL;
2053 pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result;
2055 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2057 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2059 return EINVAL;
2062 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2064 return EINVAL;
2067 pUM->devParams.maxRxFree = (uint32_t)result;
2069 else if (strcmp(pr_name, "_tx_descs") == 0)
2071 if (pUM->plumbed)
2073 return EBUSY;
2076 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2078 return EINVAL;
2081 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2083 return EINVAL;
2086 pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result;
2088 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2090 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2092 return EINVAL;
2095 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2097 return EINVAL;
2100 pUM->devParams.maxTxFree = (uint32_t)result;
2102 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2104 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2106 return EINVAL;
2109 pUM->devParams.rxCopyThreshold = (uint32_t)result;
2111 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2113 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2115 return EINVAL;
2118 pUM->devParams.txCopyThreshold = (uint32_t)result;
2120 else if (strcmp(pr_name, "_interrupt_coalesce") == 0)
2122 if (pUM->plumbed)
2124 return EBUSY;
2127 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2129 return EINVAL;
2132 if ((result > 1) || (result < 0))
2134 return EINVAL;
2137 pUM->devParams.intrCoalesce = (uint32_t)result;
2139 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0)
2141 if (pUM->plumbed)
2143 return EBUSY;
2146 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2148 return EINVAL;
2151 if ((result < USER_OPTION_INTR_COALESCE_MIN) ||
2152 (result < USER_OPTION_INTR_COALESCE_MAX))
2154 return EINVAL;
2157 pUM->devParams.intrRxPerSec = (uint32_t)(1000000 / result);
2159 else if (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0)
2161 if (pUM->plumbed)
2163 return EBUSY;
2166 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2168 return EINVAL;
2171 if ((result < USER_OPTION_INTR_COALESCE_MIN) ||
2172 (result < USER_OPTION_INTR_COALESCE_MAX))
2174 return EINVAL;
2177 pUM->devParams.intrTxPerSec = (uint32_t)(1000000 / result);
2179 else if (strcmp(pr_name, "_disable_msix") == 0)
2181 if (pUM->plumbed)
2183 return EBUSY;
2186 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2188 return EINVAL;
2191 if ((result > 1) || (result < 0))
2193 return EINVAL;
2196 pUM->devParams.disableMsix = (uint32_t)result;
2198 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0)
2200 if (pUM->plumbed)
2202 return EBUSY;
2205 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2207 return EINVAL;
2210 if ((result > 1) || (result < 0))
2212 return EINVAL;
2215 pUM->devParams.l2_fw_flow_ctrl = (uint32_t)result;
2217 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2219 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2221 return EINVAL;
2224 if ((result > 1) || (result < 0))
2226 return EINVAL;
2229 pUM->devParams.autogreeenEnable = (uint32_t)result;
2230 if (pUM->plumbed) BnxeUpdatePhy(pUM);
2232 else if (strcmp(pr_name, "_lso_enable") == 0)
2234 if (pUM->plumbed)
2236 return EBUSY;
2239 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2241 return EINVAL;
2244 if ((result > 1) || (result < 0))
2246 return EINVAL;
2249 pUM->devParams.lsoEnable = (uint32_t)result;
2251 else if (strcmp(pr_name, "_log_enable") == 0)
2253 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2255 return EINVAL;
2258 if ((result > 1) || (result < 0))
2260 return EINVAL;
2263 pUM->devParams.logEnable = (uint32_t)result;
2265 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2267 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2269 return EINVAL;
2272 if ((result > 1) || (result < 0))
2274 return EINVAL;
2277 pUM->devParams.fcoeEnable = (uint32_t)result;
2279 if (BNXE_FCOE(pUM))
2281 BnxeFcoeStartStop(pUM);
2284 else
2286 err = ENOTSUP;
2289 return err;
2293 static int BnxeMacSetProperty(void * barg,
2294 const char * pr_name,
2295 mac_prop_id_t pr_num,
2296 uint_t pr_valsize,
2297 const void * pr_val)
2299 um_device_t * pUM = barg;
2300 boolean_t reprogram = B_FALSE;
2301 boolean_t rxpause;
2302 boolean_t txpause;
2303 uint32_t mtu;
2304 link_flowctrl_t fl;
2305 int err = 0;
2307 BNXE_LOCK_ENTER_GLD(pUM);
2309 switch (pr_num)
2311 /* read-only props */
2312 case MAC_PROP_STATUS:
2313 case MAC_PROP_SPEED:
2314 case MAC_PROP_DUPLEX:
2316 case MAC_PROP_ADV_10GFDX_CAP:
2317 case MAC_PROP_ADV_1000FDX_CAP:
2318 case MAC_PROP_ADV_1000HDX_CAP:
2319 case MAC_PROP_ADV_100FDX_CAP:
2320 case MAC_PROP_ADV_100HDX_CAP:
2321 case MAC_PROP_ADV_10FDX_CAP:
2322 case MAC_PROP_ADV_10HDX_CAP:
2323 case MAC_PROP_ADV_100T4_CAP:
2325 case MAC_PROP_EN_1000HDX_CAP:
2326 case MAC_PROP_EN_100T4_CAP:
2328 default:
2330 err = ENOTSUP;
2331 break;
2333 case MAC_PROP_EN_10GFDX_CAP:
2335 pUM->hwinit.lnkcfg.param_10000fdx = *(uint8_t *)pr_val;
2336 pUM->curcfg.lnkcfg.param_10000fdx = *(uint8_t *)pr_val;
2337 reprogram = B_TRUE;
2338 break;
2340 case MAC_PROP_EN_1000FDX_CAP:
2342 pUM->hwinit.lnkcfg.param_1000fdx = *(uint8_t *)pr_val;
2343 pUM->curcfg.lnkcfg.param_1000fdx = *(uint8_t *)pr_val;
2344 reprogram = B_TRUE;
2345 break;
2347 case MAC_PROP_EN_100FDX_CAP:
2349 pUM->hwinit.lnkcfg.param_100fdx = *(uint8_t *)pr_val;
2350 pUM->curcfg.lnkcfg.param_100fdx = *(uint8_t *)pr_val;
2351 reprogram = B_TRUE;
2352 break;
2354 case MAC_PROP_EN_100HDX_CAP:
2356 pUM->hwinit.lnkcfg.param_100hdx = *(uint8_t *)pr_val;
2357 pUM->curcfg.lnkcfg.param_100hdx = *(uint8_t *)pr_val;
2358 reprogram = B_TRUE;
2359 break;
2361 case MAC_PROP_EN_10FDX_CAP:
2363 pUM->hwinit.lnkcfg.param_10fdx = *(uint8_t *)pr_val;
2364 pUM->curcfg.lnkcfg.param_10fdx = *(uint8_t *)pr_val;
2365 reprogram = B_TRUE;
2366 break;
2368 case MAC_PROP_EN_10HDX_CAP:
2370 pUM->hwinit.lnkcfg.param_10hdx = *(uint8_t *)pr_val;
2371 pUM->curcfg.lnkcfg.param_10hdx = *(uint8_t *)pr_val;
2372 reprogram = B_TRUE;
2373 break;
2375 case MAC_PROP_AUTONEG:
2377 pUM->hwinit.lnkcfg.link_autoneg = *(uint8_t *)pr_val;
2378 pUM->curcfg.lnkcfg.link_autoneg = *(uint8_t *)pr_val;
2379 reprogram = B_TRUE;
2380 break;
2382 case MAC_PROP_FLOWCTRL:
2384 bcopy(pr_val, &fl, sizeof(fl));
2386 switch (fl)
2388 case LINK_FLOWCTRL_NONE:
2390 rxpause = B_FALSE;
2391 txpause = B_FALSE;
2392 break;
2394 case LINK_FLOWCTRL_RX:
2396 rxpause = B_TRUE;
2397 txpause = B_FALSE;
2398 break;
2400 case LINK_FLOWCTRL_TX:
2402 rxpause = B_FALSE;
2403 txpause = B_TRUE;
2404 break;
2406 case LINK_FLOWCTRL_BI:
2408 rxpause = B_TRUE;
2409 txpause = B_TRUE;
2410 break;
2412 default:
2414 err = ENOTSUP;
2415 break;
2418 if (err == 0)
2420 pUM->hwinit.lnkcfg.param_rxpause = rxpause;
2421 pUM->hwinit.lnkcfg.param_txpause = txpause;
2422 pUM->curcfg.lnkcfg.param_rxpause = rxpause;
2423 pUM->curcfg.lnkcfg.param_txpause = txpause;
2424 reprogram = B_TRUE;
2427 break;
2429 case MAC_PROP_MTU:
2431 if (pUM->plumbed)
2433 err = EBUSY;
2434 break;
2437 bcopy(pr_val, &mtu, sizeof (mtu));
2439 if ((mtu < USER_OPTION_MTU_MIN) || (mtu > USER_OPTION_MTU_MAX))
2441 err = EINVAL;
2442 break;
2445 if (pUM->devParams.mtu[LM_CLI_IDX_NDIS] == mtu)
2447 break;
2450 pUM->devParams.mtu[LM_CLI_IDX_NDIS] = mtu;
2451 err = mac_maxsdu_update(pUM->pMac, pUM->devParams.mtu[LM_CLI_IDX_NDIS]);
2452 pUM->lm_dev.params.mtu[LM_CLI_IDX_NDIS] = pUM->devParams.mtu[LM_CLI_IDX_NDIS];
2453 break;
2455 case MAC_PROP_PRIVATE:
2457 err = BnxeSetPrivateProperty(pUM, pr_name, pr_valsize, pr_val);
2458 break;
2461 if (!err && reprogram)
2463 if (pUM->plumbed) BnxeUpdatePhy(pUM);
2466 BNXE_LOCK_EXIT_GLD(pUM);
2467 return err;
2470 #endif /* MC_SETPROP */
2473 #ifdef MC_GETPROP
2475 static int BnxeGetPrivateProperty(um_device_t * pUM,
2476 const char * pr_name,
2477 uint_t pr_valsize,
2478 void * pr_val)
2480 BnxeLinkCfg * lnk_cfg = &pUM->curcfg.lnkcfg;
2481 BnxeLinkCfg * hw_cfg = &pUM->hwinit.lnkcfg;
2482 int value;
2483 int err = 0;
2485 if (strcmp(pr_name, "_adv_2500fdx_cap") == 0)
2487 value = lnk_cfg->param_2500fdx;
2489 else if (strcmp(pr_name, "_en_2500fdx_cap") == 0)
2491 value = hw_cfg->param_2500fdx;
2493 else if (strcmp(pr_name, "_adv_txpause_cap") == 0)
2495 value = lnk_cfg->param_txpause;
2497 else if (strcmp(pr_name, "_en_txpause_cap") == 0)
2499 value = hw_cfg->param_txpause;
2501 else if (strcmp(pr_name, "_txpause") == 0)
2503 value = pUM->props.link_txpause;
2505 else if (strcmp(pr_name, "_adv_rxpause_cap") == 0)
2507 value = lnk_cfg->param_rxpause;
2509 else if (strcmp(pr_name, "_en_rxpause_cap") == 0)
2511 value = hw_cfg->param_rxpause;
2513 else if (strcmp(pr_name, "_rxpause") == 0)
2515 value = pUM->props.link_rxpause;
2517 else if (strcmp(pr_name, "_autoneg_flow") == 0)
2519 value = pUM->hwinit.flow_autoneg;
2521 else if (strcmp(pr_name, "_checksum") == 0)
2523 value = pUM->devParams.checksum;
2525 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
2527 value = pUM->devParams.routeTxRingPolicy;
2529 else if (strcmp(pr_name, "_num_rings") == 0)
2531 value = pUM->devParams.numRings;
2533 else if (strcmp(pr_name, "_rx_descs") == 0)
2535 value = pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS];
2537 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2539 value = pUM->devParams.maxRxFree;
2541 else if (strcmp(pr_name, "_tx_descs") == 0)
2543 value = pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS];
2545 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2547 value = pUM->devParams.maxTxFree;
2549 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2551 value = pUM->devParams.rxCopyThreshold;
2553 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2555 value = pUM->devParams.txCopyThreshold;
2557 else if (strcmp(pr_name, "_interrupt_coalesce") == 0)
2559 value = pUM->devParams.intrCoalesce;
2561 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0)
2563 value = pUM->devParams.intrRxPerSec;
2565 else if (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0)
2567 value = pUM->devParams.intrTxPerSec;
2569 else if (strcmp(pr_name, "_disable_msix") == 0)
2571 value = pUM->devParams.disableMsix;
2573 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0)
2575 value = pUM->devParams.l2_fw_flow_ctrl;
2577 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2579 value = pUM->devParams.autogreeenEnable;
2581 else if (strcmp(pr_name, "_lso_enable") == 0)
2583 value = pUM->devParams.lsoEnable;
2585 else if (strcmp(pr_name, "_log_enable") == 0)
2587 value = pUM->devParams.logEnable;
2589 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2591 value = pUM->devParams.fcoeEnable;
2593 else
2595 err = ENOTSUP;
2598 if (!err)
2600 (void)snprintf(pr_val, pr_valsize, "%d", value);
2603 return err;
2607 static int BnxeMacGetProperty(void * barg,
2608 const char * pr_name,
2609 mac_prop_id_t pr_num,
2610 uint_t pr_valsize,
2611 void * pr_val)
2613 um_device_t * pUM = barg;
2614 link_flowctrl_t link_flowctrl;
2615 link_state_t link_state;
2616 link_duplex_t link_duplex;
2617 uint64_t link_speed;
2618 BnxeLinkCfg * lnk_cfg = &pUM->curcfg.lnkcfg;
2619 BnxeLinkCfg * hw_cfg = &pUM->hwinit.lnkcfg;
2621 switch (pr_num)
2623 case MAC_PROP_MTU:
2625 ASSERT(pr_valsize >= sizeof(u32_t));
2627 bcopy(&pUM->devParams.mtu[LM_CLI_IDX_NDIS], pr_val, sizeof(u32_t));
2628 break;
2630 case MAC_PROP_DUPLEX:
2632 ASSERT(pr_valsize >= sizeof(link_duplex_t));
2634 link_duplex = pUM->props.link_duplex ?
2635 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
2636 bcopy(&link_duplex, pr_val, sizeof(link_duplex_t));
2637 break;
2639 case MAC_PROP_SPEED:
2641 ASSERT(pr_valsize >= sizeof(link_speed));
2643 link_speed = (pUM->props.link_speed * 1000000ULL);
2644 bcopy(&link_speed, pr_val, sizeof(link_speed));
2645 break;
2647 case MAC_PROP_STATUS:
2649 ASSERT(pr_valsize >= sizeof(link_state_t));
2651 link_state = pUM->props.link_speed ?
2652 LINK_STATE_UP : LINK_STATE_DOWN;
2653 bcopy(&link_state, pr_val, sizeof(link_state_t));
2654 break;
2656 case MAC_PROP_AUTONEG:
2658 *(uint8_t *)pr_val = lnk_cfg->link_autoneg;
2659 break;
2661 case MAC_PROP_FLOWCTRL:
2663 ASSERT(pr_valsize >= sizeof(link_flowctrl_t));
2665 if (!lnk_cfg->param_rxpause && !lnk_cfg->param_txpause)
2667 link_flowctrl = LINK_FLOWCTRL_NONE;
2669 if (lnk_cfg->param_rxpause && !lnk_cfg->param_txpause)
2671 link_flowctrl = LINK_FLOWCTRL_RX;
2673 if (!lnk_cfg->param_rxpause && lnk_cfg->param_txpause)
2675 link_flowctrl = LINK_FLOWCTRL_TX;
2677 if (lnk_cfg->param_rxpause && lnk_cfg->param_txpause)
2679 link_flowctrl = LINK_FLOWCTRL_BI;
2682 bcopy(&link_flowctrl, pr_val, sizeof(link_flowctrl_t));
2683 break;
2685 case MAC_PROP_ADV_10GFDX_CAP:
2687 *(uint8_t *)pr_val = lnk_cfg->param_10000fdx;
2688 break;
2690 case MAC_PROP_EN_10GFDX_CAP:
2692 *(uint8_t *)pr_val = hw_cfg->param_10000fdx;
2693 break;
2695 case MAC_PROP_ADV_1000FDX_CAP:
2697 *(uint8_t *)pr_val = lnk_cfg->param_1000fdx;
2698 break;
2700 case MAC_PROP_EN_1000FDX_CAP:
2702 *(uint8_t *)pr_val = hw_cfg->param_1000fdx;
2703 break;
2705 case MAC_PROP_ADV_1000HDX_CAP:
2706 case MAC_PROP_EN_1000HDX_CAP:
2708 *(uint8_t *)pr_val = 0;
2709 break;
2711 case MAC_PROP_ADV_100FDX_CAP:
2713 *(uint8_t *)pr_val = lnk_cfg->param_100fdx;
2714 break;
2716 case MAC_PROP_EN_100FDX_CAP:
2718 *(uint8_t *)pr_val = hw_cfg->param_100fdx;
2719 break;
2721 case MAC_PROP_ADV_100HDX_CAP:
2723 *(uint8_t *)pr_val = lnk_cfg->param_100hdx;
2724 break;
2726 case MAC_PROP_EN_100HDX_CAP:
2728 *(uint8_t *)pr_val = hw_cfg->param_100hdx;
2729 break;
2731 case MAC_PROP_ADV_100T4_CAP:
2732 case MAC_PROP_EN_100T4_CAP:
2734 *(uint8_t *)pr_val = 0;
2735 break;
2737 case MAC_PROP_ADV_10FDX_CAP:
2739 *(uint8_t *)pr_val = lnk_cfg->param_10fdx;
2740 break;
2742 case MAC_PROP_EN_10FDX_CAP:
2744 *(uint8_t *)pr_val = hw_cfg->param_10fdx;
2745 break;
2747 case MAC_PROP_ADV_10HDX_CAP:
2749 *(uint8_t *)pr_val = lnk_cfg->param_10hdx;
2750 break;
2752 case MAC_PROP_EN_10HDX_CAP:
2754 *(uint8_t *)pr_val = hw_cfg->param_10hdx;
2755 break;
2757 case MAC_PROP_PRIVATE:
2759 return BnxeGetPrivateProperty(pUM,
2760 pr_name,
2761 pr_valsize,
2762 pr_val);
2764 default:
2766 return ENOTSUP;
2769 return 0;
2772 #endif /* MC_GETPROP */
2775 #ifdef MC_PROPINFO
2777 static void BnxeMacPrivatePropertyInfo(um_device_t * pUM,
2778 const char * pr_name,
2779 mac_prop_info_handle_t prh)
2781 char valstr[64];
2782 BnxeLinkCfg * default_cfg = &bnxeLinkCfg;
2783 int default_val;
2785 bzero(valstr, sizeof (valstr));
2787 if ((strcmp(pr_name, "_adv_2500fdx_cap") == 0) ||
2788 (strcmp(pr_name, "_adv_txpause_cap") == 0) ||
2789 (strcmp(pr_name, "_txpause") == 0) ||
2790 (strcmp(pr_name, "_adv_rxpause_cap") == 0) ||
2791 (strcmp(pr_name, "_rxpause") == 0) ||
2792 (strcmp(pr_name, "_checksum") == 0) ||
2793 (strcmp(pr_name, "_num_rings") == 0) ||
2794 (strcmp(pr_name, "_rx_descs") == 0) ||
2795 (strcmp(pr_name, "_tx_descs") == 0) ||
2796 (strcmp(pr_name, "_interrupt_coalesce") == 0) ||
2797 (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0) ||
2798 (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0) ||
2799 (strcmp(pr_name, "_disable_msix") == 0) ||
2800 (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0) ||
2801 (strcmp(pr_name, "_lso_enable") == 0))
2803 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2804 return;
2807 if (strcmp(pr_name, "_autoneg_flow") == 0)
2809 default_val = B_TRUE;
2811 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
2813 default_val = BNXE_ROUTE_RING_TCPUDP;
2815 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2817 default_val = USER_OPTION_RX_MAX_FREE_DEFAULT;
2819 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2821 default_val = USER_OPTION_TX_MAX_FREE_DEFAULT;
2823 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2825 default_val = USER_OPTION_RX_DCOPY_THRESH_DEFAULT;
2827 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2829 default_val = USER_OPTION_TX_DCOPY_THRESH_DEFAULT;
2831 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2833 default_val = B_TRUE;
2835 else if (strcmp(pr_name, "_log_enable") == 0)
2837 default_val = B_TRUE;
2839 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2841 default_val = B_TRUE;
2843 else
2845 return;
2848 snprintf(valstr, sizeof (valstr), "%d", default_val);
2849 mac_prop_info_set_default_str(prh, valstr);
2853 static void BnxeMacPropertyInfo(void * barg,
2854 const char * pr_name,
2855 mac_prop_id_t pr_num,
2856 mac_prop_info_handle_t prh)
2858 um_device_t * pUM = barg;
2859 link_flowctrl_t link_flowctrl;
2860 BnxeLinkCfg * default_cfg = &bnxeLinkCfg;
2862 switch (pr_num)
2864 case MAC_PROP_STATUS:
2865 case MAC_PROP_SPEED:
2866 case MAC_PROP_DUPLEX:
2868 case MAC_PROP_ADV_10GFDX_CAP:
2869 case MAC_PROP_ADV_1000FDX_CAP:
2870 case MAC_PROP_ADV_1000HDX_CAP:
2871 case MAC_PROP_ADV_100FDX_CAP:
2872 case MAC_PROP_ADV_100HDX_CAP:
2873 case MAC_PROP_ADV_100T4_CAP:
2874 case MAC_PROP_ADV_10FDX_CAP:
2875 case MAC_PROP_ADV_10HDX_CAP:
2877 case MAC_PROP_EN_1000HDX_CAP:
2878 case MAC_PROP_EN_100T4_CAP:
2880 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2881 break;
2883 case MAC_PROP_EN_10GFDX_CAP:
2885 mac_prop_info_set_default_uint8(prh, default_cfg->param_10000fdx);
2886 break;
2888 case MAC_PROP_EN_1000FDX_CAP:
2890 mac_prop_info_set_default_uint8(prh, default_cfg->param_1000fdx);
2891 break;
2893 case MAC_PROP_EN_100FDX_CAP:
2895 mac_prop_info_set_default_uint8(prh, default_cfg->param_100fdx);
2896 break;
2898 case MAC_PROP_EN_100HDX_CAP:
2900 mac_prop_info_set_default_uint8(prh, default_cfg->param_100hdx);
2901 break;
2903 case MAC_PROP_EN_10FDX_CAP:
2905 mac_prop_info_set_default_uint8(prh, default_cfg->param_10fdx);
2906 break;
2908 case MAC_PROP_EN_10HDX_CAP:
2910 mac_prop_info_set_default_uint8(prh, default_cfg->param_10hdx);
2911 break;
2913 case MAC_PROP_MTU:
2915 mac_prop_info_set_range_uint32(prh,
2916 USER_OPTION_MTU_MIN,
2917 USER_OPTION_MTU_MAX);
2918 break;
2920 case MAC_PROP_AUTONEG:
2922 mac_prop_info_set_default_uint8(prh, default_cfg->link_autoneg);
2923 break;
2925 case MAC_PROP_FLOWCTRL:
2927 if (!default_cfg->param_rxpause && !default_cfg->param_txpause)
2929 link_flowctrl = LINK_FLOWCTRL_NONE;
2932 if (default_cfg->param_rxpause && !default_cfg->param_txpause)
2934 link_flowctrl = LINK_FLOWCTRL_RX;
2937 if (!default_cfg->param_rxpause && default_cfg->param_txpause)
2939 link_flowctrl = LINK_FLOWCTRL_TX;
2942 if (default_cfg->param_rxpause && default_cfg->param_txpause)
2944 link_flowctrl = LINK_FLOWCTRL_BI;
2947 mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl);
2948 break;
2950 case MAC_PROP_PRIVATE:
2952 BnxeMacPrivatePropertyInfo(pUM, pr_name, prh);
2953 break;
2957 #endif /* MC_PROPINFO */
2960 static mac_callbacks_t bnxe_callbacks =
2963 MC_IOCTL
2964 #ifdef MC_RESOURCES
2965 | MC_RESOURCES
2966 #endif
2967 #ifdef MC_SETPROP
2968 | MC_SETPROP
2969 #endif
2970 #ifdef MC_GETPROP
2971 | MC_GETPROP
2972 #endif
2973 #ifdef MC_PROPINFO
2974 | MC_PROPINFO
2975 #endif
2976 | MC_GETCAPAB
2978 BnxeMacStats,
2979 BnxeMacStart,
2980 BnxeMacStop,
2981 BnxeMacPromiscuous,
2982 BnxeMacMulticast,
2983 NULL,
2984 BnxeMacTx,
2985 #ifdef MC_RESOURCES
2986 BnxeMacResources,
2987 #else
2988 NULL,
2989 #endif
2990 BnxeMacIoctl,
2991 BnxeMacGetCapability,
2992 #ifdef MC_OPEN
2993 NULL,
2994 NULL,
2995 #endif
2996 #ifdef MC_SETPROP
2997 BnxeMacSetProperty,
2998 #endif
2999 #ifdef MC_GETPROP
3000 BnxeMacGetProperty,
3001 #endif
3002 #ifdef MC_PROPINFO
3003 BnxeMacPropertyInfo
3004 #endif
3008 boolean_t BnxeGldInit(um_device_t * pUM)
3010 mac_register_t * pMac;
3011 int rc;
3013 atomic_swap_32(&pUM->plumbed, B_FALSE);
3015 if ((pMac = mac_alloc(MAC_VERSION)) == NULL)
3017 BnxeLogWarn(pUM, "Failed to allocate GLD MAC memory");
3018 return B_FALSE;
3021 pMac->m_driver = pUM;
3022 pMac->m_dip = pUM->pDev;
3023 pMac->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
3024 pMac->m_callbacks = &bnxe_callbacks;
3025 pMac->m_min_sdu = 0;
3026 pMac->m_max_sdu = pUM->devParams.mtu[LM_CLI_IDX_NDIS];
3027 pMac->m_src_addr = &(pUM->lm_dev.params.mac_addr[0]);
3029 #ifdef MC_OPEN
3030 pMac->m_margin = VLAN_TAGSZ;
3031 #endif
3033 #ifdef MC_SETPROP
3034 pMac->m_priv_props = bnxeLink_priv_props;
3035 #endif
3037 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
3038 bnxe_callbacks.mc_unicst =
3039 (!pUM->devParams.numRings) ? BnxeMacUnicast : NULL;
3040 #else
3041 bnxe_callbacks.mc_unicst = BnxeMacUnicast;
3042 #endif
3044 rc = mac_register(pMac, &pUM->pMac);
3046 mac_free(pMac);
3048 if (rc != 0)
3050 BnxeLogWarn(pUM, "Failed to register with GLD (%d)", rc);
3051 return B_FALSE;
3054 /* Always report the initial link state as unknown. */
3055 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
3057 return B_TRUE;
3061 boolean_t BnxeGldFini(um_device_t * pUM)
3063 int cnt;
3065 if (pUM->plumbed)
3067 BnxeLogWarn(pUM, "Detaching device from GLD that is started!");
3068 return B_FALSE;
3071 /* We must not detach until all packets held by stack are retrieved. */
3072 if (!BnxeWaitForPacketsFromClient(pUM, LM_CLI_IDX_NDIS))
3074 return B_FALSE;
3077 if (pUM->pMac)
3079 if (mac_unregister(pUM->pMac))
3081 BnxeLogWarn(pUM, "Failed to unregister with the GLD");
3082 return B_FALSE;
3086 return B_TRUE;
3090 void BnxeGldLink(um_device_t * pUM,
3091 link_state_t state)
3093 mac_link_update(pUM->pMac, state);