20 |
20 |
*/
|
21 |
21 |
|
22 |
22 |
/*
|
23 |
|
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
23 |
* Copyright (c) 2010-2013, by Broadcom, Inc.
|
|
24 |
* All Rights Reserved.
|
24 |
25 |
*/
|
25 |
26 |
|
26 |
27 |
/*
|
27 |
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
|
28 |
* Copyright (c) 2002, 2010, Oracle and/or its affiliates.
|
|
29 |
* All rights reserved.
|
28 |
30 |
*/
|
29 |
31 |
|
30 |
32 |
#include "bge_impl.h"
|
31 |
33 |
|
32 |
34 |
#define PIO_ADDR(bgep, offset) ((void *)((caddr_t)(bgep)->io_regs+(offset)))
|
|
35 |
#define APE_ADDR(bgep, offset) ((void *)((caddr_t)(bgep)->ape_regs+(offset)))
|
33 |
36 |
|
34 |
37 |
/*
|
35 |
38 |
* Future features ... ?
|
... | ... | |
54 |
57 |
boolean_t bge_relaxed_ordering = B_TRUE;
|
55 |
58 |
|
56 |
59 |
/*
|
57 |
|
* Property names
|
58 |
|
*/
|
59 |
|
static char knownids_propname[] = "bge-known-subsystems";
|
60 |
|
|
61 |
|
/*
|
62 |
60 |
* Patchable globals:
|
63 |
61 |
*
|
64 |
62 |
* bge_autorecover
|
... | ... | |
98 |
96 |
static uint32_t bge_dma_rwctrl_5715 = PDRWCR_VAR_5715;
|
99 |
97 |
|
100 |
98 |
uint32_t bge_rx_ticks_norm = 128;
|
101 |
|
uint32_t bge_tx_ticks_norm = 2048; /* 8 for FJ2+ !?!? */
|
|
99 |
uint32_t bge_tx_ticks_norm = 512;
|
102 |
100 |
uint32_t bge_rx_count_norm = 8;
|
103 |
101 |
uint32_t bge_tx_count_norm = 128;
|
104 |
102 |
|
... | ... | |
243 |
241 |
BGE_TRACE(("bge_ind_get32($%p, 0x%lx)", (void *)bgep, regno));
|
244 |
242 |
|
245 |
243 |
#ifdef __sparc
|
246 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
|
244 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
245 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
247 |
246 |
regno = LE_32(regno);
|
|
247 |
}
|
248 |
248 |
#endif
|
249 |
249 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIAAR, regno);
|
250 |
250 |
val = pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_RIADR);
|
... | ... | |
268 |
268 |
|
269 |
269 |
val = LE_32(val);
|
270 |
270 |
#ifdef __sparc
|
271 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
|
271 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
272 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
272 |
273 |
regno = LE_32(regno);
|
|
274 |
}
|
273 |
275 |
#endif
|
274 |
276 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIAAR, regno);
|
275 |
277 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_RIADR, val);
|
... | ... | |
327 |
329 |
ddi_acc_handle_t handle;
|
328 |
330 |
uint16_t command;
|
329 |
331 |
uint32_t mhcr;
|
|
332 |
uint32_t prodid;
|
|
333 |
uint32_t pci_state;
|
330 |
334 |
uint16_t value16;
|
331 |
335 |
int i;
|
332 |
336 |
|
... | ... | |
360 |
364 |
* byte-swapped value to it. So we just write zero first for simplicity.
|
361 |
365 |
*/
|
362 |
366 |
cidp->device = pci_config_get16(handle, PCI_CONF_DEVID);
|
363 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
|
367 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
368 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
364 |
369 |
pci_config_put32(handle, PCI_CONF_BGE_MHCR, 0);
|
|
370 |
}
|
|
371 |
|
365 |
372 |
mhcr = pci_config_get32(handle, PCI_CONF_BGE_MHCR);
|
366 |
|
cidp->asic_rev = mhcr & MHCR_CHIP_REV_MASK;
|
|
373 |
cidp->asic_rev = (mhcr & MHCR_CHIP_REV_MASK);
|
|
374 |
cidp->asic_rev_prod_id = 0;
|
|
375 |
if ((cidp->asic_rev & 0xf0000000) == CHIP_ASIC_REV_USE_PROD_ID_REG) {
|
|
376 |
prodid = CHIP_ASIC_REV_PROD_ID_REG;
|
|
377 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
378 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
|
379 |
prodid = CHIP_ASIC_REV_PROD_ID_GEN2_REG;
|
|
380 |
}
|
|
381 |
cidp->asic_rev_prod_id = pci_config_get32(handle, prodid);
|
|
382 |
}
|
|
383 |
|
367 |
384 |
cidp->businfo = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE);
|
368 |
385 |
cidp->command = pci_config_get16(handle, PCI_CONF_COMM);
|
369 |
386 |
|
... | ... | |
374 |
391 |
cidp->clsize = pci_config_get8(handle, PCI_CONF_CACHE_LINESZ);
|
375 |
392 |
cidp->latency = pci_config_get8(handle, PCI_CONF_LATENCY_TIMER);
|
376 |
393 |
|
|
394 |
/* 5717 C0 is treated just like 5720 A0 */
|
|
395 |
if (pci_config_get16(bgep->cfg_handle, PCI_CONF_DEVID) ==
|
|
396 |
DEVICE_ID_5717_C0) {
|
|
397 |
cidp->device = DEVICE_ID_5720;
|
|
398 |
}
|
|
399 |
|
377 |
400 |
BGE_DEBUG(("bge_chip_cfg_init: %s bus is %s and %s; #INTA is %s",
|
378 |
401 |
cidp->businfo & PCISTATE_BUS_IS_PCI ? "PCI" : "PCI-X",
|
379 |
402 |
cidp->businfo & PCISTATE_BUS_IS_FAST ? "fast" : "slow",
|
... | ... | |
445 |
468 |
* see whether the host is truly up to date, and regenerate
|
446 |
469 |
* its interrupt if not.
|
447 |
470 |
*/
|
448 |
|
mhcr = MHCR_ENABLE_INDIRECT_ACCESS |
|
449 |
|
MHCR_ENABLE_TAGGED_STATUS_MODE |
|
450 |
|
MHCR_MASK_INTERRUPT_MODE |
|
451 |
|
MHCR_CLEAR_INTERRUPT_INTA;
|
452 |
|
|
|
471 |
mhcr = MHCR_ENABLE_INDIRECT_ACCESS |
|
|
472 |
MHCR_ENABLE_PCI_STATE_RW |
|
|
473 |
MHCR_ENABLE_TAGGED_STATUS_MODE |
|
|
474 |
MHCR_MASK_INTERRUPT_MODE |
|
|
475 |
MHCR_CLEAR_INTERRUPT_INTA;
|
453 |
476 |
if (bgep->intr_type == DDI_INTR_TYPE_FIXED)
|
454 |
477 |
mhcr |= MHCR_MASK_PCI_INT_OUTPUT;
|
455 |
478 |
|
456 |
479 |
#ifdef _BIG_ENDIAN
|
457 |
480 |
mhcr |= MHCR_ENABLE_ENDIAN_WORD_SWAP | MHCR_ENABLE_ENDIAN_BYTE_SWAP;
|
458 |
481 |
#endif /* _BIG_ENDIAN */
|
459 |
|
|
460 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
461 |
|
pci_config_put32(handle, PCI_CONF_BGE_MHCR, 0);
|
462 |
482 |
pci_config_put32(handle, PCI_CONF_BGE_MHCR, mhcr);
|
463 |
483 |
|
464 |
484 |
#ifdef BGE_IPMI_ASF
|
465 |
485 |
bgep->asf_wordswapped = B_FALSE;
|
466 |
486 |
#endif
|
|
487 |
|
|
488 |
pci_state = (PCISTATE_EXT_ROM_ENABLE | PCISTATE_EXT_ROM_RETRY);
|
|
489 |
/* allow reads and writes to the APE register and memory space */
|
|
490 |
if (bgep->ape_enabled) {
|
|
491 |
pci_state |= (PCISTATE_ALLOW_APE_CTLSPC_WR |
|
|
492 |
PCISTATE_ALLOW_APE_SHMEM_WR |
|
|
493 |
PCISTATE_ALLOW_APE_PSPACE_WR);
|
|
494 |
}
|
|
495 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_PCISTATE, pci_state);
|
|
496 |
|
467 |
497 |
/*
|
468 |
498 |
* Step 1 (also step 7): Enable PCI Memory Space accesses
|
469 |
499 |
* Disable Memory Write/Invalidate
|
... | ... | |
533 |
563 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep)) {
|
534 |
564 |
bge_cfg_clr16(bgep, PCI_CONF_DEV_CTRL_5723,
|
535 |
565 |
DEV_CTRL_NO_SNOOP | DEV_CTRL_RELAXED);
|
536 |
|
} else
|
|
566 |
} else if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
567 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
|
568 |
bge_cfg_clr16(bgep, PCI_CONF_DEV_CTRL_5717,
|
|
569 |
DEV_CTRL_NO_SNOOP | DEV_CTRL_RELAXED);
|
|
570 |
} else {
|
537 |
571 |
bge_cfg_clr16(bgep, PCI_CONF_DEV_CTRL,
|
538 |
572 |
DEV_CTRL_NO_SNOOP | DEV_CTRL_RELAXED);
|
|
573 |
}
|
539 |
574 |
}
|
540 |
575 |
}
|
541 |
576 |
|
... | ... | |
629 |
664 |
uint64_t regval;
|
630 |
665 |
|
631 |
666 |
#ifdef __amd64
|
632 |
|
if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
|
633 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
667 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
|
668 |
bge_get_em64t_type() ||
|
|
669 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
670 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
634 |
671 |
regval = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno + 4));
|
635 |
672 |
regval <<= 32;
|
636 |
673 |
regval |= ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno));
|
... | ... | |
639 |
676 |
}
|
640 |
677 |
#elif defined(__sparc)
|
641 |
678 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
642 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
679 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
680 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
643 |
681 |
regval = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno));
|
644 |
682 |
regval <<= 32;
|
645 |
683 |
regval |= ddi_get32(bgep->io_handle, PIO_ADDR(bgep, regno + 4));
|
... | ... | |
674 |
712 |
#endif /* _LITTLE_ENDIAN */
|
675 |
713 |
|
676 |
714 |
#ifdef __amd64
|
677 |
|
if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
|
678 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
715 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
|
716 |
bge_get_em64t_type() ||
|
|
717 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
718 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
679 |
719 |
ddi_put32(bgep->io_handle,
|
680 |
720 |
PIO_ADDR(bgep, regno), (uint32_t)data);
|
681 |
721 |
BGE_PCICHK(bgep);
|
... | ... | |
687 |
727 |
}
|
688 |
728 |
#elif defined(__sparc)
|
689 |
729 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
690 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
730 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
731 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
691 |
732 |
ddi_put32(bgep->io_handle,
|
692 |
733 |
PIO_ADDR(bgep, regno + 4), (uint32_t)data);
|
693 |
734 |
BGE_PCICHK(bgep);
|
... | ... | |
845 |
886 |
B_TRUE : B_FALSE);
|
846 |
887 |
}
|
847 |
888 |
#ifdef __sparc
|
848 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
|
889 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
890 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
849 |
891 |
base = LE_32(base);
|
|
892 |
}
|
850 |
893 |
#endif
|
851 |
894 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, base);
|
852 |
895 |
}
|
... | ... | |
905 |
948 |
#endif
|
906 |
949 |
|
907 |
950 |
#ifdef __sparc
|
908 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
|
951 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
952 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
909 |
953 |
addr = LE_32(addr);
|
|
954 |
}
|
910 |
955 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWBAR, addr);
|
911 |
956 |
data = LE_32(data);
|
912 |
957 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MWDAR, data);
|
... | ... | |
933 |
978 |
addr += NIC_MEM_WINDOW_OFFSET;
|
934 |
979 |
|
935 |
980 |
#ifdef __amd64
|
936 |
|
if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
|
937 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
981 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
|
982 |
bge_get_em64t_type() ||
|
|
983 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
984 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
938 |
985 |
data = ddi_get32(bgep->io_handle,
|
939 |
986 |
PIO_ADDR(bgep, addr + 4));
|
940 |
987 |
data <<= 32;
|
... | ... | |
944 |
991 |
}
|
945 |
992 |
#elif defined(__sparc)
|
946 |
993 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
947 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
994 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
995 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
948 |
996 |
data = ddi_get32(bgep->io_handle, PIO_ADDR(bgep, addr));
|
949 |
997 |
data <<= 32;
|
950 |
998 |
data |= ddi_get32(bgep->io_handle,
|
... | ... | |
976 |
1024 |
addr += NIC_MEM_WINDOW_OFFSET;
|
977 |
1025 |
|
978 |
1026 |
#ifdef __amd64
|
979 |
|
if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
|
980 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
1027 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
|
1028 |
bge_get_em64t_type() ||
|
|
1029 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1030 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
981 |
1031 |
ddi_put32(bgep->io_handle,
|
982 |
1032 |
PIO_ADDR(bgep, addr + 4), (uint32_t)data);
|
983 |
1033 |
BGE_PCICHK(bgep);
|
... | ... | |
988 |
1038 |
}
|
989 |
1039 |
#elif defined(__sparc)
|
990 |
1040 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
991 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
1041 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1042 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
992 |
1043 |
ddi_put32(bgep->io_handle,
|
993 |
1044 |
PIO_ADDR(bgep, addr + 4), (uint32_t)data);
|
994 |
1045 |
BGE_PCICHK(bgep);
|
... | ... | |
1028 |
1079 |
|
1029 |
1080 |
p = (void *)rcbp;
|
1030 |
1081 |
#ifdef __amd64
|
1031 |
|
if (DEVICE_5723_SERIES_CHIPSETS(bgep) || bge_get_em64t_type() ||
|
1032 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
1082 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
|
1083 |
bge_get_em64t_type() ||
|
|
1084 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1085 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
1033 |
1086 |
ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr),
|
1034 |
1087 |
(uint32_t)(*p));
|
1035 |
1088 |
ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 4),
|
... | ... | |
1045 |
1098 |
}
|
1046 |
1099 |
#elif defined(__sparc)
|
1047 |
1100 |
if (DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
1048 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)) {
|
|
1101 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1102 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
1049 |
1103 |
ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr + 4),
|
1050 |
1104 |
(uint32_t)(*p));
|
1051 |
1105 |
ddi_put32(bgep->io_handle, PIO_ADDR(bgep, addr),
|
... | ... | |
1246 |
1300 |
(void) bge_mii_access(bgep, regno, data, MI_COMMS_COMMAND_WRITE);
|
1247 |
1301 |
}
|
1248 |
1302 |
|
|
1303 |
uint16_t bge_phydsp_read(bge_t *bgep, bge_regno_t regno);
|
|
1304 |
#pragma no_inline(bge_phydsp_read)
|
|
1305 |
|
|
1306 |
uint16_t bge_phydsp_read(bge_t *bgep, bge_regno_t regno)
|
|
1307 |
{
|
|
1308 |
BGE_TRACE(("bge_phydsp_read($%p, 0x%lx)",
|
|
1309 |
(void *)bgep, regno));
|
|
1310 |
|
|
1311 |
ASSERT(mutex_owned(bgep->genlock));
|
|
1312 |
|
|
1313 |
bge_mii_put16(bgep, MII_DSP_ADDRESS, regno);
|
|
1314 |
return bge_mii_get16(bgep, MII_DSP_RW_PORT);
|
|
1315 |
}
|
|
1316 |
|
|
1317 |
void bge_phydsp_write(bge_t *bgep, bge_regno_t regno, uint16_t data);
|
|
1318 |
#pragma no_inline(bge_phydsp_write)
|
|
1319 |
|
|
1320 |
void bge_phydsp_write(bge_t *bgep, bge_regno_t regno, uint16_t data)
|
|
1321 |
{
|
|
1322 |
BGE_TRACE(("bge_phydsp_write($%p, 0x%lx, 0x%x)",
|
|
1323 |
(void *)bgep, regno, data));
|
|
1324 |
|
|
1325 |
ASSERT(mutex_owned(bgep->genlock));
|
|
1326 |
|
|
1327 |
bge_mii_put16(bgep, MII_DSP_ADDRESS, regno);
|
|
1328 |
bge_mii_put16(bgep, MII_DSP_RW_PORT, data);
|
|
1329 |
}
|
|
1330 |
|
1249 |
1331 |
#undef BGE_DBG
|
1250 |
1332 |
#define BGE_DBG BGE_DBG_SEEPROM /* debug flag for this code */
|
1251 |
1333 |
|
... | ... | |
1697 |
1779 |
* ENODEV if the NVmem device is missing or otherwise unusable
|
1698 |
1780 |
* EPROTO on other h/w or s/w errors.
|
1699 |
1781 |
*/
|
1700 |
|
static int
|
1701 |
|
bge_nvmem_rw32(bge_t *bgep, uint32_t cmd, bge_regno_t addr, uint32_t *dp)
|
|
1782 |
int bge_nvmem_rw32(bge_t *bgep, uint32_t cmd, bge_regno_t addr, uint32_t *dp)
|
1702 |
1783 |
{
|
1703 |
1784 |
int err;
|
1704 |
1785 |
|
... | ... | |
1720 |
1801 |
if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
|
1721 |
1802 |
DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
1722 |
1803 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1804 |
DEVICE_5725_SERIES_CHIPSETS(bgep) ||
|
1723 |
1805 |
DEVICE_5714_SERIES_CHIPSETS(bgep)) {
|
1724 |
1806 |
bge_reg_set32(bgep, NVM_ACCESS_REG,
|
1725 |
1807 |
NVM_ACCESS_ENABLE);
|
... | ... | |
1729 |
1811 |
if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
|
1730 |
1812 |
DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
1731 |
1813 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1814 |
DEVICE_5725_SERIES_CHIPSETS(bgep) ||
|
1732 |
1815 |
DEVICE_5714_SERIES_CHIPSETS(bgep)) {
|
1733 |
1816 |
bge_reg_clr32(bgep, NVM_ACCESS_REG,
|
1734 |
1817 |
NVM_ACCESS_ENABLE);
|
... | ... | |
1739 |
1822 |
if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
|
1740 |
1823 |
DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
1741 |
1824 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1825 |
DEVICE_5725_SERIES_CHIPSETS(bgep) ||
|
1742 |
1826 |
DEVICE_5714_SERIES_CHIPSETS(bgep)) {
|
1743 |
1827 |
bge_reg_set32(bgep, NVM_ACCESS_REG,
|
1744 |
1828 |
NVM_WRITE_ENABLE|NVM_ACCESS_ENABLE);
|
... | ... | |
1750 |
1834 |
if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
|
1751 |
1835 |
DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
1752 |
1836 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
1837 |
DEVICE_5725_SERIES_CHIPSETS(bgep) ||
|
1753 |
1838 |
DEVICE_5714_SERIES_CHIPSETS(bgep)) {
|
1754 |
1839 |
bge_reg_clr32(bgep, NVM_ACCESS_REG,
|
1755 |
1840 |
NVM_WRITE_ENABLE|NVM_ACCESS_ENABLE);
|
... | ... | |
1768 |
1853 |
return (err);
|
1769 |
1854 |
}
|
1770 |
1855 |
|
|
1856 |
static uint32_t bge_nvmem_access_cmd(bge_t *bgep, boolean_t read)
|
|
1857 |
{
|
|
1858 |
switch (bgep->chipid.nvtype) {
|
|
1859 |
case BGE_NVTYPE_NONE:
|
|
1860 |
case BGE_NVTYPE_UNKNOWN:
|
|
1861 |
default:
|
|
1862 |
return 0;
|
|
1863 |
|
|
1864 |
case BGE_NVTYPE_SEEPROM:
|
|
1865 |
case BGE_NVTYPE_LEGACY_SEEPROM:
|
|
1866 |
return (read) ? BGE_SEE_READ : BGE_SEE_WRITE;
|
|
1867 |
|
|
1868 |
case BGE_NVTYPE_UNBUFFERED_FLASH:
|
|
1869 |
case BGE_NVTYPE_BUFFERED_FLASH:
|
|
1870 |
return (read) ? BGE_FLASH_READ : BGE_FLASH_WRITE;
|
|
1871 |
}
|
|
1872 |
}
|
|
1873 |
|
|
1874 |
|
|
1875 |
int bge_nvmem_read32(bge_t *bgep, bge_regno_t addr, uint32_t *dp)
|
|
1876 |
{
|
|
1877 |
return bge_nvmem_rw32(bgep, bge_nvmem_access_cmd(bgep, B_TRUE), addr, dp);
|
|
1878 |
}
|
|
1879 |
|
|
1880 |
|
|
1881 |
int bge_nvmem_write32(bge_t *bgep, bge_regno_t addr, uint32_t *dp)
|
|
1882 |
{
|
|
1883 |
return bge_nvmem_rw32(bgep, bge_nvmem_access_cmd(bgep, B_FALSE), addr, dp);
|
|
1884 |
}
|
|
1885 |
|
|
1886 |
|
1771 |
1887 |
/*
|
1772 |
1888 |
* Attempt to get a MAC address from the SEEPROM or Flash, if any
|
1773 |
1889 |
*/
|
... | ... | |
1896 |
2012 |
case DEVICE_ID_5705_2:
|
1897 |
2013 |
case DEVICE_ID_5717:
|
1898 |
2014 |
case DEVICE_ID_5718:
|
|
2015 |
case DEVICE_ID_5719:
|
|
2016 |
case DEVICE_ID_5720:
|
1899 |
2017 |
case DEVICE_ID_5724:
|
|
2018 |
case DEVICE_ID_5725:
|
|
2019 |
case DEVICE_ID_5727:
|
1900 |
2020 |
case DEVICE_ID_57780:
|
1901 |
2021 |
case DEVICE_ID_5780:
|
1902 |
2022 |
case DEVICE_ID_5782:
|
... | ... | |
1942 |
2062 |
}
|
1943 |
2063 |
|
1944 |
2064 |
#undef BGE_DBG
|
|
2065 |
#define BGE_DBG BGE_DBG_APE /* debug flag for this code */
|
|
2066 |
|
|
2067 |
uint32_t bge_ape_get32(bge_t *bgep, bge_regno_t regno);
|
|
2068 |
#pragma inline(bge_ape_get32)
|
|
2069 |
|
|
2070 |
uint32_t
|
|
2071 |
bge_ape_get32(bge_t *bgep, bge_regno_t regno)
|
|
2072 |
{
|
|
2073 |
BGE_TRACE(("bge_ape_get32($%p, 0x%lx)",
|
|
2074 |
(void *)bgep, regno));
|
|
2075 |
|
|
2076 |
return (ddi_get32(bgep->ape_handle, APE_ADDR(bgep, regno)));
|
|
2077 |
}
|
|
2078 |
|
|
2079 |
void bge_ape_put32(bge_t *bgep, bge_regno_t regno, uint32_t data);
|
|
2080 |
#pragma inline(bge_ape_put32)
|
|
2081 |
|
|
2082 |
void
|
|
2083 |
bge_ape_put32(bge_t *bgep, bge_regno_t regno, uint32_t data)
|
|
2084 |
{
|
|
2085 |
BGE_TRACE(("bge_ape_put32($%p, 0x%lx, 0x%x)",
|
|
2086 |
(void *)bgep, regno, data));
|
|
2087 |
|
|
2088 |
ddi_put32(bgep->ape_handle, APE_ADDR(bgep, regno), data);
|
|
2089 |
BGE_PCICHK(bgep);
|
|
2090 |
}
|
|
2091 |
|
|
2092 |
void bge_ape_lock_init(bge_t *bgep)
|
|
2093 |
{
|
|
2094 |
int i;
|
|
2095 |
uint32_t regbase;
|
|
2096 |
uint32_t bit;
|
|
2097 |
|
|
2098 |
BGE_TRACE(("bge_ape_lock_init($%p)", (void *)bgep));
|
|
2099 |
|
|
2100 |
if (bgep->chipid.device == DEVICE_ID_5761)
|
|
2101 |
regbase = BGE_APE_LOCK_GRANT;
|
|
2102 |
else
|
|
2103 |
regbase = BGE_APE_PER_LOCK_GRANT;
|
|
2104 |
|
|
2105 |
/* Make sure the driver hasn't any stale locks. */
|
|
2106 |
for (i = BGE_APE_LOCK_PHY0; i <= BGE_APE_LOCK_GPIO; i++) {
|
|
2107 |
switch (i) {
|
|
2108 |
case BGE_APE_LOCK_PHY0:
|
|
2109 |
case BGE_APE_LOCK_PHY1:
|
|
2110 |
case BGE_APE_LOCK_PHY2:
|
|
2111 |
case BGE_APE_LOCK_PHY3:
|
|
2112 |
bit = APE_LOCK_GRANT_DRIVER;
|
|
2113 |
break;
|
|
2114 |
default:
|
|
2115 |
if (!bgep->pci_func)
|
|
2116 |
bit = APE_LOCK_GRANT_DRIVER;
|
|
2117 |
else
|
|
2118 |
bit = 1 << bgep->pci_func;
|
|
2119 |
}
|
|
2120 |
bge_ape_put32(bgep, regbase + 4 * i, bit);
|
|
2121 |
}
|
|
2122 |
}
|
|
2123 |
|
|
2124 |
static int bge_ape_lock(bge_t *bgep,
|
|
2125 |
int locknum)
|
|
2126 |
{
|
|
2127 |
int i, off;
|
|
2128 |
int ret = 0;
|
|
2129 |
uint32_t status;
|
|
2130 |
uint32_t req;
|
|
2131 |
uint32_t gnt;
|
|
2132 |
uint32_t bit;
|
|
2133 |
|
|
2134 |
BGE_TRACE(("bge_ape_lock($%p, 0x%x)", (void *)bgep, locknum));
|
|
2135 |
|
|
2136 |
if (!bgep->ape_enabled)
|
|
2137 |
return 0;
|
|
2138 |
|
|
2139 |
switch (locknum) {
|
|
2140 |
case BGE_APE_LOCK_GPIO:
|
|
2141 |
if (bgep->chipid.device == DEVICE_ID_5761)
|
|
2142 |
return 0;
|
|
2143 |
case BGE_APE_LOCK_GRC:
|
|
2144 |
case BGE_APE_LOCK_MEM:
|
|
2145 |
if (!bgep->pci_func)
|
|
2146 |
bit = APE_LOCK_REQ_DRIVER;
|
|
2147 |
else
|
|
2148 |
bit = 1 << bgep->pci_func;
|
|
2149 |
break;
|
|
2150 |
case BGE_APE_LOCK_PHY0:
|
|
2151 |
case BGE_APE_LOCK_PHY1:
|
|
2152 |
case BGE_APE_LOCK_PHY2:
|
|
2153 |
case BGE_APE_LOCK_PHY3:
|
|
2154 |
bit = APE_LOCK_REQ_DRIVER;
|
|
2155 |
break;
|
|
2156 |
default:
|
|
2157 |
return -1;
|
|
2158 |
}
|
|
2159 |
|
|
2160 |
if (bgep->chipid.device == DEVICE_ID_5761) {
|
|
2161 |
req = BGE_APE_LOCK_REQ;
|
|
2162 |
gnt = BGE_APE_LOCK_GRANT;
|
|
2163 |
} else {
|
|
2164 |
req = BGE_APE_PER_LOCK_REQ;
|
|
2165 |
gnt = BGE_APE_PER_LOCK_GRANT;
|
|
2166 |
}
|
|
2167 |
|
|
2168 |
off = 4 * locknum;
|
|
2169 |
|
|
2170 |
bge_ape_put32(bgep, req + off, bit);
|
|
2171 |
|
|
2172 |
/* Wait for up to 1 millisecond to acquire lock. */
|
|
2173 |
for (i = 0; i < 100; i++) {
|
|
2174 |
status = bge_ape_get32(bgep, gnt + off);
|
|
2175 |
if (status == bit)
|
|
2176 |
break;
|
|
2177 |
drv_usecwait(10);
|
|
2178 |
}
|
|
2179 |
|
|
2180 |
if (status != bit) {
|
|
2181 |
/* Revoke the lock request. */
|
|
2182 |
bge_ape_put32(bgep, gnt + off, bit);
|
|
2183 |
ret = -1;
|
|
2184 |
}
|
|
2185 |
|
|
2186 |
return ret;
|
|
2187 |
}
|
|
2188 |
|
|
2189 |
static void bge_ape_unlock(bge_t *bgep,
|
|
2190 |
int locknum)
|
|
2191 |
{
|
|
2192 |
uint32_t gnt;
|
|
2193 |
uint32_t bit;
|
|
2194 |
|
|
2195 |
BGE_TRACE(("bge_ape_unlock($%p, 0x%x)", (void *)bgep, locknum));
|
|
2196 |
|
|
2197 |
if (!bgep->ape_enabled)
|
|
2198 |
return;
|
|
2199 |
|
|
2200 |
switch (locknum) {
|
|
2201 |
case BGE_APE_LOCK_GPIO:
|
|
2202 |
if (bgep->chipid.device == DEVICE_ID_5761)
|
|
2203 |
return;
|
|
2204 |
case BGE_APE_LOCK_GRC:
|
|
2205 |
case BGE_APE_LOCK_MEM:
|
|
2206 |
if (!bgep->pci_func)
|
|
2207 |
bit = APE_LOCK_GRANT_DRIVER;
|
|
2208 |
else
|
|
2209 |
bit = 1 << bgep->pci_func;
|
|
2210 |
break;
|
|
2211 |
case BGE_APE_LOCK_PHY0:
|
|
2212 |
case BGE_APE_LOCK_PHY1:
|
|
2213 |
case BGE_APE_LOCK_PHY2:
|
|
2214 |
case BGE_APE_LOCK_PHY3:
|
|
2215 |
bit = APE_LOCK_GRANT_DRIVER;
|
|
2216 |
break;
|
|
2217 |
default:
|
|
2218 |
return;
|
|
2219 |
}
|
|
2220 |
|
|
2221 |
if (bgep->chipid.device == DEVICE_ID_5761)
|
|
2222 |
gnt = BGE_APE_LOCK_GRANT;
|
|
2223 |
else
|
|
2224 |
gnt = BGE_APE_PER_LOCK_GRANT;
|
|
2225 |
|
|
2226 |
bge_ape_put32(bgep, gnt + 4 * locknum, bit);
|
|
2227 |
}
|
|
2228 |
|
|
2229 |
/* wait for pending event to finish, if successful returns with MEM locked */
|
|
2230 |
static int bge_ape_event_lock(bge_t *bgep,
|
|
2231 |
uint32_t timeout_us)
|
|
2232 |
{
|
|
2233 |
uint32_t apedata;
|
|
2234 |
|
|
2235 |
BGE_TRACE(("bge_ape_event_lock($%p, %d)", (void *)bgep, timeout_us));
|
|
2236 |
|
|
2237 |
ASSERT(timeout_us > 0);
|
|
2238 |
|
|
2239 |
while (timeout_us) {
|
|
2240 |
if (bge_ape_lock(bgep, BGE_APE_LOCK_MEM))
|
|
2241 |
return -1;
|
|
2242 |
|
|
2243 |
apedata = bge_ape_get32(bgep, BGE_APE_EVENT_STATUS);
|
|
2244 |
if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
|
|
2245 |
break;
|
|
2246 |
|
|
2247 |
bge_ape_unlock(bgep, BGE_APE_LOCK_MEM);
|
|
2248 |
|
|
2249 |
drv_usecwait(10);
|
|
2250 |
timeout_us -= (timeout_us > 10) ? 10 : timeout_us;
|
|
2251 |
}
|
|
2252 |
|
|
2253 |
return timeout_us ? 0 : -1;
|
|
2254 |
}
|
|
2255 |
|
|
2256 |
/* wait for pending event to finish, returns non-zero if not finished */
|
|
2257 |
static int bge_ape_wait_for_event(bge_t *bgep,
|
|
2258 |
uint32_t timeout_us)
|
|
2259 |
{
|
|
2260 |
uint32_t i;
|
|
2261 |
uint32_t apedata;
|
|
2262 |
|
|
2263 |
BGE_TRACE(("bge_ape_wait_for_event($%p, %d)", (void *)bgep, timeout_us));
|
|
2264 |
|
|
2265 |
ASSERT(timeout_us > 0);
|
|
2266 |
|
|
2267 |
for (i = 0; i < timeout_us / 10; i++) {
|
|
2268 |
apedata = bge_ape_get32(bgep, BGE_APE_EVENT_STATUS);
|
|
2269 |
|
|
2270 |
if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
|
|
2271 |
break;
|
|
2272 |
|
|
2273 |
drv_usecwait(10);
|
|
2274 |
}
|
|
2275 |
|
|
2276 |
return i == timeout_us / 10;
|
|
2277 |
}
|
|
2278 |
|
|
2279 |
int bge_ape_scratchpad_read(bge_t *bgep,
|
|
2280 |
uint32_t *data,
|
|
2281 |
uint32_t base_off,
|
|
2282 |
uint32_t lenToRead)
|
|
2283 |
{
|
|
2284 |
int err;
|
|
2285 |
uint32_t i;
|
|
2286 |
uint32_t bufoff;
|
|
2287 |
uint32_t msgoff;
|
|
2288 |
uint32_t maxlen;
|
|
2289 |
uint32_t apedata;
|
|
2290 |
|
|
2291 |
BGE_TRACE(("bge_ape_scratchpad_read($%p, %p, 0x%0x, %d)",
|
|
2292 |
(void *)bgep, (void*)data, base_off, lenToRead));
|
|
2293 |
|
|
2294 |
if (!bgep->ape_has_ncsi)
|
|
2295 |
return 0;
|
|
2296 |
|
|
2297 |
apedata = bge_ape_get32(bgep, BGE_APE_SEG_SIG);
|
|
2298 |
if (apedata != APE_SEG_SIG_MAGIC)
|
|
2299 |
return -1;
|
|
2300 |
|
|
2301 |
apedata = bge_ape_get32(bgep, BGE_APE_FW_STATUS);
|
|
2302 |
if (!(apedata & APE_FW_STATUS_READY))
|
|
2303 |
return -1;
|
|
2304 |
|
|
2305 |
bufoff = (bge_ape_get32(bgep, BGE_APE_SEG_MSG_BUF_OFF) +
|
|
2306 |
BGE_APE_SHMEM_BASE);
|
|
2307 |
msgoff = bufoff + 2 * sizeof(uint32_t);
|
|
2308 |
maxlen = bge_ape_get32(bgep, BGE_APE_SEG_MSG_BUF_LEN);
|
|
2309 |
|
|
2310 |
while (lenToRead) {
|
|
2311 |
uint32_t transferLen;
|
|
2312 |
|
|
2313 |
/* Cap xfer sizes to scratchpad limits. */
|
|
2314 |
transferLen = (lenToRead > maxlen) ? maxlen : lenToRead;
|
|
2315 |
lenToRead -= transferLen;
|
|
2316 |
|
|
2317 |
apedata = bge_ape_get32(bgep, BGE_APE_FW_STATUS);
|
|
2318 |
if (!(apedata & APE_FW_STATUS_READY))
|
|
2319 |
return -1;
|
|
2320 |
|
|
2321 |
/* Wait for up to 1 millisecond for APE to service previous event. */
|
|
2322 |
err = bge_ape_event_lock(bgep, 1000);
|
|
2323 |
if (err)
|
|
2324 |
return err;
|
|
2325 |
|
|
2326 |
apedata = (APE_EVENT_STATUS_DRIVER_EVNT |
|
|
2327 |
APE_EVENT_STATUS_SCRTCHPD_READ |
|
|
2328 |
APE_EVENT_STATUS_EVENT_PENDING);
|
|
2329 |
bge_ape_put32(bgep, BGE_APE_EVENT_STATUS, apedata);
|
|
2330 |
|
|
2331 |
bge_ape_put32(bgep, bufoff, base_off);
|
|
2332 |
bge_ape_put32(bgep, bufoff + sizeof(uint32_t), transferLen);
|
|
2333 |
|
|
2334 |
bge_ape_unlock(bgep, BGE_APE_LOCK_MEM);
|
|
2335 |
bge_ape_put32(bgep, BGE_APE_EVENT, APE_EVENT_1);
|
|
2336 |
|
|
2337 |
base_off += transferLen;
|
|
2338 |
|
|
2339 |
if (bge_ape_wait_for_event(bgep, 30000))
|
|
2340 |
return -1;
|
|
2341 |
|
|
2342 |
for (i = 0; transferLen; i += 4, transferLen -= 4) {
|
|
2343 |
uint32_t val = bge_ape_get32(bgep, msgoff + i);
|
|
2344 |
memcpy(data, &val, sizeof(uint32_t));
|
|
2345 |
data++;
|
|
2346 |
}
|
|
2347 |
}
|
|
2348 |
|
|
2349 |
return 0;
|
|
2350 |
}
|
|
2351 |
|
|
2352 |
int bge_ape_scratchpad_write(bge_t *bgep,
|
|
2353 |
uint32_t dstoff,
|
|
2354 |
uint32_t *data,
|
|
2355 |
uint32_t lenToWrite)
|
|
2356 |
{
|
|
2357 |
int err;
|
|
2358 |
uint32_t i;
|
|
2359 |
uint32_t bufoff;
|
|
2360 |
uint32_t msgoff;
|
|
2361 |
uint32_t maxlen;
|
|
2362 |
uint32_t apedata;
|
|
2363 |
|
|
2364 |
BGE_TRACE(("bge_ape_scratchpad_write($%p, %d, %p, %d)",
|
|
2365 |
(void *)bgep, dstoff, data, lenToWrite));
|
|
2366 |
|
|
2367 |
if (!bgep->ape_has_ncsi)
|
|
2368 |
return 0;
|
|
2369 |
|
|
2370 |
apedata = bge_ape_get32(bgep, BGE_APE_SEG_SIG);
|
|
2371 |
if (apedata != APE_SEG_SIG_MAGIC)
|
|
2372 |
return -1;
|
|
2373 |
|
|
2374 |
apedata = bge_ape_get32(bgep, BGE_APE_FW_STATUS);
|
|
2375 |
if (!(apedata & APE_FW_STATUS_READY))
|
|
2376 |
return -1;
|
|
2377 |
|
|
2378 |
bufoff = (bge_ape_get32(bgep, BGE_APE_SEG_MSG_BUF_OFF) +
|
|
2379 |
BGE_APE_SHMEM_BASE);
|
|
2380 |
msgoff = bufoff + 2 * sizeof(uint32_t);
|
|
2381 |
maxlen = bge_ape_get32(bgep, BGE_APE_SEG_MSG_BUF_LEN);
|
|
2382 |
|
|
2383 |
while (lenToWrite) {
|
|
2384 |
uint32_t transferLen;
|
|
2385 |
|
|
2386 |
/* Cap xfer sizes to scratchpad limits. */
|
|
2387 |
transferLen = (lenToWrite > maxlen) ? maxlen : lenToWrite;
|
|
2388 |
lenToWrite -= transferLen;
|
|
2389 |
|
|
2390 |
/* Wait for up to 1 millisecond for
|
|
2391 |
* APE to service previous event.
|
|
2392 |
*/
|
|
2393 |
err = bge_ape_event_lock(bgep, 1000);
|
|
2394 |
if (err)
|
|
2395 |
return err;
|
|
2396 |
|
|
2397 |
bge_ape_put32(bgep, bufoff, dstoff);
|
|
2398 |
bge_ape_put32(bgep, bufoff + sizeof(uint32_t), transferLen);
|
|
2399 |
apedata = msgoff;
|
|
2400 |
|
|
2401 |
dstoff += transferLen;
|
|
2402 |
|
|
2403 |
for (i = 0; transferLen; i += 4, transferLen -= 4) {
|
|
2404 |
bge_ape_put32(bgep, apedata, *data++);
|
|
2405 |
apedata += sizeof(uint32_t);
|
|
2406 |
}
|
|
2407 |
|
|
2408 |
apedata = (APE_EVENT_STATUS_DRIVER_EVNT |
|
|
2409 |
APE_EVENT_STATUS_SCRTCHPD_WRITE |
|
|
2410 |
APE_EVENT_STATUS_EVENT_PENDING);
|
|
2411 |
bge_ape_put32(bgep, BGE_APE_EVENT_STATUS, apedata);
|
|
2412 |
|
|
2413 |
bge_ape_unlock(bgep, BGE_APE_LOCK_MEM);
|
|
2414 |
bge_ape_put32(bgep, BGE_APE_EVENT, APE_EVENT_1);
|
|
2415 |
}
|
|
2416 |
|
|
2417 |
return 0;
|
|
2418 |
}
|
|
2419 |
|
|
2420 |
static int bge_ape_send_event(bge_t *bgep, uint32_t event)
|
|
2421 |
{
|
|
2422 |
int err;
|
|
2423 |
uint32_t apedata;
|
|
2424 |
|
|
2425 |
BGE_TRACE(("bge_ape_send_event($%p, %d)", (void *)bgep, event));
|
|
2426 |
|
|
2427 |
apedata = bge_ape_get32(bgep, BGE_APE_SEG_SIG);
|
|
2428 |
if (apedata != APE_SEG_SIG_MAGIC)
|
|
2429 |
return -1;
|
|
2430 |
|
|
2431 |
apedata = bge_ape_get32(bgep, BGE_APE_FW_STATUS);
|
|
2432 |
if (!(apedata & APE_FW_STATUS_READY))
|
|
2433 |
return -1;
|
|
2434 |
|
|
2435 |
/* Wait for up to 1 millisecond for APE to service previous event. */
|
|
2436 |
err = bge_ape_event_lock(bgep, 1000);
|
|
2437 |
if (err)
|
|
2438 |
return err;
|
|
2439 |
|
|
2440 |
bge_ape_put32(bgep, BGE_APE_EVENT_STATUS,
|
|
2441 |
event | APE_EVENT_STATUS_EVENT_PENDING);
|
|
2442 |
|
|
2443 |
bge_ape_unlock(bgep, BGE_APE_LOCK_MEM);
|
|
2444 |
bge_ape_put32(bgep, BGE_APE_EVENT, APE_EVENT_1);
|
|
2445 |
|
|
2446 |
return 0;
|
|
2447 |
}
|
|
2448 |
|
|
2449 |
static void bge_ape_driver_state_change(bge_t *bgep, int mode)
|
|
2450 |
{
|
|
2451 |
uint32_t event;
|
|
2452 |
uint32_t apedata;
|
|
2453 |
|
|
2454 |
BGE_TRACE(("bge_ape_driver_state_change($%p, %d)",
|
|
2455 |
(void *)bgep, mode));
|
|
2456 |
|
|
2457 |
if (!bgep->ape_enabled)
|
|
2458 |
return;
|
|
2459 |
|
|
2460 |
switch (mode) {
|
|
2461 |
case BGE_INIT_RESET:
|
|
2462 |
bge_ape_put32(bgep, BGE_APE_HOST_SEG_SIG,
|
|
2463 |
APE_HOST_SEG_SIG_MAGIC);
|
|
2464 |
bge_ape_put32(bgep, BGE_APE_HOST_SEG_LEN,
|
|
2465 |
APE_HOST_SEG_LEN_MAGIC);
|
|
2466 |
apedata = bge_ape_get32(bgep, BGE_APE_HOST_INIT_COUNT);
|
|
2467 |
bge_ape_put32(bgep, BGE_APE_HOST_INIT_COUNT, ++apedata);
|
|
2468 |
bge_ape_put32(bgep, BGE_APE_HOST_DRIVER_ID,
|
|
2469 |
APE_HOST_DRIVER_ID_MAGIC(MAJVERSION, MINVERSION));
|
|
2470 |
bge_ape_put32(bgep, BGE_APE_HOST_BEHAVIOR,
|
|
2471 |
APE_HOST_BEHAV_NO_PHYLOCK);
|
|
2472 |
bge_ape_put32(bgep, BGE_APE_HOST_DRVR_STATE,
|
|
2473 |
BGE_APE_HOST_DRVR_STATE_START);
|
|
2474 |
|
|
2475 |
event = APE_EVENT_STATUS_STATE_START;
|
|
2476 |
break;
|
|
2477 |
case BGE_SHUTDOWN_RESET:
|
|
2478 |
/* With the interface we are currently using,
|
|
2479 |
* APE does not track driver state. Wiping
|
|
2480 |
* out the HOST SEGMENT SIGNATURE forces
|
|
2481 |
* the APE to assume OS absent status.
|
|
2482 |
*/
|
|
2483 |
bge_ape_put32(bgep, BGE_APE_HOST_SEG_SIG, 0x0);
|
|
2484 |
|
|
2485 |
#if 0
|
|
2486 |
if (WOL supported) {
|
|
2487 |
bge_ape_put32(bgep, BGE_APE_HOST_WOL_SPEED,
|
|
2488 |
BGE_APE_HOST_WOL_SPEED_AUTO);
|
|
2489 |
apedata = BGE_APE_HOST_DRVR_STATE_WOL;
|
|
2490 |
} else
|
|
2491 |
#endif
|
|
2492 |
apedata = BGE_APE_HOST_DRVR_STATE_UNLOAD;
|
|
2493 |
|
|
2494 |
bge_ape_put32(bgep, BGE_APE_HOST_DRVR_STATE, apedata);
|
|
2495 |
|
|
2496 |
event = APE_EVENT_STATUS_STATE_UNLOAD;
|
|
2497 |
break;
|
|
2498 |
case BGE_SUSPEND_RESET:
|
|
2499 |
event = APE_EVENT_STATUS_STATE_SUSPEND;
|
|
2500 |
break;
|
|
2501 |
default:
|
|
2502 |
return;
|
|
2503 |
}
|
|
2504 |
|
|
2505 |
event |= APE_EVENT_STATUS_DRIVER_EVNT | APE_EVENT_STATUS_STATE_CHNGE;
|
|
2506 |
|
|
2507 |
bge_ape_send_event(bgep, event);
|
|
2508 |
}
|
|
2509 |
|
|
2510 |
#undef BGE_DBG
|
1945 |
2511 |
#define BGE_DBG BGE_DBG_CHIP /* debug flag for this code */
|
1946 |
2512 |
|
1947 |
2513 |
static void
|
... | ... | |
1973 |
2539 |
bge_chip_id_init(bge_t *bgep)
|
1974 |
2540 |
{
|
1975 |
2541 |
char buf[MAXPATHLEN]; /* any risk of stack overflow? */
|
1976 |
|
boolean_t sys_ok;
|
1977 |
2542 |
boolean_t dev_ok;
|
1978 |
2543 |
chip_id_t *cidp;
|
1979 |
2544 |
uint32_t subid;
|
... | ... | |
1983 |
2548 |
int err;
|
1984 |
2549 |
uint_t i;
|
1985 |
2550 |
|
1986 |
|
sys_ok = dev_ok = B_FALSE;
|
|
2551 |
dev_ok = B_FALSE;
|
1987 |
2552 |
cidp = &bgep->chipid;
|
1988 |
2553 |
|
1989 |
2554 |
/*
|
... | ... | |
2026 |
2591 |
switch (cidp->device) {
|
2027 |
2592 |
case DEVICE_ID_5717:
|
2028 |
2593 |
case DEVICE_ID_5718:
|
|
2594 |
case DEVICE_ID_5719:
|
|
2595 |
case DEVICE_ID_5720:
|
2029 |
2596 |
case DEVICE_ID_5724:
|
2030 |
|
if (cidp->device == DEVICE_ID_5717)
|
|
2597 |
case DEVICE_ID_5725:
|
|
2598 |
case DEVICE_ID_5727:
|
|
2599 |
if (cidp->device == DEVICE_ID_5717) {
|
2031 |
2600 |
cidp->chip_label = 5717;
|
2032 |
|
else if (cidp->device == DEVICE_ID_5718)
|
|
2601 |
} else if (cidp->device == DEVICE_ID_5718) {
|
2033 |
2602 |
cidp->chip_label = 5718;
|
2034 |
|
else
|
|
2603 |
} else if (cidp->device == DEVICE_ID_5719) {
|
|
2604 |
cidp->chip_label = 5719;
|
|
2605 |
} else if (cidp->device == DEVICE_ID_5720) {
|
|
2606 |
if (pci_config_get16(bgep->cfg_handle, PCI_CONF_DEVID) ==
|
|
2607 |
DEVICE_ID_5717_C0) {
|
|
2608 |
cidp->chip_label = 5717;
|
|
2609 |
} else {
|
|
2610 |
cidp->chip_label = 5720;
|
|
2611 |
}
|
|
2612 |
} else if (cidp->device == DEVICE_ID_5724) {
|
2035 |
2613 |
cidp->chip_label = 5724;
|
|
2614 |
} else if (cidp->device == DEVICE_ID_5725) {
|
|
2615 |
cidp->chip_label = 5725;
|
|
2616 |
} else /* (cidp->device == DEVICE_ID_5727) */ {
|
|
2617 |
cidp->chip_label = 5727;
|
|
2618 |
}
|
2036 |
2619 |
cidp->msi_enabled = bge_enable_msi;
|
2037 |
2620 |
#ifdef __sparc
|
2038 |
2621 |
cidp->mask_pci_int = LE_32(MHCR_MASK_PCI_INT_OUTPUT);
|
... | ... | |
2048 |
2631 |
cidp->bge_mlcr_default = MLCR_DEFAULT_5717;
|
2049 |
2632 |
cidp->rx_rings = BGE_RECV_RINGS_MAX_5705;
|
2050 |
2633 |
cidp->tx_rings = BGE_SEND_RINGS_MAX_5705;
|
2051 |
|
cidp->flags |= CHIP_FLAG_NO_JUMBO;
|
2052 |
2634 |
cidp->statistic_type = BGE_STAT_REG;
|
2053 |
2635 |
dev_ok = B_TRUE;
|
2054 |
2636 |
break;
|
... | ... | |
2451 |
3033 |
* For BCM5714/5715, there is only one standard receive ring. So the
|
2452 |
3034 |
* std buffer size should be set to BGE_JUMBO_BUFF_SIZE when jumbo
|
2453 |
3035 |
* feature is enabled.
|
|
3036 |
*
|
|
3037 |
* For the BCM5718 family we hijack the standard receive ring for
|
|
3038 |
* the jumboframe traffic, keeps it simple.
|
2454 |
3039 |
*/
|
2455 |
3040 |
if (!(cidp->flags & CHIP_FLAG_NO_JUMBO) &&
|
2456 |
3041 |
(cidp->default_mtu > BGE_DEFAULT_MTU)) {
|
2457 |
|
if (DEVICE_5714_SERIES_CHIPSETS(bgep)) {
|
|
3042 |
if (DEVICE_5714_SERIES_CHIPSETS(bgep) ||
|
|
3043 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
3044 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
2458 |
3045 |
cidp->mbuf_lo_water_rdma =
|
2459 |
3046 |
RDMA_MBUF_LOWAT_5714_JUMBO;
|
2460 |
3047 |
cidp->mbuf_lo_water_rmac =
|
... | ... | |
2482 |
3069 |
cidp->nvtype = bge_nvmem_id(bgep);
|
2483 |
3070 |
|
2484 |
3071 |
/*
|
2485 |
|
* Now, we want to check whether this device is part of a
|
2486 |
|
* supported subsystem (e.g., on the motherboard of a Sun
|
2487 |
|
* branded platform).
|
2488 |
|
*
|
2489 |
|
* Rule 1: If the Subsystem Vendor ID is "Sun", then it's OK ;-)
|
2490 |
|
*/
|
2491 |
|
if (cidp->subven == VENDOR_ID_SUN)
|
2492 |
|
sys_ok = B_TRUE;
|
2493 |
|
|
2494 |
|
/*
|
2495 |
|
* Rule 2: If it's on the list on known subsystems, then it's OK.
|
2496 |
|
* Note: 0x14e41647 should *not* appear in the list, but the code
|
2497 |
|
* doesn't enforce that.
|
2498 |
|
*/
|
2499 |
|
err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, bgep->devinfo,
|
2500 |
|
DDI_PROP_DONTPASS, knownids_propname, &ids, &i);
|
2501 |
|
if (err == DDI_PROP_SUCCESS) {
|
2502 |
|
/*
|
2503 |
|
* Got the list; scan for a matching subsystem vendor/device
|
2504 |
|
*/
|
2505 |
|
subid = (cidp->subven << 16) | cidp->subdev;
|
2506 |
|
while (i--)
|
2507 |
|
if (ids[i] == subid)
|
2508 |
|
sys_ok = B_TRUE;
|
2509 |
|
ddi_prop_free(ids);
|
2510 |
|
}
|
2511 |
|
|
2512 |
|
/*
|
2513 |
|
* Rule 3: If it's a Taco/ENWS motherboard device, then it's OK
|
2514 |
|
*
|
2515 |
|
* Unfortunately, early SunBlade 1500s and 2500s didn't reprogram
|
2516 |
|
* the Subsystem Vendor ID, so it defaults to Broadcom. Therefore,
|
2517 |
|
* we have to check specially for the exact device paths to the
|
2518 |
|
* motherboard devices on those platforms ;-(
|
2519 |
|
*
|
2520 |
|
* Note: we can't just use the "supported-subsystems" mechanism
|
2521 |
|
* above, because the entry would have to be 0x14e41647 -- which
|
2522 |
|
* would then accept *any* plugin card that *didn't* contain a
|
2523 |
|
* (valid) SEEPROM ;-(
|
2524 |
|
*/
|
2525 |
|
sysname = ddi_node_name(ddi_root_node());
|
2526 |
|
devname = ddi_pathname(bgep->devinfo, buf);
|
2527 |
|
ASSERT(strlen(devname) > 0);
|
2528 |
|
if (strcmp(sysname, "SUNW,Sun-Blade-1500") == 0) /* Taco */
|
2529 |
|
if (strcmp(devname, "/pci@1f,700000/network@2") == 0)
|
2530 |
|
sys_ok = B_TRUE;
|
2531 |
|
if (strcmp(sysname, "SUNW,Sun-Blade-2500") == 0) /* ENWS */
|
2532 |
|
if (strcmp(devname, "/pci@1c,600000/network@3") == 0)
|
2533 |
|
sys_ok = B_TRUE;
|
2534 |
|
|
2535 |
|
/*
|
2536 |
3072 |
* Now check what we've discovered: is this truly a supported
|
2537 |
3073 |
* chip on (the motherboard of) a supported platform?
|
2538 |
3074 |
*
|
... | ... | |
2551 |
3087 |
"Device 'pci%04x,%04x' (%d) revision %d not supported",
|
2552 |
3088 |
cidp->vendor, cidp->device, cidp->chip_label,
|
2553 |
3089 |
cidp->revision);
|
2554 |
|
#if BGE_DEBUGGING
|
2555 |
|
else if (!sys_ok)
|
2556 |
|
bge_problem(bgep,
|
2557 |
|
"%d-based subsystem 'pci%04x,%04x' not validated",
|
2558 |
|
cidp->chip_label, cidp->subven, cidp->subdev);
|
2559 |
|
#endif
|
2560 |
3090 |
else
|
2561 |
3091 |
cidp->flags |= CHIP_FLAG_SUPPORTED;
|
|
3092 |
|
2562 |
3093 |
if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
|
2563 |
3094 |
return (EIO);
|
|
3095 |
|
2564 |
3096 |
return (0);
|
2565 |
3097 |
}
|
2566 |
3098 |
|
... | ... | |
2643 |
3175 |
bge_chip_reset_engine(bge_t *bgep, bge_regno_t regno)
|
2644 |
3176 |
{
|
2645 |
3177 |
uint32_t regval;
|
|
3178 |
uint16_t val16;
|
2646 |
3179 |
uint32_t val32;
|
|
3180 |
uint32_t mhcr;
|
2647 |
3181 |
|
2648 |
3182 |
regval = bge_reg_get32(bgep, regno);
|
2649 |
3183 |
|
... | ... | |
2663 |
3197 |
* while the reset bit is written.
|
2664 |
3198 |
* See:P500 of 57xx-PG102-RDS.pdf.
|
2665 |
3199 |
*/
|
2666 |
|
if (DEVICE_5705_SERIES_CHIPSETS(bgep)||
|
2667 |
|
DEVICE_5717_SERIES_CHIPSETS(bgep)||
|
2668 |
|
DEVICE_5721_SERIES_CHIPSETS(bgep)||
|
2669 |
|
DEVICE_5723_SERIES_CHIPSETS(bgep)||
|
2670 |
|
DEVICE_5714_SERIES_CHIPSETS(bgep)||
|
|
3200 |
if (DEVICE_5705_SERIES_CHIPSETS(bgep) ||
|
|
3201 |
DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
3202 |
DEVICE_5725_SERIES_CHIPSETS(bgep) ||
|
|
3203 |
DEVICE_5721_SERIES_CHIPSETS(bgep) ||
|
|
3204 |
DEVICE_5723_SERIES_CHIPSETS(bgep) ||
|
|
3205 |
DEVICE_5714_SERIES_CHIPSETS(bgep) ||
|
2671 |
3206 |
DEVICE_5906_SERIES_CHIPSETS(bgep)) {
|
2672 |
3207 |
regval |= MISC_CONFIG_GPHY_POWERDOWN_OVERRIDE;
|
2673 |
3208 |
if (bgep->chipid.pci_type == BGE_PCI_E) {
|
... | ... | |
2727 |
3262 |
/* PCI-E device need more reset time */
|
2728 |
3263 |
drv_usecwait(120000);
|
2729 |
3264 |
|
|
3265 |
/*
|
|
3266 |
* (re)Disable interrupts as the bit can be reset after a
|
|
3267 |
* core clock reset.
|
|
3268 |
*/
|
|
3269 |
mhcr = pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_MHCR);
|
|
3270 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR,
|
|
3271 |
mhcr | MHCR_MASK_PCI_INT_OUTPUT);
|
|
3272 |
|
2730 |
3273 |
/* Set PCIE max payload size and clear error status. */
|
2731 |
3274 |
if ((bgep->chipid.chip_label == 5721) ||
|
2732 |
3275 |
(bgep->chipid.chip_label == 5751) ||
|
... | ... | |
2746 |
3289 |
pci_config_put16(bgep->cfg_handle,
|
2747 |
3290 |
PCI_CONF_DEV_STUS_5723, DEVICE_ERROR_STUS);
|
2748 |
3291 |
}
|
|
3292 |
|
|
3293 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
3294 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
|
3295 |
val16 = pci_config_get16(bgep->cfg_handle,
|
|
3296 |
PCI_CONF_DEV_CTRL_5717);
|
|
3297 |
val16 &= ~READ_REQ_SIZE_MASK;
|
|
3298 |
val16 |= READ_REQ_SIZE_2K;
|
|
3299 |
pci_config_put16(bgep->cfg_handle,
|
|
3300 |
PCI_CONF_DEV_CTRL_5717, val16);
|
|
3301 |
}
|
2749 |
3302 |
}
|
2750 |
3303 |
|
2751 |
3304 |
BGE_PCICHK(bgep);
|
... | ... | |
2802 |
3355 |
return (B_TRUE);
|
2803 |
3356 |
|
2804 |
3357 |
default:
|
2805 |
|
regval = bge_reg_get32(bgep, regno);
|
2806 |
|
regval &= ~STATE_MACHINE_ENABLE_BIT;
|
2807 |
|
regval &= ~morebits;
|
2808 |
|
bge_reg_put32(bgep, regno, regval);
|
2809 |
|
return (bge_chip_poll_engine(bgep, regno,
|
2810 |
|
STATE_MACHINE_ENABLE_BIT, 0));
|
|
3358 |
if (DEVICE_5704_SERIES_CHIPSETS(bgep)) {
|
|
3359 |
break;
|
|
3360 |
}
|
|
3361 |
|
|
3362 |
if ((regno == RCV_LIST_SELECTOR_MODE_REG) ||
|
|
3363 |
(regno == DMA_COMPLETION_MODE_REG) ||
|
|
3364 |
(regno == MBUF_CLUSTER_FREE_MODE_REG) ||
|
|
3365 |
(regno == BUFFER_MANAGER_MODE_REG) ||
|
|
3366 |
(regno == MEMORY_ARBITER_MODE_REG)) {
|
|
3367 |
return B_TRUE;
|
|
3368 |
}
|
|
3369 |
|
|
3370 |
break;
|
2811 |
3371 |
}
|
|
3372 |
|
|
3373 |
regval = bge_reg_get32(bgep, regno);
|
|
3374 |
regval &= ~STATE_MACHINE_ENABLE_BIT;
|
|
3375 |
regval &= ~morebits;
|
|
3376 |
bge_reg_put32(bgep, regno, regval);
|
|
3377 |
|
|
3378 |
return bge_chip_poll_engine(bgep, regno, STATE_MACHINE_ENABLE_BIT, 0);
|
2812 |
3379 |
}
|
2813 |
3380 |
|
2814 |
3381 |
/*
|
... | ... | |
2880 |
3447 |
* Reprogram the Ethernet MAC mode ...
|
2881 |
3448 |
*/
|
2882 |
3449 |
macmode = regval = bge_reg_get32(bgep, ETHERNET_MAC_MODE_REG);
|
2883 |
|
if ((bgep->chipid.flags & CHIP_FLAG_SERDES) &&
|
2884 |
|
(bgep->param_loop_mode != BGE_LOOP_INTERNAL_MAC))
|
2885 |
|
if (DEVICE_5714_SERIES_CHIPSETS(bgep))
|
2886 |
|
macmode |= ETHERNET_MODE_LINK_POLARITY;
|
2887 |
|
else
|
2888 |
|
macmode &= ~ETHERNET_MODE_LINK_POLARITY;
|
2889 |
|
else
|
2890 |
|
macmode |= ETHERNET_MODE_LINK_POLARITY;
|
|
3450 |
macmode &= ~ETHERNET_MODE_LINK_POLARITY;
|
2891 |
3451 |
macmode &= ~ETHERNET_MODE_PORTMODE_MASK;
|
2892 |
3452 |
if ((bgep->chipid.flags & CHIP_FLAG_SERDES) &&
|
2893 |
3453 |
(bgep->param_loop_mode != BGE_LOOP_INTERNAL_MAC)) {
|
2894 |
|
if (DEVICE_5714_SERIES_CHIPSETS(bgep))
|
|
3454 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
3455 |
DEVICE_5725_SERIES_CHIPSETS(bgep) ||
|
|
3456 |
DEVICE_5714_SERIES_CHIPSETS(bgep))
|
2895 |
3457 |
macmode |= ETHERNET_MODE_PORTMODE_GMII;
|
2896 |
3458 |
else
|
2897 |
3459 |
macmode |= ETHERNET_MODE_PORTMODE_TBI;
|
2898 |
|
} else if (bgep->param_link_speed == 10 ||
|
2899 |
|
bgep->param_link_speed == 100)
|
|
3460 |
}
|
|
3461 |
else if (bgep->param_link_speed == 10 ||
|
|
3462 |
bgep->param_link_speed == 100)
|
2900 |
3463 |
macmode |= ETHERNET_MODE_PORTMODE_MII;
|
2901 |
3464 |
else
|
2902 |
3465 |
macmode |= ETHERNET_MODE_PORTMODE_GMII;
|
... | ... | |
3102 |
3665 |
return (retval);
|
3103 |
3666 |
}
|
3104 |
3667 |
|
3105 |
|
/*
|
3106 |
|
* This array defines the sequence of state machine control registers
|
3107 |
|
* in which the <enable> bit must be cleared to bring the chip to a
|
3108 |
|
* clean stop. Taken from Broadcom document 570X-PG102-R, p116.
|
3109 |
|
*/
|
3110 |
|
static bge_regno_t shutdown_engine_regs[] = {
|
3111 |
|
RECEIVE_MAC_MODE_REG,
|
3112 |
|
RCV_BD_INITIATOR_MODE_REG,
|
3113 |
|
RCV_LIST_PLACEMENT_MODE_REG,
|
3114 |
|
RCV_LIST_SELECTOR_MODE_REG, /* BCM5704 series only */
|
3115 |
|
RCV_DATA_BD_INITIATOR_MODE_REG,
|
3116 |
|
RCV_DATA_COMPLETION_MODE_REG,
|
3117 |
|
RCV_BD_COMPLETION_MODE_REG,
|
3118 |
|
|
3119 |
|
SEND_BD_SELECTOR_MODE_REG,
|
3120 |
|
SEND_BD_INITIATOR_MODE_REG,
|
3121 |
|
SEND_DATA_INITIATOR_MODE_REG,
|
3122 |
|
READ_DMA_MODE_REG,
|
3123 |
|
SEND_DATA_COMPLETION_MODE_REG,
|
3124 |
|
DMA_COMPLETION_MODE_REG, /* BCM5704 series only */
|
3125 |
|
SEND_BD_COMPLETION_MODE_REG,
|
3126 |
|
TRANSMIT_MAC_MODE_REG,
|
3127 |
|
|
3128 |
|
HOST_COALESCE_MODE_REG,
|
3129 |
|
WRITE_DMA_MODE_REG,
|
3130 |
|
MBUF_CLUSTER_FREE_MODE_REG, /* BCM5704 series only */
|
3131 |
|
FTQ_RESET_REG, /* special - see code */
|
3132 |
|
BUFFER_MANAGER_MODE_REG, /* BCM5704 series only */
|
3133 |
|
MEMORY_ARBITER_MODE_REG, /* BCM5704 series only */
|
3134 |
|
BGE_REGNO_NONE /* terminator */
|
3135 |
|
};
|
3136 |
|
|
3137 |
3668 |
#ifndef __sparc
|
3138 |
3669 |
static bge_regno_t quiesce_regs[] = {
|
3139 |
3670 |
READ_DMA_MODE_REG,
|
... | ... | |
3185 |
3716 |
{
|
3186 |
3717 |
bge_regno_t regno;
|
3187 |
3718 |
bge_regno_t *rbp;
|
3188 |
|
boolean_t ok;
|
|
3719 |
boolean_t ok = B_TRUE;
|
3189 |
3720 |
|
3190 |
3721 |
BGE_TRACE(("bge_chip_stop($%p)",
|
3191 |
3722 |
(void *)bgep));
|
3192 |
3723 |
|
3193 |
3724 |
ASSERT(mutex_owned(bgep->genlock));
|
3194 |
3725 |
|
3195 |
|
rbp = shutdown_engine_regs;
|
3196 |
|
/*
|
3197 |
|
* When driver try to shutdown the BCM5705/5788/5721/5751/
|
3198 |
|
* 5752/5714 and 5715 chipsets,the buffer manager and the mem
|
3199 |
|
* -ory arbiter should not be disabled.
|
3200 |
|
*/
|
3201 |
|
for (ok = B_TRUE; (regno = *rbp) != BGE_REGNO_NONE; ++rbp) {
|
3202 |
|
if (DEVICE_5704_SERIES_CHIPSETS(bgep))
|
3203 |
|
ok &= bge_chip_disable_engine(bgep, regno, 0);
|
3204 |
|
else if ((regno != RCV_LIST_SELECTOR_MODE_REG) &&
|
3205 |
|
(regno != DMA_COMPLETION_MODE_REG) &&
|
3206 |
|
(regno != MBUF_CLUSTER_FREE_MODE_REG)&&
|
3207 |
|
(regno != BUFFER_MANAGER_MODE_REG) &&
|
3208 |
|
(regno != MEMORY_ARBITER_MODE_REG))
|
3209 |
|
ok &= bge_chip_disable_engine(bgep,
|
3210 |
|
regno, 0);
|
3211 |
|
}
|
|
3726 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR,
|
|
3727 |
(pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_MHCR) |
|
|
3728 |
MHCR_MASK_PCI_INT_OUTPUT));
|
|
3729 |
|
|
3730 |
ok &= bge_chip_disable_engine(bgep, RECEIVE_MAC_MODE_REG, 0);
|
|
3731 |
ok &= bge_chip_disable_engine(bgep, RCV_BD_INITIATOR_MODE_REG, 0);
|
|
3732 |
ok &= bge_chip_disable_engine(bgep, RCV_LIST_PLACEMENT_MODE_REG, 0);
|
|
3733 |
ok &= bge_chip_disable_engine(bgep, RCV_LIST_SELECTOR_MODE_REG, 0);
|
|
3734 |
ok &= bge_chip_disable_engine(bgep, RCV_DATA_BD_INITIATOR_MODE_REG, 0);
|
|
3735 |
ok &= bge_chip_disable_engine(bgep, RCV_DATA_COMPLETION_MODE_REG, 0);
|
|
3736 |
ok &= bge_chip_disable_engine(bgep, RCV_BD_COMPLETION_MODE_REG, 0);
|
|
3737 |
|
|
3738 |
ok &= bge_chip_disable_engine(bgep, SEND_BD_SELECTOR_MODE_REG, 0);
|
|
3739 |
ok &= bge_chip_disable_engine(bgep, SEND_BD_INITIATOR_MODE_REG, 0);
|
|
3740 |
ok &= bge_chip_disable_engine(bgep, SEND_DATA_INITIATOR_MODE_REG, 0);
|
|
3741 |
ok &= bge_chip_disable_engine(bgep, READ_DMA_MODE_REG, 0);
|
|
3742 |
ok &= bge_chip_disable_engine(bgep, SEND_DATA_COMPLETION_MODE_REG, 0);
|
|
3743 |
ok &= bge_chip_disable_engine(bgep, DMA_COMPLETION_MODE_REG, 0);
|
|
3744 |
ok &= bge_chip_disable_engine(bgep, SEND_BD_COMPLETION_MODE_REG, 0);
|
|
3745 |
ok &= bge_chip_disable_engine(bgep, TRANSMIT_MAC_MODE_REG, 0);
|
|
3746 |
|
|
3747 |
bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_ENABLE_TDE);
|
|
3748 |
drv_usecwait(40);
|
|
3749 |
|
|
3750 |
ok &= bge_chip_disable_engine(bgep, HOST_COALESCE_MODE_REG, 0);
|
|
3751 |
ok &= bge_chip_disable_engine(bgep, WRITE_DMA_MODE_REG, 0);
|
|
3752 |
ok &= bge_chip_disable_engine(bgep, MBUF_CLUSTER_FREE_MODE_REG, 0);
|
|
3753 |
ok &= bge_chip_disable_engine(bgep, FTQ_RESET_REG, 0);
|
|
3754 |
ok &= bge_chip_disable_engine(bgep, BUFFER_MANAGER_MODE_REG, 0);
|
|
3755 |
ok &= bge_chip_disable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0);
|
|
3756 |
ok &= bge_chip_disable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0);
|
3212 |
3757 |
|
3213 |
3758 |
if (!ok && !fault)
|
3214 |
3759 |
ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
|
... | ... | |
3295 |
3840 |
* GENCOMM word as "the upper half of a 64-bit quantity" makes
|
3296 |
3841 |
* it work correctly on both big- and little-endian hosts.
|
3297 |
3842 |
*/
|
3298 |
|
if (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev) ==
|
3299 |
|
MHCR_CHIP_ASIC_REV_5906) {
|
|
3843 |
if (MHCR_CHIP_ASIC_REV(bgep) == MHCR_CHIP_ASIC_REV_5906) {
|
3300 |
3844 |
for (i = 0; i < 1000; ++i) {
|
3301 |
3845 |
drv_usecwait(1000);
|
3302 |
3846 |
val = bge_reg_get32(bgep, VCPU_STATUS_REG);
|
... | ... | |
3310 |
3854 |
for (i = 0; i < 1000; ++i) {
|
3311 |
3855 |
drv_usecwait(1000);
|
3312 |
3856 |
gen = bge_nic_get64(bgep, NIC_MEM_GENCOMM) >> 32;
|
|
3857 |
if (i == 0 && DEVICE_5704_SERIES_CHIPSETS(bgep))
|
|
3858 |
drv_usecwait(100000);
|
|
3859 |
mac = bge_reg_get64(bgep, MAC_ADDRESS_REG(0));
|
3313 |
3860 |
#ifdef BGE_IPMI_ASF
|
3314 |
3861 |
if (!bgep->asf_enabled) {
|
3315 |
3862 |
#endif
|
... | ... | |
3318 |
3865 |
#ifdef BGE_IPMI_ASF
|
3319 |
3866 |
}
|
3320 |
3867 |
#endif
|
3321 |
|
mac = bge_reg_get64(bgep, MAC_ADDRESS_REG(0));
|
3322 |
3868 |
if (mac != 0ULL)
|
3323 |
3869 |
break;
|
3324 |
3870 |
if (bgep->bge_chip_state != BGE_CHIP_INITIAL)
|
... | ... | |
3358 |
3904 |
chip_id_t chipid;
|
3359 |
3905 |
uint64_t mac;
|
3360 |
3906 |
uint64_t magic;
|
3361 |
|
uint32_t modeflags;
|
|
3907 |
uint32_t tmp;
|
|
3908 |
uint32_t mhcr_base;
|
3362 |
3909 |
uint32_t mhcr;
|
3363 |
3910 |
uint32_t sx0;
|
3364 |
3911 |
uint32_t i, tries;
|
... | ... | |
3395 |
3942 |
break;
|
3396 |
3943 |
}
|
3397 |
3944 |
|
|
3945 |
mhcr_base = MHCR_ENABLE_INDIRECT_ACCESS |
|
|
3946 |
MHCR_ENABLE_PCI_STATE_RW |
|
|
3947 |
MHCR_ENABLE_TAGGED_STATUS_MODE |
|
|
3948 |
MHCR_MASK_INTERRUPT_MODE |
|
|
3949 |
MHCR_MASK_PCI_INT_OUTPUT |
|
|
3950 |
MHCR_CLEAR_INTERRUPT_INTA;
|
|
3951 |
|
3398 |
3952 |
#ifdef BGE_IPMI_ASF
|
3399 |
3953 |
if (bgep->asf_enabled) {
|
3400 |
|
#ifdef __sparc
|
3401 |
|
mhcr = MHCR_ENABLE_INDIRECT_ACCESS |
|
3402 |
|
MHCR_ENABLE_TAGGED_STATUS_MODE |
|
3403 |
|
MHCR_MASK_INTERRUPT_MODE |
|
3404 |
|
MHCR_MASK_PCI_INT_OUTPUT |
|
3405 |
|
MHCR_CLEAR_INTERRUPT_INTA |
|
3406 |
|
MHCR_ENABLE_ENDIAN_WORD_SWAP |
|
3407 |
|
MHCR_ENABLE_ENDIAN_BYTE_SWAP;
|
3408 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
3409 |
|
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR,
|
3410 |
|
0);
|
|
3954 |
mhcr = mhcr_base;
|
|
3955 |
#ifdef _BIG_ENDIAN
|
|
3956 |
mhcr |= (MHCR_ENABLE_ENDIAN_WORD_SWAP |
|
|
3957 |
MHCR_ENABLE_ENDIAN_BYTE_SWAP);
|
|
3958 |
#endif
|
3411 |
3959 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcr);
|
|
3960 |
|
3412 |
3961 |
bge_reg_put32(bgep, MEMORY_ARBITER_MODE_REG,
|
3413 |
3962 |
bge_reg_get32(bgep, MEMORY_ARBITER_MODE_REG) |
|
3414 |
3963 |
MEMORY_ARBITER_ENABLE);
|
3415 |
|
#endif
|
|
3964 |
|
3416 |
3965 |
if (asf_mode == ASF_MODE_INIT) {
|
3417 |
3966 |
bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET);
|
3418 |
3967 |
} else if (asf_mode == ASF_MODE_SHUTDOWN) {
|
... | ... | |
3420 |
3969 |
}
|
3421 |
3970 |
}
|
3422 |
3971 |
#endif
|
|
3972 |
|
3423 |
3973 |
/*
|
3424 |
3974 |
* Adapted from Broadcom document 570X-PG102-R, pp 102-116.
|
3425 |
3975 |
* Updated to reflect Broadcom document 570X-PG104-R, pp 146-159.
|
... | ... | |
3434 |
3984 |
if (!bge_chip_enable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0))
|
3435 |
3985 |
retval = DDI_FAILURE;
|
3436 |
3986 |
|
3437 |
|
mhcr = MHCR_ENABLE_INDIRECT_ACCESS |
|
3438 |
|
MHCR_ENABLE_TAGGED_STATUS_MODE |
|
3439 |
|
MHCR_MASK_INTERRUPT_MODE |
|
3440 |
|
MHCR_MASK_PCI_INT_OUTPUT |
|
3441 |
|
MHCR_CLEAR_INTERRUPT_INTA;
|
3442 |
|
#ifdef _BIG_ENDIAN
|
3443 |
|
mhcr |= MHCR_ENABLE_ENDIAN_WORD_SWAP | MHCR_ENABLE_ENDIAN_BYTE_SWAP;
|
3444 |
|
#endif /* _BIG_ENDIAN */
|
3445 |
|
if (DEVICE_5717_SERIES_CHIPSETS(bgep))
|
3446 |
|
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, 0);
|
|
3987 |
mhcr = mhcr_base;
|
|
3988 |
#ifdef _BIG_ENDIAN
|
|
3989 |
mhcr |= (MHCR_ENABLE_ENDIAN_WORD_SWAP |
|
|
3990 |
MHCR_ENABLE_ENDIAN_BYTE_SWAP);
|
|
3991 |
#endif
|
3447 |
3992 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcr);
|
|
3993 |
|
3448 |
3994 |
#ifdef BGE_IPMI_ASF
|
3449 |
3995 |
if (bgep->asf_enabled)
|
3450 |
3996 |
bgep->asf_wordswapped = B_FALSE;
|
... | ... | |
3459 |
4005 |
BGE_DEBUG(("%s: fail to acquire nvram lock",
|
3460 |
4006 |
bgep->ifname));
|
3461 |
4007 |
|
|
4008 |
bge_ape_lock(bgep, BGE_APE_LOCK_GRC);
|
|
4009 |
|
3462 |
4010 |
#ifdef BGE_IPMI_ASF
|
3463 |
4011 |
if (!bgep->asf_enabled) {
|
3464 |
4012 |
#endif
|
... | ... | |
3468 |
4016 |
}
|
3469 |
4017 |
#endif
|
3470 |
4018 |
|
|
4019 |
if (DEVICE_5717_SERIES_CHIPSETS(bgep) ||
|
|
4020 |
DEVICE_5725_SERIES_CHIPSETS(bgep)) {
|
|
4021 |
bge_reg_set32(bgep, FAST_BOOT_PC, 0);
|
|
4022 |
if (!bge_chip_enable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0))
|
|
4023 |
retval = DDI_FAILURE;
|
|
4024 |
}
|
|
4025 |
|
|
4026 |
mhcr = mhcr_base;
|
|
4027 |
#ifdef _BIG_ENDIAN
|
|
4028 |
mhcr |= (MHCR_ENABLE_ENDIAN_WORD_SWAP |
|
|
4029 |
MHCR_ENABLE_ENDIAN_BYTE_SWAP);
|
|
4030 |
#endif
|
|
4031 |
pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcr);
|
|
4032 |
|
3471 |
4033 |
if (!bge_chip_reset_engine(bgep, MISC_CONFIG_REG))
|
3472 |
4034 |
retval = DDI_FAILURE;
|
|
4035 |
|
3473 |
4036 |
bge_chip_cfg_init(bgep, &chipid, enable_dma);
|
3474 |
4037 |
|
3475 |
4038 |
/*
|
... | ... | |
3485 |
4048 |
(bgep->chipid.chip_label == 5906))
|
3486 |
4049 |
bge_reg_set32(bgep, TLP_CONTROL_REG, TLP_DATA_FIFO_PROTECT);
|
3487 |
4050 |
|
3488 |
|
|
3489 |
4051 |
/*
|
3490 |
4052 |
* Step 9: enable MAC memory arbiter,bit30 and bit31 of 5714/5715 should
|
3491 |
4053 |
* not be changed.
|
... | ... | |
3502 |
4064 |
* Steps 14-15: Configure DMA endianness options. See
|
3503 |
4065 |
* the comments on the setting of the MHCR above.
|
3504 |
4066 |
*/
|
3505 |
|
#ifdef _BIG_ENDIAN
|
3506 |
|
modeflags = MODE_WORD_SWAP_FRAME | MODE_BYTE_SWAP_FRAME |
|
3507 |
|
MODE_WORD_SWAP_NONFRAME | MODE_BYTE_SWAP_NONFRAME;
|
3508 |
|
#else
|
3509 |
|
modeflags = MODE_WORD_SWAP_FRAME | MODE_BYTE_SWAP_FRAME;
|
3510 |
|
#endif /* _BIG_ENDIAN */
|
|
4067 |
tmp = MODE_WORD_SWAP_FRAME | MODE_BYTE_SWAP_FRAME;
|
|
4068 |
#ifdef _BIG_ENDIAN
|
|
4069 |
tmp |= (MODE_WORD_SWAP_NONFRAME | MODE_BYTE_SWAP_NONFRAME);
|
|
4070 |
#endif
|
3511 |
4071 |
#ifdef BGE_IPMI_ASF
|
3512 |
4072 |
if (bgep->asf_enabled)
|
3513 |
|
modeflags |= MODE_HOST_STACK_UP;
|
|
4073 |
tmp |= MODE_HOST_STACK_UP;
|
3514 |
4074 |
#endif
|
3515 |
|
bge_reg_put32(bgep, MODE_CONTROL_REG, modeflags);
|
|
4075 |
bge_reg_put32(bgep, MODE_CONTROL_REG, tmp);
|
3516 |
4076 |
|
3517 |
4077 |
#ifdef BGE_IPMI_ASF
|
3518 |
4078 |
if (bgep->asf_enabled) {
|
... | ... | |
3564 |
4124 |
#endif
|
3565 |
4125 |
}
|
3566 |
4126 |
#endif
|
|
4127 |
|
|
4128 |
bge_ape_unlock(bgep, BGE_APE_LOCK_GRC);
|
|
4129 |
|
3567 |
4130 |
/*
|
3568 |
4131 |
* Steps 16-17: poll for firmware completion
|
3569 |
4132 |
*/
|
3570 |
4133 |
mac = bge_poll_firmware(bgep);
|
3571 |
4134 |
|
|
4135 |
if (bgep->chipid.device == DEVICE_ID_5720) {
|
|
4136 |
tmp = bge_reg_get32(bgep, CPMU_CLCK_ORIDE_REG);
|
|
4137 |
bge_reg_put32(bgep, CPMU_CLCK_ORIDE_REG,
|
|
4138 |
(tmp & ~CPMU_CLCK_ORIDE_MAC_ORIDE_EN));
|
|
4139 |
}
|
|
4140 |
|
3572 |
4141 |
/*
|
3573 |
4142 |
* Step 18: enable external memory -- doesn't apply.
|
3574 |
4143 |
*
|
... | ... | |
3585 |
4154 |
*/
|
3586 |
4155 |
bge_reg_put32(bgep, MISC_LOCAL_CONTROL_REG,
|
3587 |
4156 |
bgep->chipid.bge_mlcr_default);
|
|
4157 |
|
|
4158 |
if ((bgep->chipid.flags & CHIP_FLAG_SERDES) &&
|
|
4159 |
DEVICE_5714_SERIES_CHIPSETS(bgep))
|
|
4160 |
{
|
|
4161 |
tmp = bge_reg_get32(bgep, SERDES_RX_CONTROL);
|
|
4162 |
tmp |= SERDES_RX_CONTROL_SIG_DETECT;
|
|
4163 |
bge_reg_put32(bgep, SERDES_RX_CONTROL, tmp);
|
|
4164 |
}
|
|
4165 |
|
3588 |
4166 |
bge_reg_set32(bgep, SERIAL_EEPROM_ADDRESS_REG, SEEPROM_ACCESS_INIT);
|
3589 |
4167 |
|
3590 |
4168 |
/*
|
3591 |
4169 |
* Step 20: clear the Ethernet MAC mode register
|
3592 |
4170 |
*/
|
3593 |
|
bge_reg_put32(bgep, ETHERNET_MAC_MODE_REG, 0);
|
|
4171 |
if (bgep->ape_enabled)
|
|
4172 |
bge_reg_put32(bgep, ETHERNET_MAC_MODE_REG,
|
|
4173 |
(ETHERNET_MODE_APE_TX_EN |
|
|
4174 |
ETHERNET_MODE_APE_RX_EN));
|
|
4175 |
else
|
|
4176 |
bge_reg_put32(bgep, ETHERNET_MAC_MODE_REG, 0);
|
3594 |
4177 |
|
3595 |
4178 |
/*
|
3596 |
4179 |
* Step 21: restore cache-line-size, latency timer, and
|
... | ... | |
3702 |
4285 |
uint32_t stats_mask;
|
3703 |
4286 |
uint32_t dma_wrprio;
|
3704 |
4287 |
uint64_t ring;
|