blob: 679ec3d5a9e5703cfa0a24a35ebd1bd19186a40d [file] [log] [blame]
Robert Mustacchid14abf12014-06-06 22:58:53 +00001/*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22/*
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.
27 *
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.
33 */
34
35/*
36 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
Robert Mustacchi947eaaf2017-06-16 22:58:47 +000037 * Copyright (c) 2017, Joyent, Inc.
Robert Mustacchid14abf12014-06-06 22:58:53 +000038 */
39
40#include "bnxe.h"
41
42#include <sys/mac.h>
43#include <sys/mac_ether.h>
44#include <sys/dlpi.h>
45
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 */
62
63/*
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.
68 */
69extern int secpolicy_net_config(const cred_t *, boolean_t);
70extern int drv_priv(cred_t *);
71#pragma weak secpolicy_net_config
72#pragma weak drv_priv
73
74#ifdef MC_SETPROP
75
76char * bnxeLink_priv_props[] =
77{
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
106};
107
108#endif /* MC_SETPROP */
109
110
111static int BnxeMacStats(void * pArg,
112 uint_t stat,
113 uint64_t * pVal)
114{
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;
119
120 if ((pUM == NULL) || (pVal == NULL))
121 {
122 return EINVAL;
123 }
124
125 pLM = &pUM->lm_dev;
126
127 BNXE_LOCK_ENTER_GLD(pUM);
128
129 if (!pUM->plumbed)
130 {
131 BNXE_LOCK_EXIT_GLD(pUM);
132 return EAGAIN;
133 }
134
135 *pVal = 0;
136
137 switch (stat)
138 {
139 case MAC_STAT_IFSPEED:
140 *pVal = (pUM->props.link_speed * 1000000ULL);
141 break;
142
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;
148
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;
154
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;
160
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;
166
167 case MAC_STAT_NORCVBUF:
168 lm_get_stats(pLM, LM_STATS_RCV_NO_BUFFER_DROP, (u64_t *)pVal);
169 break;
170
171 case MAC_STAT_NOXMTBUF:
172 *pVal = 0;
173 LM_FOREACH_TSS_IDX(pLM, idx)
174 {
175 *pVal += pUM->txq[idx].txRecycle;
176 }
177 break;
178
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;
185
186 case MAC_STAT_OERRORS:
187 /* XXX not available */
188 break;
189
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;
195
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;
201
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;
207
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;
213
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;
219
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;
225
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;
231
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;
237
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;
243
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;
249
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;
255
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;
261
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;
267
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;
273
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;
279
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
287
288 case ETHER_STAT_XCVR_ADDR:
289 *pVal = pLM->vars.phy_addr;
290 break;
291
292 case ETHER_STAT_XCVR_ID:
293 *pVal = 0;
294 break;
295
296 case ETHER_STAT_XCVR_INUSE:
297 switch (pUM->props.link_speed)
298 {
299 case 0: /* no speed then status is down */
300 *pVal = XCVR_NONE;
301 break;
302
303 case 1000:
304 *pVal = XCVR_1000X;
305 break;
306
307 case 100:
308 *pVal = XCVR_100X;
309 break;
310
311 case 10:
312 *pVal = XCVR_10;
313 break;
314
315 default:
316 /* catches 2500/10000 */
317 *pVal = XCVR_UNDEFINED;
318 }
319 break;
320
321#if (MAC_VERSION > 1)
322 case ETHER_STAT_CAP_10GFDX:
323 *pVal = 1;
324 break;
325#endif
326
327 case ETHER_STAT_CAP_1000FDX:
328 *pVal = 1;
329 break;
330
331#if 0
332 case ETHER_STAT_CAP_1000HDX:
333 //*pVal = linkconf->param_1000hdx;
334 *pVal = 0;
335 break;
336#endif
337
338 case ETHER_STAT_CAP_100FDX:
339 //*pVal = linkconf->param_100fdx;
340 *pVal = 1;
341 break;
342
343 case ETHER_STAT_CAP_100HDX:
344 //*pVal = linkconf->param_100hdx;
345 *pVal = 1;
346 break;
347
348 case ETHER_STAT_CAP_10FDX:
349 //*pVal = linkconf->param_10fdx;
350 *pVal = 1;
351 break;
352
353 case ETHER_STAT_CAP_10HDX:
354 //*pVal = linkconf->param_10hdx;
355 *pVal = 1;
356 break;
357
358 case ETHER_STAT_CAP_ASMPAUSE:
359 *pVal = 1;
360 break;
361
362 case ETHER_STAT_CAP_PAUSE:
363 *pVal = 1;
364 break;
365
366 case ETHER_STAT_CAP_AUTONEG:
367 *pVal = 1;
368 break;
369
370#if (MAC_VERSION > 1)
371 case ETHER_STAT_CAP_REMFAULT:
372 *pVal = 1;
373 break;
374#endif
375
376#if (MAC_VERSION > 1)
377 case ETHER_STAT_ADV_CAP_10GFDX:
378 *pVal = pUM->curcfg.lnkcfg.param_10000fdx;
379 break;
380#endif
381
382 case ETHER_STAT_ADV_CAP_1000FDX:
383 *pVal = pUM->curcfg.lnkcfg.param_1000fdx;
384 break;
385
386#if 0
387 case ETHER_STAT_ADV_CAP_1000HDX:
388 //*pVal = pUM->curcfg.lnkcfg.param_1000hdx;
389 *pVal = 0;
390 break;
391#endif
392
393 case ETHER_STAT_ADV_CAP_100FDX:
394 *pVal = pUM->curcfg.lnkcfg.param_100fdx;
395 break;
396
397 case ETHER_STAT_ADV_CAP_100HDX:
398 *pVal = pUM->curcfg.lnkcfg.param_100hdx;
399 break;
400
401 case ETHER_STAT_ADV_CAP_10FDX:
402 *pVal = pUM->curcfg.lnkcfg.param_10fdx;
403 break;
404
405 case ETHER_STAT_ADV_CAP_10HDX:
406 *pVal = pUM->curcfg.lnkcfg.param_10hdx;
407 break;
408
409 case ETHER_STAT_ADV_CAP_ASMPAUSE:
410 *pVal = 1;
411 break;
412
413 case ETHER_STAT_ADV_CAP_PAUSE:
414 *pVal = 1;
415 break;
416
417 case ETHER_STAT_ADV_CAP_AUTONEG:
418 *pVal = pUM->curcfg.lnkcfg.link_autoneg;
419 break;
420
421#if (MAC_VERSION > 1)
422 case ETHER_STAT_ADV_REMFAULT:
423 *pVal = 1;
424 break;
425#endif
426
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
433
434 case ETHER_STAT_LP_CAP_1000FDX:
435 *pVal = pUM->remote.param_1000fdx;
436 break;
437
438#if 0
439 case ETHER_STAT_LP_CAP_1000HDX:
440 //*pVal = pUM->remote.param_1000hdx;
441 *pVal = 0;
442 break;
443#endif
444
445 case ETHER_STAT_LP_CAP_100FDX:
446 *pVal = pUM->remote.param_100fdx;
447 break;
448
449 case ETHER_STAT_LP_CAP_100HDX:
450 *pVal = pUM->remote.param_100hdx;
451 break;
452
453 case ETHER_STAT_LP_CAP_10FDX:
454 *pVal = pUM->remote.param_10fdx;
455 break;
456
457 case ETHER_STAT_LP_CAP_10HDX:
458 *pVal = pUM->remote.param_10hdx;
459 break;
460
461#if 0
462 case ETHER_STAT_LP_CAP_ASMPAUSE:
463 /* XXX implement LP_ASYM_PAUSE stat */
464 break;
465
466 case ETHER_STAT_LP_CAP_PAUSE:
467 /* XXX implement LP_PAUSE stat */
468 break;
469#endif
470
471 case ETHER_STAT_LP_CAP_AUTONEG:
472 *pVal = pUM->remote.link_autoneg;
473 break;
474
475 case ETHER_STAT_LP_REMFAULT:
476 /* XXX implement LP_REMFAULT stat */
477 break;
478#endif /* LP caps not supported */
479
480#if 0
481 case ETHER_STAT_LINK_ASMPAUSE:
482 /* XXX implement ASMPAUSE stat */
483 break;
484
485 case ETHER_STAT_LINK_PAUSE:
486 /* XXX implement PAUSE stat */
487 break;
488#endif
489
490 case ETHER_STAT_LINK_AUTONEG:
491 *pVal = pUM->curcfg.lnkcfg.link_autoneg;
492 break;
493
494 case ETHER_STAT_LINK_DUPLEX:
495 *pVal = (pUM->props.link_duplex == B_TRUE) ?
496 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
497 break;
498
499 default:
500 rc = ENOTSUP;
501 }
502
503 BNXE_LOCK_EXIT_GLD(pUM);
504
505 return rc;
506}
507
508
509
510/*
511 * This routine is called by GLD to enable device for packet reception and
512 * enable interrupts.
513 */
514static int BnxeMacStart(void * pArg)
515{
516 um_device_t * pUM = (um_device_t *)pArg;
517
518 BNXE_LOCK_ENTER_GLD(pUM);
519
520 if (pUM->plumbed)
521 {
522 /* already started */
523 BNXE_LOCK_EXIT_GLD(pUM);
524 return EAGAIN;
525 }
526
527 /* Always report the initial link state as unknown. */
528 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
529
530 if (BnxeHwStartL2(pUM))
531 {
532 BNXE_LOCK_EXIT_GLD(pUM);
533 return EIO;
534 }
535
536 atomic_swap_32(&pUM->plumbed, B_TRUE);
537
538 mutex_enter(&bnxeLoaderMutex);
539 bnxeNumPlumbed++;
540 mutex_exit(&bnxeLoaderMutex);
541
542 BNXE_LOCK_EXIT_GLD(pUM);
543
544 return 0;
545}
546
547
548/*
549 * This routine stops packet reception by clearing RX MASK register. Also
550 * interrupts are disabled for this device.
551 */
552static void BnxeMacStop(void * pArg)
553{
554 um_device_t * pUM = (um_device_t *)pArg;
555
556 BNXE_LOCK_ENTER_GLD(pUM);
557
558 if (pUM->plumbed)
559 {
560 atomic_swap_32(&pUM->plumbed, B_FALSE);
561
562 BnxeHwStopL2(pUM);
563
564 /* Report the link state back to unknown. */
565 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
566
567 mutex_enter(&bnxeLoaderMutex);
568 bnxeNumPlumbed--;
569 mutex_exit(&bnxeLoaderMutex);
570 }
571
572 BNXE_LOCK_EXIT_GLD(pUM);
573}
574
575/* (flag) TRUE = on, FALSE = off */
576static int BnxeMacPromiscuous(void * pArg,
577 boolean_t flag)
578{
579 um_device_t * pUM = (um_device_t *)pArg;
580
581 BNXE_LOCK_ENTER_GLD(pUM);
582
583 if (!pUM->plumbed)
584 {
585 BNXE_LOCK_EXIT_GLD(pUM);
586 return EAGAIN;
587 }
588
589 if (flag)
590 {
591 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] |=
592 LM_RX_MASK_PROMISCUOUS_MODE;
593 }
594 else
595 {
596 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] &=
597 ~LM_RX_MASK_PROMISCUOUS_MODE;
598 }
599
600 BNXE_LOCK_ENTER_HWINIT(pUM);
601
602 if (BnxeRxMask(pUM, LM_CLI_IDX_NDIS,
603 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS]) < 0)
604 {
605 BNXE_LOCK_EXIT_HWINIT(pUM);
606 BNXE_LOCK_EXIT_GLD(pUM);
607 return ECANCELED;
608 }
609
610 BNXE_LOCK_EXIT_HWINIT(pUM);
611
612 BNXE_LOCK_EXIT_GLD(pUM);
613
614 return 0;
615}
616
617
618/*
619 * This function is used to enable or disable multicast packet reception for
620 * particular multicast addresses.
621 * (flag) TRUE = add, FALSE = remove
622 */
623static int BnxeMacMulticast(void * pArg,
624 boolean_t flag,
625 const uint8_t * pMcastAddr)
626{
627 um_device_t * pUM = (um_device_t *)pArg;
628 int rc;
629
630 BNXE_LOCK_ENTER_GLD(pUM);
631
632 if (!pUM->plumbed)
633 {
634 BNXE_LOCK_EXIT_GLD(pUM);
635 return EAGAIN;
636 }
637
638 BNXE_LOCK_ENTER_HWINIT(pUM);
639 rc = BnxeMulticast(pUM, LM_CLI_IDX_NDIS, flag, pMcastAddr, B_TRUE);
640 BNXE_LOCK_EXIT_HWINIT(pUM);
641
642 BNXE_LOCK_EXIT_GLD(pUM);
643
644 return rc;
645}
646
647
648#ifdef BNXE_RINGS
649
650#if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
651static int BnxeRxRingGroupAddMac(void * groupHandle,
652 const uint8_t * pMacAddr,
653 uint64_t flags)
654#else
655static int BnxeRxRingGroupAddMac(void * groupHandle,
656 const uint8_t * pMacAddr)
657#endif
658{
659 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle;
660 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM;
661 //u32_t idx = pRxQGroup->idx;
662 int rc;
663
664#if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
665 _NOTE(ARGUNUSED(flags))
666#endif
667
668 BNXE_LOCK_ENTER_GLD(pUM);
669
670 if (!pUM->plumbed)
671 {
672 BNXE_LOCK_EXIT_GLD(pUM);
673 return ECANCELED;
674 }
675
676 /* Validate MAC address */
677 if (IS_ETH_MULTICAST(pMacAddr))
678 {
679 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address.");
680 BNXE_LOCK_EXIT_GLD(pUM);
681 return EINVAL;
682 }
683
684 if (pUM->ucastTableLen == LM_MAX_UC_TABLE_SIZE)
685 {
686 BNXE_LOCK_EXIT_GLD(pUM);
687 return ENOMEM;
688 }
689
690 BNXE_LOCK_ENTER_HWINIT(pUM);
691
692 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr);
693
694 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE,
695 pUM->lm_dev.params.mac_addr);
696
697 BNXE_LOCK_EXIT_HWINIT(pUM);
698
699 if (rc < 0)
700 {
701 BNXE_LOCK_EXIT_GLD(pUM);
702 return ECANCELED;
703 }
704
705 pUM->ucastTableLen++;
706
707 BNXE_LOCK_EXIT_GLD(pUM);
708 return 0;
709}
710
711
712static int BnxeRxRingGroupRemMac(void * groupHandle,
713 const uint8_t * pMacAddr)
714{
715 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle;
716 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM;
717 //u32_t idx = pRxQGroup->idx;
718 int rc;
719
720 BNXE_LOCK_ENTER_GLD(pUM);
721
722 if (!pUM->plumbed)
723 {
724 BNXE_LOCK_EXIT_GLD(pUM);
725 return ECANCELED;
726 }
727
728 if (pUM->ucastTableLen == 0)
729 {
730 BNXE_LOCK_EXIT_GLD(pUM);
731 return EINVAL;
732 }
733
734 BNXE_LOCK_ENTER_HWINIT(pUM);
735
736 if (!IS_ETH_ADDRESS_EQUAL(pMacAddr, pUM->lm_dev.params.mac_addr))
737 {
738 BnxeLogWarn(pUM, "Deleting MAC address that doesn't match default");
739 /* XXX */
740 }
741
742 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_FALSE,
743 pUM->lm_dev.params.mac_addr);
744
745 memset(pUM->lm_dev.params.mac_addr, 0, sizeof(pUM->lm_dev.params.mac_addr));
746
747 BNXE_LOCK_EXIT_HWINIT(pUM);
748
749 if (rc < 0)
750 {
751 BNXE_LOCK_EXIT_GLD(pUM);
752 return ECANCELED;
753 }
754
755 pUM->ucastTableLen--;
756
757 BNXE_LOCK_EXIT_GLD(pUM);
758 return 0;
759}
760
761
762static mblk_t * BnxeTxRingSend(void * ringHandle,
763 mblk_t * pMblk)
764{
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;
770
771 while (pMblk)
772 {
773 pNextMblk = pMblk->b_next;
774 pMblk->b_next = NULL;
775
776 rc = BnxeTxSendMblk(pUM, idx, pMblk, 0, 0);
777
778 if (rc == BNXE_TX_GOODXMIT)
779 {
780 pMblk = pNextMblk;
781 continue;
782 }
783 else if (rc == BNXE_TX_DEFERPKT)
784 {
785 pMblk = pNextMblk;
786 }
787 else
788 {
789 pMblk->b_next = pNextMblk;
790 }
791
792 break;
793 }
794
795 return pMblk;
796}
797
798#endif /* BNXE_RINGS */
799
800
801static int BnxeMacUnicast(void * pArg,
802 const uint8_t * pMacAddr)
803{
804 um_device_t * pUM = (um_device_t *)pArg;
805 int rc;
806
807 BNXE_LOCK_ENTER_GLD(pUM);
808
809 if (!pUM->plumbed)
810 {
811 memcpy(pUM->gldMac, pMacAddr, ETHERNET_ADDRESS_SIZE);
812 BNXE_LOCK_EXIT_GLD(pUM);
813 return 0;
814 }
815
816 /* Validate MAC address */
817 if (IS_ETH_MULTICAST(pMacAddr))
818 {
819 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address.");
820 BNXE_LOCK_EXIT_GLD(pUM);
821 return EINVAL;
822 }
823
824 BNXE_LOCK_ENTER_HWINIT(pUM);
825
826 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr);
827
828 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE,
829 pUM->lm_dev.params.mac_addr);
830
831 BNXE_LOCK_EXIT_HWINIT(pUM);
832
833 if (rc < 0)
834 {
835 BNXE_LOCK_EXIT_GLD(pUM);
836 return EAGAIN;
837 }
838
839 BNXE_LOCK_EXIT_GLD(pUM);
840 return 0;
841}
842
843
844static mblk_t * BnxeMacTx(void * pArg,
845 mblk_t * pMblk)
846{
847 um_device_t * pUM = (um_device_t *)pArg;
848 mblk_t * pNextMblk;
849 int ring, rc;
850
851 BNXE_LOCK_ENTER_GLDTX(pUM, RW_READER);
852
853 if (!pUM->plumbed)
854 {
855 freemsgchain(pMblk);
856 BNXE_LOCK_EXIT_GLDTX(pUM);
857
858 return NULL;
859 }
860
861 while (pMblk)
862 {
863 ring = BnxeRouteTxRing(pUM, pMblk);
864
865 pNextMblk = pMblk->b_next;
866 pMblk->b_next = NULL;
867
868 //rc = BnxeTxSendMblk(pUM, NDIS_CID(&pUM->lm_dev), pMblk, 0, 0);
869 rc = BnxeTxSendMblk(pUM, ring, pMblk, 0, 0);
870
871 if (rc == BNXE_TX_GOODXMIT)
872 {
873 pMblk = pNextMblk;
874 continue;
875 }
876 else if (rc == BNXE_TX_DEFERPKT)
877 {
878 pMblk = pNextMblk;
879 }
880 else
881 {
882 pMblk->b_next = pNextMblk;
883 }
884
885 break;
886 }
887
888 BNXE_LOCK_EXIT_GLDTX(pUM);
889
890 return pMblk;
891}
892
893
894#ifdef MC_RESOURCES
895
896static void BnxeBlank(void * pArg,
897 time_t tick_cnt,
898 uint_t pkt_cnt)
899{
900 um_device_t * pUM = (um_device_t *)pArg;
901
902 if (!pUM->plumbed)
903 {
904 return;
905 }
906
907 /* XXX
908 * Need to dynamically reconfigure the hw with new interrupt
909 * coalescing params...
910 */
911}
912
913
914static void BnxeMacResources(void * pArg)
915{
916 um_device_t * pUM = (um_device_t *)pArg;
917 mac_rx_fifo_t mrf;
918 int idx;
919
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;
925
926 LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
927 {
928 pUM->macRxResourceHandles[idx] =
929 mac_resource_add(pUM->pMac, (mac_resource_t *)&mrf);
930 }
931}
932
933#endif /* MC_RESOURCES */
934
935
936static boolean_t BnxeReadReg(um_device_t * pUM,
937 struct bnxe_reg_data * pData)
938{
939 if (pData->offset & 0x3)
940 {
941 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXEREG ioctl");
942 return B_FALSE;
943 }
944
945 LM_BAR_RD32_OFFSET(&pUM->lm_dev, 0, pData->offset, &pData->value);
946
947 return B_TRUE;
948}
949
950
951static boolean_t BnxeWriteReg(um_device_t * pUM,
952 struct bnxe_reg_data * pData)
953{
954 if (pData->offset & 0x3)
955 {
956 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXEREG ioctl");
957 return B_FALSE;
958 }
959
960 LM_BAR_WR32_OFFSET(&pUM->lm_dev, 0, pData->offset, pData->value);
961
962 return B_TRUE;
963}
964
965
966static boolean_t BnxeReadNvm(um_device_t * pUM,
967 struct bnxe_nvram_data * pData)
968{
969 if (pData->offset & 0x3)
970 {
971 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXENVRM ioctl");
972 return B_FALSE;
973 }
974
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)
980 {
981 return B_FALSE;
982 }
983
984 return B_TRUE;
985}
986
987
988static boolean_t BnxeWriteNvm(um_device_t * pUM,
989 struct bnxe_nvram_data * pData)
990{
991 if (pData->offset & 0x3)
992 {
993 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXENVRM ioctl");
994 return B_FALSE;
995 }
996
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)
1002 {
1003 return B_FALSE;
1004 }
1005
1006 return B_TRUE;
1007}
1008
1009
1010static boolean_t BnxeReadPciCfg(um_device_t * pUM,
1011 struct bnxe_reg_data * pData)
1012{
1013 pData->value = pci_config_get32(pUM->pPciCfg, (off_t)pData->offset);
1014 return B_TRUE;
1015}
1016
1017typedef 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;
1023
1024typedef union _b10_stats_show_data_t
1025{
1026 u32_t op; /* ioctl sub-commond */
1027
1028 struct
1029 {
1030 u32_t num; /* return number of stats */
1031 u32_t len; /* length of each string item */
1032 } desc;
1033
1034 /* variable length... */
1035 char str[1]; /* holds names of desc.num stats, each desc.len in length */
1036
1037 struct
1038 {
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;
1045
1046
1047static boolean_t BnxeStatsShow(um_device_t * pUM,
1048 b10_stats_show_data_t * pStats,
1049 u32_t statsLen)
1050{
1051 stats_show_type_t op;
1052 const size_t stats_size = sizeof(pStats->cnt);
1053
1054 /*
1055 * All stats names MUST conform to STATS_STR_LEN length!!!
1056 */
1057
1058 #define STATS_STR_LEN 39
1059
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.
1065 */
1066
1067 const char p_stat_str[] =
1068
1069 // b10_l2_chip_statistics_t
1070
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 "
1127
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 "
1141
1142 "Tx_Lpi_Count\0 " // This counter counts the number of timers the debounced version of EEE link idle is asserted
1143
1144 // b10_l4_chip_statistics_t
1145
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 "
1170
1171 // b10_l2_driver_statistics_t
1172
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 "
1183
1184 // b10_l4_driver_statistics_t
1185
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 "
1202
1203 ;
1204
1205 ASSERT_STATIC((sizeof(p_stat_str) / STATS_STR_LEN) ==
1206 (stats_size / sizeof(u64_t)));
1207
1208 op = *((stats_show_type_t *)pStats);
1209
1210 switch (op)
1211 {
1212 case STATS_SHOW_TYPE_NUM:
1213
1214 if (statsLen < sizeof(pStats->desc))
1215 {
1216 return B_FALSE;
1217 }
1218
1219 pStats->desc.num = (stats_size / sizeof(u64_t));
1220 pStats->desc.len = STATS_STR_LEN;
1221
1222 return B_TRUE;
1223
1224 case STATS_SHOW_TYPE_STR:
1225
1226 if (statsLen != sizeof(p_stat_str))
1227 {
1228 return B_FALSE;
1229 }
1230
1231 memcpy(pStats->str, p_stat_str, sizeof(p_stat_str));
1232
1233 return B_TRUE;
1234
1235 case STATS_SHOW_TYPE_CNT:
1236
1237 if (statsLen != stats_size)
1238 {
1239 return B_FALSE;
1240 }
1241
1242 lm_stats_get_l2_chip_stats(&pUM->lm_dev,
1243 &pStats->cnt.l2_chip_stats,
1244 L2_CHIP_STATISTICS_VER_NUM_2);
1245
1246 lm_stats_get_l4_chip_stats(&pUM->lm_dev,
1247 &pStats->cnt.l4_chip_stats);
1248
1249 lm_stats_get_l2_driver_stats(&pUM->lm_dev
1250 ,&pStats->cnt.l2_drv_stats);
1251
1252 lm_stats_get_l4_driver_stats(&pUM->lm_dev,
1253 &pStats->cnt.l4_drv_stats);
1254
1255 return B_TRUE;
1256
1257 default:
1258
1259 return B_FALSE;
1260 }
1261}
1262
1263static void BnxeMacIoctl(void * pArg,
1264 queue_t * pQ,
1265 mblk_t * pMblk)
1266{
1267 um_device_t * pUM = (um_device_t *)pArg;
1268 struct iocblk * pIoctl;
1269 int rc;
1270
1271 if ((pQ == NULL) || (pMblk == NULL))
1272 {
1273 return;
1274 }
1275
1276 if (pMblk->b_datap->db_type != M_IOCTL)
1277 {
1278 miocnak(pQ, pMblk, 0, EINVAL);
1279 return;
1280 }
1281
1282 pIoctl = (struct iocblk *)pMblk->b_rptr;
1283
1284 BNXE_LOCK_ENTER_GLD(pUM);
1285
1286 switch (pIoctl->ioc_cmd)
1287 {
1288 case GIOCBNXELLDP:
1289
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))
1293 {
1294 miocnak(pQ, pMblk, 0, EINVAL);
1295 break;
1296 }
1297
1298 if (((b10_lldp_params_get_t *)pMblk->b_cont->b_rptr)->ver_num !=
1299 LLDP_PARAMS_VER_NUM)
1300 {
1301 miocnak(pQ, pMblk, 0, EINVAL);
1302 break;
1303 }
1304
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)
1308 {
1309 miocnak(pQ, pMblk, 0,
1310 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL);
1311 break;
1312 }
1313
1314 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1315 break;
1316
1317 case GIOCBNXEDCBX:
1318
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))
1322 {
1323 miocnak(pQ, pMblk, 0, EINVAL);
1324 break;
1325 }
1326
1327 if (((b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr)->ver_num !=
1328 DCBX_PARAMS_VER_NUM)
1329 {
1330 miocnak(pQ, pMblk, 0, EINVAL);
1331 break;
1332 }
1333
1334 if (lm_dcbx_read_params(&pUM->lm_dev,
1335 (b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr) !=
1336 LM_STATUS_SUCCESS)
1337 {
1338 miocnak(pQ, pMblk, 0,
1339 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL);
1340 break;
1341 }
1342
1343 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1344 break;
1345
1346 case SIOCBNXEDCBX:
1347
1348 /* XXX */
1349 miocnak(pQ, pMblk, 0, EINVAL);
1350 break;
1351
1352 case GIOCBNXEREG:
1353
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))
1357 {
1358 miocnak(pQ, pMblk, 0, EINVAL);
1359 break;
1360 }
1361
1362 if (!BnxeReadReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1363 {
1364 miocnak(pQ, pMblk, 0, EINVAL);
1365 }
1366 else
1367 {
1368 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1369 }
1370
1371 break;
1372
1373 case SIOCBNXEREG:
1374
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))
1378 {
1379 miocnak(pQ, pMblk, 0, EINVAL);
1380 break;
1381 }
1382
1383 if (!BnxeWriteReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1384 {
1385 miocnak(pQ, pMblk, 0, EINVAL);
1386 }
1387 else
1388 {
1389 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1390 }
1391
1392 break;
1393
1394 case GIOCBNXENVRM:
1395
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))
1399 {
1400 miocnak(pQ, pMblk, 0, EINVAL);
1401 break;
1402 }
1403
1404 if (!BnxeReadNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr))
1405 {
1406 miocnak(pQ, pMblk, 0, EINVAL);
1407 }
1408 else
1409 {
1410 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1411 }
1412
1413 break;
1414
1415 case SIOCBNXENVRM:
1416
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))
1420 {
1421 miocnak(pQ, pMblk, 0, EINVAL);
1422 break;
1423 }
1424
1425 if (!BnxeWriteNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr))
1426 {
1427 miocnak(pQ, pMblk, 0, EINVAL);
1428 }
1429 else
1430 {
1431 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1432 }
1433
1434 break;
1435
1436 case GIOCBNXEPCI:
1437
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))
1441 {
1442 miocnak(pQ, pMblk, 0, EINVAL);
1443 break;
1444 }
1445
1446 if (!BnxeReadPciCfg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1447 {
1448 miocnak(pQ, pMblk, 0, EINVAL);
1449 }
1450 else
1451 {
1452 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1453 }
1454
1455 break;
1456
1457 case GIOCBNXESTATS:
1458
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))
1463 {
1464 miocnak(pQ, pMblk, 0, EINVAL);
1465 break;
1466 }
1467
1468 if (!BnxeStatsShow(pUM,
1469 (b10_stats_show_data_t *)pMblk->b_cont->b_rptr,
1470 pIoctl->ioc_count))
1471 {
1472 miocnak(pQ, pMblk, 0, EINVAL);
1473 }
1474 else
1475 {
1476 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1477 }
1478
1479 break;
1480
1481 default:
1482
1483 miocnak(pQ, pMblk, 0, EINVAL);
1484 break;
1485 }
1486
1487 BNXE_LOCK_EXIT_GLD(pUM);
1488}
1489
1490
1491#ifdef BNXE_RINGS
1492
1493#if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1494static mblk_t * BnxeRxRingPoll(void * ringHandle,
1495 int numBytes,
1496 int numPkts)
1497#else
1498static mblk_t * BnxeRxRingPoll(void * ringHandle,
1499 int numBytes)
1500#endif
1501{
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;
1508
1509#if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1510 _NOTE(ARGUNUSED(numPkts))
1511#endif
1512
1513 if (numBytes <= 0)
1514 {
1515 return NULL;
1516 }
1517
1518 if (pRxQ->inPollMode == B_FALSE)
1519 {
1520 BnxeLogWarn(pUM, "Polling on ring %d when NOT in poll mode!", idx);
1521 return NULL;
1522 }
1523
1524 BNXE_LOCK_ENTER_INTR(pUM, idx);
1525
1526 pRxQ->pollCnt++;
1527
1528 BnxePollRxRing(pUM, idx, &pktsRxed, &pktsTxed);
1529
1530 if (pktsTxed) BnxeTxRingProcess(pUM, idx);
1531 if (pktsRxed) pMblk = BnxeRxRingProcess(pUM, idx, TRUE, numBytes);
1532
1533 /*
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.
1537 */
1538 lm_sq_post_pending(&pUM->lm_dev);
1539
1540 BNXE_LOCK_EXIT_INTR(pUM, idx);
1541
1542 return pMblk;
1543}
1544
1545
1546static int BnxeRxRingStart(mac_ring_driver_t ringHandle
1547#if defined(__S11) || defined(__S12)
1548 , uint64_t genNumber
1549#endif
1550 )
1551{
1552 RxQueue * pRxQ = (RxQueue *)ringHandle;
1553 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1554 u32_t idx = pRxQ->idx;
1555
1556 BnxeLogDbg(pUM, "Starting Rx Ring %d", idx);
1557
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);
1567
1568 return 0;
1569}
1570
1571
1572#if defined(__S11) || defined(__S12)
1573
1574static int BnxeRingStat(mac_ring_driver_t ringHandle,
1575 uint_t stat,
1576 uint64_t * val)
1577{
1578 RxQueue * pRxQ = (RxQueue *)ringHandle;
1579 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1580
1581 switch (stat)
1582 {
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;
1591 }
1592
1593 return 0;
1594}
1595
1596#endif /* __S11 or __S12 */
1597
1598
1599#if defined(__S11) || defined(__S12)
1600static int BnxeRxRingIntrEnable(mac_ring_driver_t ringHandle)
1601#else
1602static int BnxeRxRingIntrEnable(mac_intr_handle_t ringHandle)
1603#endif
1604{
1605 RxQueue * pRxQ = (RxQueue *)ringHandle;
1606 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1607
1608 BnxeLogDbg(pUM, "Enabling Interrupt for Rx Ring %d", pRxQ->idx);
1609
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)))
1614 {
1615 return 0; /* ok, already enabled */
1616 }
1617
1618 BnxeIntrIguSbEnable(pUM, pRxQ->idx, B_FALSE);
1619
1620 return 0;
1621}
1622
1623
1624#if defined(__S11) || defined(__S12)
1625static int BnxeRxRingIntrDisable(mac_ring_driver_t ringHandle)
1626#else
1627static int BnxeRxRingIntrDisable(mac_intr_handle_t ringHandle)
1628#endif
1629{
1630 RxQueue * pRxQ = (RxQueue *)ringHandle;
1631 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1632
1633 BnxeLogDbg(pUM, "Disabling Interrupt for Rx Ring %d", pRxQ->idx);
1634
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)))
1639 {
1640 return -1; /* NO, keep enabled! */
1641 }
1642
1643 BnxeIntrIguSbDisable(pUM, pRxQ->idx, B_FALSE);
1644
1645 return 0;
1646}
1647
1648
1649/* callback function for MAC layer to register rings */
1650static 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)
1656{
1657 um_device_t * pUM = (um_device_t *)arg;
1658 RxQueue * pRxQ;
1659 TxQueue * pTxQ;
1660
1661 switch (ringType)
1662 {
1663 case MAC_RING_TYPE_RX:
1664
1665 BnxeLogInfo(pUM, "Initializing Rx Ring %d (Ring Group %d)",
1666 ringIndex, ringGroupIndex);
1667
1668 ASSERT(ringGroupIndex == 0);
1669 ASSERT(ringIndex < pUM->devParams.numRings);
1670
1671 pRxQ = &pUM->rxq[ringIndex];
1672 pRxQ->ringHandle = ringHandle;
1673
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;
1681
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;
1687
1688 break;
1689
1690 case MAC_RING_TYPE_TX:
1691
1692 BnxeLogInfo(pUM, "Initializing Tx Ring %d (Ring Group %d)",
1693 ringIndex, ringGroupIndex);
1694
1695 ASSERT(ringGroupIndex == 0);
1696 ASSERT(ringIndex < pUM->devParams.numRings);
1697
1698 pTxQ = &pUM->txq[ringIndex];
1699 pTxQ->ringHandle = ringHandle;
1700
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;
1708
1709 break;
1710
1711 default:
1712 break;
1713 }
1714}
1715
1716
1717/* callback function for MAC layer to register groups */
1718static 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)
1723{
1724 um_device_t * pUM = (um_device_t *)arg;
1725 RxQueueGroup * pRxQGroup;
1726
1727 switch (ringType)
1728 {
1729 case MAC_RING_TYPE_RX:
1730
1731 BnxeLogInfo(pUM, "Initializing Rx Group %d", ringGroupIndex);
1732
1733 pRxQGroup = &pUM->rxqGroup[ringGroupIndex];
1734 pRxQGroup->groupHandle = groupHandle;
1735
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
1746
1747 break;
1748
1749 case MAC_RING_TYPE_TX:
1750 default:
1751 break;
1752 }
1753}
1754
1755#endif /* BNXE_RINGS */
1756
1757
1758static boolean_t BnxeMacGetCapability(void * pArg,
1759 mac_capab_t capability,
1760 void * pCapabilityData)
1761{
1762 um_device_t * pUM = (um_device_t *)pArg;
1763 mac_capab_lso_t * pCapLSO;
1764 mac_capab_rings_t * pCapRings;
1765
1766 switch (capability)
1767 {
1768 case MAC_CAPAB_HCKSUM:
1769
1770 *((u32_t *)pCapabilityData) = 0;
1771
1772 if (pUM->devParams.enabled_oflds &
1773 (LM_OFFLOAD_TX_IP_CKSUM | LM_OFFLOAD_RX_IP_CKSUM))
1774 {
1775 *((u32_t *)pCapabilityData) |= HCKSUM_IPHDRCKSUM;
1776 }
1777
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))
1781 {
1782 *((u32_t *)pCapabilityData) |= HCKSUM_INET_PARTIAL;
1783 }
1784
1785 break;
1786
1787 case MAC_CAPAB_LSO:
1788
1789 pCapLSO = (mac_capab_lso_t *)pCapabilityData;
1790
1791 if (pUM->devParams.lsoEnable)
1792 {
1793 pCapLSO->lso_flags = LSO_TX_BASIC_TCP_IPV4;
1794 pCapLSO->lso_basic_tcp_ipv4.lso_max = BNXE_LSO_MAXLEN;
1795 break;
1796 }
1797
1798 return B_FALSE;
1799
1800#ifdef BNXE_RINGS
1801
1802 case MAC_CAPAB_RINGS:
1803
1804 if (!pUM->devParams.numRings)
1805 {
1806 return B_FALSE;
1807 }
1808
1809 pCapRings = (mac_capab_rings_t *)pCapabilityData;
1810
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
1823
1824 switch (pCapRings->mr_type)
1825 {
1826 case MAC_RING_TYPE_RX:
1827
1828 pCapRings->mr_gnum = USER_OPTION_RX_RING_GROUPS_DEFAULT;
1829 pCapRings->mr_gget = BnxeFillGroup;
1830 break;
1831
1832 case MAC_RING_TYPE_TX:
1833
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;
1841
1842 default:
1843
1844 return B_FALSE;
1845 }
1846
1847 break;
1848
1849#endif /* BNXE_RINGS */
1850
1851#if !(defined(__S11) || defined(__S12))
1852
1853 case MAC_CAPAB_POLL:
1854
1855 /*
1856 * There's nothing for us to fill in, simply returning B_TRUE stating
1857 * that we support polling is sufficient.
1858 */
1859 break;
1860
1861#endif /* not __S11 or __S12 */
1862
Robert Mustacchi947eaaf2017-06-16 22:58:47 +00001863#if defined(ILLUMOS)
1864 case MAC_CAPAB_TRANSCEIVER:
1865 return bnxe_fill_transceiver(pUM, pCapabilityData);
1866#endif
1867
Robert Mustacchid14abf12014-06-06 22:58:53 +00001868 default:
1869
1870 return B_FALSE;
1871 }
1872
1873 return B_TRUE;
1874}
1875
1876
1877#ifdef MC_SETPROP
1878
1879static int BnxeSetPrivateProperty(um_device_t * pUM,
1880 const char * pr_name,
1881 uint_t pr_valsize,
1882 const void * pr_val)
1883{
1884 int err = 0;
1885 long result;
1886
1887 if (strcmp(pr_name, "_en_2500fdx_cap") == 0)
1888 {
1889 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1890 {
1891 return EINVAL;
1892 }
1893
1894 if ((result > 1) || (result < 0))
1895 {
1896 return EINVAL;
1897 }
1898
1899 pUM->hwinit.lnkcfg.param_2500fdx = (uint32_t)result;
1900 pUM->curcfg.lnkcfg.param_2500fdx = (uint32_t)result;
1901 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1902 }
1903 else if (strcmp(pr_name, "_en_txpause_cap") == 0)
1904 {
1905 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1906 {
1907 return EINVAL;
1908 }
1909
1910 if ((result > 1) || (result < 0))
1911 {
1912 return EINVAL;
1913 }
1914
1915 pUM->hwinit.lnkcfg.param_txpause = (uint32_t)result;
1916 pUM->curcfg.lnkcfg.param_txpause = (uint32_t)result;
1917 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1918 }
1919 else if (strcmp(pr_name, "_en_rxpause_cap") == 0)
1920 {
1921 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1922 {
1923 return EINVAL;
1924 }
1925
1926 if ((result > 1) || (result < 0))
1927 {
1928 return EINVAL;
1929 }
1930
1931 pUM->hwinit.lnkcfg.param_rxpause = (uint32_t)result;
1932 pUM->curcfg.lnkcfg.param_rxpause = (uint32_t)result;
1933 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1934 }
1935 else if (strcmp(pr_name, "_autoneg_flow") == 0)
1936 {
1937 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1938 {
1939 return EINVAL;
1940 }
1941
1942 if ((result > 1) || (result < 0))
1943 {
1944 return EINVAL;
1945 }
1946
1947 pUM->hwinit.flow_autoneg = (uint32_t)result;
1948 pUM->curcfg.flow_autoneg = (uint32_t)result;
1949 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1950 }
1951 else if (strcmp(pr_name, "_checksum") == 0)
1952 {
1953 if (pUM->plumbed)
1954 {
1955 return EBUSY;
1956 }
1957
1958 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1959 {
1960 return EINVAL;
1961 }
1962
1963 switch (result)
1964 {
1965 case USER_OPTION_CKSUM_NONE:
1966
1967 pUM->devParams.enabled_oflds = LM_OFFLOAD_NONE;
1968 break;
1969
1970 case USER_OPTION_CKSUM_L3:
1971
1972 pUM->devParams.enabled_oflds = (LM_OFFLOAD_TX_IP_CKSUM |
1973 LM_OFFLOAD_RX_IP_CKSUM);
1974 break;
1975
1976 case USER_OPTION_CKSUM_L3_L4:
1977
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;
1985
1986 default:
1987
1988 return EINVAL;
1989 }
1990
1991 pUM->devParams.checksum = (uint32_t)result;
1992 }
1993 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
1994 {
1995 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1996 {
1997 return EINVAL;
1998 }
1999
2000 switch (result)
2001 {
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:
2006
2007 break;
2008
2009 default:
2010
2011 return EINVAL;
2012 }
2013
2014 pUM->devParams.routeTxRingPolicy = (uint32_t)result;
2015 }
2016 else if (strcmp(pr_name, "_num_rings") == 0)
2017 {
2018 if (pUM->plumbed)
2019 {
2020 return EBUSY;
2021 }
2022
2023 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2024 {
2025 return EINVAL;
2026 }
2027
2028 if ((result < USER_OPTION_NUM_RINGS_MIN) ||
2029 (result > USER_OPTION_NUM_RINGS_MAX))
2030 {
2031 return EINVAL;
2032 }
2033
2034 pUM->devParams.numRings = (uint32_t)result;
2035 }
2036 else if (strcmp(pr_name, "_rx_descs") == 0)
2037 {
2038 if (pUM->plumbed)
2039 {
2040 return EBUSY;
2041 }
2042
2043 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2044 {
2045 return EINVAL;
2046 }
2047
2048 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2049 {
2050 return EINVAL;
2051 }
2052
2053 pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result;
2054 }
2055 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2056 {
2057 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2058 {
2059 return EINVAL;
2060 }
2061
2062 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2063 {
2064 return EINVAL;
2065 }
2066
2067 pUM->devParams.maxRxFree = (uint32_t)result;
2068 }
2069 else if (strcmp(pr_name, "_tx_descs") == 0)
2070 {
2071 if (pUM->plumbed)
2072 {
2073 return EBUSY;
2074 }
2075
2076 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2077 {
2078 return EINVAL;
2079 }
2080
2081 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2082 {
2083 return EINVAL;
2084 }
2085
2086 pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result;
2087 }
2088 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2089 {
2090 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2091 {
2092 return EINVAL;
2093 }
2094
2095 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2096 {
2097 return EINVAL;
2098 }
2099
2100 pUM->devParams.maxTxFree = (uint32_t)result;
2101 }
2102 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2103 {
2104 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2105 {
2106 return EINVAL;
2107 }
2108
2109 pUM->devParams.rxCopyThreshold = (uint32_t)result;
2110 }
2111 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2112 {
2113 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2114 {
2115 return EINVAL;
2116 }
2117
2118 pUM->devParams.txCopyThreshold = (uint32_t)result;
2119 }
2120 else if (strcmp(pr_name, "_interrupt_coalesce") == 0)
2121 {
2122 if (pUM->plumbed)
2123 {
2124 return EBUSY;
2125 }
2126
2127 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2128 {
2129 return EINVAL;
2130 }
2131
2132 if ((result > 1) || (result < 0))
2133 {
2134 return EINVAL;
2135 }
2136
2137 pUM->devParams.intrCoalesce = (uint32_t)result;
2138 }
2139 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0)
2140 {
2141 if (pUM->plumbed)
2142 {
2143 return EBUSY;
2144 }
2145
2146 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2147 {
2148 return EINVAL;
2149 }
2150
2151 if ((result < USER_OPTION_INTR_COALESCE_MIN) ||
2152 (result < USER_OPTION_INTR_COALESCE_MAX))
2153 {
2154 return EINVAL;
2155 }
2156
2157 pUM->devParams.intrRxPerSec = (uint32_t)(1000000 / result);
2158 }
2159 else if (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0)
2160 {
2161 if (pUM->plumbed)
2162 {
2163 return EBUSY;
2164 }
2165
2166 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2167 {
2168 return EINVAL;
2169 }
2170
2171 if ((result < USER_OPTION_INTR_COALESCE_MIN) ||
2172 (result < USER_OPTION_INTR_COALESCE_MAX))
2173 {
2174 return EINVAL;
2175 }
2176
2177 pUM->devParams.intrTxPerSec = (uint32_t)(1000000 / result);
2178 }
2179 else if (strcmp(pr_name, "_disable_msix") == 0)
2180 {
2181 if (pUM->plumbed)
2182 {
2183 return EBUSY;
2184 }
2185
2186 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2187 {
2188 return EINVAL;
2189 }
2190
2191 if ((result > 1) || (result < 0))
2192 {
2193 return EINVAL;
2194 }
2195
2196 pUM->devParams.disableMsix = (uint32_t)result;
2197 }
2198 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0)
2199 {
2200 if (pUM->plumbed)
2201 {
2202 return EBUSY;
2203 }
2204
2205 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2206 {
2207 return EINVAL;
2208 }
2209
2210 if ((result > 1) || (result < 0))
2211 {
2212 return EINVAL;
2213 }
2214
2215 pUM->devParams.l2_fw_flow_ctrl = (uint32_t)result;
2216 }
2217 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2218 {
2219 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2220 {
2221 return EINVAL;
2222 }
2223
2224 if ((result > 1) || (result < 0))
2225 {
2226 return EINVAL;
2227 }
2228
2229 pUM->devParams.autogreeenEnable = (uint32_t)result;
2230 if (pUM->plumbed) BnxeUpdatePhy(pUM);
2231 }
2232 else if (strcmp(pr_name, "_lso_enable") == 0)
2233 {
2234 if (pUM->plumbed)
2235 {
2236 return EBUSY;
2237 }
2238
2239 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2240 {
2241 return EINVAL;
2242 }
2243
2244 if ((result > 1) || (result < 0))
2245 {
2246 return EINVAL;
2247 }
2248
2249 pUM->devParams.lsoEnable = (uint32_t)result;
2250 }
2251 else if (strcmp(pr_name, "_log_enable") == 0)
2252 {
2253 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2254 {
2255 return EINVAL;
2256 }
2257
2258 if ((result > 1) || (result < 0))
2259 {
2260 return EINVAL;
2261 }
2262
2263 pUM->devParams.logEnable = (uint32_t)result;
2264 }
2265 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2266 {
2267 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2268 {
2269 return EINVAL;
2270 }
2271
2272 if ((result > 1) || (result < 0))
2273 {
2274 return EINVAL;
2275 }
2276
2277 pUM->devParams.fcoeEnable = (uint32_t)result;
2278
2279 if (BNXE_FCOE(pUM))
2280 {
2281 BnxeFcoeStartStop(pUM);
2282 }
2283 }
2284 else
2285 {
2286 err = ENOTSUP;
2287 }
2288
2289 return err;
2290}
2291
2292
2293static 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)
2298{
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;
2306
2307 BNXE_LOCK_ENTER_GLD(pUM);
2308
2309 switch (pr_num)
2310 {
2311 /* read-only props */
2312 case MAC_PROP_STATUS:
2313 case MAC_PROP_SPEED:
2314 case MAC_PROP_DUPLEX:
2315
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:
2324
2325 case MAC_PROP_EN_1000HDX_CAP:
2326 case MAC_PROP_EN_100T4_CAP:
2327
2328 default:
2329
2330 err = ENOTSUP;
2331 break;
2332
2333 case MAC_PROP_EN_10GFDX_CAP:
2334
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;
2339
2340 case MAC_PROP_EN_1000FDX_CAP:
2341
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;
2346
2347 case MAC_PROP_EN_100FDX_CAP:
2348
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;
2353
2354 case MAC_PROP_EN_100HDX_CAP:
2355
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;
2360
2361 case MAC_PROP_EN_10FDX_CAP:
2362
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;
2367
2368 case MAC_PROP_EN_10HDX_CAP:
2369
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;
2374
2375 case MAC_PROP_AUTONEG:
2376
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;
2381
2382 case MAC_PROP_FLOWCTRL:
2383
2384 bcopy(pr_val, &fl, sizeof(fl));
2385
2386 switch (fl)
2387 {
2388 case LINK_FLOWCTRL_NONE:
2389
2390 rxpause = B_FALSE;
2391 txpause = B_FALSE;
2392 break;
2393
2394 case LINK_FLOWCTRL_RX:
2395
2396 rxpause = B_TRUE;
2397 txpause = B_FALSE;
2398 break;
2399
2400 case LINK_FLOWCTRL_TX:
2401
2402 rxpause = B_FALSE;
2403 txpause = B_TRUE;
2404 break;
2405
2406 case LINK_FLOWCTRL_BI:
2407
2408 rxpause = B_TRUE;
2409 txpause = B_TRUE;
2410 break;
2411
2412 default:
2413
2414 err = ENOTSUP;
2415 break;
2416 }
2417
2418 if (err == 0)
2419 {
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;
2425 }
2426
2427 break;
2428
2429 case MAC_PROP_MTU:
2430
2431 if (pUM->plumbed)
2432 {
2433 err = EBUSY;
2434 break;
2435 }
2436
2437 bcopy(pr_val, &mtu, sizeof (mtu));
2438
2439 if ((mtu < USER_OPTION_MTU_MIN) || (mtu > USER_OPTION_MTU_MAX))
2440 {
2441 err = EINVAL;
2442 break;
2443 }
2444
2445 if (pUM->devParams.mtu[LM_CLI_IDX_NDIS] == mtu)
2446 {
2447 break;
2448 }
2449
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;
2454
2455 case MAC_PROP_PRIVATE:
2456
2457 err = BnxeSetPrivateProperty(pUM, pr_name, pr_valsize, pr_val);
2458 break;
2459 }
2460
2461 if (!err && reprogram)
2462 {
2463 if (pUM->plumbed) BnxeUpdatePhy(pUM);
2464 }
2465
2466 BNXE_LOCK_EXIT_GLD(pUM);
2467 return err;
2468}
2469
2470#endif /* MC_SETPROP */
2471
2472
2473#ifdef MC_GETPROP
2474
2475static int BnxeGetPrivateProperty(um_device_t * pUM,
2476 const char * pr_name,
2477 uint_t pr_valsize,
2478 void * pr_val)
2479{
2480 BnxeLinkCfg * lnk_cfg = &pUM->curcfg.lnkcfg;
2481 BnxeLinkCfg * hw_cfg = &pUM->hwinit.lnkcfg;
2482 int value;
2483 int err = 0;
2484
2485 if (strcmp(pr_name, "_adv_2500fdx_cap") == 0)
2486 {
2487 value = lnk_cfg->param_2500fdx;
2488 }
2489 else if (strcmp(pr_name, "_en_2500fdx_cap") == 0)
2490 {
2491 value = hw_cfg->param_2500fdx;
2492 }
2493 else if (strcmp(pr_name, "_adv_txpause_cap") == 0)
2494 {
2495 value = lnk_cfg->param_txpause;
2496 }
2497 else if (strcmp(pr_name, "_en_txpause_cap") == 0)
2498 {
2499 value = hw_cfg->param_txpause;
2500 }
2501 else if (strcmp(pr_name, "_txpause") == 0)
2502 {
2503 value = pUM->props.link_txpause;
2504 }
2505 else if (strcmp(pr_name, "_adv_rxpause_cap") == 0)
2506 {
2507 value = lnk_cfg->param_rxpause;
2508 }
2509 else if (strcmp(pr_name, "_en_rxpause_cap") == 0)
2510 {
2511 value = hw_cfg->param_rxpause;
2512 }
2513 else if (strcmp(pr_name, "_rxpause") == 0)
2514 {
2515 value = pUM->props.link_rxpause;
2516 }
2517 else if (strcmp(pr_name, "_autoneg_flow") == 0)
2518 {
2519 value = pUM->hwinit.flow_autoneg;
2520 }
2521 else if (strcmp(pr_name, "_checksum") == 0)
2522 {
2523 value = pUM->devParams.checksum;
2524 }
2525 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
2526 {
2527 value = pUM->devParams.routeTxRingPolicy;
2528 }
2529 else if (strcmp(pr_name, "_num_rings") == 0)
2530 {
2531 value = pUM->devParams.numRings;
2532 }
2533 else if (strcmp(pr_name, "_rx_descs") == 0)
2534 {
2535 value = pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS];
2536 }
2537 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2538 {
2539 value = pUM->devParams.maxRxFree;
2540 }
2541 else if (strcmp(pr_name, "_tx_descs") == 0)
2542 {
2543 value = pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS];
2544 }
2545 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2546 {
2547 value = pUM->devParams.maxTxFree;
2548 }
2549 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2550 {
2551 value = pUM->devParams.rxCopyThreshold;
2552 }
2553 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2554 {
2555 value = pUM->devParams.txCopyThreshold;
2556 }
2557 else if (strcmp(pr_name, "_interrupt_coalesce") == 0)
2558 {
2559 value = pUM->devParams.intrCoalesce;
2560 }
2561 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0)
2562 {
2563 value = pUM->devParams.intrRxPerSec;
2564 }
2565 else if (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0)
2566 {
2567 value = pUM->devParams.intrTxPerSec;
2568 }
2569 else if (strcmp(pr_name, "_disable_msix") == 0)
2570 {
2571 value = pUM->devParams.disableMsix;
2572 }
2573 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0)
2574 {
2575 value = pUM->devParams.l2_fw_flow_ctrl;
2576 }
2577 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2578 {
2579 value = pUM->devParams.autogreeenEnable;
2580 }
2581 else if (strcmp(pr_name, "_lso_enable") == 0)
2582 {
2583 value = pUM->devParams.lsoEnable;
2584 }
2585 else if (strcmp(pr_name, "_log_enable") == 0)
2586 {
2587 value = pUM->devParams.logEnable;
2588 }
2589 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2590 {
2591 value = pUM->devParams.fcoeEnable;
2592 }
2593 else
2594 {
2595 err = ENOTSUP;
2596 }
2597
2598 if (!err)
2599 {
2600 (void)snprintf(pr_val, pr_valsize, "%d", value);
2601 }
2602
2603 return err;
2604}
2605
2606
2607static 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)
2612{
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;
2620
2621 switch (pr_num)
2622 {
2623 case MAC_PROP_MTU:
2624
2625 ASSERT(pr_valsize >= sizeof(u32_t));
2626
2627 bcopy(&pUM->devParams.mtu[LM_CLI_IDX_NDIS], pr_val, sizeof(u32_t));
2628 break;
2629
2630 case MAC_PROP_DUPLEX:
2631
2632 ASSERT(pr_valsize >= sizeof(link_duplex_t));
2633
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;
2638
2639 case MAC_PROP_SPEED:
2640
2641 ASSERT(pr_valsize >= sizeof(link_speed));
2642
2643 link_speed = (pUM->props.link_speed * 1000000ULL);
2644 bcopy(&link_speed, pr_val, sizeof(link_speed));
2645 break;
2646
2647 case MAC_PROP_STATUS:
2648
2649 ASSERT(pr_valsize >= sizeof(link_state_t));
2650
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;
2655
2656 case MAC_PROP_AUTONEG:
2657
2658 *(uint8_t *)pr_val = lnk_cfg->link_autoneg;
2659 break;
2660
2661 case MAC_PROP_FLOWCTRL:
2662
2663 ASSERT(pr_valsize >= sizeof(link_flowctrl_t));
2664
2665 if (!lnk_cfg->param_rxpause && !lnk_cfg->param_txpause)
2666 {
2667 link_flowctrl = LINK_FLOWCTRL_NONE;
2668 }
2669 if (lnk_cfg->param_rxpause && !lnk_cfg->param_txpause)
2670 {
2671 link_flowctrl = LINK_FLOWCTRL_RX;
2672 }
2673 if (!lnk_cfg->param_rxpause && lnk_cfg->param_txpause)
2674 {
2675 link_flowctrl = LINK_FLOWCTRL_TX;
2676 }
2677 if (lnk_cfg->param_rxpause && lnk_cfg->param_txpause)
2678 {
2679 link_flowctrl = LINK_FLOWCTRL_BI;
2680 }
2681
2682 bcopy(&link_flowctrl, pr_val, sizeof(link_flowctrl_t));
2683 break;
2684
2685 case MAC_PROP_ADV_10GFDX_CAP:
2686
2687 *(uint8_t *)pr_val = lnk_cfg->param_10000fdx;
2688 break;
2689
2690 case MAC_PROP_EN_10GFDX_CAP:
2691
2692 *(uint8_t *)pr_val = hw_cfg->param_10000fdx;
2693 break;
2694
2695 case MAC_PROP_ADV_1000FDX_CAP:
2696
2697 *(uint8_t *)pr_val = lnk_cfg->param_1000fdx;
2698 break;
2699
2700 case MAC_PROP_EN_1000FDX_CAP:
2701
2702 *(uint8_t *)pr_val = hw_cfg->param_1000fdx;
2703 break;
2704
2705 case MAC_PROP_ADV_1000HDX_CAP:
2706 case MAC_PROP_EN_1000HDX_CAP:
2707
2708 *(uint8_t *)pr_val = 0;
2709 break;
2710
2711 case MAC_PROP_ADV_100FDX_CAP:
2712
2713 *(uint8_t *)pr_val = lnk_cfg->param_100fdx;
2714 break;
2715
2716 case MAC_PROP_EN_100FDX_CAP:
2717
2718 *(uint8_t *)pr_val = hw_cfg->param_100fdx;
2719 break;
2720
2721 case MAC_PROP_ADV_100HDX_CAP:
2722
2723 *(uint8_t *)pr_val = lnk_cfg->param_100hdx;
2724 break;
2725
2726 case MAC_PROP_EN_100HDX_CAP:
2727
2728 *(uint8_t *)pr_val = hw_cfg->param_100hdx;
2729 break;
2730
2731 case MAC_PROP_ADV_100T4_CAP:
2732 case MAC_PROP_EN_100T4_CAP:
2733
2734 *(uint8_t *)pr_val = 0;
2735 break;
2736
2737 case MAC_PROP_ADV_10FDX_CAP:
2738
2739 *(uint8_t *)pr_val = lnk_cfg->param_10fdx;
2740 break;
2741
2742 case MAC_PROP_EN_10FDX_CAP:
2743
2744 *(uint8_t *)pr_val = hw_cfg->param_10fdx;
2745 break;
2746
2747 case MAC_PROP_ADV_10HDX_CAP:
2748
2749 *(uint8_t *)pr_val = lnk_cfg->param_10hdx;
2750 break;
2751
2752 case MAC_PROP_EN_10HDX_CAP:
2753
2754 *(uint8_t *)pr_val = hw_cfg->param_10hdx;
2755 break;
2756
2757 case MAC_PROP_PRIVATE:
2758
2759 return BnxeGetPrivateProperty(pUM,
2760 pr_name,
2761 pr_valsize,
2762 pr_val);
2763
2764 default:
2765
2766 return ENOTSUP;
2767 }
2768
2769 return 0;
2770}
2771
2772#endif /* MC_GETPROP */
2773
2774
2775#ifdef MC_PROPINFO
2776
2777static void BnxeMacPrivatePropertyInfo(um_device_t * pUM,
2778 const char * pr_name,
2779 mac_prop_info_handle_t prh)
2780{
2781 char valstr[64];
2782 BnxeLinkCfg * default_cfg = &bnxeLinkCfg;
2783 int default_val;
2784
2785 bzero(valstr, sizeof (valstr));
2786
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))
2802 {
2803 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2804 return;
2805 }
2806
2807 if (strcmp(pr_name, "_autoneg_flow") == 0)
2808 {
2809 default_val = B_TRUE;
2810 }
2811 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
2812 {
2813 default_val = BNXE_ROUTE_RING_TCPUDP;
2814 }
2815 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2816 {
2817 default_val = USER_OPTION_RX_MAX_FREE_DEFAULT;
2818 }
2819 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2820 {
2821 default_val = USER_OPTION_TX_MAX_FREE_DEFAULT;
2822 }
2823 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2824 {
2825 default_val = USER_OPTION_RX_DCOPY_THRESH_DEFAULT;
2826 }
2827 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2828 {
2829 default_val = USER_OPTION_TX_DCOPY_THRESH_DEFAULT;
2830 }
2831 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2832 {
2833 default_val = B_TRUE;
2834 }
2835 else if (strcmp(pr_name, "_log_enable") == 0)
2836 {
2837 default_val = B_TRUE;
2838 }
2839 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2840 {
2841 default_val = B_TRUE;
2842 }
2843 else
2844 {
2845 return;
2846 }
2847
2848 snprintf(valstr, sizeof (valstr), "%d", default_val);
2849 mac_prop_info_set_default_str(prh, valstr);
2850}
2851
2852
2853static void BnxeMacPropertyInfo(void * barg,
2854 const char * pr_name,
2855 mac_prop_id_t pr_num,
2856 mac_prop_info_handle_t prh)
2857{
2858 um_device_t * pUM = barg;
2859 link_flowctrl_t link_flowctrl;
2860 BnxeLinkCfg * default_cfg = &bnxeLinkCfg;
2861
2862 switch (pr_num)
2863 {
2864 case MAC_PROP_STATUS:
2865 case MAC_PROP_SPEED:
2866 case MAC_PROP_DUPLEX:
2867
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:
2876
2877 case MAC_PROP_EN_1000HDX_CAP:
2878 case MAC_PROP_EN_100T4_CAP:
2879
2880 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2881 break;
2882
2883 case MAC_PROP_EN_10GFDX_CAP:
2884
2885 mac_prop_info_set_default_uint8(prh, default_cfg->param_10000fdx);
2886 break;
2887
2888 case MAC_PROP_EN_1000FDX_CAP:
2889
2890 mac_prop_info_set_default_uint8(prh, default_cfg->param_1000fdx);
2891 break;
2892
2893 case MAC_PROP_EN_100FDX_CAP:
2894
2895 mac_prop_info_set_default_uint8(prh, default_cfg->param_100fdx);
2896 break;
2897
2898 case MAC_PROP_EN_100HDX_CAP:
2899
2900 mac_prop_info_set_default_uint8(prh, default_cfg->param_100hdx);
2901 break;
2902
2903 case MAC_PROP_EN_10FDX_CAP:
2904
2905 mac_prop_info_set_default_uint8(prh, default_cfg->param_10fdx);
2906 break;
2907
2908 case MAC_PROP_EN_10HDX_CAP:
2909
2910 mac_prop_info_set_default_uint8(prh, default_cfg->param_10hdx);
2911 break;
2912
2913 case MAC_PROP_MTU:
2914
2915 mac_prop_info_set_range_uint32(prh,
2916 USER_OPTION_MTU_MIN,
2917 USER_OPTION_MTU_MAX);
2918 break;
2919
2920 case MAC_PROP_AUTONEG:
2921
2922 mac_prop_info_set_default_uint8(prh, default_cfg->link_autoneg);
2923 break;
2924
2925 case MAC_PROP_FLOWCTRL:
2926
2927 if (!default_cfg->param_rxpause && !default_cfg->param_txpause)
2928 {
2929 link_flowctrl = LINK_FLOWCTRL_NONE;
2930 }
2931
2932 if (default_cfg->param_rxpause && !default_cfg->param_txpause)
2933 {
2934 link_flowctrl = LINK_FLOWCTRL_RX;
2935 }
2936
2937 if (!default_cfg->param_rxpause && default_cfg->param_txpause)
2938 {
2939 link_flowctrl = LINK_FLOWCTRL_TX;
2940 }
2941
2942 if (default_cfg->param_rxpause && default_cfg->param_txpause)
2943 {
2944 link_flowctrl = LINK_FLOWCTRL_BI;
2945 }
2946
2947 mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl);
2948 break;
2949
2950 case MAC_PROP_PRIVATE:
2951
2952 BnxeMacPrivatePropertyInfo(pUM, pr_name, prh);
2953 break;
2954 }
2955}
2956
2957#endif /* MC_PROPINFO */