| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_smsc.c,v 1.69 2020/06/27 13:33:26 jmcneill Exp $ */ | | 1 | /* $NetBSD: if_smsc.c,v 1.70 2021/04/25 05:16:26 rin Exp $ */ |
2 | | | 2 | |
3 | /* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */ | | 3 | /* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */ |
4 | /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */ | | 4 | /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */ |
5 | /*- | | 5 | /*- |
6 | * Copyright (c) 2012 | | 6 | * Copyright (c) 2012 |
7 | * Ben Gray <bgray@freebsd.org>. | | 7 | * Ben Gray <bgray@freebsd.org>. |
8 | * All rights reserved. | | 8 | * All rights reserved. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -51,27 +51,27 @@ | | | @@ -51,27 +51,27 @@ |
51 | * the H/W checksum will be incorrect, however the rx code compensates for this. | | 51 | * the H/W checksum will be incorrect, however the rx code compensates for this. |
52 | * | | 52 | * |
53 | * TX checksuming is more complicated, the device requires a special header to | | 53 | * TX checksuming is more complicated, the device requires a special header to |
54 | * be prefixed onto the start of the frame which indicates the start and end | | 54 | * be prefixed onto the start of the frame which indicates the start and end |
55 | * positions of the UDP or TCP frame. This requires the driver to manually | | 55 | * positions of the UDP or TCP frame. This requires the driver to manually |
56 | * go through the packet data and decode the headers prior to sending. | | 56 | * go through the packet data and decode the headers prior to sending. |
57 | * On Linux they generally provide cues to the location of the csum and the | | 57 | * On Linux they generally provide cues to the location of the csum and the |
58 | * area to calculate it over, on FreeBSD we seem to have to do it all ourselves, | | 58 | * area to calculate it over, on FreeBSD we seem to have to do it all ourselves, |
59 | * hence this is not as optimal and therefore h/w TX checksum is currently not | | 59 | * hence this is not as optimal and therefore h/w TX checksum is currently not |
60 | * implemented. | | 60 | * implemented. |
61 | */ | | 61 | */ |
62 | | | 62 | |
63 | #include <sys/cdefs.h> | | 63 | #include <sys/cdefs.h> |
64 | __KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.69 2020/06/27 13:33:26 jmcneill Exp $"); | | 64 | __KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.70 2021/04/25 05:16:26 rin Exp $"); |
65 | | | 65 | |
66 | #ifdef _KERNEL_OPT | | 66 | #ifdef _KERNEL_OPT |
67 | #include "opt_usb.h" | | 67 | #include "opt_usb.h" |
68 | #endif | | 68 | #endif |
69 | | | 69 | |
70 | #include <sys/param.h> | | 70 | #include <sys/param.h> |
71 | | | 71 | |
72 | #include <dev/usb/usbnet.h> | | 72 | #include <dev/usb/usbnet.h> |
73 | #include <dev/usb/usbhist.h> | | 73 | #include <dev/usb/usbhist.h> |
74 | | | 74 | |
75 | #include <dev/usb/if_smscreg.h> | | 75 | #include <dev/usb/if_smscreg.h> |
76 | | | 76 | |
77 | #include "ioconf.h" | | 77 | #include "ioconf.h" |
| @@ -908,33 +908,35 @@ smsc_attach(device_t parent, device_t se | | | @@ -908,33 +908,35 @@ smsc_attach(device_t parent, device_t se |
908 | un->un_eaddr[2] = (uint8_t)((mac_l >> 16) & 0xff); | | 908 | un->un_eaddr[2] = (uint8_t)((mac_l >> 16) & 0xff); |
909 | un->un_eaddr[1] = (uint8_t)((mac_l >> 8) & 0xff); | | 909 | un->un_eaddr[1] = (uint8_t)((mac_l >> 8) & 0xff); |
910 | un->un_eaddr[0] = (uint8_t)((mac_l) & 0xff); | | 910 | un->un_eaddr[0] = (uint8_t)((mac_l) & 0xff); |
911 | } | | 911 | } |
912 | } | | 912 | } |
913 | usbnet_unbusy(un); | | 913 | usbnet_unbusy(un); |
914 | usbnet_unlock_core(un); | | 914 | usbnet_unlock_core(un); |
915 | | | 915 | |
916 | usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, | | 916 | usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, |
917 | 0, &unm); | | 917 | 0, &unm); |
918 | } | | 918 | } |
919 | | | 919 | |
920 | static void | | 920 | static void |
921 | smsc_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len) | | 921 | smsc_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) |
922 | { | | 922 | { |
923 | USMSCHIST_FUNC(); USMSCHIST_CALLED(); | | 923 | USMSCHIST_FUNC(); USMSCHIST_CALLED(); |
924 | struct smsc_softc * const sc = usbnet_softc(un); | | 924 | struct smsc_softc * const sc = usbnet_softc(un); |
925 | struct ifnet *ifp = usbnet_ifp(un); | | 925 | struct ifnet *ifp = usbnet_ifp(un); |
926 | uint8_t *buf = c->unc_buf; | | 926 | uint8_t *buf = c->unc_buf; |
| | | 927 | int count; |
927 | | | 928 | |
| | | 929 | count = 0; |
928 | DPRINTF("total_len %jd/%#jx", total_len, total_len, 0, 0); | | 930 | DPRINTF("total_len %jd/%#jx", total_len, total_len, 0, 0); |
929 | while (total_len != 0) { | | 931 | while (total_len != 0) { |
930 | uint32_t rxhdr; | | 932 | uint32_t rxhdr; |
931 | if (total_len < sizeof(rxhdr)) { | | 933 | if (total_len < sizeof(rxhdr)) { |
932 | DPRINTF("total_len %jd < sizeof(rxhdr) %jd", | | 934 | DPRINTF("total_len %jd < sizeof(rxhdr) %jd", |
933 | total_len, sizeof(rxhdr), 0, 0); | | 935 | total_len, sizeof(rxhdr), 0, 0); |
934 | if_statinc(ifp, if_ierrors); | | 936 | if_statinc(ifp, if_ierrors); |
935 | return; | | 937 | return; |
936 | } | | 938 | } |
937 | | | 939 | |
938 | memcpy(&rxhdr, buf, sizeof(rxhdr)); | | 940 | memcpy(&rxhdr, buf, sizeof(rxhdr)); |
939 | rxhdr = le32toh(rxhdr); | | 941 | rxhdr = le32toh(rxhdr); |
940 | buf += sizeof(rxhdr); | | 942 | buf += sizeof(rxhdr); |
| @@ -1035,27 +1037,32 @@ smsc_uno_rx_loop(struct usbnet * un, str | | | @@ -1035,27 +1037,32 @@ smsc_uno_rx_loop(struct usbnet * un, str |
1035 | /* round up to next longword */ | | 1037 | /* round up to next longword */ |
1036 | pktlen = (pktlen + 3) & ~0x3; | | 1038 | pktlen = (pktlen + 3) & ~0x3; |
1037 | | | 1039 | |
1038 | /* total_len does not include the padding */ | | 1040 | /* total_len does not include the padding */ |
1039 | if (pktlen > total_len) | | 1041 | if (pktlen > total_len) |
1040 | pktlen = total_len; | | 1042 | pktlen = total_len; |
1041 | | | 1043 | |
1042 | buf += pktlen; | | 1044 | buf += pktlen; |
1043 | total_len -= pktlen; | | 1045 | total_len -= pktlen; |
1044 | | | 1046 | |
1045 | /* push the packet up */ | | 1047 | /* push the packet up */ |
1046 | usbnet_enqueue(un, pktbuf, buflen, csum_flags, csum_data, | | 1048 | usbnet_enqueue(un, pktbuf, buflen, csum_flags, csum_data, |
1047 | mbuf_flags); | | 1049 | mbuf_flags); |
| | | 1050 | |
| | | 1051 | count++; |
1048 | } | | 1052 | } |
| | | 1053 | |
| | | 1054 | if (count != 0) |
| | | 1055 | rnd_add_uint32(usbnet_rndsrc(un), count); |
1049 | } | | 1056 | } |
1050 | | | 1057 | |
1051 | static unsigned | | 1058 | static unsigned |
1052 | smsc_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) | | 1059 | smsc_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) |
1053 | { | | 1060 | { |
1054 | uint32_t txhdr; | | 1061 | uint32_t txhdr; |
1055 | uint32_t frm_len = 0; | | 1062 | uint32_t frm_len = 0; |
1056 | | | 1063 | |
1057 | const size_t hdrsz = sizeof(txhdr) * 2; | | 1064 | const size_t hdrsz = sizeof(txhdr) * 2; |
1058 | | | 1065 | |
1059 | if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdrsz) | | 1066 | if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdrsz) |
1060 | return 0; | | 1067 | return 0; |
1061 | | | 1068 | |