| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_wm.c,v 1.339 2015/07/15 07:40:54 msaitoh Exp $ */ | | 1 | /* $NetBSD: if_wm.c,v 1.340 2015/07/21 03:15:50 knakahara Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. | | 4 | * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. | | 7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -71,27 +71,27 @@ | | | @@ -71,27 +71,27 @@ |
71 | * Device driver for the Intel i8254x family of Gigabit Ethernet chips. | | 71 | * Device driver for the Intel i8254x family of Gigabit Ethernet chips. |
72 | * | | 72 | * |
73 | * TODO (in order of importance): | | 73 | * TODO (in order of importance): |
74 | * | | 74 | * |
75 | * - Check XXX'ed comments | | 75 | * - Check XXX'ed comments |
76 | * - EEE (Energy Efficiency Ethernet) | | 76 | * - EEE (Energy Efficiency Ethernet) |
77 | * - MSI/MSI-X | | 77 | * - MSI/MSI-X |
78 | * - Virtual Function | | 78 | * - Virtual Function |
79 | * - Set LED correctly (based on contents in EEPROM) | | 79 | * - Set LED correctly (based on contents in EEPROM) |
80 | * - Rework how parameters are loaded from the EEPROM. | | 80 | * - Rework how parameters are loaded from the EEPROM. |
81 | */ | | 81 | */ |
82 | | | 82 | |
83 | #include <sys/cdefs.h> | | 83 | #include <sys/cdefs.h> |
84 | __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.339 2015/07/15 07:40:54 msaitoh Exp $"); | | 84 | __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.340 2015/07/21 03:15:50 knakahara Exp $"); |
85 | | | 85 | |
86 | #ifdef _KERNEL_OPT | | 86 | #ifdef _KERNEL_OPT |
87 | #include "opt_net_mpsafe.h" | | 87 | #include "opt_net_mpsafe.h" |
88 | #endif | | 88 | #endif |
89 | | | 89 | |
90 | #include <sys/param.h> | | 90 | #include <sys/param.h> |
91 | #include <sys/systm.h> | | 91 | #include <sys/systm.h> |
92 | #include <sys/callout.h> | | 92 | #include <sys/callout.h> |
93 | #include <sys/mbuf.h> | | 93 | #include <sys/mbuf.h> |
94 | #include <sys/malloc.h> | | 94 | #include <sys/malloc.h> |
95 | #include <sys/kernel.h> | | 95 | #include <sys/kernel.h> |
96 | #include <sys/socket.h> | | 96 | #include <sys/socket.h> |
97 | #include <sys/ioctl.h> | | 97 | #include <sys/ioctl.h> |
| @@ -145,47 +145,49 @@ __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1. | | | @@ -145,47 +145,49 @@ __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1. |
145 | int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX | WM_DEBUG_LINK | WM_DEBUG_GMII | | 145 | int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX | WM_DEBUG_LINK | WM_DEBUG_GMII |
146 | | WM_DEBUG_MANAGE | WM_DEBUG_NVM; | | 146 | | WM_DEBUG_MANAGE | WM_DEBUG_NVM; |
147 | | | 147 | |
148 | #define DPRINTF(x, y) if (wm_debug & (x)) printf y | | 148 | #define DPRINTF(x, y) if (wm_debug & (x)) printf y |
149 | #else | | 149 | #else |
150 | #define DPRINTF(x, y) /* nothing */ | | 150 | #define DPRINTF(x, y) /* nothing */ |
151 | #endif /* WM_DEBUG */ | | 151 | #endif /* WM_DEBUG */ |
152 | | | 152 | |
153 | #ifdef NET_MPSAFE | | 153 | #ifdef NET_MPSAFE |
154 | #define WM_MPSAFE 1 | | 154 | #define WM_MPSAFE 1 |
155 | #endif | | 155 | #endif |
156 | | | 156 | |
157 | #ifdef __HAVE_PCI_MSI_MSIX | | 157 | #ifdef __HAVE_PCI_MSI_MSIX |
158 | #define WM_MSI_MSIX 1 /* Enable by default */ | | 158 | #if 0 /* off by default */ |
| | | 159 | #define WM_MSI_MSIX 1 |
| | | 160 | #endif |
159 | #endif | | 161 | #endif |
160 | | | 162 | |
161 | /* | | 163 | /* |
162 | * This device driver divides interrupt to TX, RX and link state. | | 164 | * This device driver divides interrupt to TX, RX and link state. |
163 | * Each MSI-X vector indexes are below. | | 165 | * Each MSI-X vector indexes are below. |
164 | */ | | 166 | */ |
165 | #define WM_NINTR 3 | | 167 | #define WM_MSIX_NINTR 3 |
166 | #define WM_TX_INTR_INDEX 0 | | 168 | #define WM_MSIX_TXINTR_IDX 0 |
167 | #define WM_RX_INTR_INDEX 1 | | 169 | #define WM_MSIX_RXINTR_IDX 1 |
168 | #define WM_LINK_INTR_INDEX 2 | | 170 | #define WM_MSIX_LINKINTR_IDX 2 |
169 | #define WM_MAX_NINTR WM_NINTR | | 171 | #define WM_MAX_NINTR WM_MSIX_NINTR |
170 | | | 172 | |
171 | /* | | 173 | /* |
172 | * This device driver set affinity to each interrupts like below (round-robin). | | 174 | * This device driver set affinity to each interrupts like below (round-robin). |
173 | * If the number CPUs is less than the number of interrupts, this driver usase | | 175 | * If the number CPUs is less than the number of interrupts, this driver usase |
174 | * the same CPU for multiple interrupts. | | 176 | * the same CPU for multiple interrupts. |
175 | */ | | 177 | */ |
176 | #define WM_TX_INTR_CPUID 0 | | 178 | #define WM_MSIX_TXINTR_CPUID 0 |
177 | #define WM_RX_INTR_CPUID 1 | | 179 | #define WM_MSIX_RXINTR_CPUID 1 |
178 | #define WM_LINK_INTR_CPUID 2 | | 180 | #define WM_MSIX_LINKINTR_CPUID 2 |
179 | | | 181 | |
180 | /* | | 182 | /* |
181 | * Transmit descriptor list size. Due to errata, we can only have | | 183 | * Transmit descriptor list size. Due to errata, we can only have |
182 | * 256 hardware descriptors in the ring on < 82544, but we use 4096 | | 184 | * 256 hardware descriptors in the ring on < 82544, but we use 4096 |
183 | * on >= 82544. We tell the upper layers that they can queue a lot | | 185 | * on >= 82544. We tell the upper layers that they can queue a lot |
184 | * of packets, and we go ahead and manage up to 64 (16 for the i82547) | | 186 | * of packets, and we go ahead and manage up to 64 (16 for the i82547) |
185 | * of them at a time. | | 187 | * of them at a time. |
186 | * | | 188 | * |
187 | * We allow up to 256 (!) DMA segments per packet. Pathological packet | | 189 | * We allow up to 256 (!) DMA segments per packet. Pathological packet |
188 | * chains containing many small mbufs have been observed in zero-copy | | 190 | * chains containing many small mbufs have been observed in zero-copy |
189 | * situations with jumbo frames. | | 191 | * situations with jumbo frames. |
190 | */ | | 192 | */ |
191 | #define WM_NTXSEGS 256 | | 193 | #define WM_NTXSEGS 256 |
| @@ -768,26 +770,40 @@ static void wm_set_eee_i350(struct wm_so | | | @@ -768,26 +770,40 @@ static void wm_set_eee_i350(struct wm_so |
768 | * Basically, PHY's workarounds are in the PHY drivers. | | 770 | * Basically, PHY's workarounds are in the PHY drivers. |
769 | */ | | 771 | */ |
770 | static void wm_kmrn_lock_loss_workaround_ich8lan(struct wm_softc *); | | 772 | static void wm_kmrn_lock_loss_workaround_ich8lan(struct wm_softc *); |
771 | static void wm_gig_downshift_workaround_ich8lan(struct wm_softc *); | | 773 | static void wm_gig_downshift_workaround_ich8lan(struct wm_softc *); |
772 | static void wm_hv_phy_workaround_ich8lan(struct wm_softc *); | | 774 | static void wm_hv_phy_workaround_ich8lan(struct wm_softc *); |
773 | static void wm_lv_phy_workaround_ich8lan(struct wm_softc *); | | 775 | static void wm_lv_phy_workaround_ich8lan(struct wm_softc *); |
774 | static void wm_k1_gig_workaround_hv(struct wm_softc *, int); | | 776 | static void wm_k1_gig_workaround_hv(struct wm_softc *, int); |
775 | static void wm_set_mdio_slow_mode_hv(struct wm_softc *); | | 777 | static void wm_set_mdio_slow_mode_hv(struct wm_softc *); |
776 | static void wm_configure_k1_ich8lan(struct wm_softc *, int); | | 778 | static void wm_configure_k1_ich8lan(struct wm_softc *, int); |
777 | static void wm_reset_init_script_82575(struct wm_softc *); | | 779 | static void wm_reset_init_script_82575(struct wm_softc *); |
778 | static void wm_reset_mdicnfg_82580(struct wm_softc *); | | 780 | static void wm_reset_mdicnfg_82580(struct wm_softc *); |
779 | static void wm_pll_workaround_i210(struct wm_softc *); | | 781 | static void wm_pll_workaround_i210(struct wm_softc *); |
780 | | | 782 | |
| | | 783 | #ifdef WM_MSI_MSIX |
| | | 784 | struct _msix_matrix { |
| | | 785 | const char *intrname; |
| | | 786 | int(*func)(void *); |
| | | 787 | int intridx; |
| | | 788 | int cpuid; |
| | | 789 | } msix_matrix[WM_MSIX_NINTR] = { |
| | | 790 | { "TX", wm_txintr_msix, WM_MSIX_TXINTR_IDX, WM_MSIX_TXINTR_CPUID }, |
| | | 791 | { "RX", wm_rxintr_msix, WM_MSIX_RXINTR_IDX, WM_MSIX_TXINTR_CPUID }, |
| | | 792 | { "LINK", wm_linkintr_msix, WM_MSIX_LINKINTR_IDX, |
| | | 793 | WM_MSIX_LINKINTR_CPUID }, |
| | | 794 | }; |
| | | 795 | #endif |
| | | 796 | |
781 | CFATTACH_DECL3_NEW(wm, sizeof(struct wm_softc), | | 797 | CFATTACH_DECL3_NEW(wm, sizeof(struct wm_softc), |
782 | wm_match, wm_attach, wm_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); | | 798 | wm_match, wm_attach, wm_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); |
783 | | | 799 | |
784 | /* | | 800 | /* |
785 | * Devices supported by this driver. | | 801 | * Devices supported by this driver. |
786 | */ | | 802 | */ |
787 | static const struct wm_product { | | 803 | static const struct wm_product { |
788 | pci_vendor_id_t wmp_vendor; | | 804 | pci_vendor_id_t wmp_vendor; |
789 | pci_product_id_t wmp_product; | | 805 | pci_product_id_t wmp_product; |
790 | const char *wmp_name; | | 806 | const char *wmp_name; |
791 | wm_chip_type wmp_type; | | 807 | wm_chip_type wmp_type; |
792 | uint32_t wmp_flags; | | 808 | uint32_t wmp_flags; |
793 | #define WMP_F_UNKNOWN WM_MEDIATYPE_UNKNOWN | | 809 | #define WMP_F_UNKNOWN WM_MEDIATYPE_UNKNOWN |
| @@ -1396,27 +1412,28 @@ wm_match(device_t parent, cfdata_t cf, v | | | @@ -1396,27 +1412,28 @@ wm_match(device_t parent, cfdata_t cf, v |
1396 | | | 1412 | |
1397 | /* The attach function (ca_attach) */ | | 1413 | /* The attach function (ca_attach) */ |
1398 | static void | | 1414 | static void |
1399 | wm_attach(device_t parent, device_t self, void *aux) | | 1415 | wm_attach(device_t parent, device_t self, void *aux) |
1400 | { | | 1416 | { |
1401 | struct wm_softc *sc = device_private(self); | | 1417 | struct wm_softc *sc = device_private(self); |
1402 | struct pci_attach_args *pa = aux; | | 1418 | struct pci_attach_args *pa = aux; |
1403 | prop_dictionary_t dict; | | 1419 | prop_dictionary_t dict; |
1404 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | | 1420 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
1405 | pci_chipset_tag_t pc = pa->pa_pc; | | 1421 | pci_chipset_tag_t pc = pa->pa_pc; |
1406 | #ifndef WM_MSI_MSIX | | 1422 | #ifndef WM_MSI_MSIX |
1407 | pci_intr_handle_t ih; | | 1423 | pci_intr_handle_t ih; |
1408 | #else | | 1424 | #else |
1409 | bool intr_established = false; | | 1425 | int counts[PCI_INTR_TYPE_SIZE]; |
| | | 1426 | pci_intr_type_t max_type; |
1410 | #endif | | 1427 | #endif |
1411 | const char *intrstr = NULL; | | 1428 | const char *intrstr = NULL; |
1412 | const char *eetype, *xname; | | 1429 | const char *eetype, *xname; |
1413 | bus_space_tag_t memt; | | 1430 | bus_space_tag_t memt; |
1414 | bus_space_handle_t memh; | | 1431 | bus_space_handle_t memh; |
1415 | bus_size_t memsize; | | 1432 | bus_size_t memsize; |
1416 | int memh_valid; | | 1433 | int memh_valid; |
1417 | int i, error; | | 1434 | int i, error; |
1418 | const struct wm_product *wmp; | | 1435 | const struct wm_product *wmp; |
1419 | prop_data_t ea; | | 1436 | prop_data_t ea; |
1420 | prop_number_t pn; | | 1437 | prop_number_t pn; |
1421 | uint8_t enaddr[ETHER_ADDR_LEN]; | | 1438 | uint8_t enaddr[ETHER_ADDR_LEN]; |
1422 | uint16_t cfg1, cfg2, swdpin, nvmword; | | 1439 | uint16_t cfg1, cfg2, swdpin, nvmword; |
| @@ -1587,187 +1604,119 @@ wm_attach(device_t parent, device_t self | | | @@ -1587,187 +1604,119 @@ wm_attach(device_t parent, device_t self |
1587 | pci_intr_setattr(pc, &ih, PCI_INTR_MPSAFE, true); | | 1604 | pci_intr_setattr(pc, &ih, PCI_INTR_MPSAFE, true); |
1588 | #endif | | 1605 | #endif |
1589 | sc->sc_ihs[0] = pci_intr_establish(pc, ih, IPL_NET, wm_intr_legacy,sc); | | 1606 | sc->sc_ihs[0] = pci_intr_establish(pc, ih, IPL_NET, wm_intr_legacy,sc); |
1590 | if (sc->sc_ihs[0] == NULL) { | | 1607 | if (sc->sc_ihs[0] == NULL) { |
1591 | aprint_error_dev(sc->sc_dev, "unable to establish interrupt"); | | 1608 | aprint_error_dev(sc->sc_dev, "unable to establish interrupt"); |
1592 | if (intrstr != NULL) | | 1609 | if (intrstr != NULL) |
1593 | aprint_error(" at %s", intrstr); | | 1610 | aprint_error(" at %s", intrstr); |
1594 | aprint_error("\n"); | | 1611 | aprint_error("\n"); |
1595 | return; | | 1612 | return; |
1596 | } | | 1613 | } |
1597 | aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); | | 1614 | aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); |
1598 | sc->sc_nintrs = 1; | | 1615 | sc->sc_nintrs = 1; |
1599 | #else /* WM_MSI_MSIX */ | | 1616 | #else /* WM_MSI_MSIX */ |
1600 | if (pci_msix_alloc_exact(pa, &sc->sc_intrs, WM_NINTR) == 0) { | | 1617 | /* Allocation settings */ |
1601 | /* 1st, try to use MSI-X */ | | 1618 | max_type = PCI_INTR_TYPE_MSIX; |
| | | 1619 | counts[PCI_INTR_TYPE_MSIX] = WM_MAX_NINTR; |
| | | 1620 | counts[PCI_INTR_TYPE_MSI] = 1; |
| | | 1621 | counts[PCI_INTR_TYPE_INTX] = 1; |
| | | 1622 | |
| | | 1623 | alloc_retry: |
| | | 1624 | if (pci_intr_alloc(pa, &sc->sc_intrs, counts, max_type) != 0) { |
| | | 1625 | aprint_error_dev(sc->sc_dev, "failed to allocate interrupt\n"); |
| | | 1626 | return; |
| | | 1627 | } |
| | | 1628 | |
| | | 1629 | if (pci_intr_type(sc->sc_intrs[0]) == PCI_INTR_TYPE_MSIX) { |
1602 | void *vih; | | 1630 | void *vih; |
1603 | kcpuset_t *affinity; | | 1631 | kcpuset_t *affinity; |
1604 | | | 1632 | |
1605 | kcpuset_create(&affinity, false); | | 1633 | kcpuset_create(&affinity, false); |
1606 | | | 1634 | |
1607 | /* | | 1635 | for (i = 0; i < WM_MSIX_NINTR; i++) { |
1608 | * for TX | | 1636 | intrstr = pci_intr_string(pc, |
1609 | */ | | 1637 | sc->sc_intrs[msix_matrix[i].intridx], intrbuf, |
1610 | intrstr = pci_intr_string(pc, sc->sc_intrs[WM_TX_INTR_INDEX], | | 1638 | sizeof(intrbuf)); |
1611 | intrbuf, sizeof(intrbuf)); | | | |
1612 | #ifdef WM_MPSAFE | | 1639 | #ifdef WM_MPSAFE |
1613 | pci_intr_setattr(pc, &sc->sc_intrs[WM_TX_INTR_INDEX], | | 1640 | pci_intr_setattr(pc, |
1614 | PCI_INTR_MPSAFE, true); | | 1641 | &sc->sc_intrs[msix_matrix[i].intridx], |
1615 | #endif | | 1642 | PCI_INTR_MPSAFE, true); |
1616 | vih = pci_intr_establish(pc, sc->sc_intrs[WM_TX_INTR_INDEX], | | 1643 | #endif |
1617 | IPL_NET, wm_txintr_msix, sc); | | 1644 | vih = pci_intr_establish(pc, |
1618 | if (vih == NULL) { | | 1645 | sc->sc_intrs[msix_matrix[i].intridx], IPL_NET, |
1619 | aprint_error_dev(sc->sc_dev, | | 1646 | msix_matrix[i].func, sc); |
1620 | "unable to establish MSI-X(for TX)%s%s\n", | | 1647 | if (vih == NULL) { |
1621 | intrstr ? " at " : "", intrstr ? intrstr : ""); | | 1648 | aprint_error_dev(sc->sc_dev, |
1622 | pci_intr_release(sc->sc_pc, sc->sc_intrs, | | 1649 | "unable to establish MSI-X(for %s)%s%s\n", |
1623 | WM_NINTR); | | 1650 | msix_matrix[i].intrname, |
1624 | goto msi; | | 1651 | intrstr ? " at " : "", |
1625 | } | | 1652 | intrstr ? intrstr : ""); |
1626 | kcpuset_zero(affinity); | | 1653 | pci_intr_release(sc->sc_pc, sc->sc_intrs, |
1627 | /* Round-robin affinity */ | | 1654 | WM_MSIX_NINTR); |
1628 | kcpuset_set(affinity, WM_TX_INTR_CPUID % ncpu); | | 1655 | kcpuset_destroy(affinity); |
1629 | error = pci_intr_distribute(vih, affinity, NULL); | | 1656 | |
1630 | if (error == 0) { | | 1657 | /* Setup for MSI: Disable MSI-X */ |
1631 | aprint_normal_dev(sc->sc_dev, | | 1658 | max_type = PCI_INTR_TYPE_MSI; |
1632 | "for TX interrupting at %s affinity to %u\n", | | 1659 | counts[PCI_INTR_TYPE_MSI] = 1; |
1633 | intrstr, WM_TX_INTR_CPUID % ncpu); | | 1660 | counts[PCI_INTR_TYPE_INTX] = 1; |
1634 | } else { | | 1661 | goto alloc_retry; |
1635 | aprint_normal_dev(sc->sc_dev, | | 1662 | } |
1636 | "for TX interrupting at %s\n", | | 1663 | kcpuset_zero(affinity); |
1637 | intrstr); | | 1664 | /* Round-robin affinity */ |
1638 | } | | 1665 | kcpuset_set(affinity, msix_matrix[i].cpuid % ncpu); |
1639 | sc->sc_ihs[WM_TX_INTR_INDEX] = vih; | | 1666 | error = pci_intr_distribute(vih, affinity, NULL); |
1640 | | | 1667 | if (error == 0) { |
1641 | /* | | 1668 | aprint_normal_dev(sc->sc_dev, |
1642 | * for RX | | 1669 | "for TX interrupting at %s affinity to %u\n", |
1643 | */ | | 1670 | intrstr, msix_matrix[i].cpuid % ncpu); |
1644 | intrstr = pci_intr_string(pc, sc->sc_intrs[WM_RX_INTR_INDEX], | | 1671 | } else { |
1645 | intrbuf, sizeof(intrbuf)); | | 1672 | aprint_normal_dev(sc->sc_dev, |
1646 | #ifdef WM_MPSAFE | | 1673 | "for TX interrupting at %s\n", intrstr); |
1647 | pci_intr_setattr(pc, &sc->sc_intrs[WM_RX_INTR_INDEX], | | 1674 | } |
1648 | PCI_INTR_MPSAFE, true); | | 1675 | sc->sc_ihs[msix_matrix[i].intridx] = vih; |
1649 | #endif | | | |
1650 | vih = pci_intr_establish(pc, sc->sc_intrs[WM_RX_INTR_INDEX], | | | |
1651 | IPL_NET, wm_rxintr_msix, sc); | | | |
1652 | if (vih == NULL) { | | | |
1653 | aprint_error_dev(sc->sc_dev, | | | |
1654 | "unable to establish MSI-X(for RX)%s%s\n", | | | |
1655 | intrstr ? " at " : "", intrstr ? intrstr : ""); | | | |
1656 | pci_intr_release(sc->sc_pc, sc->sc_intrs, | | | |
1657 | WM_NINTR); | | | |
1658 | goto msi; | | | |
1659 | } | | | |
1660 | kcpuset_zero(affinity); | | | |
1661 | kcpuset_set(affinity, WM_RX_INTR_CPUID % ncpu); | | | |
1662 | error = pci_intr_distribute(vih, affinity, NULL); | | | |
1663 | if (error == 0) { | | | |
1664 | aprint_normal_dev(sc->sc_dev, | | | |
1665 | "for RX interrupting at %s affinity to %u\n", | | | |
1666 | intrstr, WM_RX_INTR_CPUID % ncpu); | | | |
1667 | } else { | | | |
1668 | aprint_normal_dev(sc->sc_dev, | | | |
1669 | "for RX interrupting at %s\n", | | | |
1670 | intrstr); | | | |
1671 | } | | | |
1672 | sc->sc_ihs[WM_RX_INTR_INDEX] = vih; | | | |
1673 | | | | |
1674 | /* | | | |
1675 | * for link state changing | | | |
1676 | */ | | | |
1677 | intrstr = pci_intr_string(pc, sc->sc_intrs[WM_LINK_INTR_INDEX], | | | |
1678 | intrbuf, sizeof(intrbuf)); | | | |
1679 | #ifdef WM_MPSAFE | | | |
1680 | pci_intr_setattr(pc, &sc->sc_intrs[WM_LINK_INTR_INDEX], | | | |
1681 | PCI_INTR_MPSAFE, true); | | | |
1682 | #endif | | | |
1683 | vih = pci_intr_establish(pc, sc->sc_intrs[WM_LINK_INTR_INDEX], | | | |
1684 | IPL_NET, wm_linkintr_msix, sc); | | | |
1685 | if (vih == NULL) { | | | |
1686 | aprint_error_dev(sc->sc_dev, | | | |
1687 | "unable to establish MSI-X(for LINK)%s%s\n", | | | |
1688 | intrstr ? " at " : "", intrstr ? intrstr : ""); | | | |
1689 | pci_intr_release(sc->sc_pc, sc->sc_intrs, | | | |
1690 | WM_NINTR); | | | |
1691 | goto msi; | | | |
1692 | } | | | |
1693 | kcpuset_zero(affinity); | | | |
1694 | kcpuset_set(affinity, WM_LINK_INTR_CPUID % ncpu); | | | |
1695 | error = pci_intr_distribute(vih, affinity, NULL); | | | |
1696 | if (error == 0) { | | | |
1697 | aprint_normal_dev(sc->sc_dev, | | | |
1698 | "for LINK interrupting at %s affinity to %u\n", | | | |
1699 | intrstr, WM_LINK_INTR_CPUID % ncpu); | | | |
1700 | } else { | | | |
1701 | aprint_normal_dev(sc->sc_dev, | | | |
1702 | "for LINK interrupting at %s\n", | | | |
1703 | intrstr); | | | |
1704 | } | | 1676 | } |
1705 | sc->sc_ihs[WM_LINK_INTR_INDEX] = vih; | | | |
1706 | | | 1677 | |
1707 | sc->sc_nintrs = WM_NINTR; | | 1678 | sc->sc_nintrs = WM_MSIX_NINTR; |
1708 | kcpuset_destroy(affinity); | | 1679 | kcpuset_destroy(affinity); |
1709 | intr_established = true; | | 1680 | } else { |
1710 | } | | 1681 | /* MSI or INTx */ |
1711 | | | | |
1712 | msi: | | | |
1713 | if ((intr_established == false) | | | |
1714 | && (pci_msi_alloc_exact(pa, &sc->sc_intrs, 1) == 0)) { | | | |
1715 | /* 2nd, try to use MSI */ | | | |
1716 | intrstr = pci_intr_string(pc, sc->sc_intrs[0], intrbuf, | | | |
1717 | sizeof(intrbuf)); | | | |
1718 | #ifdef WM_MPSAFE | | | |
1719 | pci_intr_setattr(pc, &sc->sc_intrs[0], PCI_INTR_MPSAFE, true); | | | |
1720 | #endif | | | |
1721 | sc->sc_ihs[0] = pci_intr_establish(pc, sc->sc_intrs[0], | | | |
1722 | IPL_NET, wm_intr_legacy, sc); | | | |
1723 | if (sc->sc_ihs[0] == NULL) { | | | |
1724 | aprint_error_dev(sc->sc_dev, "unable to establish MSI\n"); | | | |
1725 | pci_intr_release(sc->sc_pc, sc->sc_intrs, | | | |
1726 | 1); | | | |
1727 | goto intx; | | | |
1728 | } | | | |
1729 | aprint_normal_dev(sc->sc_dev, "MSI at %s\n", intrstr); | | | |
1730 | | | | |
1731 | sc->sc_nintrs = 1; | | | |
1732 | intr_established = true; | | | |
1733 | } | | | |
1734 | | | | |
1735 | intx: | | | |
1736 | if ((intr_established == false) | | | |
1737 | && (pci_intx_alloc(pa, &sc->sc_intrs) == 0)) { | | | |
1738 | /* Last, try to use INTx */ | | | |
1739 | intrstr = pci_intr_string(pc, sc->sc_intrs[0], intrbuf, | | 1682 | intrstr = pci_intr_string(pc, sc->sc_intrs[0], intrbuf, |
1740 | sizeof(intrbuf)); | | 1683 | sizeof(intrbuf)); |
1741 | #ifdef WM_MPSAFE | | 1684 | #ifdef WM_MPSAFE |
1742 | pci_intr_setattr(pc, &sc->sc_intrs[0], PCI_INTR_MPSAFE, true); | | 1685 | pci_intr_setattr(pc, &sc->sc_intrs[0], PCI_INTR_MPSAFE, true); |
1743 | #endif | | 1686 | #endif |
1744 | sc->sc_ihs[0] = pci_intr_establish(pc, sc->sc_intrs[0], | | 1687 | sc->sc_ihs[0] = pci_intr_establish(pc, sc->sc_intrs[0], |
1745 | IPL_NET, wm_intr_legacy, sc); | | 1688 | IPL_NET, wm_intr_legacy, sc); |
1746 | if (sc->sc_ihs[0] == NULL) { | | 1689 | if (sc->sc_ihs[0] == NULL) { |
1747 | aprint_error_dev(sc->sc_dev, "unable to establish MSI\n"); | | 1690 | aprint_error_dev(sc->sc_dev,"unable to establish %s\n", |
| | | 1691 | (pci_intr_type(sc->sc_intrs[0]) |
| | | 1692 | == PCI_INTR_TYPE_MSI) ? "MSI" : "INTx"); |
1748 | pci_intr_release(sc->sc_pc, sc->sc_intrs, 1); | | 1693 | pci_intr_release(sc->sc_pc, sc->sc_intrs, 1); |
1749 | goto int_failed; | | 1694 | switch (pci_intr_type(sc->sc_intrs[0])) { |
| | | 1695 | case PCI_INTR_TYPE_MSI: |
| | | 1696 | /* The next try is for INTx: Disable MSI */ |
| | | 1697 | max_type = PCI_INTR_TYPE_INTX; |
| | | 1698 | counts[PCI_INTR_TYPE_INTX] = 1; |
| | | 1699 | goto alloc_retry; |
| | | 1700 | case PCI_INTR_TYPE_INTX: |
| | | 1701 | default: |
| | | 1702 | return; |
| | | 1703 | } |
1750 | } | | 1704 | } |
1751 | aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); | | 1705 | aprint_normal_dev(sc->sc_dev, "%s at %s\n", |
| | | 1706 | (pci_intr_type(sc->sc_intrs[0]) == PCI_INTR_TYPE_MSI) |
| | | 1707 | ? "MSI" : "interrupting", intrstr); |
1752 | | | 1708 | |
1753 | sc->sc_nintrs = 1; | | 1709 | sc->sc_nintrs = 1; |
1754 | intr_established = true; | | | |
1755 | } | | | |
1756 | | | | |
1757 | int_failed: | | | |
1758 | if (intr_established == false) { | | | |
1759 | aprint_error_dev(sc->sc_dev, "failed to allocate interrput\n"); | | | |
1760 | return; | | | |
1761 | } | | 1710 | } |
1762 | #endif /* WM_MSI_MSIX */ | | 1711 | #endif /* WM_MSI_MSIX */ |
1763 | | | 1712 | |
1764 | /* | | 1713 | /* |
1765 | * Check the function ID (unit number of the chip). | | 1714 | * Check the function ID (unit number of the chip). |
1766 | */ | | 1715 | */ |
1767 | if ((sc->sc_type == WM_T_82546) || (sc->sc_type == WM_T_82546_3) | | 1716 | if ((sc->sc_type == WM_T_82546) || (sc->sc_type == WM_T_82546_3) |
1768 | || (sc->sc_type == WM_T_82571) || (sc->sc_type == WM_T_80003) | | 1717 | || (sc->sc_type == WM_T_82571) || (sc->sc_type == WM_T_80003) |
1769 | || (sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) | | 1718 | || (sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) |
1770 | || (sc->sc_type == WM_T_82580) | | 1719 | || (sc->sc_type == WM_T_82580) |
1771 | || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354)) | | 1720 | || (sc->sc_type == WM_T_I350) || (sc->sc_type == WM_T_I354)) |
1772 | sc->sc_funcid = (CSR_READ(sc, WMREG_STATUS) | | 1721 | sc->sc_funcid = (CSR_READ(sc, WMREG_STATUS) |
1773 | >> STATUS_FUNCID_SHIFT) & STATUS_FUNCID_MASK; | | 1722 | >> STATUS_FUNCID_SHIFT) & STATUS_FUNCID_MASK; |
| @@ -4536,125 +4485,126 @@ wm_init_locked(struct ifnet *ifp) | | | @@ -4536,125 +4485,126 @@ wm_init_locked(struct ifnet *ifp) |
4536 | CSR_WRITE(sc, WMREG_RXCSUM, reg); | | 4485 | CSR_WRITE(sc, WMREG_RXCSUM, reg); |
4537 | | | 4486 | |
4538 | /* Set up MSI-X */ | | 4487 | /* Set up MSI-X */ |
4539 | if (sc->sc_nintrs > 1) { | | 4488 | if (sc->sc_nintrs > 1) { |
4540 | uint32_t ivar; | | 4489 | uint32_t ivar; |
4541 | | | 4490 | |
4542 | if (sc->sc_type == WM_T_82575) { | | 4491 | if (sc->sc_type == WM_T_82575) { |
4543 | /* Interrupt control */ | | 4492 | /* Interrupt control */ |
4544 | reg = CSR_READ(sc, WMREG_CTRL_EXT); | | 4493 | reg = CSR_READ(sc, WMREG_CTRL_EXT); |
4545 | reg |= CTRL_EXT_PBA | CTRL_EXT_EIAME | CTRL_EXT_NSICR; | | 4494 | reg |= CTRL_EXT_PBA | CTRL_EXT_EIAME | CTRL_EXT_NSICR; |
4546 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg); | | 4495 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg); |
4547 | | | 4496 | |
4548 | /* TX */ | | 4497 | /* TX */ |
4549 | CSR_WRITE(sc, WMREG_MSIXBM(WM_TX_INTR_INDEX), | | 4498 | CSR_WRITE(sc, WMREG_MSIXBM(WM_MSIX_TXINTR_IDX), |
4550 | EITR_TX_QUEUE0); | | 4499 | EITR_TX_QUEUE0); |
4551 | /* RX */ | | 4500 | /* RX */ |
4552 | CSR_WRITE(sc, WMREG_MSIXBM(WM_RX_INTR_INDEX), | | 4501 | CSR_WRITE(sc, WMREG_MSIXBM(WM_MSIX_RXINTR_IDX), |
4553 | EITR_RX_QUEUE0); | | 4502 | EITR_RX_QUEUE0); |
4554 | /* Link status */ | | 4503 | /* Link status */ |
4555 | CSR_WRITE(sc, WMREG_MSIXBM(WM_LINK_INTR_INDEX), | | 4504 | CSR_WRITE(sc, WMREG_MSIXBM(WM_MSIX_LINKINTR_IDX), |
4556 | EITR_OTHER); | | 4505 | EITR_OTHER); |
4557 | } else if (sc->sc_type == WM_T_82574) { | | 4506 | } else if (sc->sc_type == WM_T_82574) { |
4558 | /* Interrupt control */ | | 4507 | /* Interrupt control */ |
4559 | reg = CSR_READ(sc, WMREG_CTRL_EXT); | | 4508 | reg = CSR_READ(sc, WMREG_CTRL_EXT); |
4560 | reg |= CTRL_EXT_PBA | CTRL_EXT_EIAME; | | 4509 | reg |= CTRL_EXT_PBA | CTRL_EXT_EIAME; |
4561 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg); | | 4510 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg); |
4562 | | | 4511 | |
4563 | /* TX, RX and Link status */ | | 4512 | /* TX, RX and Link status */ |
4564 | ivar = __SHIFTIN((IVAR_VALID_82574 | WM_TX_INTR_INDEX), | | 4513 | ivar = __SHIFTIN((IVAR_VALID_82574|WM_MSIX_TXINTR_IDX), |
4565 | IVAR_TX_MASK_Q_82574(0)); | | 4514 | IVAR_TX_MASK_Q_82574(0)); |
4566 | ivar |= __SHIFTIN((IVAR_VALID_82574 |WM_RX_INTR_INDEX), | | 4515 | ivar |= __SHIFTIN((IVAR_VALID_82574 |
| | | 4516 | | WM_MSIX_RXINTR_IDX), |
4567 | IVAR_RX_MASK_Q_82574(0)); | | 4517 | IVAR_RX_MASK_Q_82574(0)); |
4568 | ivar |=__SHIFTIN((IVAR_VALID_82574|WM_LINK_INTR_INDEX), | | 4518 | ivar |=__SHIFTIN((IVAR_VALID_82574|WM_MSIX_LINKINTR_IDX), |
4569 | IVAR_OTHER_MASK); | | 4519 | IVAR_OTHER_MASK); |
4570 | CSR_WRITE(sc, WMREG_IVAR, ivar | IVAR_INT_ON_ALL_WB); | | 4520 | CSR_WRITE(sc, WMREG_IVAR, ivar | IVAR_INT_ON_ALL_WB); |
4571 | } else { | | 4521 | } else { |
4572 | /* Interrupt control */ | | 4522 | /* Interrupt control */ |
4573 | CSR_WRITE(sc, WMREG_GPIE, GPIE_NSICR | | 4523 | CSR_WRITE(sc, WMREG_GPIE, GPIE_NSICR |
4574 | | GPIE_MULTI_MSIX | GPIE_EIAME | | 4524 | | GPIE_MULTI_MSIX | GPIE_EIAME |
4575 | | GPIE_PBA); | | 4525 | | GPIE_PBA); |
4576 | | | 4526 | |
4577 | switch (sc->sc_type) { | | 4527 | switch (sc->sc_type) { |
4578 | case WM_T_82580: | | 4528 | case WM_T_82580: |
4579 | case WM_T_I350: | | 4529 | case WM_T_I350: |
4580 | case WM_T_I354: | | 4530 | case WM_T_I354: |
4581 | case WM_T_I210: | | 4531 | case WM_T_I210: |
4582 | case WM_T_I211: | | 4532 | case WM_T_I211: |
4583 | /* TX */ | | 4533 | /* TX */ |
4584 | ivar = CSR_READ(sc, WMREG_IVAR_Q(0)); | | 4534 | ivar = CSR_READ(sc, WMREG_IVAR_Q(0)); |
4585 | ivar &= ~IVAR_TX_MASK_Q(0); | | 4535 | ivar &= ~IVAR_TX_MASK_Q(0); |
4586 | ivar |= __SHIFTIN( | | 4536 | ivar |= __SHIFTIN( |
4587 | (WM_TX_INTR_INDEX | IVAR_VALID), | | 4537 | (WM_MSIX_TXINTR_IDX | IVAR_VALID), |
4588 | IVAR_TX_MASK_Q(0)); | | 4538 | IVAR_TX_MASK_Q(0)); |
4589 | CSR_WRITE(sc, WMREG_IVAR_Q(0), ivar); | | 4539 | CSR_WRITE(sc, WMREG_IVAR_Q(0), ivar); |
4590 | | | 4540 | |
4591 | /* RX */ | | 4541 | /* RX */ |
4592 | ivar = CSR_READ(sc, WMREG_IVAR_Q(0)); | | 4542 | ivar = CSR_READ(sc, WMREG_IVAR_Q(0)); |
4593 | ivar &= ~IVAR_RX_MASK_Q(0); | | 4543 | ivar &= ~IVAR_RX_MASK_Q(0); |
4594 | ivar |= __SHIFTIN( | | 4544 | ivar |= __SHIFTIN( |
4595 | (WM_RX_INTR_INDEX | IVAR_VALID), | | 4545 | (WM_MSIX_RXINTR_IDX | IVAR_VALID), |
4596 | IVAR_RX_MASK_Q(0)); | | 4546 | IVAR_RX_MASK_Q(0)); |
4597 | CSR_WRITE(sc, WMREG_IVAR_Q(0), ivar); | | 4547 | CSR_WRITE(sc, WMREG_IVAR_Q(0), ivar); |
4598 | break; | | 4548 | break; |
4599 | case WM_T_82576: | | 4549 | case WM_T_82576: |
4600 | /* TX */ | | 4550 | /* TX */ |
4601 | ivar = CSR_READ(sc, WMREG_IVAR_Q_82576(0)); | | 4551 | ivar = CSR_READ(sc, WMREG_IVAR_Q_82576(0)); |
4602 | ivar &= ~IVAR_TX_MASK_Q_82576(0); | | 4552 | ivar &= ~IVAR_TX_MASK_Q_82576(0); |
4603 | ivar |= __SHIFTIN( | | 4553 | ivar |= __SHIFTIN( |
4604 | (WM_TX_INTR_INDEX | IVAR_VALID), | | 4554 | (WM_MSIX_TXINTR_IDX | IVAR_VALID), |
4605 | IVAR_TX_MASK_Q_82576(0)); | | 4555 | IVAR_TX_MASK_Q_82576(0)); |
4606 | CSR_WRITE(sc, WMREG_IVAR_Q_82576(0), ivar); | | 4556 | CSR_WRITE(sc, WMREG_IVAR_Q_82576(0), ivar); |
4607 | | | 4557 | |
4608 | /* RX */ | | 4558 | /* RX */ |
4609 | ivar = CSR_READ(sc, WMREG_IVAR_Q_82576(0)); | | 4559 | ivar = CSR_READ(sc, WMREG_IVAR_Q_82576(0)); |
4610 | ivar &= ~IVAR_RX_MASK_Q_82576(0); | | 4560 | ivar &= ~IVAR_RX_MASK_Q_82576(0); |
4611 | ivar |= __SHIFTIN( | | 4561 | ivar |= __SHIFTIN( |
4612 | (WM_RX_INTR_INDEX | IVAR_VALID), | | 4562 | (WM_MSIX_RXINTR_IDX | IVAR_VALID), |
4613 | IVAR_RX_MASK_Q_82576(0)); | | 4563 | IVAR_RX_MASK_Q_82576(0)); |
4614 | CSR_WRITE(sc, WMREG_IVAR_Q_82576(0), ivar); | | 4564 | CSR_WRITE(sc, WMREG_IVAR_Q_82576(0), ivar); |
4615 | break; | | 4565 | break; |
4616 | default: | | 4566 | default: |
4617 | break; | | 4567 | break; |
4618 | } | | 4568 | } |
4619 | | | 4569 | |
4620 | /* Link status */ | | 4570 | /* Link status */ |
4621 | ivar = __SHIFTIN((WM_LINK_INTR_INDEX | IVAR_VALID), | | 4571 | ivar = __SHIFTIN((WM_MSIX_LINKINTR_IDX | IVAR_VALID), |
4622 | IVAR_MISC_OTHER); | | 4572 | IVAR_MISC_OTHER); |
4623 | CSR_WRITE(sc, WMREG_IVAR_MISC, ivar); | | 4573 | CSR_WRITE(sc, WMREG_IVAR_MISC, ivar); |
4624 | } | | 4574 | } |
4625 | } | | 4575 | } |
4626 | | | 4576 | |
4627 | /* Set up the interrupt registers. */ | | 4577 | /* Set up the interrupt registers. */ |
4628 | CSR_WRITE(sc, WMREG_IMC, 0xffffffffU); | | 4578 | CSR_WRITE(sc, WMREG_IMC, 0xffffffffU); |
4629 | sc->sc_icr = ICR_TXDW | ICR_LSC | ICR_RXSEQ | ICR_RXDMT0 | | | 4579 | sc->sc_icr = ICR_TXDW | ICR_LSC | ICR_RXSEQ | ICR_RXDMT0 | |
4630 | ICR_RXO | ICR_RXT0; | | 4580 | ICR_RXO | ICR_RXT0; |
4631 | if (sc->sc_nintrs > 1) { | | 4581 | if (sc->sc_nintrs > 1) { |
4632 | uint32_t mask; | | 4582 | uint32_t mask; |
4633 | switch (sc->sc_type) { | | 4583 | switch (sc->sc_type) { |
4634 | case WM_T_82574: | | 4584 | case WM_T_82574: |
4635 | CSR_WRITE(sc, WMREG_EIAC_82574, | | 4585 | CSR_WRITE(sc, WMREG_EIAC_82574, |
4636 | WMREG_EIAC_82574_MSIX_MASK); | | 4586 | WMREG_EIAC_82574_MSIX_MASK); |
4637 | sc->sc_icr |= WMREG_EIAC_82574_MSIX_MASK; | | 4587 | sc->sc_icr |= WMREG_EIAC_82574_MSIX_MASK; |
4638 | CSR_WRITE(sc, WMREG_IMS, sc->sc_icr); | | 4588 | CSR_WRITE(sc, WMREG_IMS, sc->sc_icr); |
4639 | break; | | 4589 | break; |
4640 | default: | | 4590 | default: |
4641 | if (sc->sc_type == WM_T_82575) | | 4591 | if (sc->sc_type == WM_T_82575) |
4642 | mask = EITR_RX_QUEUE0 |EITR_TX_QUEUE0 | | 4592 | mask = EITR_RX_QUEUE0 |EITR_TX_QUEUE0 |
4643 | | EITR_OTHER; | | 4593 | | EITR_OTHER; |
4644 | else | | 4594 | else |
4645 | mask = (1 << WM_RX_INTR_INDEX) | | 4595 | mask = (1 << WM_MSIX_RXINTR_IDX) |
4646 | | (1 << WM_TX_INTR_INDEX) | | 4596 | | (1 << WM_MSIX_TXINTR_IDX) |
4647 | | (1 << WM_LINK_INTR_INDEX); | | 4597 | | (1 << WM_MSIX_LINKINTR_IDX); |
4648 | CSR_WRITE(sc, WMREG_EIAC, mask); | | 4598 | CSR_WRITE(sc, WMREG_EIAC, mask); |
4649 | CSR_WRITE(sc, WMREG_EIAM, mask); | | 4599 | CSR_WRITE(sc, WMREG_EIAM, mask); |
4650 | CSR_WRITE(sc, WMREG_EIMS, mask); | | 4600 | CSR_WRITE(sc, WMREG_EIMS, mask); |
4651 | CSR_WRITE(sc, WMREG_IMS, ICR_LSC); | | 4601 | CSR_WRITE(sc, WMREG_IMS, ICR_LSC); |
4652 | break; | | 4602 | break; |
4653 | } | | 4603 | } |
4654 | } else | | 4604 | } else |
4655 | CSR_WRITE(sc, WMREG_IMS, sc->sc_icr); | | 4605 | CSR_WRITE(sc, WMREG_IMS, sc->sc_icr); |
4656 | | | 4606 | |
4657 | if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9) | | 4607 | if ((sc->sc_type == WM_T_ICH8) || (sc->sc_type == WM_T_ICH9) |
4658 | || (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH) | | 4608 | || (sc->sc_type == WM_T_ICH10) || (sc->sc_type == WM_T_PCH) |
4659 | || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)) { | | 4609 | || (sc->sc_type == WM_T_PCH2) || (sc->sc_type == WM_T_PCH_LPT)) { |
4660 | reg = CSR_READ(sc, WMREG_KABGTXD); | | 4610 | reg = CSR_READ(sc, WMREG_KABGTXD); |
| @@ -6642,45 +6592,45 @@ wm_txintr_msix(void *arg) | | | @@ -6642,45 +6592,45 @@ wm_txintr_msix(void *arg) |
6642 | { | | 6592 | { |
6643 | struct wm_softc *sc = arg; | | 6593 | struct wm_softc *sc = arg; |
6644 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | | 6594 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
6645 | int handled = 0; | | 6595 | int handled = 0; |
6646 | | | 6596 | |
6647 | DPRINTF(WM_DEBUG_TX, | | 6597 | DPRINTF(WM_DEBUG_TX, |
6648 | ("%s: TX: got Tx intr\n", device_xname(sc->sc_dev))); | | 6598 | ("%s: TX: got Tx intr\n", device_xname(sc->sc_dev))); |
6649 | | | 6599 | |
6650 | if (sc->sc_type == WM_T_82574) | | 6600 | if (sc->sc_type == WM_T_82574) |
6651 | CSR_WRITE(sc, WMREG_IMC, ICR_TXQ0); /* 82574 only */ | | 6601 | CSR_WRITE(sc, WMREG_IMC, ICR_TXQ0); /* 82574 only */ |
6652 | else if (sc->sc_type == WM_T_82575) | | 6602 | else if (sc->sc_type == WM_T_82575) |
6653 | CSR_WRITE(sc, WMREG_EIMC, EITR_TX_QUEUE0); | | 6603 | CSR_WRITE(sc, WMREG_EIMC, EITR_TX_QUEUE0); |
6654 | else | | 6604 | else |
6655 | CSR_WRITE(sc, WMREG_EIMC, 1 << WM_TX_INTR_INDEX); | | 6605 | CSR_WRITE(sc, WMREG_EIMC, 1 << WM_MSIX_TXINTR_IDX); |
6656 | | | 6606 | |
6657 | WM_TX_LOCK(sc); | | 6607 | WM_TX_LOCK(sc); |
6658 | | | 6608 | |
6659 | if (sc->sc_stopping) | | 6609 | if (sc->sc_stopping) |
6660 | goto out; | | 6610 | goto out; |
6661 | | | 6611 | |
6662 | WM_EVCNT_INCR(&sc->sc_ev_txdw); | | 6612 | WM_EVCNT_INCR(&sc->sc_ev_txdw); |
6663 | handled = wm_txeof(sc); | | 6613 | handled = wm_txeof(sc); |
6664 | | | 6614 | |
6665 | out: | | 6615 | out: |
6666 | WM_TX_UNLOCK(sc); | | 6616 | WM_TX_UNLOCK(sc); |
6667 | | | 6617 | |
6668 | if (sc->sc_type == WM_T_82574) | | 6618 | if (sc->sc_type == WM_T_82574) |
6669 | CSR_WRITE(sc, WMREG_IMS, ICR_TXQ0); /* 82574 only */ | | 6619 | CSR_WRITE(sc, WMREG_IMS, ICR_TXQ0); /* 82574 only */ |
6670 | else if (sc->sc_type == WM_T_82575) | | 6620 | else if (sc->sc_type == WM_T_82575) |
6671 | CSR_WRITE(sc, WMREG_EIMS, EITR_TX_QUEUE0); | | 6621 | CSR_WRITE(sc, WMREG_EIMS, EITR_TX_QUEUE0); |
6672 | else | | 6622 | else |
6673 | CSR_WRITE(sc, WMREG_EIMS, 1 << WM_TX_INTR_INDEX); | | 6623 | CSR_WRITE(sc, WMREG_EIMS, 1 << WM_MSIX_TXINTR_IDX); |
6674 | | | 6624 | |
6675 | if (handled) { | | 6625 | if (handled) { |
6676 | /* Try to get more packets going. */ | | 6626 | /* Try to get more packets going. */ |
6677 | ifp->if_start(ifp); | | 6627 | ifp->if_start(ifp); |
6678 | } | | 6628 | } |
6679 | | | 6629 | |
6680 | return handled; | | 6630 | return handled; |
6681 | } | | 6631 | } |
6682 | | | 6632 | |
6683 | /* | | 6633 | /* |
6684 | * wm_rxintr_msix: | | 6634 | * wm_rxintr_msix: |
6685 | * | | 6635 | * |
6686 | * Interrupt service routine for RX interrupt for MSI-X. | | 6636 | * Interrupt service routine for RX interrupt for MSI-X. |
| @@ -6688,84 +6638,84 @@ out: | | | @@ -6688,84 +6638,84 @@ out: |
6688 | static int | | 6638 | static int |
6689 | wm_rxintr_msix(void *arg) | | 6639 | wm_rxintr_msix(void *arg) |
6690 | { | | 6640 | { |
6691 | struct wm_softc *sc = arg; | | 6641 | struct wm_softc *sc = arg; |
6692 | | | 6642 | |
6693 | DPRINTF(WM_DEBUG_TX, | | 6643 | DPRINTF(WM_DEBUG_TX, |
6694 | ("%s: RX: got Rx intr\n", device_xname(sc->sc_dev))); | | 6644 | ("%s: RX: got Rx intr\n", device_xname(sc->sc_dev))); |
6695 | | | 6645 | |
6696 | if (sc->sc_type == WM_T_82574) | | 6646 | if (sc->sc_type == WM_T_82574) |
6697 | CSR_WRITE(sc, WMREG_IMC, ICR_RXQ0); /* 82574 only */ | | 6647 | CSR_WRITE(sc, WMREG_IMC, ICR_RXQ0); /* 82574 only */ |
6698 | else if (sc->sc_type == WM_T_82575) | | 6648 | else if (sc->sc_type == WM_T_82575) |
6699 | CSR_WRITE(sc, WMREG_EIMC, EITR_RX_QUEUE0); | | 6649 | CSR_WRITE(sc, WMREG_EIMC, EITR_RX_QUEUE0); |
6700 | else | | 6650 | else |
6701 | CSR_WRITE(sc, WMREG_EIMC, 1 << WM_RX_INTR_INDEX); | | 6651 | CSR_WRITE(sc, WMREG_EIMC, 1 << WM_MSIX_RXINTR_IDX); |
6702 | | | 6652 | |
6703 | WM_RX_LOCK(sc); | | 6653 | WM_RX_LOCK(sc); |
6704 | | | 6654 | |
6705 | if (sc->sc_stopping) | | 6655 | if (sc->sc_stopping) |
6706 | goto out; | | 6656 | goto out; |
6707 | | | 6657 | |
6708 | WM_EVCNT_INCR(&sc->sc_ev_rxintr); | | 6658 | WM_EVCNT_INCR(&sc->sc_ev_rxintr); |
6709 | wm_rxeof(sc); | | 6659 | wm_rxeof(sc); |
6710 | | | 6660 | |
6711 | out: | | 6661 | out: |
6712 | WM_RX_UNLOCK(sc); | | 6662 | WM_RX_UNLOCK(sc); |
6713 | | | 6663 | |
6714 | if (sc->sc_type == WM_T_82574) | | 6664 | if (sc->sc_type == WM_T_82574) |
6715 | CSR_WRITE(sc, WMREG_IMS, ICR_RXQ0); | | 6665 | CSR_WRITE(sc, WMREG_IMS, ICR_RXQ0); |
6716 | else if (sc->sc_type == WM_T_82575) | | 6666 | else if (sc->sc_type == WM_T_82575) |
6717 | CSR_WRITE(sc, WMREG_EIMS, EITR_RX_QUEUE0); | | 6667 | CSR_WRITE(sc, WMREG_EIMS, EITR_RX_QUEUE0); |
6718 | else | | 6668 | else |
6719 | CSR_WRITE(sc, WMREG_EIMS, 1 << WM_RX_INTR_INDEX); | | 6669 | CSR_WRITE(sc, WMREG_EIMS, 1 << WM_MSIX_RXINTR_IDX); |
6720 | | | 6670 | |
6721 | return 1; | | 6671 | return 1; |
6722 | } | | 6672 | } |
6723 | | | 6673 | |
6724 | /* | | 6674 | /* |
6725 | * wm_linkintr_msix: | | 6675 | * wm_linkintr_msix: |
6726 | * | | 6676 | * |
6727 | * Interrupt service routine for link status change for MSI-X. | | 6677 | * Interrupt service routine for link status change for MSI-X. |
6728 | */ | | 6678 | */ |
6729 | static int | | 6679 | static int |
6730 | wm_linkintr_msix(void *arg) | | 6680 | wm_linkintr_msix(void *arg) |
6731 | { | | 6681 | { |
6732 | struct wm_softc *sc = arg; | | 6682 | struct wm_softc *sc = arg; |
6733 | | | 6683 | |
6734 | DPRINTF(WM_DEBUG_TX, | | 6684 | DPRINTF(WM_DEBUG_TX, |
6735 | ("%s: LINK: got link intr\n", device_xname(sc->sc_dev))); | | 6685 | ("%s: LINK: got link intr\n", device_xname(sc->sc_dev))); |
6736 | | | 6686 | |
6737 | if (sc->sc_type == WM_T_82574) | | 6687 | if (sc->sc_type == WM_T_82574) |
6738 | CSR_WRITE(sc, WMREG_IMC, ICR_OTHER); /* 82574 only */ | | 6688 | CSR_WRITE(sc, WMREG_IMC, ICR_OTHER); /* 82574 only */ |
6739 | else if (sc->sc_type == WM_T_82575) | | 6689 | else if (sc->sc_type == WM_T_82575) |
6740 | CSR_WRITE(sc, WMREG_EIMC, EITR_OTHER); | | 6690 | CSR_WRITE(sc, WMREG_EIMC, EITR_OTHER); |
6741 | else | | 6691 | else |
6742 | CSR_WRITE(sc, WMREG_EIMC, 1 << WM_LINK_INTR_INDEX); | | 6692 | CSR_WRITE(sc, WMREG_EIMC, 1 << WM_MSIX_LINKINTR_IDX); |
6743 | WM_TX_LOCK(sc); | | 6693 | WM_TX_LOCK(sc); |
6744 | if (sc->sc_stopping) | | 6694 | if (sc->sc_stopping) |
6745 | goto out; | | 6695 | goto out; |
6746 | | | 6696 | |
6747 | WM_EVCNT_INCR(&sc->sc_ev_linkintr); | | 6697 | WM_EVCNT_INCR(&sc->sc_ev_linkintr); |
6748 | wm_linkintr(sc, ICR_LSC); | | 6698 | wm_linkintr(sc, ICR_LSC); |
6749 | | | 6699 | |
6750 | out: | | 6700 | out: |
6751 | WM_TX_UNLOCK(sc); | | 6701 | WM_TX_UNLOCK(sc); |
6752 | | | 6702 | |
6753 | if (sc->sc_type == WM_T_82574) | | 6703 | if (sc->sc_type == WM_T_82574) |
6754 | CSR_WRITE(sc, WMREG_IMS, ICR_OTHER | ICR_LSC); /* 82574 only */ | | 6704 | CSR_WRITE(sc, WMREG_IMS, ICR_OTHER | ICR_LSC); /* 82574 only */ |
6755 | else if (sc->sc_type == WM_T_82575) | | 6705 | else if (sc->sc_type == WM_T_82575) |
6756 | CSR_WRITE(sc, WMREG_EIMS, EITR_OTHER); | | 6706 | CSR_WRITE(sc, WMREG_EIMS, EITR_OTHER); |
6757 | else | | 6707 | else |
6758 | CSR_WRITE(sc, WMREG_EIMS, 1 << WM_LINK_INTR_INDEX); | | 6708 | CSR_WRITE(sc, WMREG_EIMS, 1 << WM_MSIX_LINKINTR_IDX); |
6759 | | | 6709 | |
6760 | return 1; | | 6710 | return 1; |
6761 | } | | 6711 | } |
6762 | #endif /* WM_MSI_MSIX */ | | 6712 | #endif /* WM_MSI_MSIX */ |
6763 | | | 6713 | |
6764 | /* | | 6714 | /* |
6765 | * Media related. | | 6715 | * Media related. |
6766 | * GMII, SGMII, TBI (and SERDES) | | 6716 | * GMII, SGMII, TBI (and SERDES) |
6767 | */ | | 6717 | */ |
6768 | | | 6718 | |
6769 | /* Common */ | | 6719 | /* Common */ |
6770 | | | 6720 | |
6771 | /* | | 6721 | /* |