1 /*
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.
37 * Copyright (c) 2017, Joyent, Inc.
38 * Copyright 2023 Oxide Computer Company
39 */
40
41 #include "bnxe.h"
42
43 #include <sys/mac.h>
44 #include <sys/mac_ether.h>
45 #include <sys/dlpi.h>
46
47 #if !(defined(__S11) || defined(__S12))
48 #define mri_driver mr_driver
49 #define mri_start mr_start
50 #define mri_stop mr_stop
51 #define mri_intr mr_intr
52 #define mri_poll mr_poll
53 #define mri_tx mr_send
54 #define mgi_driver mrg_driver
55 #define mgi_start mrg_start
56 #define mgi_stop mrg_stop
57 #define mgi_count mrg_count
58 #define mgi_addmac mrg_addmac
59 #define mgi_remmac mrg_addmac
60 #define mr_gaddring mr_gadd_ring
61 #define mr_gremring mr_grem_ring
62 #endif /* not __S11 or __S12 */
63
64 /*
65 * Reconfiguring the network devices parameters require net_config
66 * privilege starting Solaris 10. Only root user is allowed to
67 * update device parameter in Solaris 9 and earlier version. Following
68 * declaration allows single binary image to run on all OS versions.
69 */
70 extern int secpolicy_net_config(const cred_t *, boolean_t);
71 extern int drv_priv(cred_t *);
72 #pragma weak secpolicy_net_config
73 #pragma weak drv_priv
74
75 #ifdef MC_SETPROP
76
77 char * bnxeLink_priv_props[] =
78 {
79 "_adv_2500fdx_cap",
80 "_en_2500fdx_cap",
81 "_adv_txpause_cap",
82 "_en_txpause_cap",
83 "_txpause",
84 "_adv_rxpause_cap",
85 "_en_rxpause_cap",
86 "_rxpause",
87 "_autoneg_flow",
88 "_checksum",
89 "_num_rings",
90 "_rx_descs",
91 "_rx_free_reclaim",
92 "_rx_copy_threshold",
93 "_tx_descs",
94 "_tx_free_reclaim",
95 "_tx_copy_threshold",
96 "_tx_ring_policy",
97 "_interrupt_coalesce",
98 "_rx_interrupt_coalesce_usec",
99 "_tx_interrupt_coalesce_usec",
100 "_disable_msix",
101 "_l2_fw_flow_ctrl",
102 "_autogreeen_enable",
103 "_lso_enable",
104 "_log_enable",
105 "_fcoe_enable",
106 NULL
107 };
108
109 #endif /* MC_SETPROP */
110
111
BnxeMacStats(void * pArg,uint_t stat,uint64_t * pVal)112 static int BnxeMacStats(void * pArg,
113 uint_t stat,
114 uint64_t * pVal)
115 {
116 um_device_t * pUM = (um_device_t *)pArg;
117 lm_device_t * pLM;
118 b10_l2_chip_statistics_t b10_l2_stats;
119 int idx, rc = 0;
120
121 if ((pUM == NULL) || (pVal == NULL))
122 {
123 return EINVAL;
124 }
125
126 pLM = &pUM->lm_dev;
127
128 BNXE_LOCK_ENTER_GLD(pUM);
129
130 if (!pUM->plumbed)
131 {
132 BNXE_LOCK_EXIT_GLD(pUM);
133 return EAGAIN;
134 }
135
136 *pVal = 0;
137
138 switch (stat)
139 {
140 case MAC_STAT_IFSPEED:
141 *pVal = (pUM->props.link_speed * 1000000ULL);
142 break;
143
144 case MAC_STAT_MULTIRCV:
145 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
146 L2_CHIP_STATISTICS_VER_NUM_1);
147 *pVal = b10_l2_stats.IfHCInMulticastPkts;
148 break;
149
150 case MAC_STAT_BRDCSTRCV:
151 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
152 L2_CHIP_STATISTICS_VER_NUM_1);
153 *pVal = b10_l2_stats.IfHCInBroadcastPkts;
154 break;
155
156 case MAC_STAT_MULTIXMT:
157 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
158 L2_CHIP_STATISTICS_VER_NUM_1);
159 *pVal = b10_l2_stats.IfHCOutMulticastPkts;
160 break;
161
162 case MAC_STAT_BRDCSTXMT:
163 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
164 L2_CHIP_STATISTICS_VER_NUM_1);
165 *pVal = b10_l2_stats.IfHCOutBroadcastPkts;
166 break;
167
168 case MAC_STAT_NORCVBUF:
169 lm_get_stats(pLM, LM_STATS_RCV_NO_BUFFER_DROP, (u64_t *)pVal);
170 break;
171
172 case MAC_STAT_NOXMTBUF:
173 *pVal = 0;
174 LM_FOREACH_TSS_IDX(pLM, idx)
175 {
176 *pVal += pUM->txq[idx].txRecycle;
177 }
178 break;
179
180 case MAC_STAT_IERRORS:
181 case ETHER_STAT_MACRCV_ERRORS:
182 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
183 L2_CHIP_STATISTICS_VER_NUM_1);
184 *pVal = b10_l2_stats.IfInErrors;
185 break;
186
187 case MAC_STAT_OERRORS:
188 /* XXX not available */
189 break;
190
191 case MAC_STAT_COLLISIONS:
192 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
193 L2_CHIP_STATISTICS_VER_NUM_1);
194 *pVal = b10_l2_stats.EtherStatsCollisions;
195 break;
196
197 case MAC_STAT_RBYTES:
198 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
199 L2_CHIP_STATISTICS_VER_NUM_1);
200 *pVal = b10_l2_stats.IfHCInOctets;
201 break;
202
203 case MAC_STAT_IPACKETS:
204 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
205 L2_CHIP_STATISTICS_VER_NUM_1);
206 *pVal = b10_l2_stats.IfHCInPkts;
207 break;
208
209 case MAC_STAT_OBYTES:
210 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
211 L2_CHIP_STATISTICS_VER_NUM_1);
212 *pVal = b10_l2_stats.IfHCOutOctets;
213 break;
214
215 case MAC_STAT_OPACKETS:
216 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
217 L2_CHIP_STATISTICS_VER_NUM_1);
218 *pVal = b10_l2_stats.IfHCOutPkts;
219 break;
220
221 case ETHER_STAT_ALIGN_ERRORS:
222 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
223 L2_CHIP_STATISTICS_VER_NUM_1);
224 *pVal = b10_l2_stats.Dot3StatsAlignmentErrors;
225 break;
226
227 case ETHER_STAT_FCS_ERRORS:
228 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
229 L2_CHIP_STATISTICS_VER_NUM_1);
230 *pVal = b10_l2_stats.Dot3StatsFCSErrors;
231 break;
232
233 case ETHER_STAT_FIRST_COLLISIONS:
234 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
235 L2_CHIP_STATISTICS_VER_NUM_1);
236 *pVal = b10_l2_stats.Dot3StatsSingleCollisionFrames;
237 break;
238
239 case ETHER_STAT_MULTI_COLLISIONS:
240 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
241 L2_CHIP_STATISTICS_VER_NUM_1);
242 *pVal = b10_l2_stats.Dot3StatsMultipleCollisionFrames;
243 break;
244
245 case ETHER_STAT_DEFER_XMTS:
246 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
247 L2_CHIP_STATISTICS_VER_NUM_1);
248 *pVal = b10_l2_stats.Dot3StatsDeferredTransmissions;
249 break;
250
251 case ETHER_STAT_TX_LATE_COLLISIONS:
252 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
253 L2_CHIP_STATISTICS_VER_NUM_1);
254 *pVal = b10_l2_stats.Dot3StatsLateCollisions;
255 break;
256
257 case ETHER_STAT_EX_COLLISIONS:
258 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
259 L2_CHIP_STATISTICS_VER_NUM_1);
260 *pVal = b10_l2_stats.Dot3StatsExcessiveCollisions;
261 break;
262
263 case ETHER_STAT_MACXMT_ERRORS:
264 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
265 L2_CHIP_STATISTICS_VER_NUM_1);
266 *pVal = b10_l2_stats.Dot3StatsInternalMacTransmitErrors;
267 break;
268
269 case ETHER_STAT_CARRIER_ERRORS:
270 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
271 L2_CHIP_STATISTICS_VER_NUM_1);
272 *pVal = b10_l2_stats.Dot3StatsCarrierSenseErrors;
273 break;
274
275 case ETHER_STAT_TOOLONG_ERRORS:
276 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
277 L2_CHIP_STATISTICS_VER_NUM_1);
278 *pVal = b10_l2_stats.EtherStatsOverrsizePkts;
279 break;
280
281 #if (MAC_VERSION > 1)
282 case ETHER_STAT_TOOSHORT_ERRORS:
283 lm_stats_get_l2_chip_stats(pLM, &b10_l2_stats,
284 L2_CHIP_STATISTICS_VER_NUM_1);
285 *pVal = b10_l2_stats.EtherStatsUndersizePkts;
286 break;
287 #endif
288
289 case ETHER_STAT_XCVR_ADDR:
290 *pVal = pLM->vars.phy_addr;
291 break;
292
293 case ETHER_STAT_XCVR_ID:
294 *pVal = 0;
295 break;
296
297 case ETHER_STAT_XCVR_INUSE:
298 *pVal = (uint64_t)bnxe_phy_to_media(pUM);
299 break;
300
301 #if (MAC_VERSION > 1)
302 case ETHER_STAT_CAP_10GFDX:
303 *pVal = 1;
304 break;
305 #endif
306
307 case ETHER_STAT_CAP_1000FDX:
308 *pVal = 1;
309 break;
310
311 #if 0
312 case ETHER_STAT_CAP_1000HDX:
313 //*pVal = linkconf->param_1000hdx;
314 *pVal = 0;
315 break;
316 #endif
317
318 case ETHER_STAT_CAP_100FDX:
319 //*pVal = linkconf->param_100fdx;
320 *pVal = 1;
321 break;
322
323 case ETHER_STAT_CAP_100HDX:
324 //*pVal = linkconf->param_100hdx;
325 *pVal = 1;
326 break;
327
328 case ETHER_STAT_CAP_10FDX:
329 //*pVal = linkconf->param_10fdx;
330 *pVal = 1;
331 break;
332
333 case ETHER_STAT_CAP_10HDX:
334 //*pVal = linkconf->param_10hdx;
335 *pVal = 1;
336 break;
337
338 case ETHER_STAT_CAP_ASMPAUSE:
339 *pVal = 1;
340 break;
341
342 case ETHER_STAT_CAP_PAUSE:
343 *pVal = 1;
344 break;
345
346 case ETHER_STAT_CAP_AUTONEG:
347 *pVal = 1;
348 break;
349
350 #if (MAC_VERSION > 1)
351 case ETHER_STAT_CAP_REMFAULT:
352 *pVal = 1;
353 break;
354 #endif
355
356 #if (MAC_VERSION > 1)
357 case ETHER_STAT_ADV_CAP_10GFDX:
358 *pVal = pUM->curcfg.lnkcfg.param_10000fdx;
359 break;
360 #endif
361
362 case ETHER_STAT_ADV_CAP_1000FDX:
363 *pVal = pUM->curcfg.lnkcfg.param_1000fdx;
364 break;
365
366 #if 0
367 case ETHER_STAT_ADV_CAP_1000HDX:
368 //*pVal = pUM->curcfg.lnkcfg.param_1000hdx;
369 *pVal = 0;
370 break;
371 #endif
372
373 case ETHER_STAT_ADV_CAP_100FDX:
374 *pVal = pUM->curcfg.lnkcfg.param_100fdx;
375 break;
376
377 case ETHER_STAT_ADV_CAP_100HDX:
378 *pVal = pUM->curcfg.lnkcfg.param_100hdx;
379 break;
380
381 case ETHER_STAT_ADV_CAP_10FDX:
382 *pVal = pUM->curcfg.lnkcfg.param_10fdx;
383 break;
384
385 case ETHER_STAT_ADV_CAP_10HDX:
386 *pVal = pUM->curcfg.lnkcfg.param_10hdx;
387 break;
388
389 case ETHER_STAT_ADV_CAP_ASMPAUSE:
390 *pVal = 1;
391 break;
392
393 case ETHER_STAT_ADV_CAP_PAUSE:
394 *pVal = 1;
395 break;
396
397 case ETHER_STAT_ADV_CAP_AUTONEG:
398 *pVal = pUM->curcfg.lnkcfg.link_autoneg;
399 break;
400
401 #if (MAC_VERSION > 1)
402 case ETHER_STAT_ADV_REMFAULT:
403 *pVal = 1;
404 break;
405 #endif
406
407 #if 0 /* LP caps not supported */
408 #if (MAC_VERSION > 1)
409 case ETHER_STAT_LP_CAP_10GFDX:
410 *pVal = pUM->remote.param_10000fdx;
411 break;
412 #endif
413
414 case ETHER_STAT_LP_CAP_1000FDX:
415 *pVal = pUM->remote.param_1000fdx;
416 break;
417
418 #if 0
419 case ETHER_STAT_LP_CAP_1000HDX:
420 //*pVal = pUM->remote.param_1000hdx;
421 *pVal = 0;
422 break;
423 #endif
424
425 case ETHER_STAT_LP_CAP_100FDX:
426 *pVal = pUM->remote.param_100fdx;
427 break;
428
429 case ETHER_STAT_LP_CAP_100HDX:
430 *pVal = pUM->remote.param_100hdx;
431 break;
432
433 case ETHER_STAT_LP_CAP_10FDX:
434 *pVal = pUM->remote.param_10fdx;
435 break;
436
437 case ETHER_STAT_LP_CAP_10HDX:
438 *pVal = pUM->remote.param_10hdx;
439 break;
440
441 #if 0
442 case ETHER_STAT_LP_CAP_ASMPAUSE:
443 /* XXX implement LP_ASYM_PAUSE stat */
444 break;
445
446 case ETHER_STAT_LP_CAP_PAUSE:
447 /* XXX implement LP_PAUSE stat */
448 break;
449 #endif
450
451 case ETHER_STAT_LP_CAP_AUTONEG:
452 *pVal = pUM->remote.link_autoneg;
453 break;
454
455 case ETHER_STAT_LP_REMFAULT:
456 /* XXX implement LP_REMFAULT stat */
457 break;
458 #endif /* LP caps not supported */
459
460 #if 0
461 case ETHER_STAT_LINK_ASMPAUSE:
462 /* XXX implement ASMPAUSE stat */
463 break;
464
465 case ETHER_STAT_LINK_PAUSE:
466 /* XXX implement PAUSE stat */
467 break;
468 #endif
469
470 case ETHER_STAT_LINK_AUTONEG:
471 *pVal = pUM->curcfg.lnkcfg.link_autoneg;
472 break;
473
474 case ETHER_STAT_LINK_DUPLEX:
475 *pVal = (pUM->props.link_duplex == B_TRUE) ?
476 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
477 break;
478
479 default:
480 rc = ENOTSUP;
481 }
482
483 BNXE_LOCK_EXIT_GLD(pUM);
484
485 return rc;
486 }
487
488
489
490 /*
491 * This routine is called by GLD to enable device for packet reception and
492 * enable interrupts.
493 */
BnxeMacStart(void * pArg)494 static int BnxeMacStart(void * pArg)
495 {
496 um_device_t * pUM = (um_device_t *)pArg;
497
498 BNXE_LOCK_ENTER_GLD(pUM);
499
500 if (pUM->plumbed)
501 {
502 /* already started */
503 BNXE_LOCK_EXIT_GLD(pUM);
504 return EAGAIN;
505 }
506
507 /* Always report the initial link state as unknown. */
508 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
509
510 if (BnxeHwStartL2(pUM))
511 {
512 BNXE_LOCK_EXIT_GLD(pUM);
513 return EIO;
514 }
515
516 atomic_swap_32(&pUM->plumbed, B_TRUE);
517
518 mutex_enter(&bnxeLoaderMutex);
519 bnxeNumPlumbed++;
520 mutex_exit(&bnxeLoaderMutex);
521
522 BNXE_LOCK_EXIT_GLD(pUM);
523
524 return 0;
525 }
526
527
528 /*
529 * This routine stops packet reception by clearing RX MASK register. Also
530 * interrupts are disabled for this device.
531 */
BnxeMacStop(void * pArg)532 static void BnxeMacStop(void * pArg)
533 {
534 um_device_t * pUM = (um_device_t *)pArg;
535
536 BNXE_LOCK_ENTER_GLD(pUM);
537
538 if (pUM->plumbed)
539 {
540 atomic_swap_32(&pUM->plumbed, B_FALSE);
541
542 BnxeHwStopL2(pUM);
543
544 /* Report the link state back to unknown. */
545 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
546
547 mutex_enter(&bnxeLoaderMutex);
548 bnxeNumPlumbed--;
549 mutex_exit(&bnxeLoaderMutex);
550 }
551
552 BNXE_LOCK_EXIT_GLD(pUM);
553 }
554
555 /* (flag) TRUE = on, FALSE = off */
BnxeMacPromiscuous(void * pArg,boolean_t flag)556 static int BnxeMacPromiscuous(void * pArg,
557 boolean_t flag)
558 {
559 um_device_t * pUM = (um_device_t *)pArg;
560
561 BNXE_LOCK_ENTER_GLD(pUM);
562
563 if (!pUM->plumbed)
564 {
565 BNXE_LOCK_EXIT_GLD(pUM);
566 return EAGAIN;
567 }
568
569 if (flag)
570 {
571 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] |=
572 LM_RX_MASK_PROMISCUOUS_MODE;
573 }
574 else
575 {
576 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS] &=
577 ~LM_RX_MASK_PROMISCUOUS_MODE;
578 }
579
580 BNXE_LOCK_ENTER_HWINIT(pUM);
581
582 if (BnxeRxMask(pUM, LM_CLI_IDX_NDIS,
583 pUM->devParams.rx_filter_mask[LM_CLI_IDX_NDIS]) < 0)
584 {
585 BNXE_LOCK_EXIT_HWINIT(pUM);
586 BNXE_LOCK_EXIT_GLD(pUM);
587 return ECANCELED;
588 }
589
590 BNXE_LOCK_EXIT_HWINIT(pUM);
591
592 BNXE_LOCK_EXIT_GLD(pUM);
593
594 return 0;
595 }
596
597
598 /*
599 * This function is used to enable or disable multicast packet reception for
600 * particular multicast addresses.
601 * (flag) TRUE = add, FALSE = remove
602 */
BnxeMacMulticast(void * pArg,boolean_t flag,const uint8_t * pMcastAddr)603 static int BnxeMacMulticast(void * pArg,
604 boolean_t flag,
605 const uint8_t * pMcastAddr)
606 {
607 um_device_t * pUM = (um_device_t *)pArg;
608 int rc;
609
610 BNXE_LOCK_ENTER_GLD(pUM);
611
612 if (!pUM->plumbed)
613 {
614 BNXE_LOCK_EXIT_GLD(pUM);
615 return EAGAIN;
616 }
617
618 BNXE_LOCK_ENTER_HWINIT(pUM);
619 rc = BnxeMulticast(pUM, LM_CLI_IDX_NDIS, flag, pMcastAddr, B_TRUE);
620 BNXE_LOCK_EXIT_HWINIT(pUM);
621
622 BNXE_LOCK_EXIT_GLD(pUM);
623
624 return rc;
625 }
626
627
628 #ifdef BNXE_RINGS
629
630 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
BnxeRxRingGroupAddMac(void * groupHandle,const uint8_t * pMacAddr,uint64_t flags)631 static int BnxeRxRingGroupAddMac(void * groupHandle,
632 const uint8_t * pMacAddr,
633 uint64_t flags)
634 #else
635 static int BnxeRxRingGroupAddMac(void * groupHandle,
636 const uint8_t * pMacAddr)
637 #endif
638 {
639 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle;
640 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM;
641 //u32_t idx = pRxQGroup->idx;
642 int rc;
643
644 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
645 _NOTE(ARGUNUSED(flags))
646 #endif
647
648 BNXE_LOCK_ENTER_GLD(pUM);
649
650 if (!pUM->plumbed)
651 {
652 BNXE_LOCK_EXIT_GLD(pUM);
653 return ECANCELED;
654 }
655
656 /* Validate MAC address */
657 if (IS_ETH_MULTICAST(pMacAddr))
658 {
659 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address.");
660 BNXE_LOCK_EXIT_GLD(pUM);
661 return EINVAL;
662 }
663
664 if (pUM->ucastTableLen == LM_MAX_UC_TABLE_SIZE)
665 {
666 BNXE_LOCK_EXIT_GLD(pUM);
667 return ENOMEM;
668 }
669
670 BNXE_LOCK_ENTER_HWINIT(pUM);
671
672 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr);
673
674 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE,
675 pUM->lm_dev.params.mac_addr);
676
677 BNXE_LOCK_EXIT_HWINIT(pUM);
678
679 if (rc < 0)
680 {
681 BNXE_LOCK_EXIT_GLD(pUM);
682 return ECANCELED;
683 }
684
685 pUM->ucastTableLen++;
686
687 BNXE_LOCK_EXIT_GLD(pUM);
688 return 0;
689 }
690
691
BnxeRxRingGroupRemMac(void * groupHandle,const uint8_t * pMacAddr)692 static int BnxeRxRingGroupRemMac(void * groupHandle,
693 const uint8_t * pMacAddr)
694 {
695 RxQueueGroup * pRxQGroup = (RxQueueGroup *)groupHandle;
696 um_device_t * pUM = (um_device_t *)pRxQGroup->pUM;
697 //u32_t idx = pRxQGroup->idx;
698 int rc;
699
700 BNXE_LOCK_ENTER_GLD(pUM);
701
702 if (!pUM->plumbed)
703 {
704 BNXE_LOCK_EXIT_GLD(pUM);
705 return ECANCELED;
706 }
707
708 if (pUM->ucastTableLen == 0)
709 {
710 BNXE_LOCK_EXIT_GLD(pUM);
711 return EINVAL;
712 }
713
714 BNXE_LOCK_ENTER_HWINIT(pUM);
715
716 if (!IS_ETH_ADDRESS_EQUAL(pMacAddr, pUM->lm_dev.params.mac_addr))
717 {
718 BnxeLogWarn(pUM, "Deleting MAC address that doesn't match default");
719 /* XXX */
720 }
721
722 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_FALSE,
723 pUM->lm_dev.params.mac_addr);
724
725 memset(pUM->lm_dev.params.mac_addr, 0, sizeof(pUM->lm_dev.params.mac_addr));
726
727 BNXE_LOCK_EXIT_HWINIT(pUM);
728
729 if (rc < 0)
730 {
731 BNXE_LOCK_EXIT_GLD(pUM);
732 return ECANCELED;
733 }
734
735 pUM->ucastTableLen--;
736
737 BNXE_LOCK_EXIT_GLD(pUM);
738 return 0;
739 }
740
741
BnxeTxRingSend(void * ringHandle,mblk_t * pMblk)742 static mblk_t * BnxeTxRingSend(void * ringHandle,
743 mblk_t * pMblk)
744 {
745 TxQueue * pTxQ = (TxQueue *)ringHandle;
746 um_device_t * pUM = (um_device_t *)pTxQ->pUM;
747 u32_t idx = pTxQ->idx;
748 mblk_t * pNextMblk;
749 int rc;
750
751 while (pMblk)
752 {
753 pNextMblk = pMblk->b_next;
754 pMblk->b_next = NULL;
755
756 rc = BnxeTxSendMblk(pUM, idx, pMblk, 0, 0);
757
758 if (rc == BNXE_TX_GOODXMIT)
759 {
760 pMblk = pNextMblk;
761 continue;
762 }
763 else if (rc == BNXE_TX_DEFERPKT)
764 {
765 pMblk = pNextMblk;
766 }
767 else
768 {
769 pMblk->b_next = pNextMblk;
770 }
771
772 break;
773 }
774
775 return pMblk;
776 }
777
778 #endif /* BNXE_RINGS */
779
780
BnxeMacUnicast(void * pArg,const uint8_t * pMacAddr)781 static int BnxeMacUnicast(void * pArg,
782 const uint8_t * pMacAddr)
783 {
784 um_device_t * pUM = (um_device_t *)pArg;
785 int rc;
786
787 BNXE_LOCK_ENTER_GLD(pUM);
788
789 if (!pUM->plumbed)
790 {
791 memcpy(pUM->gldMac, pMacAddr, ETHERNET_ADDRESS_SIZE);
792 BNXE_LOCK_EXIT_GLD(pUM);
793 return 0;
794 }
795
796 /* Validate MAC address */
797 if (IS_ETH_MULTICAST(pMacAddr))
798 {
799 BnxeLogWarn(pUM, "Cannot program a mcast/bcast address as a MAC Address.");
800 BNXE_LOCK_EXIT_GLD(pUM);
801 return EINVAL;
802 }
803
804 BNXE_LOCK_ENTER_HWINIT(pUM);
805
806 COPY_ETH_ADDRESS(pMacAddr, pUM->lm_dev.params.mac_addr);
807
808 rc = BnxeMacAddress(pUM, LM_CLI_IDX_NDIS, B_TRUE,
809 pUM->lm_dev.params.mac_addr);
810
811 BNXE_LOCK_EXIT_HWINIT(pUM);
812
813 if (rc < 0)
814 {
815 BNXE_LOCK_EXIT_GLD(pUM);
816 return EAGAIN;
817 }
818
819 BNXE_LOCK_EXIT_GLD(pUM);
820 return 0;
821 }
822
823
BnxeMacTx(void * pArg,mblk_t * pMblk)824 static mblk_t * BnxeMacTx(void * pArg,
825 mblk_t * pMblk)
826 {
827 um_device_t * pUM = (um_device_t *)pArg;
828 mblk_t * pNextMblk;
829 int ring, rc;
830
831 BNXE_LOCK_ENTER_GLDTX(pUM, RW_READER);
832
833 if (!pUM->plumbed)
834 {
835 freemsgchain(pMblk);
836 BNXE_LOCK_EXIT_GLDTX(pUM);
837
838 return NULL;
839 }
840
841 while (pMblk)
842 {
843 ring = BnxeRouteTxRing(pUM, pMblk);
844
845 pNextMblk = pMblk->b_next;
846 pMblk->b_next = NULL;
847
848 //rc = BnxeTxSendMblk(pUM, NDIS_CID(&pUM->lm_dev), pMblk, 0, 0);
849 rc = BnxeTxSendMblk(pUM, ring, pMblk, 0, 0);
850
851 if (rc == BNXE_TX_GOODXMIT)
852 {
853 pMblk = pNextMblk;
854 continue;
855 }
856 else if (rc == BNXE_TX_DEFERPKT)
857 {
858 pMblk = pNextMblk;
859 }
860 else
861 {
862 pMblk->b_next = pNextMblk;
863 }
864
865 break;
866 }
867
868 BNXE_LOCK_EXIT_GLDTX(pUM);
869
870 return pMblk;
871 }
872
873
874 #ifdef MC_RESOURCES
875
BnxeBlank(void * pArg,time_t tick_cnt,uint_t pkt_cnt)876 static void BnxeBlank(void * pArg,
877 time_t tick_cnt,
878 uint_t pkt_cnt)
879 {
880 um_device_t * pUM = (um_device_t *)pArg;
881
882 if (!pUM->plumbed)
883 {
884 return;
885 }
886
887 /* XXX
888 * Need to dynamically reconfigure the hw with new interrupt
889 * coalescing params...
890 */
891 }
892
893
BnxeMacResources(void * pArg)894 static void BnxeMacResources(void * pArg)
895 {
896 um_device_t * pUM = (um_device_t *)pArg;
897 mac_rx_fifo_t mrf;
898 int idx;
899
900 mrf.mrf_type = MAC_RX_FIFO;
901 mrf.mrf_blank = BnxeBlank;
902 mrf.mrf_arg = (void *)pUM;
903 mrf.mrf_normal_blank_time = 25;
904 mrf.mrf_normal_pkt_count = 8;
905
906 LM_FOREACH_RSS_IDX(&pUM->lm_dev, idx)
907 {
908 pUM->macRxResourceHandles[idx] =
909 mac_resource_add(pUM->pMac, (mac_resource_t *)&mrf);
910 }
911 }
912
913 #endif /* MC_RESOURCES */
914
915
BnxeReadReg(um_device_t * pUM,struct bnxe_reg_data * pData)916 static boolean_t BnxeReadReg(um_device_t * pUM,
917 struct bnxe_reg_data * pData)
918 {
919 if (pData->offset & 0x3)
920 {
921 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXEREG ioctl");
922 return B_FALSE;
923 }
924
925 LM_BAR_RD32_OFFSET(&pUM->lm_dev, 0, pData->offset, &pData->value);
926
927 return B_TRUE;
928 }
929
930
BnxeWriteReg(um_device_t * pUM,struct bnxe_reg_data * pData)931 static boolean_t BnxeWriteReg(um_device_t * pUM,
932 struct bnxe_reg_data * pData)
933 {
934 if (pData->offset & 0x3)
935 {
936 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXEREG ioctl");
937 return B_FALSE;
938 }
939
940 LM_BAR_WR32_OFFSET(&pUM->lm_dev, 0, pData->offset, pData->value);
941
942 return B_TRUE;
943 }
944
945
BnxeReadNvm(um_device_t * pUM,struct bnxe_nvram_data * pData)946 static boolean_t BnxeReadNvm(um_device_t * pUM,
947 struct bnxe_nvram_data * pData)
948 {
949 if (pData->offset & 0x3)
950 {
951 BnxeLogWarn(pUM, "Invalid register offset for GIOCBNXENVRM ioctl");
952 return B_FALSE;
953 }
954
955 if (lm_nvram_read(&pUM->lm_dev,
956 pData->offset,
957 pData->value,
958 (pData->num_of_u32 * sizeof(u32_t))) !=
959 LM_STATUS_SUCCESS)
960 {
961 return B_FALSE;
962 }
963
964 return B_TRUE;
965 }
966
967
BnxeWriteNvm(um_device_t * pUM,struct bnxe_nvram_data * pData)968 static boolean_t BnxeWriteNvm(um_device_t * pUM,
969 struct bnxe_nvram_data * pData)
970 {
971 if (pData->offset & 0x3)
972 {
973 BnxeLogWarn(pUM, "Invalid register offset for SIOCBNXENVRM ioctl");
974 return B_FALSE;
975 }
976
977 if (lm_nvram_write(&pUM->lm_dev,
978 pData->offset,
979 pData->value,
980 (pData->num_of_u32 * sizeof(u32_t))) !=
981 LM_STATUS_SUCCESS)
982 {
983 return B_FALSE;
984 }
985
986 return B_TRUE;
987 }
988
989
BnxeReadPciCfg(um_device_t * pUM,struct bnxe_reg_data * pData)990 static boolean_t BnxeReadPciCfg(um_device_t * pUM,
991 struct bnxe_reg_data * pData)
992 {
993 pData->value = pci_config_get32(pUM->pPciCfg, (off_t)pData->offset);
994 return B_TRUE;
995 }
996
997 typedef enum {
998 STATS_SHOW_TYPE_NUM,
999 STATS_SHOW_TYPE_STR,
1000 STATS_SHOW_TYPE_CNT,
1001 STATS_SHOW_TYPE_MAX
1002 } stats_show_type_t;
1003
1004 typedef union _b10_stats_show_data_t
1005 {
1006 u32_t op; /* ioctl sub-commond */
1007
1008 struct
1009 {
1010 u32_t num; /* return number of stats */
1011 u32_t len; /* length of each string item */
1012 } desc;
1013
1014 /* variable length... */
1015 char str[1]; /* holds names of desc.num stats, each desc.len in length */
1016
1017 struct
1018 {
1019 b10_l2_chip_statistics_v2_t l2_chip_stats;
1020 b10_l4_chip_statistics_t l4_chip_stats;
1021 b10_l2_driver_statistics_t l2_drv_stats;
1022 b10_l4_driver_statistics_t l4_drv_stats;
1023 } cnt;
1024 } b10_stats_show_data_t;
1025
1026
BnxeStatsShow(um_device_t * pUM,b10_stats_show_data_t * pStats,u32_t statsLen)1027 static boolean_t BnxeStatsShow(um_device_t * pUM,
1028 b10_stats_show_data_t * pStats,
1029 u32_t statsLen)
1030 {
1031 stats_show_type_t op;
1032 const size_t stats_size = sizeof(pStats->cnt);
1033
1034 /*
1035 * All stats names MUST conform to STATS_STR_LEN length!!!
1036 */
1037
1038 #define STATS_STR_LEN 39
1039
1040 /* XXX
1041 * Note: these strings must be updated whenever any of
1042 * b10_l2_chip_statistics_t, b10_l4_chip_statistics_t,
1043 * b10_l2_driver_statistics_t or b10_l4_driver_statistics_t
1044 * are changed, or additional statistics are required.
1045 */
1046
1047 const char p_stat_str[] =
1048
1049 // b10_l2_chip_statistics_t
1050
1051 "l2_chip_stats_ver_num\0 "
1052 "IfHCInOctets\0 "
1053 "IfHCInBadOctets\0 "
1054 "IfHCOutOctets\0 "
1055 "IfHCOutBadOctets\0 "
1056 "IfHCOutPkts\0 "
1057 "IfHCInPkts\0 "
1058 "IfHCInUcastPkts\0 "
1059 "IfHCInMulticastPkts\0 "
1060 "IfHCInBroadcastPkts\0 "
1061 "IfHCOutUcastPkts\0 "
1062 "IfHCOutMulticastPkts\0 "
1063 "IfHCOutBroadcastPkts\0 "
1064 "IfHCInUcastOctets\0 "
1065 "IfHCInMulticastOctets\0 "
1066 "IfHCInBroadcastOctets\0 "
1067 "IfHCOutUcastOctets\0 "
1068 "IfHCOutMulticastOctets\0 "
1069 "IfHCOutBroadcastOctets\0 "
1070 "IfHCOutDiscards\0 "
1071 "IfHCInFalseCarrierErrors\0 "
1072 "Dot3StatsInternalMacTransmitErrors\0 "
1073 "Dot3StatsCarrierSenseErrors\0 "
1074 "Dot3StatsFCSErrors\0 "
1075 "Dot3StatsAlignmentErrors\0 "
1076 "Dot3StatsSingleCollisionFrames\0 "
1077 "Dot3StatsMultipleCollisionFrames\0 "
1078 "Dot3StatsDeferredTransmissions\0 "
1079 "Dot3StatsExcessiveCollisions\0 "
1080 "Dot3StatsLateCollisions\0 "
1081 "EtherStatsCollisions\0 "
1082 "EtherStatsFragments\0 "
1083 "EtherStatsJabbers\0 "
1084 "EtherStatsUndersizePkts\0 "
1085 "EtherStatsOverrsizePkts\0 "
1086 "EtherStatsPktsTx64Octets\0 "
1087 "EtherStatsPktsTx65Octetsto127Octets\0 "
1088 "EtherStatsPktsTx128Octetsto255Octets\0 "
1089 "EtherStatsPktsTx256Octetsto511Octets\0 "
1090 "EtherStatsPktsTx512Octetsto1023Octets\0 "
1091 "EtherStatsPktsTx1024Octetsto1522Octets\0"
1092 "EtherStatsPktsTxOver1522Octets\0 "
1093 "XonPauseFramesReceived\0 "
1094 "XoffPauseFramesReceived\0 "
1095 "OutXonSent\0 "
1096 "OutXoffSent\0 "
1097 "FlowControlDone\0 "
1098 "MacControlFramesReceived\0 "
1099 "XoffStateEntered\0 "
1100 "IfInFramesL2FilterDiscards\0 "
1101 "IfInTTL0Discards\0 "
1102 "IfInxxOverflowDiscards\0 "
1103 "IfInMBUFDiscards\0 "
1104 "IfInErrors\0 "
1105 "IfInErrorsOctets\0 "
1106 "IfInNoBrbBuffer\0 "
1107
1108 "Nig_brb_packet\0 "
1109 "Nig_brb_truncate\0 "
1110 "Nig_flow_ctrl_discard\0 "
1111 "Nig_flow_ctrl_octets\0 "
1112 "Nig_flow_ctrl_packet\0 "
1113 "Nig_mng_discard\0 "
1114 "Nig_mng_octet_inp\0 "
1115 "Nig_mng_octet_out\0 "
1116 "Nig_mng_packet_inp\0 "
1117 "Nig_mng_packet_out\0 "
1118 "Nig_pbf_octets\0 "
1119 "Nig_pbf_packet\0 "
1120 "Nig_safc_inp\0 "
1121
1122 "Tx_Lpi_Count\0 " // This counter counts the number of timers the debounced version of EEE link idle is asserted
1123
1124 // b10_l4_chip_statistics_t
1125
1126 "l4_chip_stats_ver_num\0 "
1127 "NoTxCqes\0 "
1128 "InTCP4Segments\0 "
1129 "OutTCP4Segments\0 "
1130 "RetransmittedTCP4Segments\0 "
1131 "InTCP4Errors\0 "
1132 "InIP4Receives\0 "
1133 "InIP4HeaderErrors\0 "
1134 "InIP4Discards\0 "
1135 "InIP4Delivers\0 "
1136 "InIP4Octets\0 "
1137 "OutIP4Octets\0 "
1138 "InIP4TruncatedPackets\0 "
1139 "InTCP6Segments\0 "
1140 "OutTCP6Segments\0 "
1141 "RetransmittedTCP6Segments\0 "
1142 "InTCP6Errors\0 "
1143 "InIP6Receives\0 "
1144 "InIP6HeaderErrors\0 "
1145 "InIP6Discards\0 "
1146 "InIP6Delivers\0 "
1147 "InIP6Octets\0 "
1148 "OutIP6Octets\0 "
1149 "InIP6TruncatedPackets\0 "
1150
1151 // b10_l2_driver_statistics_t
1152
1153 "l2_driver_stats_ver_num\0 "
1154 "RxIPv4FragCount\0 "
1155 "RxIpCsErrorCount\0 "
1156 "RxTcpCsErrorCount\0 "
1157 "RxLlcSnapCount\0 "
1158 "RxPhyErrorCount\0 "
1159 "RxIpv6ExtCount\0 "
1160 "TxNoL2Bd\0 "
1161 "TxNoSqWqe\0 "
1162 "TxL2AssemblyBufUse\0 "
1163
1164 // b10_l4_driver_statistics_t
1165
1166 "l4_driver_stats_ver_num\0 "
1167 "CurrentlyIpv4Established\0 "
1168 "OutIpv4Resets\0 "
1169 "OutIpv4Fin\0 "
1170 "InIpv4Reset\0 "
1171 "InIpv4Fin\0 "
1172 "CurrentlyIpv6Established\0 "
1173 "OutIpv6Resets\0 "
1174 "OutIpv6Fin\0 "
1175 "InIpv6Reset\0 "
1176 "InIpv6Fin\0 "
1177 "RxIndicateReturnPendingCnt\0 "
1178 "RxIndicateReturnDoneCnt\0 "
1179 "RxActiveGenBufCnt\0 "
1180 "TxNoL4Bd\0 "
1181 "TxL4AssemblyBufUse\0 "
1182
1183 ;
1184
1185 ASSERT_STATIC((sizeof(p_stat_str) / STATS_STR_LEN) ==
1186 (stats_size / sizeof(u64_t)));
1187
1188 op = *((stats_show_type_t *)pStats);
1189
1190 switch (op)
1191 {
1192 case STATS_SHOW_TYPE_NUM:
1193
1194 if (statsLen < sizeof(pStats->desc))
1195 {
1196 return B_FALSE;
1197 }
1198
1199 pStats->desc.num = (stats_size / sizeof(u64_t));
1200 pStats->desc.len = STATS_STR_LEN;
1201
1202 return B_TRUE;
1203
1204 case STATS_SHOW_TYPE_STR:
1205
1206 if (statsLen != sizeof(p_stat_str))
1207 {
1208 return B_FALSE;
1209 }
1210
1211 memcpy(pStats->str, p_stat_str, sizeof(p_stat_str));
1212
1213 return B_TRUE;
1214
1215 case STATS_SHOW_TYPE_CNT:
1216
1217 if (statsLen != stats_size)
1218 {
1219 return B_FALSE;
1220 }
1221
1222 lm_stats_get_l2_chip_stats(&pUM->lm_dev,
1223 &pStats->cnt.l2_chip_stats,
1224 L2_CHIP_STATISTICS_VER_NUM_2);
1225
1226 lm_stats_get_l4_chip_stats(&pUM->lm_dev,
1227 &pStats->cnt.l4_chip_stats);
1228
1229 lm_stats_get_l2_driver_stats(&pUM->lm_dev
1230 ,&pStats->cnt.l2_drv_stats);
1231
1232 lm_stats_get_l4_driver_stats(&pUM->lm_dev,
1233 &pStats->cnt.l4_drv_stats);
1234
1235 return B_TRUE;
1236
1237 default:
1238
1239 return B_FALSE;
1240 }
1241 }
1242
BnxeMacIoctl(void * pArg,queue_t * pQ,mblk_t * pMblk)1243 static void BnxeMacIoctl(void * pArg,
1244 queue_t * pQ,
1245 mblk_t * pMblk)
1246 {
1247 um_device_t * pUM = (um_device_t *)pArg;
1248 struct iocblk * pIoctl;
1249 int rc;
1250
1251 if ((pQ == NULL) || (pMblk == NULL))
1252 {
1253 return;
1254 }
1255
1256 if (pMblk->b_datap->db_type != M_IOCTL)
1257 {
1258 miocnak(pQ, pMblk, 0, EINVAL);
1259 return;
1260 }
1261
1262 pIoctl = (struct iocblk *)pMblk->b_rptr;
1263
1264 BNXE_LOCK_ENTER_GLD(pUM);
1265
1266 switch (pIoctl->ioc_cmd)
1267 {
1268 case GIOCBNXELLDP:
1269
1270 if ((pIoctl->ioc_count != sizeof(b10_lldp_params_get_t)) ||
1271 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1272 (miocpullup(pMblk, sizeof(b10_lldp_params_get_t)) < 0))
1273 {
1274 miocnak(pQ, pMblk, 0, EINVAL);
1275 break;
1276 }
1277
1278 if (((b10_lldp_params_get_t *)pMblk->b_cont->b_rptr)->ver_num !=
1279 LLDP_PARAMS_VER_NUM)
1280 {
1281 miocnak(pQ, pMblk, 0, EINVAL);
1282 break;
1283 }
1284
1285 if (lm_dcbx_lldp_read_params(&pUM->lm_dev,
1286 (b10_lldp_params_get_t *)pMblk->b_cont->b_rptr) !=
1287 LM_STATUS_SUCCESS)
1288 {
1289 miocnak(pQ, pMblk, 0,
1290 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL);
1291 break;
1292 }
1293
1294 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1295 break;
1296
1297 case GIOCBNXEDCBX:
1298
1299 if ((pIoctl->ioc_count != sizeof(b10_dcbx_params_get_t)) ||
1300 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1301 (miocpullup(pMblk, sizeof(b10_dcbx_params_get_t)) < 0))
1302 {
1303 miocnak(pQ, pMblk, 0, EINVAL);
1304 break;
1305 }
1306
1307 if (((b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr)->ver_num !=
1308 DCBX_PARAMS_VER_NUM)
1309 {
1310 miocnak(pQ, pMblk, 0, EINVAL);
1311 break;
1312 }
1313
1314 if (lm_dcbx_read_params(&pUM->lm_dev,
1315 (b10_dcbx_params_get_t *)pMblk->b_cont->b_rptr) !=
1316 LM_STATUS_SUCCESS)
1317 {
1318 miocnak(pQ, pMblk, 0,
1319 (!IS_DCB_ENABLED(&pUM->lm_dev)) ? ENOTSUP : EINVAL);
1320 break;
1321 }
1322
1323 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1324 break;
1325
1326 case SIOCBNXEDCBX:
1327
1328 /* XXX */
1329 miocnak(pQ, pMblk, 0, EINVAL);
1330 break;
1331
1332 case GIOCBNXEREG:
1333
1334 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) ||
1335 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1336 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0))
1337 {
1338 miocnak(pQ, pMblk, 0, EINVAL);
1339 break;
1340 }
1341
1342 if (!BnxeReadReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1343 {
1344 miocnak(pQ, pMblk, 0, EINVAL);
1345 }
1346 else
1347 {
1348 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1349 }
1350
1351 break;
1352
1353 case SIOCBNXEREG:
1354
1355 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) ||
1356 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1357 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0))
1358 {
1359 miocnak(pQ, pMblk, 0, EINVAL);
1360 break;
1361 }
1362
1363 if (!BnxeWriteReg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1364 {
1365 miocnak(pQ, pMblk, 0, EINVAL);
1366 }
1367 else
1368 {
1369 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1370 }
1371
1372 break;
1373
1374 case GIOCBNXENVRM:
1375
1376 if ((pIoctl->ioc_count < sizeof(struct bnxe_nvram_data)) ||
1377 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1378 (miocpullup(pMblk, pIoctl->ioc_count) < 0))
1379 {
1380 miocnak(pQ, pMblk, 0, EINVAL);
1381 break;
1382 }
1383
1384 if (!BnxeReadNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr))
1385 {
1386 miocnak(pQ, pMblk, 0, EINVAL);
1387 }
1388 else
1389 {
1390 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1391 }
1392
1393 break;
1394
1395 case SIOCBNXENVRM:
1396
1397 if ((pIoctl->ioc_count < sizeof(struct bnxe_nvram_data)) ||
1398 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1399 (miocpullup(pMblk, pIoctl->ioc_count) < 0))
1400 {
1401 miocnak(pQ, pMblk, 0, EINVAL);
1402 break;
1403 }
1404
1405 if (!BnxeWriteNvm(pUM, (struct bnxe_nvram_data *)pMblk->b_cont->b_rptr))
1406 {
1407 miocnak(pQ, pMblk, 0, EINVAL);
1408 }
1409 else
1410 {
1411 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1412 }
1413
1414 break;
1415
1416 case GIOCBNXEPCI:
1417
1418 if ((pIoctl->ioc_count != sizeof(struct bnxe_reg_data)) ||
1419 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1420 (miocpullup(pMblk, sizeof(struct bnxe_reg_data)) < 0))
1421 {
1422 miocnak(pQ, pMblk, 0, EINVAL);
1423 break;
1424 }
1425
1426 if (!BnxeReadPciCfg(pUM, (struct bnxe_reg_data *)pMblk->b_cont->b_rptr))
1427 {
1428 miocnak(pQ, pMblk, 0, EINVAL);
1429 }
1430 else
1431 {
1432 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1433 }
1434
1435 break;
1436
1437 case GIOCBNXESTATS:
1438
1439 /* min size = sizeof(op) in b10_stats_show_data_t */
1440 if ((pIoctl->ioc_count < sizeof(u32_t)) ||
1441 (pMblk->b_cont == NULL) || (pMblk->b_cont->b_rptr == NULL) ||
1442 (miocpullup(pMblk, pIoctl->ioc_count) < 0))
1443 {
1444 miocnak(pQ, pMblk, 0, EINVAL);
1445 break;
1446 }
1447
1448 if (!BnxeStatsShow(pUM,
1449 (b10_stats_show_data_t *)pMblk->b_cont->b_rptr,
1450 pIoctl->ioc_count))
1451 {
1452 miocnak(pQ, pMblk, 0, EINVAL);
1453 }
1454 else
1455 {
1456 miocack(pQ, pMblk, pIoctl->ioc_count, 0);
1457 }
1458
1459 break;
1460
1461 default:
1462
1463 miocnak(pQ, pMblk, 0, EINVAL);
1464 break;
1465 }
1466
1467 BNXE_LOCK_EXIT_GLD(pUM);
1468 }
1469
1470
1471 #ifdef BNXE_RINGS
1472
1473 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
BnxeRxRingPoll(void * ringHandle,int numBytes,int numPkts)1474 static mblk_t * BnxeRxRingPoll(void * ringHandle,
1475 int numBytes,
1476 int numPkts)
1477 #else
1478 static mblk_t * BnxeRxRingPoll(void * ringHandle,
1479 int numBytes)
1480 #endif
1481 {
1482 RxQueue * pRxQ = (RxQueue *)ringHandle;
1483 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1484 u32_t idx = pRxQ->idx;
1485 mblk_t * pMblk = NULL;
1486 boolean_t pktsRxed = 0;
1487 boolean_t pktsTxed = 0;
1488
1489 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1490 _NOTE(ARGUNUSED(numPkts))
1491 #endif
1492
1493 if (numBytes <= 0)
1494 {
1495 return NULL;
1496 }
1497
1498 if (pRxQ->inPollMode == B_FALSE)
1499 {
1500 BnxeLogWarn(pUM, "Polling on ring %d when NOT in poll mode!", idx);
1501 return NULL;
1502 }
1503
1504 BNXE_LOCK_ENTER_INTR(pUM, idx);
1505
1506 pRxQ->pollCnt++;
1507
1508 BnxePollRxRing(pUM, idx, &pktsRxed, &pktsTxed);
1509
1510 if (pktsTxed) BnxeTxRingProcess(pUM, idx);
1511 if (pktsRxed) pMblk = BnxeRxRingProcess(pUM, idx, TRUE, numBytes);
1512
1513 /*
1514 * This is here for the off chance that all rings are in polling
1515 * mode and the default interrupt hasn't fired recently to handle
1516 * the sq.
1517 */
1518 lm_sq_post_pending(&pUM->lm_dev);
1519
1520 BNXE_LOCK_EXIT_INTR(pUM, idx);
1521
1522 return pMblk;
1523 }
1524
1525
BnxeRxRingStart(mac_ring_driver_t ringHandle,uint64_t genNumber)1526 static int BnxeRxRingStart(mac_ring_driver_t ringHandle
1527 #if defined(__S11) || defined(__S12)
1528 , uint64_t genNumber
1529 #endif
1530 )
1531 {
1532 RxQueue * pRxQ = (RxQueue *)ringHandle;
1533 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1534 u32_t idx = pRxQ->idx;
1535
1536 BnxeLogDbg(pUM, "Starting Rx Ring %d", idx);
1537
1538 BNXE_LOCK_ENTER_RX(pUM, idx);
1539 #if defined(__S11) || defined(__S12)
1540 pRxQ->genNumber = genNumber;
1541 #endif
1542 pRxQ->inPollMode = B_FALSE;
1543 pRxQ->intrDisableCnt = 0;
1544 pRxQ->intrEnableCnt = 0;
1545 pRxQ->pollCnt = 0;
1546 BNXE_LOCK_EXIT_RX(pUM, idx);
1547
1548 return 0;
1549 }
1550
1551
1552 #if defined(__S11) || defined(__S12)
1553
BnxeRingStat(mac_ring_driver_t ringHandle,uint_t stat,uint64_t * val)1554 static int BnxeRingStat(mac_ring_driver_t ringHandle,
1555 uint_t stat,
1556 uint64_t * val)
1557 {
1558 RxQueue * pRxQ = (RxQueue *)ringHandle;
1559 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1560
1561 switch (stat)
1562 {
1563 case MAC_STAT_OERRORS:
1564 case MAC_STAT_OBYTES:
1565 case MAC_STAT_OPACKETS:
1566 case MAC_STAT_IERRORS:
1567 case MAC_STAT_RBYTES: /* MAC_STAT_IBYTES */
1568 case MAC_STAT_IPACKETS:
1569 default:
1570 return ENOTSUP;
1571 }
1572
1573 return 0;
1574 }
1575
1576 #endif /* __S11 or __S12 */
1577
1578
1579 #if defined(__S11) || defined(__S12)
BnxeRxRingIntrEnable(mac_ring_driver_t ringHandle)1580 static int BnxeRxRingIntrEnable(mac_ring_driver_t ringHandle)
1581 #else
1582 static int BnxeRxRingIntrEnable(mac_intr_handle_t ringHandle)
1583 #endif
1584 {
1585 RxQueue * pRxQ = (RxQueue *)ringHandle;
1586 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1587
1588 BnxeLogDbg(pUM, "Enabling Interrupt for Rx Ring %d", pRxQ->idx);
1589
1590 /* polling not allowed on LM_NON_RSS_SB when overlapped with FCoE */
1591 if ((pRxQ->idx == LM_NON_RSS_SB(&pUM->lm_dev)) &&
1592 CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE) &&
1593 (pUM->rssIntr.intrCount == LM_MAX_RSS_CHAINS(&pUM->lm_dev)))
1594 {
1595 return 0; /* ok, already enabled */
1596 }
1597
1598 BnxeIntrIguSbEnable(pUM, pRxQ->idx, B_FALSE);
1599
1600 return 0;
1601 }
1602
1603
1604 #if defined(__S11) || defined(__S12)
BnxeRxRingIntrDisable(mac_ring_driver_t ringHandle)1605 static int BnxeRxRingIntrDisable(mac_ring_driver_t ringHandle)
1606 #else
1607 static int BnxeRxRingIntrDisable(mac_intr_handle_t ringHandle)
1608 #endif
1609 {
1610 RxQueue * pRxQ = (RxQueue *)ringHandle;
1611 um_device_t * pUM = (um_device_t *)pRxQ->pUM;
1612
1613 BnxeLogDbg(pUM, "Disabling Interrupt for Rx Ring %d", pRxQ->idx);
1614
1615 /* polling not allowed on LM_NON_RSS_SB when overlapped with FCoE */
1616 if ((pRxQ->idx == LM_NON_RSS_SB(&pUM->lm_dev)) &&
1617 CLIENT_BOUND(pUM, LM_CLI_IDX_FCOE) &&
1618 (pUM->rssIntr.intrCount == LM_MAX_RSS_CHAINS(&pUM->lm_dev)))
1619 {
1620 return -1; /* NO, keep enabled! */
1621 }
1622
1623 BnxeIntrIguSbDisable(pUM, pRxQ->idx, B_FALSE);
1624
1625 return 0;
1626 }
1627
1628
1629 /* callback function for MAC layer to register rings */
BnxeFillRing(void * arg,mac_ring_type_t ringType,const int ringGroupIndex,const int ringIndex,mac_ring_info_t * pRingInfo,mac_ring_handle_t ringHandle)1630 static void BnxeFillRing(void * arg,
1631 mac_ring_type_t ringType,
1632 const int ringGroupIndex,
1633 const int ringIndex,
1634 mac_ring_info_t * pRingInfo,
1635 mac_ring_handle_t ringHandle)
1636 {
1637 um_device_t * pUM = (um_device_t *)arg;
1638 RxQueue * pRxQ;
1639 TxQueue * pTxQ;
1640
1641 switch (ringType)
1642 {
1643 case MAC_RING_TYPE_RX:
1644
1645 BnxeLogInfo(pUM, "Initializing Rx Ring %d (Ring Group %d)",
1646 ringIndex, ringGroupIndex);
1647
1648 ASSERT(ringGroupIndex == 0);
1649 ASSERT(ringIndex < pUM->devParams.numRings);
1650
1651 pRxQ = &pUM->rxq[ringIndex];
1652 pRxQ->ringHandle = ringHandle;
1653
1654 pRingInfo->mri_driver = (mac_ring_driver_t)pRxQ;
1655 pRingInfo->mri_start = BnxeRxRingStart;
1656 pRingInfo->mri_stop = NULL;
1657 #if defined(__S11) || defined(__S12)
1658 pRingInfo->mri_stat = BnxeRingStat;
1659 #endif
1660 pRingInfo->mri_poll = BnxeRxRingPoll;
1661
1662 #if !(defined(__S11) || defined(__S12))
1663 pRingInfo->mri_intr.mi_handle = (mac_intr_handle_t)pRxQ;
1664 #endif
1665 pRingInfo->mri_intr.mi_enable = (mac_intr_enable_t)BnxeRxRingIntrEnable;
1666 pRingInfo->mri_intr.mi_disable = (mac_intr_disable_t)BnxeRxRingIntrDisable;
1667
1668 break;
1669
1670 case MAC_RING_TYPE_TX:
1671
1672 BnxeLogInfo(pUM, "Initializing Tx Ring %d (Ring Group %d)",
1673 ringIndex, ringGroupIndex);
1674
1675 ASSERT(ringGroupIndex == 0);
1676 ASSERT(ringIndex < pUM->devParams.numRings);
1677
1678 pTxQ = &pUM->txq[ringIndex];
1679 pTxQ->ringHandle = ringHandle;
1680
1681 pRingInfo->mri_driver = (mac_ring_driver_t)pTxQ;
1682 pRingInfo->mri_start = NULL;
1683 pRingInfo->mri_stop = NULL;
1684 #if defined(__S11) || defined(__S12)
1685 pRingInfo->mri_stat = BnxeRingStat;
1686 #endif
1687 pRingInfo->mri_tx = (mac_ring_send_t)BnxeTxRingSend;
1688
1689 break;
1690
1691 default:
1692 break;
1693 }
1694 }
1695
1696
1697 /* callback function for MAC layer to register groups */
BnxeFillGroup(void * arg,mac_ring_type_t ringType,const int ringGroupIndex,mac_group_info_t * pGroupInfo,mac_group_handle_t groupHandle)1698 static void BnxeFillGroup(void * arg,
1699 mac_ring_type_t ringType,
1700 const int ringGroupIndex,
1701 mac_group_info_t * pGroupInfo,
1702 mac_group_handle_t groupHandle)
1703 {
1704 um_device_t * pUM = (um_device_t *)arg;
1705 RxQueueGroup * pRxQGroup;
1706
1707 switch (ringType)
1708 {
1709 case MAC_RING_TYPE_RX:
1710
1711 BnxeLogInfo(pUM, "Initializing Rx Group %d", ringGroupIndex);
1712
1713 pRxQGroup = &pUM->rxqGroup[ringGroupIndex];
1714 pRxQGroup->groupHandle = groupHandle;
1715
1716 pGroupInfo->mgi_driver = (mac_group_driver_t)pRxQGroup;
1717 pGroupInfo->mgi_start = NULL;
1718 pGroupInfo->mgi_stop = NULL;
1719 pGroupInfo->mgi_addmac = BnxeRxRingGroupAddMac;
1720 pGroupInfo->mgi_remmac = BnxeRxRingGroupRemMac;
1721 pGroupInfo->mgi_count = (pUM->devParams.numRings /
1722 USER_OPTION_RX_RING_GROUPS_DEFAULT);
1723 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1724 pGroupInfo->mgi_flags = MAC_GROUP_DEFAULT;
1725 #endif
1726
1727 break;
1728
1729 case MAC_RING_TYPE_TX:
1730 default:
1731 break;
1732 }
1733 }
1734
1735 #endif /* BNXE_RINGS */
1736
1737
BnxeMacGetCapability(void * pArg,mac_capab_t capability,void * pCapabilityData)1738 static boolean_t BnxeMacGetCapability(void * pArg,
1739 mac_capab_t capability,
1740 void * pCapabilityData)
1741 {
1742 um_device_t * pUM = (um_device_t *)pArg;
1743 mac_capab_lso_t * pCapLSO;
1744 mac_capab_rings_t * pCapRings;
1745
1746 switch (capability)
1747 {
1748 case MAC_CAPAB_HCKSUM:
1749
1750 *((u32_t *)pCapabilityData) = 0;
1751
1752 if (pUM->devParams.enabled_oflds &
1753 (LM_OFFLOAD_TX_IP_CKSUM | LM_OFFLOAD_RX_IP_CKSUM))
1754 {
1755 *((u32_t *)pCapabilityData) |= HCKSUM_IPHDRCKSUM;
1756 }
1757
1758 if (pUM->devParams.enabled_oflds &
1759 (LM_OFFLOAD_TX_TCP_CKSUM | LM_OFFLOAD_TX_UDP_CKSUM |
1760 LM_OFFLOAD_RX_TCP_CKSUM | LM_OFFLOAD_RX_UDP_CKSUM))
1761 {
1762 *((u32_t *)pCapabilityData) |= HCKSUM_INET_PARTIAL;
1763 }
1764
1765 break;
1766
1767 case MAC_CAPAB_LSO:
1768
1769 pCapLSO = (mac_capab_lso_t *)pCapabilityData;
1770
1771 if (pUM->devParams.lsoEnable)
1772 {
1773 pCapLSO->lso_flags = LSO_TX_BASIC_TCP_IPV4;
1774 pCapLSO->lso_basic_tcp_ipv4.lso_max = BNXE_LSO_MAXLEN;
1775 break;
1776 }
1777
1778 return B_FALSE;
1779
1780 #ifdef BNXE_RINGS
1781
1782 case MAC_CAPAB_RINGS:
1783
1784 if (!pUM->devParams.numRings)
1785 {
1786 return B_FALSE;
1787 }
1788
1789 pCapRings = (mac_capab_rings_t *)pCapabilityData;
1790
1791 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1792 pCapRings->mr_version = MAC_RINGS_VERSION_1;
1793 pCapRings->mr_flags = MAC_RINGS_FLAGS_NONE;
1794 #endif
1795 pCapRings->mr_group_type = MAC_GROUP_TYPE_STATIC;
1796 pCapRings->mr_rnum = pUM->devParams.numRings;
1797 pCapRings->mr_rget = BnxeFillRing;
1798 pCapRings->mr_gaddring = NULL;
1799 pCapRings->mr_gremring = NULL;
1800 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1801 pCapRings->mr_ggetringtc = NULL;
1802 #endif
1803
1804 switch (pCapRings->mr_type)
1805 {
1806 case MAC_RING_TYPE_RX:
1807
1808 pCapRings->mr_gnum = USER_OPTION_RX_RING_GROUPS_DEFAULT;
1809 pCapRings->mr_gget = BnxeFillGroup;
1810 break;
1811
1812 case MAC_RING_TYPE_TX:
1813
1814 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
1815 pCapRings->mr_gnum = 1;
1816 #else
1817 pCapRings->mr_gnum = 0;
1818 #endif
1819 pCapRings->mr_gget = NULL;
1820 break;
1821
1822 default:
1823
1824 return B_FALSE;
1825 }
1826
1827 break;
1828
1829 #endif /* BNXE_RINGS */
1830
1831 #if !(defined(__S11) || defined(__S12))
1832
1833 case MAC_CAPAB_POLL:
1834
1835 /*
1836 * There's nothing for us to fill in, simply returning B_TRUE stating
1837 * that we support polling is sufficient.
1838 */
1839 break;
1840
1841 #endif /* not __S11 or __S12 */
1842
1843 #if defined(ILLUMOS)
1844 case MAC_CAPAB_TRANSCEIVER:
1845 return bnxe_fill_transceiver(pUM, pCapabilityData);
1846 #endif
1847
1848 default:
1849
1850 return B_FALSE;
1851 }
1852
1853 return B_TRUE;
1854 }
1855
1856
1857 #ifdef MC_SETPROP
1858
BnxeSetPrivateProperty(um_device_t * pUM,const char * pr_name,uint_t pr_valsize,const void * pr_val)1859 static int BnxeSetPrivateProperty(um_device_t * pUM,
1860 const char * pr_name,
1861 uint_t pr_valsize,
1862 const void * pr_val)
1863 {
1864 int err = 0;
1865 long result;
1866
1867 if (strcmp(pr_name, "_en_2500fdx_cap") == 0)
1868 {
1869 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1870 {
1871 return EINVAL;
1872 }
1873
1874 if ((result > 1) || (result < 0))
1875 {
1876 return EINVAL;
1877 }
1878
1879 pUM->hwinit.lnkcfg.param_2500fdx = (uint32_t)result;
1880 pUM->curcfg.lnkcfg.param_2500fdx = (uint32_t)result;
1881 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1882 }
1883 else if (strcmp(pr_name, "_en_txpause_cap") == 0)
1884 {
1885 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1886 {
1887 return EINVAL;
1888 }
1889
1890 if ((result > 1) || (result < 0))
1891 {
1892 return EINVAL;
1893 }
1894
1895 pUM->hwinit.lnkcfg.param_txpause = (uint32_t)result;
1896 pUM->curcfg.lnkcfg.param_txpause = (uint32_t)result;
1897 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1898 }
1899 else if (strcmp(pr_name, "_en_rxpause_cap") == 0)
1900 {
1901 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1902 {
1903 return EINVAL;
1904 }
1905
1906 if ((result > 1) || (result < 0))
1907 {
1908 return EINVAL;
1909 }
1910
1911 pUM->hwinit.lnkcfg.param_rxpause = (uint32_t)result;
1912 pUM->curcfg.lnkcfg.param_rxpause = (uint32_t)result;
1913 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1914 }
1915 else if (strcmp(pr_name, "_autoneg_flow") == 0)
1916 {
1917 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1918 {
1919 return EINVAL;
1920 }
1921
1922 if ((result > 1) || (result < 0))
1923 {
1924 return EINVAL;
1925 }
1926
1927 pUM->hwinit.flow_autoneg = (uint32_t)result;
1928 pUM->curcfg.flow_autoneg = (uint32_t)result;
1929 if (pUM->plumbed) BnxeUpdatePhy(pUM);
1930 }
1931 else if (strcmp(pr_name, "_checksum") == 0)
1932 {
1933 if (pUM->plumbed)
1934 {
1935 return EBUSY;
1936 }
1937
1938 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1939 {
1940 return EINVAL;
1941 }
1942
1943 switch (result)
1944 {
1945 case USER_OPTION_CKSUM_NONE:
1946
1947 pUM->devParams.enabled_oflds = LM_OFFLOAD_NONE;
1948 break;
1949
1950 case USER_OPTION_CKSUM_L3:
1951
1952 pUM->devParams.enabled_oflds = (LM_OFFLOAD_TX_IP_CKSUM |
1953 LM_OFFLOAD_RX_IP_CKSUM);
1954 break;
1955
1956 case USER_OPTION_CKSUM_L3_L4:
1957
1958 pUM->devParams.enabled_oflds = (LM_OFFLOAD_TX_IP_CKSUM |
1959 LM_OFFLOAD_RX_IP_CKSUM |
1960 LM_OFFLOAD_TX_TCP_CKSUM |
1961 LM_OFFLOAD_RX_TCP_CKSUM |
1962 LM_OFFLOAD_TX_UDP_CKSUM |
1963 LM_OFFLOAD_RX_UDP_CKSUM);
1964 break;
1965
1966 default:
1967
1968 return EINVAL;
1969 }
1970
1971 pUM->devParams.checksum = (uint32_t)result;
1972 }
1973 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
1974 {
1975 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
1976 {
1977 return EINVAL;
1978 }
1979
1980 switch (result)
1981 {
1982 case BNXE_ROUTE_RING_NONE:
1983 case BNXE_ROUTE_RING_TCPUDP:
1984 case BNXE_ROUTE_RING_DEST_MAC:
1985 case BNXE_ROUTE_RING_MSG_PRIO:
1986
1987 break;
1988
1989 default:
1990
1991 return EINVAL;
1992 }
1993
1994 pUM->devParams.routeTxRingPolicy = (uint32_t)result;
1995 }
1996 else if (strcmp(pr_name, "_num_rings") == 0)
1997 {
1998 if (pUM->plumbed)
1999 {
2000 return EBUSY;
2001 }
2002
2003 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2004 {
2005 return EINVAL;
2006 }
2007
2008 if ((result < USER_OPTION_NUM_RINGS_MIN) ||
2009 (result > USER_OPTION_NUM_RINGS_MAX))
2010 {
2011 return EINVAL;
2012 }
2013
2014 pUM->devParams.numRings = (uint32_t)result;
2015 }
2016 else if (strcmp(pr_name, "_rx_descs") == 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_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2029 {
2030 return EINVAL;
2031 }
2032
2033 pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result;
2034 }
2035 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2036 {
2037 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2038 {
2039 return EINVAL;
2040 }
2041
2042 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2043 {
2044 return EINVAL;
2045 }
2046
2047 pUM->devParams.maxRxFree = (uint32_t)result;
2048 }
2049 else if (strcmp(pr_name, "_tx_descs") == 0)
2050 {
2051 if (pUM->plumbed)
2052 {
2053 return EBUSY;
2054 }
2055
2056 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2057 {
2058 return EINVAL;
2059 }
2060
2061 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2062 {
2063 return EINVAL;
2064 }
2065
2066 pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS] = (uint32_t)result;
2067 }
2068 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2069 {
2070 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2071 {
2072 return EINVAL;
2073 }
2074
2075 if ((result < USER_OPTION_BDS_MIN) || (result > USER_OPTION_BDS_MAX))
2076 {
2077 return EINVAL;
2078 }
2079
2080 pUM->devParams.maxTxFree = (uint32_t)result;
2081 }
2082 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2083 {
2084 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2085 {
2086 return EINVAL;
2087 }
2088
2089 pUM->devParams.rxCopyThreshold = (uint32_t)result;
2090 }
2091 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2092 {
2093 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2094 {
2095 return EINVAL;
2096 }
2097
2098 pUM->devParams.txCopyThreshold = (uint32_t)result;
2099 }
2100 else if (strcmp(pr_name, "_interrupt_coalesce") == 0)
2101 {
2102 if (pUM->plumbed)
2103 {
2104 return EBUSY;
2105 }
2106
2107 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2108 {
2109 return EINVAL;
2110 }
2111
2112 if ((result > 1) || (result < 0))
2113 {
2114 return EINVAL;
2115 }
2116
2117 pUM->devParams.intrCoalesce = (uint32_t)result;
2118 }
2119 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0)
2120 {
2121 if (pUM->plumbed)
2122 {
2123 return EBUSY;
2124 }
2125
2126 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2127 {
2128 return EINVAL;
2129 }
2130
2131 if ((result < USER_OPTION_INTR_COALESCE_MIN) ||
2132 (result < USER_OPTION_INTR_COALESCE_MAX))
2133 {
2134 return EINVAL;
2135 }
2136
2137 pUM->devParams.intrRxPerSec = (uint32_t)(1000000 / result);
2138 }
2139 else if (strcmp(pr_name, "_tx_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.intrTxPerSec = (uint32_t)(1000000 / result);
2158 }
2159 else if (strcmp(pr_name, "_disable_msix") == 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 > 1) || (result < 0))
2172 {
2173 return EINVAL;
2174 }
2175
2176 pUM->devParams.disableMsix = (uint32_t)result;
2177 }
2178 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0)
2179 {
2180 if (pUM->plumbed)
2181 {
2182 return EBUSY;
2183 }
2184
2185 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2186 {
2187 return EINVAL;
2188 }
2189
2190 if ((result > 1) || (result < 0))
2191 {
2192 return EINVAL;
2193 }
2194
2195 pUM->devParams.l2_fw_flow_ctrl = (uint32_t)result;
2196 }
2197 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2198 {
2199 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2200 {
2201 return EINVAL;
2202 }
2203
2204 if ((result > 1) || (result < 0))
2205 {
2206 return EINVAL;
2207 }
2208
2209 pUM->devParams.autogreeenEnable = (uint32_t)result;
2210 if (pUM->plumbed) BnxeUpdatePhy(pUM);
2211 }
2212 else if (strcmp(pr_name, "_lso_enable") == 0)
2213 {
2214 if (pUM->plumbed)
2215 {
2216 return EBUSY;
2217 }
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.lsoEnable = (uint32_t)result;
2230 }
2231 else if (strcmp(pr_name, "_log_enable") == 0)
2232 {
2233 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2234 {
2235 return EINVAL;
2236 }
2237
2238 if ((result > 1) || (result < 0))
2239 {
2240 return EINVAL;
2241 }
2242
2243 pUM->devParams.logEnable = (uint32_t)result;
2244 }
2245 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2246 {
2247 if (ddi_strtol(pr_val, (char **)NULL, 0, &result))
2248 {
2249 return EINVAL;
2250 }
2251
2252 if ((result > 1) || (result < 0))
2253 {
2254 return EINVAL;
2255 }
2256
2257 pUM->devParams.fcoeEnable = (uint32_t)result;
2258
2259 if (BNXE_FCOE(pUM))
2260 {
2261 BnxeFcoeStartStop(pUM);
2262 }
2263 }
2264 else
2265 {
2266 err = ENOTSUP;
2267 }
2268
2269 return err;
2270 }
2271
2272
BnxeMacSetProperty(void * barg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,const void * pr_val)2273 static int BnxeMacSetProperty(void * barg,
2274 const char * pr_name,
2275 mac_prop_id_t pr_num,
2276 uint_t pr_valsize,
2277 const void * pr_val)
2278 {
2279 um_device_t * pUM = barg;
2280 boolean_t reprogram = B_FALSE;
2281 boolean_t rxpause;
2282 boolean_t txpause;
2283 uint32_t mtu;
2284 link_flowctrl_t fl;
2285 int err = 0;
2286
2287 BNXE_LOCK_ENTER_GLD(pUM);
2288
2289 switch (pr_num)
2290 {
2291 /* read-only props */
2292 case MAC_PROP_STATUS:
2293 case MAC_PROP_SPEED:
2294 case MAC_PROP_DUPLEX:
2295 case MAC_PROP_MEDIA:
2296
2297 case MAC_PROP_ADV_10GFDX_CAP:
2298 case MAC_PROP_ADV_1000FDX_CAP:
2299 case MAC_PROP_ADV_1000HDX_CAP:
2300 case MAC_PROP_ADV_100FDX_CAP:
2301 case MAC_PROP_ADV_100HDX_CAP:
2302 case MAC_PROP_ADV_10FDX_CAP:
2303 case MAC_PROP_ADV_10HDX_CAP:
2304 case MAC_PROP_ADV_100T4_CAP:
2305
2306 case MAC_PROP_EN_1000HDX_CAP:
2307 case MAC_PROP_EN_100T4_CAP:
2308
2309 default:
2310
2311 err = ENOTSUP;
2312 break;
2313
2314 case MAC_PROP_EN_10GFDX_CAP:
2315
2316 pUM->hwinit.lnkcfg.param_10000fdx = *(uint8_t *)pr_val;
2317 pUM->curcfg.lnkcfg.param_10000fdx = *(uint8_t *)pr_val;
2318 reprogram = B_TRUE;
2319 break;
2320
2321 case MAC_PROP_EN_1000FDX_CAP:
2322
2323 pUM->hwinit.lnkcfg.param_1000fdx = *(uint8_t *)pr_val;
2324 pUM->curcfg.lnkcfg.param_1000fdx = *(uint8_t *)pr_val;
2325 reprogram = B_TRUE;
2326 break;
2327
2328 case MAC_PROP_EN_100FDX_CAP:
2329
2330 pUM->hwinit.lnkcfg.param_100fdx = *(uint8_t *)pr_val;
2331 pUM->curcfg.lnkcfg.param_100fdx = *(uint8_t *)pr_val;
2332 reprogram = B_TRUE;
2333 break;
2334
2335 case MAC_PROP_EN_100HDX_CAP:
2336
2337 pUM->hwinit.lnkcfg.param_100hdx = *(uint8_t *)pr_val;
2338 pUM->curcfg.lnkcfg.param_100hdx = *(uint8_t *)pr_val;
2339 reprogram = B_TRUE;
2340 break;
2341
2342 case MAC_PROP_EN_10FDX_CAP:
2343
2344 pUM->hwinit.lnkcfg.param_10fdx = *(uint8_t *)pr_val;
2345 pUM->curcfg.lnkcfg.param_10fdx = *(uint8_t *)pr_val;
2346 reprogram = B_TRUE;
2347 break;
2348
2349 case MAC_PROP_EN_10HDX_CAP:
2350
2351 pUM->hwinit.lnkcfg.param_10hdx = *(uint8_t *)pr_val;
2352 pUM->curcfg.lnkcfg.param_10hdx = *(uint8_t *)pr_val;
2353 reprogram = B_TRUE;
2354 break;
2355
2356 case MAC_PROP_AUTONEG:
2357
2358 pUM->hwinit.lnkcfg.link_autoneg = *(uint8_t *)pr_val;
2359 pUM->curcfg.lnkcfg.link_autoneg = *(uint8_t *)pr_val;
2360 reprogram = B_TRUE;
2361 break;
2362
2363 case MAC_PROP_FLOWCTRL:
2364
2365 bcopy(pr_val, &fl, sizeof(fl));
2366
2367 switch (fl)
2368 {
2369 case LINK_FLOWCTRL_NONE:
2370
2371 rxpause = B_FALSE;
2372 txpause = B_FALSE;
2373 break;
2374
2375 case LINK_FLOWCTRL_RX:
2376
2377 rxpause = B_TRUE;
2378 txpause = B_FALSE;
2379 break;
2380
2381 case LINK_FLOWCTRL_TX:
2382
2383 rxpause = B_FALSE;
2384 txpause = B_TRUE;
2385 break;
2386
2387 case LINK_FLOWCTRL_BI:
2388
2389 rxpause = B_TRUE;
2390 txpause = B_TRUE;
2391 break;
2392
2393 default:
2394
2395 err = ENOTSUP;
2396 break;
2397 }
2398
2399 if (err == 0)
2400 {
2401 pUM->hwinit.lnkcfg.param_rxpause = rxpause;
2402 pUM->hwinit.lnkcfg.param_txpause = txpause;
2403 pUM->curcfg.lnkcfg.param_rxpause = rxpause;
2404 pUM->curcfg.lnkcfg.param_txpause = txpause;
2405 reprogram = B_TRUE;
2406 }
2407
2408 break;
2409
2410 case MAC_PROP_MTU:
2411
2412 if (pUM->plumbed)
2413 {
2414 err = EBUSY;
2415 break;
2416 }
2417
2418 bcopy(pr_val, &mtu, sizeof (mtu));
2419
2420 if ((mtu < USER_OPTION_MTU_MIN) || (mtu > USER_OPTION_MTU_MAX))
2421 {
2422 err = EINVAL;
2423 break;
2424 }
2425
2426 if (pUM->devParams.mtu[LM_CLI_IDX_NDIS] == mtu)
2427 {
2428 break;
2429 }
2430
2431 pUM->devParams.mtu[LM_CLI_IDX_NDIS] = mtu;
2432 err = mac_maxsdu_update(pUM->pMac, pUM->devParams.mtu[LM_CLI_IDX_NDIS]);
2433 pUM->lm_dev.params.mtu[LM_CLI_IDX_NDIS] = pUM->devParams.mtu[LM_CLI_IDX_NDIS];
2434 break;
2435
2436 case MAC_PROP_PRIVATE:
2437
2438 err = BnxeSetPrivateProperty(pUM, pr_name, pr_valsize, pr_val);
2439 break;
2440 }
2441
2442 if (!err && reprogram)
2443 {
2444 if (pUM->plumbed) BnxeUpdatePhy(pUM);
2445 }
2446
2447 BNXE_LOCK_EXIT_GLD(pUM);
2448 return err;
2449 }
2450
2451 #endif /* MC_SETPROP */
2452
2453
2454 #ifdef MC_GETPROP
2455
BnxeGetPrivateProperty(um_device_t * pUM,const char * pr_name,uint_t pr_valsize,void * pr_val)2456 static int BnxeGetPrivateProperty(um_device_t * pUM,
2457 const char * pr_name,
2458 uint_t pr_valsize,
2459 void * pr_val)
2460 {
2461 BnxeLinkCfg * lnk_cfg = &pUM->curcfg.lnkcfg;
2462 BnxeLinkCfg * hw_cfg = &pUM->hwinit.lnkcfg;
2463 int value;
2464 int err = 0;
2465
2466 if (strcmp(pr_name, "_adv_2500fdx_cap") == 0)
2467 {
2468 value = lnk_cfg->param_2500fdx;
2469 }
2470 else if (strcmp(pr_name, "_en_2500fdx_cap") == 0)
2471 {
2472 value = hw_cfg->param_2500fdx;
2473 }
2474 else if (strcmp(pr_name, "_adv_txpause_cap") == 0)
2475 {
2476 value = lnk_cfg->param_txpause;
2477 }
2478 else if (strcmp(pr_name, "_en_txpause_cap") == 0)
2479 {
2480 value = hw_cfg->param_txpause;
2481 }
2482 else if (strcmp(pr_name, "_txpause") == 0)
2483 {
2484 value = pUM->props.link_txpause;
2485 }
2486 else if (strcmp(pr_name, "_adv_rxpause_cap") == 0)
2487 {
2488 value = lnk_cfg->param_rxpause;
2489 }
2490 else if (strcmp(pr_name, "_en_rxpause_cap") == 0)
2491 {
2492 value = hw_cfg->param_rxpause;
2493 }
2494 else if (strcmp(pr_name, "_rxpause") == 0)
2495 {
2496 value = pUM->props.link_rxpause;
2497 }
2498 else if (strcmp(pr_name, "_autoneg_flow") == 0)
2499 {
2500 value = pUM->hwinit.flow_autoneg;
2501 }
2502 else if (strcmp(pr_name, "_checksum") == 0)
2503 {
2504 value = pUM->devParams.checksum;
2505 }
2506 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
2507 {
2508 value = pUM->devParams.routeTxRingPolicy;
2509 }
2510 else if (strcmp(pr_name, "_num_rings") == 0)
2511 {
2512 value = pUM->devParams.numRings;
2513 }
2514 else if (strcmp(pr_name, "_rx_descs") == 0)
2515 {
2516 value = pUM->devParams.numRxDesc[LM_CLI_IDX_NDIS];
2517 }
2518 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2519 {
2520 value = pUM->devParams.maxRxFree;
2521 }
2522 else if (strcmp(pr_name, "_tx_descs") == 0)
2523 {
2524 value = pUM->devParams.numTxDesc[LM_CLI_IDX_NDIS];
2525 }
2526 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2527 {
2528 value = pUM->devParams.maxTxFree;
2529 }
2530 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2531 {
2532 value = pUM->devParams.rxCopyThreshold;
2533 }
2534 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2535 {
2536 value = pUM->devParams.txCopyThreshold;
2537 }
2538 else if (strcmp(pr_name, "_interrupt_coalesce") == 0)
2539 {
2540 value = pUM->devParams.intrCoalesce;
2541 }
2542 else if (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0)
2543 {
2544 value = pUM->devParams.intrRxPerSec;
2545 }
2546 else if (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0)
2547 {
2548 value = pUM->devParams.intrTxPerSec;
2549 }
2550 else if (strcmp(pr_name, "_disable_msix") == 0)
2551 {
2552 value = pUM->devParams.disableMsix;
2553 }
2554 else if (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0)
2555 {
2556 value = pUM->devParams.l2_fw_flow_ctrl;
2557 }
2558 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2559 {
2560 value = pUM->devParams.autogreeenEnable;
2561 }
2562 else if (strcmp(pr_name, "_lso_enable") == 0)
2563 {
2564 value = pUM->devParams.lsoEnable;
2565 }
2566 else if (strcmp(pr_name, "_log_enable") == 0)
2567 {
2568 value = pUM->devParams.logEnable;
2569 }
2570 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2571 {
2572 value = pUM->devParams.fcoeEnable;
2573 }
2574 else
2575 {
2576 err = ENOTSUP;
2577 }
2578
2579 if (!err)
2580 {
2581 (void)snprintf(pr_val, pr_valsize, "%d", value);
2582 }
2583
2584 return err;
2585 }
2586
2587
BnxeMacGetProperty(void * barg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,void * pr_val)2588 static int BnxeMacGetProperty(void * barg,
2589 const char * pr_name,
2590 mac_prop_id_t pr_num,
2591 uint_t pr_valsize,
2592 void * pr_val)
2593 {
2594 um_device_t * pUM = barg;
2595 link_flowctrl_t link_flowctrl;
2596 link_state_t link_state;
2597 link_duplex_t link_duplex;
2598 uint64_t link_speed;
2599 mac_ether_media_t link_media;
2600 BnxeLinkCfg * lnk_cfg = &pUM->curcfg.lnkcfg;
2601 BnxeLinkCfg * hw_cfg = &pUM->hwinit.lnkcfg;
2602
2603 switch (pr_num)
2604 {
2605 case MAC_PROP_MTU:
2606
2607 ASSERT(pr_valsize >= sizeof(u32_t));
2608
2609 bcopy(&pUM->devParams.mtu[LM_CLI_IDX_NDIS], pr_val, sizeof(u32_t));
2610 break;
2611
2612 case MAC_PROP_DUPLEX:
2613
2614 ASSERT(pr_valsize >= sizeof(link_duplex_t));
2615
2616 link_duplex = pUM->props.link_duplex ?
2617 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
2618 bcopy(&link_duplex, pr_val, sizeof(link_duplex_t));
2619 break;
2620
2621 case MAC_PROP_SPEED:
2622
2623 ASSERT(pr_valsize >= sizeof(link_speed));
2624
2625 link_speed = (pUM->props.link_speed * 1000000ULL);
2626 bcopy(&link_speed, pr_val, sizeof(link_speed));
2627 break;
2628
2629 case MAC_PROP_STATUS:
2630
2631 ASSERT(pr_valsize >= sizeof(link_state_t));
2632
2633 link_state = pUM->props.link_speed ?
2634 LINK_STATE_UP : LINK_STATE_DOWN;
2635 bcopy(&link_state, pr_val, sizeof(link_state_t));
2636 break;
2637
2638 case MAC_PROP_MEDIA:
2639 ASSERT(pr_valsize >= sizeof(mac_ether_media_t));
2640
2641 link_media = bnxe_phy_to_media(pUM);
2642 bcopy(&link_media, pr_val, sizeof(mac_ether_media_t));
2643 break;
2644
2645 case MAC_PROP_AUTONEG:
2646
2647 *(uint8_t *)pr_val = lnk_cfg->link_autoneg;
2648 break;
2649
2650 case MAC_PROP_FLOWCTRL:
2651
2652 ASSERT(pr_valsize >= sizeof(link_flowctrl_t));
2653
2654 if (!lnk_cfg->param_rxpause && !lnk_cfg->param_txpause)
2655 {
2656 link_flowctrl = LINK_FLOWCTRL_NONE;
2657 }
2658 if (lnk_cfg->param_rxpause && !lnk_cfg->param_txpause)
2659 {
2660 link_flowctrl = LINK_FLOWCTRL_RX;
2661 }
2662 if (!lnk_cfg->param_rxpause && lnk_cfg->param_txpause)
2663 {
2664 link_flowctrl = LINK_FLOWCTRL_TX;
2665 }
2666 if (lnk_cfg->param_rxpause && lnk_cfg->param_txpause)
2667 {
2668 link_flowctrl = LINK_FLOWCTRL_BI;
2669 }
2670
2671 bcopy(&link_flowctrl, pr_val, sizeof(link_flowctrl_t));
2672 break;
2673
2674 case MAC_PROP_ADV_10GFDX_CAP:
2675
2676 *(uint8_t *)pr_val = lnk_cfg->param_10000fdx;
2677 break;
2678
2679 case MAC_PROP_EN_10GFDX_CAP:
2680
2681 *(uint8_t *)pr_val = hw_cfg->param_10000fdx;
2682 break;
2683
2684 case MAC_PROP_ADV_1000FDX_CAP:
2685
2686 *(uint8_t *)pr_val = lnk_cfg->param_1000fdx;
2687 break;
2688
2689 case MAC_PROP_EN_1000FDX_CAP:
2690
2691 *(uint8_t *)pr_val = hw_cfg->param_1000fdx;
2692 break;
2693
2694 case MAC_PROP_ADV_1000HDX_CAP:
2695 case MAC_PROP_EN_1000HDX_CAP:
2696
2697 *(uint8_t *)pr_val = 0;
2698 break;
2699
2700 case MAC_PROP_ADV_100FDX_CAP:
2701
2702 *(uint8_t *)pr_val = lnk_cfg->param_100fdx;
2703 break;
2704
2705 case MAC_PROP_EN_100FDX_CAP:
2706
2707 *(uint8_t *)pr_val = hw_cfg->param_100fdx;
2708 break;
2709
2710 case MAC_PROP_ADV_100HDX_CAP:
2711
2712 *(uint8_t *)pr_val = lnk_cfg->param_100hdx;
2713 break;
2714
2715 case MAC_PROP_EN_100HDX_CAP:
2716
2717 *(uint8_t *)pr_val = hw_cfg->param_100hdx;
2718 break;
2719
2720 case MAC_PROP_ADV_100T4_CAP:
2721 case MAC_PROP_EN_100T4_CAP:
2722
2723 *(uint8_t *)pr_val = 0;
2724 break;
2725
2726 case MAC_PROP_ADV_10FDX_CAP:
2727
2728 *(uint8_t *)pr_val = lnk_cfg->param_10fdx;
2729 break;
2730
2731 case MAC_PROP_EN_10FDX_CAP:
2732
2733 *(uint8_t *)pr_val = hw_cfg->param_10fdx;
2734 break;
2735
2736 case MAC_PROP_ADV_10HDX_CAP:
2737
2738 *(uint8_t *)pr_val = lnk_cfg->param_10hdx;
2739 break;
2740
2741 case MAC_PROP_EN_10HDX_CAP:
2742
2743 *(uint8_t *)pr_val = hw_cfg->param_10hdx;
2744 break;
2745
2746 case MAC_PROP_PRIVATE:
2747
2748 return BnxeGetPrivateProperty(pUM,
2749 pr_name,
2750 pr_valsize,
2751 pr_val);
2752
2753 default:
2754
2755 return ENOTSUP;
2756 }
2757
2758 return 0;
2759 }
2760
2761 #endif /* MC_GETPROP */
2762
2763
2764 #ifdef MC_PROPINFO
2765
BnxeMacPrivatePropertyInfo(um_device_t * pUM,const char * pr_name,mac_prop_info_handle_t prh)2766 static void BnxeMacPrivatePropertyInfo(um_device_t * pUM,
2767 const char * pr_name,
2768 mac_prop_info_handle_t prh)
2769 {
2770 char valstr[64];
2771 BnxeLinkCfg * default_cfg = &bnxeLinkCfg;
2772 int default_val;
2773
2774 bzero(valstr, sizeof (valstr));
2775
2776 if ((strcmp(pr_name, "_adv_2500fdx_cap") == 0) ||
2777 (strcmp(pr_name, "_adv_txpause_cap") == 0) ||
2778 (strcmp(pr_name, "_txpause") == 0) ||
2779 (strcmp(pr_name, "_adv_rxpause_cap") == 0) ||
2780 (strcmp(pr_name, "_rxpause") == 0) ||
2781 (strcmp(pr_name, "_checksum") == 0) ||
2782 (strcmp(pr_name, "_num_rings") == 0) ||
2783 (strcmp(pr_name, "_rx_descs") == 0) ||
2784 (strcmp(pr_name, "_tx_descs") == 0) ||
2785 (strcmp(pr_name, "_interrupt_coalesce") == 0) ||
2786 (strcmp(pr_name, "_rx_interrupt_coalesce_usec") == 0) ||
2787 (strcmp(pr_name, "_tx_interrupt_coalesce_usec") == 0) ||
2788 (strcmp(pr_name, "_disable_msix") == 0) ||
2789 (strcmp(pr_name, "_l2_fw_flow_ctrl") == 0) ||
2790 (strcmp(pr_name, "_lso_enable") == 0))
2791 {
2792 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2793 return;
2794 }
2795
2796 if (strcmp(pr_name, "_autoneg_flow") == 0)
2797 {
2798 default_val = B_TRUE;
2799 }
2800 else if (strcmp(pr_name, "_tx_ring_policy") == 0)
2801 {
2802 default_val = BNXE_ROUTE_RING_TCPUDP;
2803 }
2804 else if (strcmp(pr_name, "_rx_free_reclaim") == 0)
2805 {
2806 default_val = USER_OPTION_RX_MAX_FREE_DEFAULT;
2807 }
2808 else if (strcmp(pr_name, "_tx_free_reclaim") == 0)
2809 {
2810 default_val = USER_OPTION_TX_MAX_FREE_DEFAULT;
2811 }
2812 else if (strcmp(pr_name, "_rx_copy_threshold") == 0)
2813 {
2814 default_val = USER_OPTION_RX_DCOPY_THRESH_DEFAULT;
2815 }
2816 else if (strcmp(pr_name, "_tx_copy_threshold") == 0)
2817 {
2818 default_val = USER_OPTION_TX_DCOPY_THRESH_DEFAULT;
2819 }
2820 else if (strcmp(pr_name, "_autogreeen_enable") == 0)
2821 {
2822 default_val = B_TRUE;
2823 }
2824 else if (strcmp(pr_name, "_log_enable") == 0)
2825 {
2826 default_val = B_TRUE;
2827 }
2828 else if (strcmp(pr_name, "_fcoe_enable") == 0)
2829 {
2830 default_val = B_TRUE;
2831 }
2832 else
2833 {
2834 return;
2835 }
2836
2837 snprintf(valstr, sizeof (valstr), "%d", default_val);
2838 mac_prop_info_set_default_str(prh, valstr);
2839 }
2840
2841
BnxeMacPropertyInfo(void * barg,const char * pr_name,mac_prop_id_t pr_num,mac_prop_info_handle_t prh)2842 static void BnxeMacPropertyInfo(void * barg,
2843 const char * pr_name,
2844 mac_prop_id_t pr_num,
2845 mac_prop_info_handle_t prh)
2846 {
2847 um_device_t * pUM = barg;
2848 link_flowctrl_t link_flowctrl;
2849 BnxeLinkCfg * default_cfg = &bnxeLinkCfg;
2850
2851 switch (pr_num)
2852 {
2853 case MAC_PROP_STATUS:
2854 case MAC_PROP_SPEED:
2855 case MAC_PROP_DUPLEX:
2856
2857 case MAC_PROP_ADV_10GFDX_CAP:
2858 case MAC_PROP_ADV_1000FDX_CAP:
2859 case MAC_PROP_ADV_1000HDX_CAP:
2860 case MAC_PROP_ADV_100FDX_CAP:
2861 case MAC_PROP_ADV_100HDX_CAP:
2862 case MAC_PROP_ADV_100T4_CAP:
2863 case MAC_PROP_ADV_10FDX_CAP:
2864 case MAC_PROP_ADV_10HDX_CAP:
2865
2866 case MAC_PROP_EN_1000HDX_CAP:
2867 case MAC_PROP_EN_100T4_CAP:
2868
2869 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2870 break;
2871
2872 case MAC_PROP_EN_10GFDX_CAP:
2873
2874 mac_prop_info_set_default_uint8(prh, default_cfg->param_10000fdx);
2875 break;
2876
2877 case MAC_PROP_EN_1000FDX_CAP:
2878
2879 mac_prop_info_set_default_uint8(prh, default_cfg->param_1000fdx);
2880 break;
2881
2882 case MAC_PROP_EN_100FDX_CAP:
2883
2884 mac_prop_info_set_default_uint8(prh, default_cfg->param_100fdx);
2885 break;
2886
2887 case MAC_PROP_EN_100HDX_CAP:
2888
2889 mac_prop_info_set_default_uint8(prh, default_cfg->param_100hdx);
2890 break;
2891
2892 case MAC_PROP_EN_10FDX_CAP:
2893
2894 mac_prop_info_set_default_uint8(prh, default_cfg->param_10fdx);
2895 break;
2896
2897 case MAC_PROP_EN_10HDX_CAP:
2898
2899 mac_prop_info_set_default_uint8(prh, default_cfg->param_10hdx);
2900 break;
2901
2902 case MAC_PROP_MTU:
2903
2904 mac_prop_info_set_range_uint32(prh,
2905 USER_OPTION_MTU_MIN,
2906 USER_OPTION_MTU_MAX);
2907 break;
2908
2909 case MAC_PROP_AUTONEG:
2910
2911 mac_prop_info_set_default_uint8(prh, default_cfg->link_autoneg);
2912 break;
2913
2914 case MAC_PROP_FLOWCTRL:
2915
2916 if (!default_cfg->param_rxpause && !default_cfg->param_txpause)
2917 {
2918 link_flowctrl = LINK_FLOWCTRL_NONE;
2919 }
2920
2921 if (default_cfg->param_rxpause && !default_cfg->param_txpause)
2922 {
2923 link_flowctrl = LINK_FLOWCTRL_RX;
2924 }
2925
2926 if (!default_cfg->param_rxpause && default_cfg->param_txpause)
2927 {
2928 link_flowctrl = LINK_FLOWCTRL_TX;
2929 }
2930
2931 if (default_cfg->param_rxpause && default_cfg->param_txpause)
2932 {
2933 link_flowctrl = LINK_FLOWCTRL_BI;
2934 }
2935
2936 mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl);
2937 break;
2938
2939 case MAC_PROP_PRIVATE:
2940
2941 BnxeMacPrivatePropertyInfo(pUM, pr_name, prh);
2942 break;
2943 }
2944 }
2945
2946 #endif /* MC_PROPINFO */
2947
2948
2949 static mac_callbacks_t bnxe_callbacks =
2950 {
2951 (
2952 MC_IOCTL
2953 #ifdef MC_RESOURCES
2954 | MC_RESOURCES
2955 #endif
2956 #ifdef MC_SETPROP
2957 | MC_SETPROP
2958 #endif
2959 #ifdef MC_GETPROP
2960 | MC_GETPROP
2961 #endif
2962 #ifdef MC_PROPINFO
2963 | MC_PROPINFO
2964 #endif
2965 | MC_GETCAPAB
2966 ),
2967 BnxeMacStats,
2968 BnxeMacStart,
2969 BnxeMacStop,
2970 BnxeMacPromiscuous,
2971 BnxeMacMulticast,
2972 NULL,
2973 BnxeMacTx,
2974 #ifdef MC_RESOURCES
2975 BnxeMacResources,
2976 #else
2977 NULL,
2978 #endif
2979 BnxeMacIoctl,
2980 BnxeMacGetCapability,
2981 #ifdef MC_OPEN
2982 NULL,
2983 NULL,
2984 #endif
2985 #ifdef MC_SETPROP
2986 BnxeMacSetProperty,
2987 #endif
2988 #ifdef MC_GETPROP
2989 BnxeMacGetProperty,
2990 #endif
2991 #ifdef MC_PROPINFO
2992 BnxeMacPropertyInfo
2993 #endif
2994 };
2995
2996
BnxeGldInit(um_device_t * pUM)2997 boolean_t BnxeGldInit(um_device_t * pUM)
2998 {
2999 mac_register_t * pMac;
3000 int rc;
3001
3002 atomic_swap_32(&pUM->plumbed, B_FALSE);
3003
3004 if ((pMac = mac_alloc(MAC_VERSION)) == NULL)
3005 {
3006 BnxeLogWarn(pUM, "Failed to allocate GLD MAC memory");
3007 return B_FALSE;
3008 }
3009
3010 pMac->m_driver = pUM;
3011 pMac->m_dip = pUM->pDev;
3012 pMac->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
3013 pMac->m_callbacks = &bnxe_callbacks;
3014 pMac->m_min_sdu = 0;
3015 pMac->m_max_sdu = pUM->devParams.mtu[LM_CLI_IDX_NDIS];
3016 pMac->m_src_addr = &(pUM->lm_dev.params.mac_addr[0]);
3017
3018 #ifdef MC_OPEN
3019 pMac->m_margin = VLAN_TAGSZ;
3020 #endif
3021
3022 #ifdef MC_SETPROP
3023 pMac->m_priv_props = bnxeLink_priv_props;
3024 #endif
3025
3026 #if (defined(__S11) || defined(__S12)) && !defined(ILLUMOS)
3027 bnxe_callbacks.mc_unicst =
3028 (!pUM->devParams.numRings) ? BnxeMacUnicast : NULL;
3029 #else
3030 bnxe_callbacks.mc_unicst = BnxeMacUnicast;
3031 #endif
3032
3033 rc = mac_register(pMac, &pUM->pMac);
3034
3035 mac_free(pMac);
3036
3037 if (rc != 0)
3038 {
3039 BnxeLogWarn(pUM, "Failed to register with GLD (%d)", rc);
3040 return B_FALSE;
3041 }
3042
3043 /* Always report the initial link state as unknown. */
3044 mac_link_update(pUM->pMac, LINK_STATE_UNKNOWN);
3045
3046 return B_TRUE;
3047 }
3048
3049
BnxeGldFini(um_device_t * pUM)3050 boolean_t BnxeGldFini(um_device_t * pUM)
3051 {
3052 int cnt;
3053
3054 if (pUM->plumbed)
3055 {
3056 BnxeLogWarn(pUM, "Detaching device from GLD that is started!");
3057 return B_FALSE;
3058 }
3059
3060 /* We must not detach until all packets held by stack are retrieved. */
3061 if (!BnxeWaitForPacketsFromClient(pUM, LM_CLI_IDX_NDIS))
3062 {
3063 return B_FALSE;
3064 }
3065
3066 if (pUM->pMac)
3067 {
3068 if (mac_unregister(pUM->pMac))
3069 {
3070 BnxeLogWarn(pUM, "Failed to unregister with the GLD");
3071 return B_FALSE;
3072 }
3073 }
3074
3075 return B_TRUE;
3076 }
3077
3078
BnxeGldLink(um_device_t * pUM,link_state_t state)3079 void BnxeGldLink(um_device_t * pUM,
3080 link_state_t state)
3081 {
3082 mac_link_update(pUM->pMac, state);
3083 }
3084
3085