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