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 2008 NetXen, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <sys/types.h>
28 #include <sys/conf.h>
29 #include <sys/debug.h>
30 #include <sys/stropts.h>
31 #include <sys/stream.h>
32 #include <sys/strlog.h>
33 #include <sys/kmem.h>
34 #include <sys/stat.h>
35 #include <sys/kstat.h>
36 #include <sys/vtrace.h>
37 #include <sys/dlpi.h>
38 #include <sys/strsun.h>
39 #include <sys/ethernet.h>
40 #include <sys/modctl.h>
41 #include <sys/errno.h>
42 #include <sys/dditypes.h>
43 #include <sys/ddi.h>
44 #include <sys/sunddi.h>
45 #include <sys/sysmacros.h>
46
47 #include <sys/pci.h>
48
49 #include "unm_inc.h"
50 #include "unm_nic.h"
51
52 static long phy_lock_timeout = 100000000;
53
phy_lock(struct unm_adapter_s * adapter)54 static int phy_lock(struct unm_adapter_s *adapter)
55 {
56 u32 done = 0;
57 int timeout = 0;
58
59 while (!done) {
60 /* acquire semaphore3 from PCI HW block */
61 adapter->unm_nic_pci_read_immediate(adapter,
62 UNM_PCIE_REG(PCIE_SEM3_LOCK), &done);
63 if (done == 1)
64 break;
65 if (timeout >= phy_lock_timeout)
66 return (-1);
67 timeout++;
68 }
69
70 adapter->unm_crb_writelit_adapter(adapter, UNM_PHY_LOCK_ID,
71 PHY_LOCK_DRIVER);
72 return (0);
73 }
74
75 static void
phy_unlock(struct unm_adapter_s * adapter)76 phy_unlock(struct unm_adapter_s *adapter)
77 {
78 u32 val;
79
80 /* release semaphore3 */
81 adapter->unm_nic_pci_read_immediate(adapter,
82 UNM_PCIE_REG(PCIE_SEM3_UNLOCK), &val);
83 }
84
85 /*
86 * unm_niu_gbe_phy_read - read a register from the GbE PHY via
87 * mii management interface.
88 *
89 * Note: The MII management interface goes through port 0.
90 * Individual phys are addressed as follows:
91 * [15:8] phy id
92 * [7:0] register number
93 *
94 * Returns: 0 success
95 * -1 error
96 *
97 */
98 long
unm_niu_gbe_phy_read(struct unm_adapter_s * adapter,long reg,unm_crbword_t * readval)99 unm_niu_gbe_phy_read(struct unm_adapter_s *adapter, long reg,
100 unm_crbword_t *readval)
101 {
102 long phy = adapter->physical_port;
103 unm_niu_gb_mii_mgmt_address_t address;
104 unm_niu_gb_mii_mgmt_command_t command;
105 unm_niu_gb_mii_mgmt_indicators_t status;
106
107 long timeout = 0;
108 long result = 0;
109 long restore = 0;
110 unm_niu_gb_mac_config_0_t mac_cfg0;
111
112 if (phy_lock(adapter) != 0)
113 return (-1);
114
115 /*
116 * MII mgmt all goes through port 0 MAC interface, so it cannot be
117 * in reset
118 */
119 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(0),
120 &mac_cfg0, 4);
121 if (mac_cfg0.soft_reset) {
122 unm_niu_gb_mac_config_0_t temp;
123 *(unm_crbword_t *)&temp = 0;
124 temp.tx_reset_pb = 1;
125 temp.rx_reset_pb = 1;
126 temp.tx_reset_mac = 1;
127 temp.rx_reset_mac = 1;
128 adapter->unm_nic_hw_write_wx(adapter,
129 UNM_NIU_GB_MAC_CONFIG_0(0), &temp, 4);
130 restore = 1;
131 }
132
133 *(unm_crbword_t *)&address = 0;
134 address.reg_addr = (unm_crbword_t)reg;
135 address.phy_addr = (unm_crbword_t)phy;
136 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_ADDR(0),
137 &address, 4);
138
139 *(unm_crbword_t *)&command = 0; /* turn off any prior activity */
140 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_COMMAND(0),
141 &command, 4);
142
143 /* send read command */
144 command.read_cycle = 1;
145 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_COMMAND(0),
146 &command, 4);
147
148 *(unm_crbword_t *)&status = 0;
149 do {
150 adapter->unm_nic_hw_read_wx(adapter,
151 UNM_NIU_GB_MII_MGMT_INDICATE(0), &status, 4);
152 timeout++;
153 } while ((status.busy || status.notvalid) &&
154 (timeout++ < UNM_NIU_PHY_WAITMAX));
155
156 if (timeout < UNM_NIU_PHY_WAITMAX) {
157 adapter->unm_nic_hw_read_wx(adapter,
158 UNM_NIU_GB_MII_MGMT_STATUS(0), readval, 4);
159 result = 0;
160 } else
161 result = -1;
162
163 if (restore)
164 adapter->unm_nic_hw_write_wx(adapter,
165 UNM_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4);
166
167 phy_unlock(adapter);
168
169 return (result);
170 }
171
172 /*
173 * Return the current station MAC address.
174 * Note that the passed-in value must already be in network byte order.
175 */
176 int
unm_niu_macaddr_get(struct unm_adapter_s * adapter,unsigned char * addr)177 unm_niu_macaddr_get(struct unm_adapter_s *adapter, unsigned char *addr)
178 {
179 __uint64_t result;
180 int phy = adapter->physical_port;
181
182 if (addr == NULL)
183 return (-1);
184 if ((phy < 0) || (phy > 3))
185 return (-1);
186
187 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
188 if (adapter->curr_window != 0) {
189 adapter->unm_nic_pci_change_crbwindow(adapter, 0);
190 }
191
192 result = UNM_NIC_PCI_READ_32((void *)pci_base_offset(adapter,
193 UNM_NIU_GB_STATION_ADDR_1(phy))) >> 16;
194 result |= ((uint64_t)UNM_NIC_PCI_READ_32((void *)pci_base_offset(
195 adapter, UNM_NIU_GB_STATION_ADDR_0(phy)))) << 16;
196
197 (void) memcpy(addr, &result, sizeof (unm_ethernet_macaddr_t));
198
199 adapter->unm_nic_pci_change_crbwindow(adapter, 1);
200
201 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
202
203 return (0);
204 }
205
206 /*
207 * Set the station MAC address.
208 * Note that the passed-in value must already be in network byte order.
209 */
210 int
unm_niu_macaddr_set(struct unm_adapter_s * adapter,unm_ethernet_macaddr_t addr)211 unm_niu_macaddr_set(struct unm_adapter_s *adapter, unm_ethernet_macaddr_t addr)
212 {
213 unm_crbword_t temp = 0;
214 int phy = adapter->physical_port;
215
216 if ((phy < 0) || (phy > 3))
217 return (-1);
218
219 (void) memcpy(&temp, addr, 2);
220 temp <<= 16;
221 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_STATION_ADDR_1(phy),
222 &temp, 4);
223 temp = 0;
224 (void) memcpy(&temp, ((__uint8_t *)addr)+2, sizeof (unm_crbword_t));
225 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_STATION_ADDR_0(phy),
226 &temp, 4);
227 return (0);
228 }
229
230 /* Enable a GbE interface */
231 native_t
unm_niu_enable_gbe_port(struct unm_adapter_s * adapter)232 unm_niu_enable_gbe_port(struct unm_adapter_s *adapter)
233 {
234 unm_niu_gb_mac_config_0_t mac_cfg0;
235 unm_niu_gb_mac_config_1_t mac_cfg1;
236 unm_niu_gb_mii_mgmt_config_t mii_cfg;
237 native_t port = adapter->physical_port;
238 int zero = 0;
239 int one = 1;
240 u32 port_mode = 0;
241
242 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) {
243 return (-1);
244 }
245
246 if (adapter->link_speed != MBPS_10 &&
247 adapter->link_speed != MBPS_100 &&
248 adapter->link_speed != MBPS_1000) {
249
250 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
251 /*
252 * Do NOT fail this call because the cable is unplugged.
253 * Updated when the link comes up...
254 */
255 adapter->link_speed = MBPS_1000;
256 } else {
257 return (-1);
258 }
259 }
260
261 port_mode = adapter->unm_nic_pci_read_normalize(adapter,
262 UNM_PORT_MODE_ADDR);
263 if (port_mode == UNM_PORT_MODE_802_3_AP) {
264 *(unm_crbword_t *)&mac_cfg0 = 0x0000003f;
265 *(unm_crbword_t *)&mac_cfg1 = 0x0000f2df;
266 unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_0(port), &mac_cfg0,
267 adapter);
268 unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_1(port), &mac_cfg1,
269 adapter);
270 } else {
271 *(unm_crbword_t *)&mac_cfg0 = 0;
272 mac_cfg0.soft_reset = 1;
273 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0,
274 adapter);
275
276 *(unm_crbword_t *)&mac_cfg0 = 0;
277 mac_cfg0.tx_enable = 1;
278 mac_cfg0.rx_enable = 1;
279 mac_cfg0.rx_flowctl = 0;
280 mac_cfg0.tx_reset_pb = 1;
281 mac_cfg0.rx_reset_pb = 1;
282 mac_cfg0.tx_reset_mac = 1;
283 mac_cfg0.rx_reset_mac = 1;
284
285 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0,
286 adapter);
287
288 *(unm_crbword_t *)&mac_cfg1 = 0;
289 mac_cfg1.preamblelen = 0xf;
290 mac_cfg1.duplex = 1;
291 mac_cfg1.crc_enable = 1;
292 mac_cfg1.padshort = 1;
293 mac_cfg1.checklength = 1;
294 mac_cfg1.hugeframes = 1;
295
296 switch (adapter->link_speed) {
297 case MBPS_10:
298 case MBPS_100: /* Fall Through */
299 mac_cfg1.intfmode = 1;
300 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_1
301 (port), &mac_cfg1, adapter);
302
303 /* set mii mode */
304 unm_crb_write_adapter(
305 UNM_NIU_GB0_GMII_MODE+(port<<3),
306 &zero, adapter);
307 unm_crb_write_adapter(
308 UNM_NIU_GB0_MII_MODE+(port<< 3),
309 &one, adapter);
310 break;
311
312 case MBPS_1000:
313 mac_cfg1.intfmode = 2;
314 unm_crb_write_adapter(
315 UNM_NIU_GB_MAC_CONFIG_1(port),
316 &mac_cfg1, adapter);
317
318 /* set gmii mode */
319 unm_crb_write_adapter(
320 UNM_NIU_GB0_MII_MODE+(port << 3),
321 &zero, adapter);
322 unm_crb_write_adapter(
323 UNM_NIU_GB0_GMII_MODE+(port << 3),
324 &one, adapter);
325 break;
326
327 default:
328 /* Will not happen */
329 break;
330 }
331
332 *(unm_crbword_t *)&mii_cfg = 0;
333 mii_cfg.clockselect = 7;
334 unm_crb_write_adapter(UNM_NIU_GB_MII_MGMT_CONFIG(port),
335 &mii_cfg, adapter);
336
337 *(unm_crbword_t *)&mac_cfg0 = 0;
338 mac_cfg0.tx_enable = 1;
339 mac_cfg0.rx_enable = 1;
340 mac_cfg0.tx_flowctl = 0;
341 mac_cfg0.rx_flowctl = 0;
342 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port),
343 &mac_cfg0, adapter);
344 }
345
346 return (0);
347 }
348
349 /* Disable a GbE interface */
350 native_t
unm_niu_disable_gbe_port(struct unm_adapter_s * adapter)351 unm_niu_disable_gbe_port(struct unm_adapter_s *adapter)
352 {
353 native_t port = adapter->physical_port;
354 unm_niu_gb_mac_config_0_t mac_cfg0;
355
356 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
357 return (-1);
358
359 *(unm_crbword_t *)&mac_cfg0 = 0;
360 mac_cfg0.soft_reset = 1;
361
362 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
363 adapter->unm_nic_hw_write_wx(adapter,
364 UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 0);
365 else
366 adapter->unm_nic_hw_write_wx(adapter,
367 UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4);
368 return (0);
369 }
370
371 /* Disable an XG interface */
372 native_t
unm_niu_disable_xg_port(struct unm_adapter_s * adapter)373 unm_niu_disable_xg_port(struct unm_adapter_s *adapter)
374 {
375 native_t port = adapter->physical_port;
376 unm_niu_xg_mac_config_0_t mac_cfg;
377
378 *(unm_crbword_t *)&mac_cfg = 0;
379 mac_cfg.soft_reset = 1;
380
381 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
382 if (port != 0)
383 return (-1);
384 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0,
385 &mac_cfg, 4);
386 } else {
387 if ((port < 0) || (port >= UNM_NIU_MAX_XG_PORTS))
388 return (-1);
389 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
390 (port * 0x10000), &mac_cfg, 4);
391 }
392 return (0);
393 }
394
395
396 /* Set promiscuous mode for a GbE interface */
397 native_t
unm_niu_set_promiscuous_mode(struct unm_adapter_s * adapter,unm_niu_prom_mode_t mode)398 unm_niu_set_promiscuous_mode(struct unm_adapter_s *adapter,
399 unm_niu_prom_mode_t mode)
400 {
401 native_t port = adapter->physical_port;
402 unm_niu_gb_drop_crc_t reg;
403 unm_niu_gb_mac_config_0_t mac_cfg;
404 unm_crbword_t data;
405 int cnt = 0, ret = 0;
406 ulong_t val;
407
408 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
409 return (-1);
410
411 /* Turn off mac */
412 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
413 &mac_cfg, 4);
414 mac_cfg.rx_enable = 0;
415 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
416 &mac_cfg, 4);
417
418 /* wait until mac is drained by sre */
419 /* Port 0 rx fifo bit 5 */
420 val = (0x20 << port);
421 adapter->unm_crb_writelit_adapter(adapter, UNM_NIU_FRAME_COUNT_SELECT,
422 val);
423
424 do {
425 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_FRAME_COUNT,
426 &val, 4);
427 cnt++;
428 if (cnt > 2000) {
429 ret = -1;
430 break;
431 }
432 drv_usecwait(10);
433 } while (val);
434
435 /* now set promiscuous mode */
436 if (ret != -1) {
437 if (mode == UNM_NIU_PROMISCOUS_MODE)
438 data = 0;
439 else
440 data = 1;
441
442 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR,
443 ®, 4);
444 switch (port) {
445 case 0:
446 reg.drop_gb0 = data;
447 break;
448 case 1:
449 reg.drop_gb1 = data;
450 break;
451 case 2:
452 reg.drop_gb2 = data;
453 break;
454 case 3:
455 reg.drop_gb3 = data;
456 break;
457 default:
458 ret = -1;
459 break;
460 }
461 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR,
462 ®, 4);
463 }
464
465 /* turn the mac on back */
466 mac_cfg.rx_enable = 1;
467 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
468 &mac_cfg, 4);
469
470 return (ret);
471 }
472
473 /*
474 * Set the MAC address for an XG port
475 * Note that the passed-in value must already be in network byte order.
476 */
477 int
unm_niu_xg_macaddr_set(struct unm_adapter_s * adapter,unm_ethernet_macaddr_t addr)478 unm_niu_xg_macaddr_set(struct unm_adapter_s *adapter,
479 unm_ethernet_macaddr_t addr)
480 {
481 int phy = adapter->physical_port;
482 unm_crbword_t temp = 0;
483 u32 port_mode = 0;
484
485 if ((phy < 0) || (phy > 3))
486 return (-1);
487
488 switch (phy) {
489 case 0:
490 (void) memcpy(&temp, addr, 2);
491 temp <<= 16;
492 port_mode = adapter->unm_nic_pci_read_normalize(adapter,
493 UNM_PORT_MODE_ADDR);
494 if (port_mode == UNM_PORT_MODE_802_3_AP) {
495 adapter->unm_nic_hw_write_wx(adapter,
496 UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4);
497 temp = 0;
498 (void) memcpy(&temp, ((__uint8_t *)addr) + 2,
499 sizeof (unm_crbword_t));
500 adapter->unm_nic_hw_write_wx(adapter,
501 UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4);
502 } else {
503 adapter->unm_nic_hw_write_wx(adapter,
504 UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4);
505 temp = 0;
506 (void) memcpy(&temp, ((__uint8_t *)addr) + 2,
507 sizeof (unm_crbword_t));
508 adapter->unm_nic_hw_write_wx(adapter,
509 UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4);
510 }
511 break;
512
513 case 1:
514 (void) memcpy(&temp, addr, 2);
515 temp <<= 16;
516 port_mode = adapter->unm_nic_pci_read_normalize(adapter,
517 UNM_PORT_MODE_ADDR);
518 if (port_mode == UNM_PORT_MODE_802_3_AP) {
519 adapter->unm_nic_hw_write_wx(adapter,
520 UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4);
521 temp = 0;
522 (void) memcpy(&temp, ((__uint8_t *)addr) + 2,
523 sizeof (unm_crbword_t));
524 adapter->unm_nic_hw_write_wx(adapter,
525 UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4);
526 } else {
527 adapter->unm_nic_hw_write_wx(adapter,
528 UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4);
529 temp = 0;
530 (void) memcpy(&temp, ((__uint8_t *)addr) + 2,
531 sizeof (unm_crbword_t));
532 adapter->unm_nic_hw_write_wx(adapter,
533 UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4);
534 }
535 break;
536
537 default:
538 cmn_err(CE_WARN, "Unknown port %d\n", phy);
539 return (DDI_FAILURE);
540 }
541
542 return (0);
543 }
544
545 native_t
unm_niu_xg_set_promiscuous_mode(struct unm_adapter_s * adapter,unm_niu_prom_mode_t mode)546 unm_niu_xg_set_promiscuous_mode(struct unm_adapter_s *adapter,
547 unm_niu_prom_mode_t mode)
548 {
549 long reg;
550 unm_niu_xg_mac_config_0_t mac_cfg;
551 native_t port = adapter->physical_port;
552 int cnt = 0;
553 int result = 0;
554 u32 port_mode = 0;
555
556 if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS))
557 return (-1);
558
559 port_mode = adapter->unm_nic_pci_read_normalize(adapter,
560 UNM_PORT_MODE_ADDR);
561
562 if (port_mode == UNM_PORT_MODE_802_3_AP) {
563 reg = 0;
564 adapter->unm_nic_hw_write_wx(adapter,
565 UNM_NIU_GB_DROP_WRONGADDR, (void*)®, 4);
566 } else {
567 /* Turn off mac */
568 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
569 (0x10000 * port), &mac_cfg, 4);
570 mac_cfg.rx_enable = 0;
571 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
572 (0x10000 * port), &mac_cfg, 4);
573
574 /* wait until mac is drained by sre */
575 if ((adapter->ahw.boardcfg.board_type !=
576 UNM_BRDTYPE_P2_SB31_10G_IMEZ) &&
577 (adapter->ahw.boardcfg.board_type !=
578 UNM_BRDTYPE_P2_SB31_10G_HMEZ)) {
579 /* single port case bit 9 */
580 reg = 0x0200;
581 adapter->unm_crb_writelit_adapter(adapter,
582 UNM_NIU_FRAME_COUNT_SELECT, reg);
583 } else {
584 /* Port 0 rx fifo bit 5 */
585 reg = (0x20 << port);
586 adapter->unm_crb_writelit_adapter(adapter,
587 UNM_NIU_FRAME_COUNT_SELECT, reg);
588 }
589 do {
590 adapter->unm_nic_hw_read_wx(adapter,
591 UNM_NIU_FRAME_COUNT, ®, 4);
592 cnt++;
593 if (cnt > 2000) {
594 result = -1;
595 break;
596 }
597 drv_usecwait(10);
598 } while (reg);
599
600 /* now set promiscuous mode */
601 if (result != -1) {
602 adapter->unm_nic_hw_read_wx(adapter,
603 UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4);
604 if (mode == UNM_NIU_PROMISCOUS_MODE) {
605 reg = (reg | 0x2000UL);
606 } else { /* FIXME use the correct mode value here */
607 reg = (reg & ~0x2000UL);
608 }
609 adapter->unm_crb_writelit_adapter(adapter,
610 UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
611 }
612
613 /* turn the mac back on */
614 mac_cfg.rx_enable = 1;
615 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
616 (0x10000 * port), &mac_cfg, 4);
617 }
618
619 return (result);
620 }
621
622 int
unm_niu_xg_set_tx_flow_ctl(struct unm_adapter_s * adapter,int enable)623 unm_niu_xg_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable)
624 {
625 int port = adapter->physical_port;
626 unm_niu_xg_pause_ctl_t reg;
627
628 if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS))
629 return (-1);
630
631 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XG_PAUSE_CTL, ®, 4);
632 if (port == 0)
633 reg.xg0_mask = !enable;
634 else
635 reg.xg1_mask = !enable;
636
637 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XG_PAUSE_CTL, ®, 4);
638
639 return (0);
640 }
641
642 int
unm_niu_gbe_set_tx_flow_ctl(struct unm_adapter_s * adapter,int enable)643 unm_niu_gbe_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable)
644 {
645 int port = adapter->physical_port;
646 unm_niu_gb_pause_ctl_t reg;
647
648 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
649 return (-1);
650
651 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_PAUSE_CTL, ®, 4);
652 switch (port) {
653 case (0):
654 reg.gb0_mask = !enable;
655 break;
656 case (1):
657 reg.gb1_mask = !enable;
658 break;
659 case (2):
660 reg.gb2_mask = !enable;
661 break;
662 case (3):
663 default:
664 reg.gb3_mask = !enable;
665 break;
666 }
667 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_PAUSE_CTL, ®, 4);
668
669 return (0);
670 }
671
672 int
unm_niu_gbe_set_rx_flow_ctl(struct unm_adapter_s * adapter,int enable)673 unm_niu_gbe_set_rx_flow_ctl(struct unm_adapter_s *adapter, int enable)
674 {
675 int port = adapter->physical_port;
676 unm_niu_gb_mac_config_0_t reg;
677
678 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
679 return (-1);
680
681 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
682 ®, 4);
683 reg.rx_flowctl = enable;
684 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
685 ®, 4);
686
687 return (0);
688 }
689