| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_cnmac.c,v 1.24 2020/06/23 05:17:13 simonb Exp $ */ | | 1 | /* $NetBSD: if_cnmac.c,v 1.25 2021/05/27 01:43:32 simonb Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2007 Internet Initiative Japan, Inc. | | 4 | * Copyright (c) 2007 Internet Initiative Japan, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: if_cnmac.c,v 1.24 2020/06/23 05:17:13 simonb Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: if_cnmac.c,v 1.25 2021/05/27 01:43:32 simonb Exp $"); |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * If no free send buffer is available, free all the sent buffers and bail out. | | 33 | * If no free send buffer is available, free all the sent buffers and bail out. |
34 | */ | | 34 | */ |
35 | #define CNMAC_SEND_QUEUE_CHECK | | 35 | #define CNMAC_SEND_QUEUE_CHECK |
36 | | | 36 | |
37 | /* XXX XXX XXX XXX XXX XXX */ | | 37 | /* XXX XXX XXX XXX XXX XXX */ |
38 | | | 38 | |
39 | #include <sys/param.h> | | 39 | #include <sys/param.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/pool.h> | | 41 | #include <sys/pool.h> |
42 | #include <sys/mbuf.h> | | 42 | #include <sys/mbuf.h> |
43 | #include <sys/malloc.h> | | 43 | #include <sys/malloc.h> |
| @@ -268,27 +268,30 @@ cnmac_attach(device_t parent, device_t s | | | @@ -268,27 +268,30 @@ cnmac_attach(device_t parent, device_t s |
268 | } | | 268 | } |
269 | | | 269 | |
270 | cnmac_board_mac_addr(enaddr, sizeof(enaddr), sc); | | 270 | cnmac_board_mac_addr(enaddr, sizeof(enaddr), sc); |
271 | printf("%s: Ethernet address %s\n", device_xname(self), | | 271 | printf("%s: Ethernet address %s\n", device_xname(self), |
272 | ether_sprintf(enaddr)); | | 272 | ether_sprintf(enaddr)); |
273 | | | 273 | |
274 | SIMPLEQ_INIT(&sc->sc_sendq); | | 274 | SIMPLEQ_INIT(&sc->sc_sendq); |
275 | sc->sc_soft_req_thresh = 15/* XXX */; | | 275 | sc->sc_soft_req_thresh = 15/* XXX */; |
276 | sc->sc_ext_callback_cnt = 0; | | 276 | sc->sc_ext_callback_cnt = 0; |
277 | | | 277 | |
278 | octgmx_stats_init(sc->sc_gmx_port); | | 278 | octgmx_stats_init(sc->sc_gmx_port); |
279 | | | 279 | |
280 | callout_init(&sc->sc_tick_misc_ch, 0); | | 280 | callout_init(&sc->sc_tick_misc_ch, 0); |
| | | 281 | callout_setfunc(&sc->sc_tick_misc_ch, cnmac_tick_misc, sc); |
| | | 282 | |
281 | callout_init(&sc->sc_tick_free_ch, 0); | | 283 | callout_init(&sc->sc_tick_free_ch, 0); |
| | | 284 | callout_setfunc(&sc->sc_tick_free_ch, cnmac_tick_free, sc); |
282 | | | 285 | |
283 | const int dv_unit = device_unit(self); | | 286 | const int dv_unit = device_unit(self); |
284 | octfau_op_init(&sc->sc_fau_done, | | 287 | octfau_op_init(&sc->sc_fau_done, |
285 | OCTEON_CVMSEG_ETHER_OFFSET(dv_unit, csm_ether_fau_done), | | 288 | OCTEON_CVMSEG_ETHER_OFFSET(dv_unit, csm_ether_fau_done), |
286 | OCT_FAU_REG_ADDR_END - (8 * (dv_unit + 1))/* XXX */); | | 289 | OCT_FAU_REG_ADDR_END - (8 * (dv_unit + 1))/* XXX */); |
287 | octfau_op_set_8(&sc->sc_fau_done, 0); | | 290 | octfau_op_set_8(&sc->sc_fau_done, 0); |
288 | | | 291 | |
289 | cnmac_pip_init(sc); | | 292 | cnmac_pip_init(sc); |
290 | cnmac_ipd_init(sc); | | 293 | cnmac_ipd_init(sc); |
291 | cnmac_pko_init(sc); | | 294 | cnmac_pko_init(sc); |
292 | | | 295 | |
293 | cnmac_configure_common(sc); | | 296 | cnmac_configure_common(sc); |
294 | | | 297 | |
| @@ -988,26 +991,27 @@ cnmac_start(struct ifnet *ifp) | | | @@ -988,26 +991,27 @@ cnmac_start(struct ifnet *ifp) |
988 | | | 991 | |
989 | /* XXX XXX XXX */ | | 992 | /* XXX XXX XXX */ |
990 | cnmac_send_queue_flush_fetch(sc); | | 993 | cnmac_send_queue_flush_fetch(sc); |
991 | | | 994 | |
992 | /* | | 995 | /* |
993 | * If no free send buffer is available, free all the sent | | 996 | * If no free send buffer is available, free all the sent |
994 | * buffers and bail out. | | 997 | * buffers and bail out. |
995 | */ | | 998 | */ |
996 | if (cnmac_send_queue_is_full(sc)) { | | 999 | if (cnmac_send_queue_is_full(sc)) { |
997 | SET(ifp->if_flags, IFF_OACTIVE); | | 1000 | SET(ifp->if_flags, IFF_OACTIVE); |
998 | if (wdc > 0) | | 1001 | if (wdc > 0) |
999 | octpko_op_doorbell_write(sc->sc_port, | | 1002 | octpko_op_doorbell_write(sc->sc_port, |
1000 | sc->sc_port, wdc); | | 1003 | sc->sc_port, wdc); |
| | | 1004 | callout_schedule(&sc->sc_tick_free_ch, 1); |
1001 | return; | | 1005 | return; |
1002 | } | | 1006 | } |
1003 | /* XXX XXX XXX */ | | 1007 | /* XXX XXX XXX */ |
1004 | | | 1008 | |
1005 | IFQ_DEQUEUE(&ifp->if_snd, m); | | 1009 | IFQ_DEQUEUE(&ifp->if_snd, m); |
1006 | | | 1010 | |
1007 | bpf_mtap(ifp, m, BPF_D_OUT); | | 1011 | bpf_mtap(ifp, m, BPF_D_OUT); |
1008 | | | 1012 | |
1009 | /* XXX XXX XXX */ | | 1013 | /* XXX XXX XXX */ |
1010 | if (sc->sc_soft_req_cnt > sc->sc_soft_req_thresh) | | 1014 | if (sc->sc_soft_req_cnt > sc->sc_soft_req_thresh) |
1011 | cnmac_send_queue_flush(sc); | | 1015 | cnmac_send_queue_flush(sc); |
1012 | if (cnmac_send(sc, m, &wdc)) { | | 1016 | if (cnmac_send(sc, m, &wdc)) { |
1013 | IF_DROP(&ifp->if_snd); | | 1017 | IF_DROP(&ifp->if_snd); |
| @@ -1021,26 +1025,27 @@ cnmac_start(struct ifnet *ifp) | | | @@ -1021,26 +1025,27 @@ cnmac_start(struct ifnet *ifp) |
1021 | if (sc->sc_flush) | | 1025 | if (sc->sc_flush) |
1022 | cnmac_send_queue_flush_sync(sc); | | 1026 | cnmac_send_queue_flush_sync(sc); |
1023 | /* XXX XXX XXX */ | | 1027 | /* XXX XXX XXX */ |
1024 | | | 1028 | |
1025 | /* Send next iobdma request */ | | 1029 | /* Send next iobdma request */ |
1026 | cnmac_send_queue_flush_prefetch(sc); | | 1030 | cnmac_send_queue_flush_prefetch(sc); |
1027 | } | | 1031 | } |
1028 | | | 1032 | |
1029 | if (wdc > 0) | | 1033 | if (wdc > 0) |
1030 | octpko_op_doorbell_write(sc->sc_port, sc->sc_port, wdc); | | 1034 | octpko_op_doorbell_write(sc->sc_port, sc->sc_port, wdc); |
1031 | | | 1035 | |
1032 | last: | | 1036 | last: |
1033 | cnmac_send_queue_flush_fetch(sc); | | 1037 | cnmac_send_queue_flush_fetch(sc); |
| | | 1038 | callout_schedule(&sc->sc_tick_free_ch, 1); |
1034 | } | | 1039 | } |
1035 | | | 1040 | |
1036 | static void | | 1041 | static void |
1037 | cnmac_watchdog(struct ifnet *ifp) | | 1042 | cnmac_watchdog(struct ifnet *ifp) |
1038 | { | | 1043 | { |
1039 | struct cnmac_softc *sc = ifp->if_softc; | | 1044 | struct cnmac_softc *sc = ifp->if_softc; |
1040 | | | 1045 | |
1041 | printf("%s: device timeout\n", device_xname(sc->sc_dev)); | | 1046 | printf("%s: device timeout\n", device_xname(sc->sc_dev)); |
1042 | | | 1047 | |
1043 | cnmac_configure(sc); | | 1048 | cnmac_configure(sc); |
1044 | | | 1049 | |
1045 | SET(ifp->if_flags, IFF_RUNNING); | | 1050 | SET(ifp->if_flags, IFF_RUNNING); |
1046 | CLR(ifp->if_flags, IFF_OACTIVE); | | 1051 | CLR(ifp->if_flags, IFF_OACTIVE); |
| @@ -1063,51 +1068,50 @@ cnmac_init(struct ifnet *ifp) | | | @@ -1063,51 +1068,50 @@ cnmac_init(struct ifnet *ifp) |
1063 | cnmac_configure(sc); | | 1068 | cnmac_configure(sc); |
1064 | | | 1069 | |
1065 | octpko_enable(sc->sc_pko); | | 1070 | octpko_enable(sc->sc_pko); |
1066 | octipd_enable(sc->sc_ipd); | | 1071 | octipd_enable(sc->sc_ipd); |
1067 | | | 1072 | |
1068 | sc->sc_init_flag = 1; | | 1073 | sc->sc_init_flag = 1; |
1069 | } else { | | 1074 | } else { |
1070 | octgmx_port_enable(sc->sc_gmx_port, 1); | | 1075 | octgmx_port_enable(sc->sc_gmx_port, 1); |
1071 | } | | 1076 | } |
1072 | mii_ifmedia_change(&sc->sc_mii); | | 1077 | mii_ifmedia_change(&sc->sc_mii); |
1073 | | | 1078 | |
1074 | octgmx_set_filter(sc->sc_gmx_port); | | 1079 | octgmx_set_filter(sc->sc_gmx_port); |
1075 | | | 1080 | |
1076 | callout_reset(&sc->sc_tick_misc_ch, hz, cnmac_tick_misc, sc); | | 1081 | callout_schedule(&sc->sc_tick_misc_ch, hz); |
1077 | callout_reset(&sc->sc_tick_free_ch, hz, cnmac_tick_free, sc); | | 1082 | callout_schedule(&sc->sc_tick_free_ch, hz); |
1078 | | | 1083 | |
1079 | SET(ifp->if_flags, IFF_RUNNING); | | 1084 | SET(ifp->if_flags, IFF_RUNNING); |
1080 | CLR(ifp->if_flags, IFF_OACTIVE); | | 1085 | CLR(ifp->if_flags, IFF_OACTIVE); |
1081 | | | 1086 | |
1082 | return 0; | | 1087 | return 0; |
1083 | } | | 1088 | } |
1084 | | | 1089 | |
1085 | static void | | 1090 | static void |
1086 | cnmac_stop(struct ifnet *ifp, int disable) | | 1091 | cnmac_stop(struct ifnet *ifp, int disable) |
1087 | { | | 1092 | { |
1088 | struct cnmac_softc *sc = ifp->if_softc; | | 1093 | struct cnmac_softc *sc = ifp->if_softc; |
1089 | | | 1094 | |
1090 | callout_stop(&sc->sc_tick_misc_ch); | | 1095 | callout_stop(&sc->sc_tick_misc_ch); |
1091 | callout_stop(&sc->sc_tick_free_ch); | | 1096 | callout_stop(&sc->sc_tick_free_ch); |
1092 | | | 1097 | |
1093 | mii_down(&sc->sc_mii); | | 1098 | mii_down(&sc->sc_mii); |
1094 | | | 1099 | |
1095 | octgmx_port_enable(sc->sc_gmx_port, 0); | | 1100 | octgmx_port_enable(sc->sc_gmx_port, 0); |
1096 | | | 1101 | |
1097 | /* Mark the interface as down and cancel the watchdog timer. */ | | 1102 | /* Mark the interface as down and cancel the watchdog timer. */ |
1098 | CLR(ifp->if_flags, IFF_RUNNING | IFF_OACTIVE); | | 1103 | CLR(ifp->if_flags, IFF_RUNNING | IFF_OACTIVE); |
1099 | ifp->if_timer = 0; | | 1104 | ifp->if_timer = 0; |
1100 | | | | |
1101 | } | | 1105 | } |
1102 | | | 1106 | |
1103 | /* ---- misc */ | | 1107 | /* ---- misc */ |
1104 | | | 1108 | |
1105 | static int | | 1109 | static int |
1106 | cnmac_reset(struct cnmac_softc *sc) | | 1110 | cnmac_reset(struct cnmac_softc *sc) |
1107 | { | | 1111 | { |
1108 | octgmx_reset_speed(sc->sc_gmx_port); | | 1112 | octgmx_reset_speed(sc->sc_gmx_port); |
1109 | octgmx_reset_flowctl(sc->sc_gmx_port); | | 1113 | octgmx_reset_flowctl(sc->sc_gmx_port); |
1110 | octgmx_reset_timing(sc->sc_gmx_port); | | 1114 | octgmx_reset_timing(sc->sc_gmx_port); |
1111 | | | 1115 | |
1112 | return 0; | | 1116 | return 0; |
1113 | } | | 1117 | } |
| @@ -1324,33 +1328,28 @@ cnmac_tick_free(void *arg) | | | @@ -1324,33 +1328,28 @@ cnmac_tick_free(void *arg) |
1324 | int timo; | | 1328 | int timo; |
1325 | int s; | | 1329 | int s; |
1326 | | | 1330 | |
1327 | s = splnet(); | | 1331 | s = splnet(); |
1328 | /* XXX XXX XXX */ | | 1332 | /* XXX XXX XXX */ |
1329 | if (sc->sc_soft_req_cnt > 0) { | | 1333 | if (sc->sc_soft_req_cnt > 0) { |
1330 | cnmac_send_queue_flush_prefetch(sc); | | 1334 | cnmac_send_queue_flush_prefetch(sc); |
1331 | cnmac_send_queue_flush_fetch(sc); | | 1335 | cnmac_send_queue_flush_fetch(sc); |
1332 | cnmac_send_queue_flush(sc); | | 1336 | cnmac_send_queue_flush(sc); |
1333 | cnmac_send_queue_flush_sync(sc); | | 1337 | cnmac_send_queue_flush_sync(sc); |
1334 | } | | 1338 | } |
1335 | /* XXX XXX XXX */ | | 1339 | /* XXX XXX XXX */ |
1336 | | | 1340 | |
1337 | /* XXX XXX XXX */ | | 1341 | timo = (sc->sc_ext_callback_cnt > 0) ? 1 : hz; |
1338 | /* ??? */ | | | |
1339 | timo = hz - (100 * sc->sc_ext_callback_cnt); | | | |
1340 | if (timo < 10) | | | |
1341 | timo = 10; | | | |
1342 | callout_schedule(&sc->sc_tick_free_ch, timo); | | 1342 | callout_schedule(&sc->sc_tick_free_ch, timo); |
1343 | /* XXX XXX XXX */ | | | |
1344 | splx(s); | | 1343 | splx(s); |
1345 | } | | 1344 | } |
1346 | | | 1345 | |
1347 | /* | | 1346 | /* |
1348 | * cnmac_tick_misc | | 1347 | * cnmac_tick_misc |
1349 | * | | 1348 | * |
1350 | * => collect statistics | | 1349 | * => collect statistics |
1351 | * => check link status | | 1350 | * => check link status |
1352 | * => called at softclock | | 1351 | * => called at softclock |
1353 | */ | | 1352 | */ |
1354 | static void | | 1353 | static void |
1355 | cnmac_tick_misc(void *arg) | | 1354 | cnmac_tick_misc(void *arg) |
1356 | { | | 1355 | { |