| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_wm.c,v 1.445 2016/11/16 07:24:52 msaitoh Exp $ */ | | 1 | /* $NetBSD: if_wm.c,v 1.446 2016/11/16 08:14:39 msaitoh 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 |
| @@ -74,27 +74,27 @@ | | | @@ -74,27 +74,27 @@ |
74 | * | | 74 | * |
75 | * - Check XXX'ed comments | | 75 | * - Check XXX'ed comments |
76 | * - Disable D0 LPLU on 8257[12356], 82580 and I350. | | 76 | * - Disable D0 LPLU on 8257[12356], 82580 and I350. |
77 | * - TX Multi queue improvement (refine queue selection logic) | | 77 | * - TX Multi queue improvement (refine queue selection logic) |
78 | * - Advanced Receive Descriptor | | 78 | * - Advanced Receive Descriptor |
79 | * - EEE (Energy Efficiency Ethernet) | | 79 | * - EEE (Energy Efficiency Ethernet) |
80 | * - Virtual Function | | 80 | * - Virtual Function |
81 | * - Set LED correctly (based on contents in EEPROM) | | 81 | * - Set LED correctly (based on contents in EEPROM) |
82 | * - Rework how parameters are loaded from the EEPROM. | | 82 | * - Rework how parameters are loaded from the EEPROM. |
83 | * - Image Unique ID | | 83 | * - Image Unique ID |
84 | */ | | 84 | */ |
85 | | | 85 | |
86 | #include <sys/cdefs.h> | | 86 | #include <sys/cdefs.h> |
87 | __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.445 2016/11/16 07:24:52 msaitoh Exp $"); | | 87 | __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.446 2016/11/16 08:14:39 msaitoh Exp $"); |
88 | | | 88 | |
89 | #ifdef _KERNEL_OPT | | 89 | #ifdef _KERNEL_OPT |
90 | #include "opt_net_mpsafe.h" | | 90 | #include "opt_net_mpsafe.h" |
91 | #endif | | 91 | #endif |
92 | | | 92 | |
93 | #include <sys/param.h> | | 93 | #include <sys/param.h> |
94 | #include <sys/systm.h> | | 94 | #include <sys/systm.h> |
95 | #include <sys/callout.h> | | 95 | #include <sys/callout.h> |
96 | #include <sys/mbuf.h> | | 96 | #include <sys/mbuf.h> |
97 | #include <sys/malloc.h> | | 97 | #include <sys/malloc.h> |
98 | #include <sys/kmem.h> | | 98 | #include <sys/kmem.h> |
99 | #include <sys/kernel.h> | | 99 | #include <sys/kernel.h> |
100 | #include <sys/socket.h> | | 100 | #include <sys/socket.h> |
| @@ -2181,47 +2181,30 @@ alloc_retry: | | | @@ -2181,47 +2181,30 @@ alloc_retry: |
2181 | if ((sc->sc_nvm_ver_major < 3) | | 2181 | if ((sc->sc_nvm_ver_major < 3) |
2182 | || ((sc->sc_nvm_ver_major == 3) | | 2182 | || ((sc->sc_nvm_ver_major == 3) |
2183 | && (sc->sc_nvm_ver_minor < 25))) { | | 2183 | && (sc->sc_nvm_ver_minor < 25))) { |
2184 | aprint_verbose_dev(sc->sc_dev, | | 2184 | aprint_verbose_dev(sc->sc_dev, |
2185 | "ROM image version %d.%d is older than 3.25\n", | | 2185 | "ROM image version %d.%d is older than 3.25\n", |
2186 | sc->sc_nvm_ver_major, sc->sc_nvm_ver_minor); | | 2186 | sc->sc_nvm_ver_major, sc->sc_nvm_ver_minor); |
2187 | sc->sc_flags |= WM_F_PLL_WA_I210; | | 2187 | sc->sc_flags |= WM_F_PLL_WA_I210; |
2188 | } | | 2188 | } |
2189 | } | | 2189 | } |
2190 | if ((sc->sc_flags & WM_F_PLL_WA_I210) != 0) | | 2190 | if ((sc->sc_flags & WM_F_PLL_WA_I210) != 0) |
2191 | wm_pll_workaround_i210(sc); | | 2191 | wm_pll_workaround_i210(sc); |
2192 | | | 2192 | |
2193 | wm_get_wakeup(sc); | | 2193 | wm_get_wakeup(sc); |
2194 | switch (sc->sc_type) { | | 2194 | |
2195 | case WM_T_82571: | | 2195 | /* Non-AMT based hardware can now take control from firmware */ |
2196 | case WM_T_82572: | | 2196 | if ((sc->sc_flags & WM_F_HAS_AMT) == 0) |
2197 | case WM_T_82573: | | 2197 | wm_get_hw_control(sc); |
2198 | case WM_T_82574: | | | |
2199 | case WM_T_82583: | | | |
2200 | case WM_T_80003: | | | |
2201 | case WM_T_ICH8: | | | |
2202 | case WM_T_ICH9: | | | |
2203 | case WM_T_ICH10: | | | |
2204 | case WM_T_PCH: | | | |
2205 | case WM_T_PCH2: | | | |
2206 | case WM_T_PCH_LPT: | | | |
2207 | case WM_T_PCH_SPT: | | | |
2208 | /* Non-AMT based hardware can now take control from firmware */ | | | |
2209 | if ((sc->sc_flags & WM_F_HAS_AMT) == 0) | | | |
2210 | wm_get_hw_control(sc); | | | |
2211 | break; | | | |
2212 | default: | | | |
2213 | break; | | | |
2214 | } | | | |
2215 | | | 2198 | |
2216 | /* | | 2199 | /* |
2217 | * Read the Ethernet address from the EEPROM, if not first found | | 2200 | * Read the Ethernet address from the EEPROM, if not first found |
2218 | * in device properties. | | 2201 | * in device properties. |
2219 | */ | | 2202 | */ |
2220 | ea = prop_dictionary_get(dict, "mac-address"); | | 2203 | ea = prop_dictionary_get(dict, "mac-address"); |
2221 | if (ea != NULL) { | | 2204 | if (ea != NULL) { |
2222 | KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); | | 2205 | KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); |
2223 | KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); | | 2206 | KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); |
2224 | memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN); | | 2207 | memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN); |
2225 | } else { | | 2208 | } else { |
2226 | if (wm_read_mac_addr(sc, enaddr) != 0) { | | 2209 | if (wm_read_mac_addr(sc, enaddr) != 0) { |
2227 | aprint_error_dev(sc->sc_dev, | | 2210 | aprint_error_dev(sc->sc_dev, |
| @@ -4738,47 +4721,29 @@ wm_init_locked(struct ifnet *ifp) | | | @@ -4738,47 +4721,29 @@ wm_init_locked(struct ifnet *ifp) |
4738 | wm_stop_locked(ifp, 0); | | 4721 | wm_stop_locked(ifp, 0); |
4739 | | | 4722 | |
4740 | /* update statistics before reset */ | | 4723 | /* update statistics before reset */ |
4741 | ifp->if_collisions += CSR_READ(sc, WMREG_COLC); | | 4724 | ifp->if_collisions += CSR_READ(sc, WMREG_COLC); |
4742 | ifp->if_ierrors += CSR_READ(sc, WMREG_RXERRC); | | 4725 | ifp->if_ierrors += CSR_READ(sc, WMREG_RXERRC); |
4743 | | | 4726 | |
4744 | /* PCH_SPT hardware workaround */ | | 4727 | /* PCH_SPT hardware workaround */ |
4745 | if (sc->sc_type == WM_T_PCH_SPT) | | 4728 | if (sc->sc_type == WM_T_PCH_SPT) |
4746 | wm_flush_desc_rings(sc); | | 4729 | wm_flush_desc_rings(sc); |
4747 | | | 4730 | |
4748 | /* Reset the chip to a known state. */ | | 4731 | /* Reset the chip to a known state. */ |
4749 | wm_reset(sc); | | 4732 | wm_reset(sc); |
4750 | | | 4733 | |
4751 | switch (sc->sc_type) { | | 4734 | /* AMT based hardware can now take control from firmware */ |
4752 | case WM_T_82571: | | 4735 | if ((sc->sc_flags & WM_F_HAS_AMT) != 0) |
4753 | case WM_T_82572: | | 4736 | wm_get_hw_control(sc); |
4754 | case WM_T_82573: | | | |
4755 | case WM_T_82574: | | | |
4756 | case WM_T_82583: | | | |
4757 | case WM_T_80003: | | | |
4758 | case WM_T_ICH8: | | | |
4759 | case WM_T_ICH9: | | | |
4760 | case WM_T_ICH10: | | | |
4761 | case WM_T_PCH: | | | |
4762 | case WM_T_PCH2: | | | |
4763 | case WM_T_PCH_LPT: | | | |
4764 | case WM_T_PCH_SPT: | | | |
4765 | /* AMT based hardware can now take control from firmware */ | | | |
4766 | if ((sc->sc_flags & WM_F_HAS_AMT) != 0) | | | |
4767 | wm_get_hw_control(sc); | | | |
4768 | break; | | | |
4769 | default: | | | |
4770 | break; | | | |
4771 | } | | | |
4772 | | | 4737 | |
4773 | /* Init hardware bits */ | | 4738 | /* Init hardware bits */ |
4774 | wm_initialize_hardware_bits(sc); | | 4739 | wm_initialize_hardware_bits(sc); |
4775 | | | 4740 | |
4776 | /* Reset the PHY. */ | | 4741 | /* Reset the PHY. */ |
4777 | if (sc->sc_flags & WM_F_HAS_MII) | | 4742 | if (sc->sc_flags & WM_F_HAS_MII) |
4778 | wm_gmii_reset(sc); | | 4743 | wm_gmii_reset(sc); |
4779 | | | 4744 | |
4780 | /* Calculate (E)ITR value */ | | 4745 | /* Calculate (E)ITR value */ |
4781 | if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) { | | 4746 | if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) { |
4782 | sc->sc_itr = 450; /* For EITR */ | | 4747 | sc->sc_itr = 450; /* For EITR */ |
4783 | } else if (sc->sc_type >= WM_T_82543) { | | 4748 | } else if (sc->sc_type >= WM_T_82543) { |
4784 | /* | | 4749 | /* |
| @@ -11876,66 +11841,47 @@ wm_phy_resetisblocked(struct wm_softc *s | | | @@ -11876,66 +11841,47 @@ wm_phy_resetisblocked(struct wm_softc *s |
11876 | } | | 11841 | } |
11877 | | | 11842 | |
11878 | return false; | | 11843 | return false; |
11879 | } | | 11844 | } |
11880 | | | 11845 | |
11881 | static void | | 11846 | static void |
11882 | wm_get_hw_control(struct wm_softc *sc) | | 11847 | wm_get_hw_control(struct wm_softc *sc) |
11883 | { | | 11848 | { |
11884 | uint32_t reg; | | 11849 | uint32_t reg; |
11885 | | | 11850 | |
11886 | DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n", | | 11851 | DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n", |
11887 | device_xname(sc->sc_dev), __func__)); | | 11852 | device_xname(sc->sc_dev), __func__)); |
11888 | | | 11853 | |
11889 | switch (sc->sc_type) { | | 11854 | if (sc->sc_type == WM_T_82573) { |
11890 | case WM_T_82573: | | | |
11891 | reg = CSR_READ(sc, WMREG_SWSM); | | 11855 | reg = CSR_READ(sc, WMREG_SWSM); |
11892 | CSR_WRITE(sc, WMREG_SWSM, reg | SWSM_DRV_LOAD); | | 11856 | CSR_WRITE(sc, WMREG_SWSM, reg | SWSM_DRV_LOAD); |
11893 | break; | | 11857 | } else if (sc->sc_type >= WM_T_82571) { |
11894 | case WM_T_82571: | | | |
11895 | case WM_T_82572: | | | |
11896 | case WM_T_82574: | | | |
11897 | case WM_T_82583: | | | |
11898 | case WM_T_80003: | | | |
11899 | case WM_T_ICH8: | | | |
11900 | case WM_T_ICH9: | | | |
11901 | case WM_T_ICH10: | | | |
11902 | case WM_T_PCH: | | | |
11903 | case WM_T_PCH2: | | | |
11904 | case WM_T_PCH_LPT: | | | |
11905 | case WM_T_PCH_SPT: | | | |
11906 | reg = CSR_READ(sc, WMREG_CTRL_EXT); | | 11858 | reg = CSR_READ(sc, WMREG_CTRL_EXT); |
11907 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_DRV_LOAD); | | 11859 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg | CTRL_EXT_DRV_LOAD); |
11908 | break; | | | |
11909 | default: | | | |
11910 | break; | | | |
11911 | } | | 11860 | } |
11912 | } | | 11861 | } |
11913 | | | 11862 | |
11914 | static void | | 11863 | static void |
11915 | wm_release_hw_control(struct wm_softc *sc) | | 11864 | wm_release_hw_control(struct wm_softc *sc) |
11916 | { | | 11865 | { |
11917 | uint32_t reg; | | 11866 | uint32_t reg; |
11918 | | | 11867 | |
11919 | DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n", | | 11868 | DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n", |
11920 | device_xname(sc->sc_dev), __func__)); | | 11869 | device_xname(sc->sc_dev), __func__)); |
11921 | | | 11870 | |
11922 | if ((sc->sc_flags & WM_F_HAS_MANAGE) == 0) | | | |
11923 | return; | | | |
11924 | | | | |
11925 | if (sc->sc_type == WM_T_82573) { | | 11871 | if (sc->sc_type == WM_T_82573) { |
11926 | reg = CSR_READ(sc, WMREG_SWSM); | | 11872 | reg = CSR_READ(sc, WMREG_SWSM); |
11927 | CSR_WRITE(sc, WMREG_SWSM, reg & ~SWSM_DRV_LOAD); | | 11873 | CSR_WRITE(sc, WMREG_SWSM, reg & ~SWSM_DRV_LOAD); |
11928 | } else { | | 11874 | } else if (sc->sc_type >= WM_T_82571) { |
11929 | reg = CSR_READ(sc, WMREG_CTRL_EXT); | | 11875 | reg = CSR_READ(sc, WMREG_CTRL_EXT); |
11930 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg & ~CTRL_EXT_DRV_LOAD); | | 11876 | CSR_WRITE(sc, WMREG_CTRL_EXT, reg & ~CTRL_EXT_DRV_LOAD); |
11931 | } | | 11877 | } |
11932 | } | | 11878 | } |
11933 | | | 11879 | |
11934 | static void | | 11880 | static void |
11935 | wm_gate_hw_phy_config_ich8lan(struct wm_softc *sc, bool gate) | | 11881 | wm_gate_hw_phy_config_ich8lan(struct wm_softc *sc, bool gate) |
11936 | { | | 11882 | { |
11937 | uint32_t reg; | | 11883 | uint32_t reg; |
11938 | | | 11884 | |
11939 | DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n", | | 11885 | DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n", |
11940 | device_xname(sc->sc_dev), __func__)); | | 11886 | device_xname(sc->sc_dev), __func__)); |
11941 | | | 11887 | |