From 165dd8ea1256d71d6a4f52c0a66dcc2799ef8f99 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 8 Apr 2015 15:37:49 +0200 Subject: Update to FreeBSD Stable/9 2015-04-08 --- freebsd/include/arpa/inet.h | 2 +- freebsd/include/arpa/nameser.h | 156 +++- freebsd/include/arpa/nameser_compat.h | 2 +- freebsd/include/res_update.h | 2 +- freebsd/include/resolv.h | 51 +- freebsd/lib/libc/include/isc/eventlib.h | 22 +- freebsd/lib/libc/include/isc/list.h | 3 +- freebsd/lib/libc/include/port_before.h | 1 + freebsd/lib/libc/inet/inet_addr.c | 2 +- freebsd/lib/libc/inet/inet_cidr_ntop.c | 4 +- freebsd/lib/libc/inet/inet_cidr_pton.c | 2 +- freebsd/lib/libc/inet/inet_net_ntop.c | 2 +- freebsd/lib/libc/inet/inet_net_pton.c | 22 +- freebsd/lib/libc/inet/inet_neta.c | 2 +- freebsd/lib/libc/inet/inet_ntoa.c | 2 +- freebsd/lib/libc/inet/inet_ntop.c | 2 +- freebsd/lib/libc/inet/inet_pton.c | 2 +- freebsd/lib/libc/inet/nsap_addr.c | 2 +- freebsd/lib/libc/isc/ev_streams.c | 2 +- freebsd/lib/libc/isc/ev_timers.c | 2 +- freebsd/lib/libc/isc/eventlib_p.h | 2 +- freebsd/lib/libc/nameser/ns_name.c | 255 +++++- freebsd/lib/libc/nameser/ns_netint.c | 4 +- freebsd/lib/libc/nameser/ns_parse.c | 70 +- freebsd/lib/libc/nameser/ns_print.c | 356 +++++++- freebsd/lib/libc/nameser/ns_samedomain.c | 2 +- freebsd/lib/libc/nameser/ns_ttl.c | 4 +- freebsd/lib/libc/resolv/herror.c | 2 +- freebsd/lib/libc/resolv/res_comp.c | 2 +- freebsd/lib/libc/resolv/res_data.c | 19 +- freebsd/lib/libc/resolv/res_debug.c | 77 +- freebsd/lib/libc/resolv/res_findzonecut.c | 2 +- freebsd/lib/libc/resolv/res_init.c | 69 +- freebsd/lib/libc/resolv/res_mkquery.c | 47 +- freebsd/lib/libc/resolv/res_mkupdate.c | 5 +- freebsd/lib/libc/resolv/res_query.c | 44 +- freebsd/lib/libc/resolv/res_send.c | 52 +- freebsd/lib/libc/resolv/res_update.c | 2 +- freebsd/sbin/ifconfig/af_inet6.c | 6 +- freebsd/sbin/ifconfig/ifconfig.c | 2 +- freebsd/sbin/ping6/ping6.c | 10 +- freebsd/sys/cam/cam.h | 3 +- freebsd/sys/cam/scsi/scsi_all.c | 31 +- freebsd/sys/cam/scsi/scsi_all.h | 2 +- freebsd/sys/dev/bce/if_bcefw.h | 6 +- freebsd/sys/dev/bce/if_bcereg.h | 2 +- freebsd/sys/dev/bge/if_bge.c | 6 +- freebsd/sys/dev/e1000/e1000_80003es2lan.c | 358 ++++---- freebsd/sys/dev/e1000/e1000_80003es2lan.h | 12 +- freebsd/sys/dev/e1000/e1000_82542.c | 7 +- freebsd/sys/dev/e1000/e1000_82571.c | 35 +- freebsd/sys/dev/e1000/e1000_82571.h | 35 +- freebsd/sys/dev/e1000/e1000_82575.c | 467 +++++++++-- freebsd/sys/dev/e1000/e1000_82575.h | 9 +- freebsd/sys/dev/e1000/e1000_api.c | 23 +- freebsd/sys/dev/e1000/e1000_api.h | 4 +- freebsd/sys/dev/e1000/e1000_defines.h | 56 +- freebsd/sys/dev/e1000/e1000_hw.h | 32 +- freebsd/sys/dev/e1000/e1000_i210.h | 23 +- freebsd/sys/dev/e1000/e1000_ich8lan.c | 806 +++++++++++++----- freebsd/sys/dev/e1000/e1000_ich8lan.h | 76 +- freebsd/sys/dev/e1000/e1000_mac.c | 55 +- freebsd/sys/dev/e1000/e1000_mac.h | 7 +- freebsd/sys/dev/e1000/e1000_manage.c | 9 +- freebsd/sys/dev/e1000/e1000_mbx.c | 31 +- freebsd/sys/dev/e1000/e1000_mbx.h | 78 +- freebsd/sys/dev/e1000/e1000_nvm.c | 26 +- freebsd/sys/dev/e1000/e1000_osdep.h | 13 +- freebsd/sys/dev/e1000/e1000_phy.c | 315 +++++-- freebsd/sys/dev/e1000/e1000_phy.h | 22 +- freebsd/sys/dev/e1000/e1000_regs.h | 16 +- freebsd/sys/dev/e1000/e1000_vf.c | 15 +- freebsd/sys/dev/e1000/e1000_vf.h | 108 +-- freebsd/sys/dev/e1000/if_em.c | 21 +- freebsd/sys/dev/e1000/if_igb.c | 1011 +++++++++++++---------- freebsd/sys/dev/e1000/if_igb.h | 255 +++--- freebsd/sys/dev/e1000/if_lem.c | 4 +- freebsd/sys/dev/mii/e1000phy.c | 25 +- freebsd/sys/dev/mii/micphy.c | 2 +- freebsd/sys/dev/mii/ukphy.c | 2 +- freebsd/sys/dev/pci/pci.c | 33 +- freebsd/sys/dev/re/if_re.c | 6 + freebsd/sys/dev/sdhci/sdhci.c | 4 +- freebsd/sys/dev/usb/controller/ehci.c | 4 +- freebsd/sys/dev/usb/controller/usb_controller.c | 49 +- freebsd/sys/dev/usb/controller/xhcireg.h | 2 + freebsd/sys/dev/usb/quirk/usb_quirk.c | 37 +- freebsd/sys/dev/usb/quirk/usb_quirk.h | 1 + freebsd/sys/dev/usb/usb_bus.h | 7 + freebsd/sys/dev/usb/usb_busdma.h | 4 +- freebsd/sys/dev/usb/usb_core.h | 1 + freebsd/sys/dev/usb/usb_dev.c | 33 +- freebsd/sys/dev/usb/usb_device.c | 117 ++- freebsd/sys/dev/usb/usb_device.h | 1 + freebsd/sys/dev/usb/usb_dynamic.c | 2 +- freebsd/sys/dev/usb/usb_freebsd.h | 2 +- freebsd/sys/dev/usb/usb_generic.c | 9 +- freebsd/sys/dev/usb/usb_hub.c | 14 +- freebsd/sys/dev/usb/usb_msctest.c | 38 +- freebsd/sys/dev/usb/usb_msctest.h | 1 + freebsd/sys/dev/usb/usb_process.c | 4 +- freebsd/sys/dev/usb/usb_request.c | 2 - freebsd/sys/dev/usb/usb_transfer.c | 31 +- freebsd/sys/fs/devfs/devfs_int.h | 1 + freebsd/sys/kern/kern_mib.c | 65 +- freebsd/sys/kern/kern_synch.c | 3 +- freebsd/sys/kern/kern_time.c | 18 +- freebsd/sys/kern/subr_bus.c | 7 +- freebsd/sys/kern/subr_hints.c | 2 +- freebsd/sys/kern/subr_rman.c | 182 ++-- freebsd/sys/kern/subr_uio.c | 2 +- freebsd/sys/kern/sys_generic.c | 33 +- freebsd/sys/kern/uipc_sockbuf.c | 31 + freebsd/sys/kern/uipc_socket.c | 14 +- freebsd/sys/kern/uipc_usrreq.c | 2 +- freebsd/sys/net/bpf.c | 88 +- freebsd/sys/net/ieee8023ad_lacp.c | 14 +- freebsd/sys/net/if.c | 123 ++- freebsd/sys/net/if_lagg.c | 41 +- freebsd/sys/net/if_stf.c | 2 - freebsd/sys/net/if_var.h | 42 +- freebsd/sys/net/if_vlan.c | 6 +- freebsd/sys/net/route.c | 14 +- freebsd/sys/netinet/cc/cc.c | 52 +- freebsd/sys/netinet/if_ether.c | 8 +- freebsd/sys/netinet/igmp.c | 9 +- freebsd/sys/netinet/in.c | 28 +- freebsd/sys/netinet/ip_output.c | 10 +- freebsd/sys/netinet/sctp_input.c | 44 +- freebsd/sys/netinet/sctp_output.c | 8 +- freebsd/sys/netinet/sctp_sysctl.c | 8 +- freebsd/sys/netinet/sctp_usrreq.c | 20 +- freebsd/sys/netinet/tcp_hostcache.c | 24 +- freebsd/sys/netinet/tcp_input.c | 19 +- freebsd/sys/netinet/tcp_output.c | 106 ++- freebsd/sys/netinet/tcp_reass.c | 2 +- freebsd/sys/netinet/tcp_subr.c | 4 + freebsd/sys/netinet/tcp_var.h | 6 +- freebsd/sys/netinet6/icmp6.c | 2 - freebsd/sys/netinet6/in6.c | 27 +- freebsd/sys/netinet6/in6_mcast.c | 2 + freebsd/sys/netinet6/in6_pcb.c | 12 +- freebsd/sys/netinet6/in6_src.c | 10 + freebsd/sys/netinet6/in6_var.h | 1 + freebsd/sys/netinet6/ip6_input.c | 29 +- freebsd/sys/netinet6/ip6_output.c | 17 +- freebsd/sys/netinet6/ip6_var.h | 3 +- freebsd/sys/netinet6/nd6.c | 2 + freebsd/sys/netinet6/nd6.h | 2 +- freebsd/sys/netinet6/nd6_nbr.c | 39 +- freebsd/sys/netinet6/nd6_rtr.c | 12 +- freebsd/sys/netinet6/scope6.c | 31 +- freebsd/sys/netinet6/scope6_var.h | 3 +- freebsd/sys/sys/conf.h | 1 + freebsd/sys/sys/mman.h | 1 + freebsd/sys/sys/rman.h | 4 +- freebsd/sys/sys/sleepqueue.h | 7 - freebsd/sys/sys/sockbuf.h | 2 + freebsd/sys/sys/socket.h | 6 +- freebsd/sys/sys/sysctl.h | 302 ++++--- freebsd/sys/sys/sysproto.h | 4 +- freebsd/sys/sys/systm.h | 16 +- freebsd/sys/sys/timetc.h | 2 +- freebsd/sys/vm/uma_core.c | 2 - freebsd/usr.bin/netstat/inet6.c | 14 +- rtemsbsd/include/rtems/bsd/local/usbdevs.h | 92 ++- rtemsbsd/include/rtems/bsd/local/usbdevs_data.h | 486 ++++++++++- 167 files changed, 5530 insertions(+), 2366 deletions(-) diff --git a/freebsd/include/arpa/inet.h b/freebsd/include/arpa/inet.h index 079ba7a2..d8d8e0ea 100644 --- a/freebsd/include/arpa/inet.h +++ b/freebsd/include/arpa/inet.h @@ -51,7 +51,7 @@ /*% * @(#)inet.h 8.1 (Berkeley) 6/2/93 - * $Id: inet.h,v 1.2.18.1 2005/04/27 05:00:50 sra Exp $ + * $Id: inet.h,v 1.3 2005/04/27 04:56:16 sra Exp $ * $FreeBSD$ */ diff --git a/freebsd/include/arpa/nameser.h b/freebsd/include/arpa/nameser.h index b0250fd3..9d08d329 100644 --- a/freebsd/include/arpa/nameser.h +++ b/freebsd/include/arpa/nameser.h @@ -1,7 +1,24 @@ +/* + * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1996-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + /* * Copyright (c) 1983, 1989, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +30,7 @@ * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -28,24 +45,7 @@ */ /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * $Id: nameser.h,v 1.7.18.2 2008/04/03 23:15:15 marka Exp $ + * $Id: nameser.h,v 1.16 2009/03/03 01:52:48 each Exp $ * $FreeBSD$ */ @@ -68,15 +68,18 @@ * contains a new enough lib/nameser/ to support the feature you need. */ -#define __NAMESER 19991006 /*%< New interface version stamp. */ +#define __NAMESER 20090302 /*%< New interface version stamp. */ /* * Define constants based on RFC0883, RFC1034, RFC 1035 */ #define NS_PACKETSZ 512 /*%< default UDP packet size */ -#define NS_MAXDNAME 1025 /*%< maximum domain name */ +#define NS_MAXDNAME 1025 /*%< maximum domain name (presentation format)*/ #define NS_MAXMSG 65535 /*%< maximum message size */ #define NS_MAXCDNAME 255 /*%< maximum compressed domain name */ #define NS_MAXLABEL 63 /*%< maximum length of domain label */ +#define NS_MAXLABELS 128 /*%< theoretical max #/labels per domain name */ +#define NS_MAXNNAME 256 /*%< maximum uncompressed (binary) domain name*/ +#define NS_MAXPADDR (sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") #define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ #define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ #define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ @@ -102,6 +105,18 @@ typedef enum __ns_sect { ns_s_max = 4 } ns_sect; +/*% + * Network name (compressed or not) type. Equivilent to a pointer when used + * in a function prototype. Can be const'd. + */ +typedef u_char ns_nname[NS_MAXNNAME]; +typedef const u_char *ns_nname_ct; +typedef u_char *ns_nname_t; + +struct ns_namemap { ns_nname_ct base; int len; }; +typedef struct ns_namemap *ns_namemap_t; +typedef const struct ns_namemap *ns_namemap_ct; + /*% * This is a message handle. It is caller allocated and has no dynamic data. * This structure is intended to be opaque to all but ns_parse.c, thus the @@ -116,6 +131,17 @@ typedef struct __ns_msg { const u_char *_msg_ptr; } ns_msg; +/* + * This is a newmsg handle, used when constructing new messages with + * ns_newmsg_init, et al. + */ +struct ns_newmsg { + ns_msg msg; + const u_char *dnptrs[25]; + const u_char **lastdnptr; +}; +typedef struct ns_newmsg ns_newmsg; + /* Private data structure - do not use from outside library. */ struct _ns_flagdata { int mask, shift; }; extern struct _ns_flagdata _ns_flagdata[]; @@ -140,8 +166,23 @@ typedef struct __ns_rr { const u_char * rdata; } ns_rr; +/* + * Same thing, but using uncompressed network binary names, and real C types. + */ +typedef struct __ns_rr2 { + ns_nname nname; + size_t nnamel; + int type; + int rr_class; + u_int ttl; + int rdlength; + const u_char * rdata; +} ns_rr2; + /* Accessor macros - this is part of the public interface. */ #define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") +#define ns_rr_nname(rr) ((const ns_nname_t)(rr).nname) +#define ns_rr_nnamel(rr) ((rr).nnamel + 0) #define ns_rr_type(rr) ((ns_type)((rr).type + 0)) #define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0)) #define ns_rr_ttl(rr) ((rr).ttl + 0) @@ -216,9 +257,9 @@ typedef enum __ns_update_operation { * This structure is used for TSIG authenticated messages */ struct ns_tsig_key { - char name[NS_MAXDNAME], alg[NS_MAXDNAME]; - unsigned char *data; - int len; + char name[NS_MAXDNAME], alg[NS_MAXDNAME]; + unsigned char *data; + int len; }; typedef struct ns_tsig_key ns_tsig_key; @@ -274,7 +315,7 @@ typedef enum __ns_type { ns_t_key = 25, /*%< Security key. */ ns_t_px = 26, /*%< X.400 mail mapping. */ ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ - ns_t_aaaa = 28, /*%< Ip6 Address. */ + ns_t_aaaa = 28, /*%< IPv6 Address. */ ns_t_loc = 29, /*%< Location Information. */ ns_t_nxt = 30, /*%< Next domain (security). */ ns_t_eid = 31, /*%< Endpoint identifier. */ @@ -284,11 +325,22 @@ typedef enum __ns_type { ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ ns_t_kx = 36, /*%< Key Exchange */ ns_t_cert = 37, /*%< Certification record */ - ns_t_a6 = 38, /*%< IPv6 address (deprecates AAAA) */ - ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */ + ns_t_a6 = 38, /*%< IPv6 address (experimental) */ + ns_t_dname = 39, /*%< Non-terminal DNAME */ ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ + ns_t_ds = 43, /*%< Delegation Signer */ + ns_t_sshfp = 44, /*%< SSH Fingerprint */ + ns_t_ipseckey = 45, /*%< IPSEC Key */ + ns_t_rrsig = 46, /*%< RRset Signature */ + ns_t_nsec = 47, /*%< Negative security */ + ns_t_dnskey = 48, /*%< DNS Key */ + ns_t_dhcid = 49, /*%< Dynamic host configuratin identifier */ + ns_t_nsec3 = 50, /*%< Negative security type 3 */ + ns_t_nsec3param = 51, /*%< Negative security type 3 parameters */ + ns_t_hip = 55, /*%< Host Identity Protocol */ + ns_t_spf = 99, /*%< Sender Policy Framework */ ns_t_tkey = 249, /*%< Transaction key */ ns_t_tsig = 250, /*%< Transaction signature. */ ns_t_ixfr = 251, /*%< Incremental zone transfer. */ @@ -297,6 +349,7 @@ typedef enum __ns_type { ns_t_maila = 254, /*%< Transfer mail agent records. */ ns_t_any = 255, /*%< Wildcard match. */ ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ + ns_t_dlv = 32769, /*%< DNSSEC look-aside validatation. */ ns_t_max = 65536 } ns_type; @@ -475,6 +528,7 @@ typedef enum __ns_cert_types { #define ns_initparse __ns_initparse #define ns_skiprr __ns_skiprr #define ns_parserr __ns_parserr +#define ns_parserr2 __ns_parserr2 #define ns_sprintrr __ns_sprintrr #define ns_sprintrrf __ns_sprintrrf #define ns_format_ttl __ns_format_ttl @@ -485,12 +539,19 @@ typedef enum __ns_cert_types { #define ns_name_ntol __ns_name_ntol #define ns_name_ntop __ns_name_ntop #define ns_name_pton __ns_name_pton +#define ns_name_pton2 __ns_name_pton2 #define ns_name_unpack __ns_name_unpack +#define ns_name_unpack2 __ns_name_unpack2 #define ns_name_pack __ns_name_pack #define ns_name_compress __ns_name_compress #define ns_name_uncompress __ns_name_uncompress #define ns_name_skip __ns_name_skip #define ns_name_rollback __ns_name_rollback +#define ns_name_length __ns_name_length +#define ns_name_eq __ns_name_eq +#define ns_name_owned __ns_name_owned +#define ns_name_map __ns_name_map +#define ns_name_labels __ns_name_labels #if 0 #define ns_sign __ns_sign #define ns_sign2 __ns_sign2 @@ -508,6 +569,16 @@ typedef enum __ns_cert_types { #endif #define ns_makecanon __ns_makecanon #define ns_samename __ns_samename +#define ns_newmsg_init __ns_newmsg_init +#define ns_newmsg_copy __ns_newmsg_copy +#define ns_newmsg_id __ns_newmsg_id +#define ns_newmsg_flag __ns_newmsg_flag +#define ns_newmsg_q __ns_newmsg_q +#define ns_newmsg_rr __ns_newmsg_rr +#define ns_newmsg_done __ns_newmsg_done +#define ns_rdata_unpack __ns_rdata_unpack +#define ns_rdata_equal __ns_rdata_equal +#define ns_rdata_refers __ns_rdata_refers __BEGIN_DECLS int ns_msg_getflag(ns_msg, int); @@ -518,6 +589,7 @@ void ns_put32(u_long, u_char *); int ns_initparse(const u_char *, int, ns_msg *); int ns_skiprr(const u_char *, const u_char *, ns_sect, int); int ns_parserr(ns_msg *, ns_sect, int, ns_rr *); +int ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *); int ns_sprintrr(const ns_msg *, const ns_rr *, const char *, const char *, char *, size_t); int ns_sprintrrf(const u_char *, size_t, const char *, @@ -532,8 +604,12 @@ u_int32_t ns_datetosecs(const char *cp, int *errp); int ns_name_ntol(const u_char *, u_char *, size_t); int ns_name_ntop(const u_char *, char *, size_t); int ns_name_pton(const char *, u_char *, size_t); +int ns_name_pton2(const char *, u_char *, size_t, size_t *); int ns_name_unpack(const u_char *, const u_char *, const u_char *, u_char *, size_t); +int ns_name_unpack2(const u_char *, const u_char *, + const u_char *, u_char *, size_t, + size_t *); int ns_name_pack(const u_char *, u_char *, int, const u_char **, const u_char **); int ns_name_uncompress(const u_char *, const u_char *, @@ -543,6 +619,11 @@ int ns_name_compress(const char *, u_char *, size_t, int ns_name_skip(const u_char **, const u_char *); void ns_name_rollback(const u_char *, const u_char **, const u_char **); +ssize_t ns_name_length(ns_nname_ct, size_t); +int ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t); +int ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int); +int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int); +int ns_name_labels(ns_nname_ct, size_t); #if 0 int ns_sign(u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t); @@ -570,6 +651,25 @@ int ns_subdomain(const char *, const char *); #endif int ns_makecanon(const char *, char *, size_t); int ns_samename(const char *, const char *); +int ns_newmsg_init(u_char *buffer, size_t bufsiz, ns_newmsg *); +int ns_newmsg_copy(ns_newmsg *, ns_msg *); +void ns_newmsg_id(ns_newmsg *handle, u_int16_t id); +void ns_newmsg_flag(ns_newmsg *handle, ns_flag flag, u_int value); +int ns_newmsg_q(ns_newmsg *handle, ns_nname_ct qname, + ns_type qtype, ns_class qclass); +int ns_newmsg_rr(ns_newmsg *handle, ns_sect sect, + ns_nname_ct name, ns_type type, + ns_class rr_class, u_int32_t ttl, + u_int16_t rdlen, const u_char *rdata); +size_t ns_newmsg_done(ns_newmsg *handle); +ssize_t ns_rdata_unpack(const u_char *, const u_char *, ns_type, + const u_char *, size_t, u_char *, size_t); +int ns_rdata_equal(ns_type, + const u_char *, size_t, + const u_char *, size_t); +int ns_rdata_refers(ns_type, + const u_char *, size_t, + const u_char *); __END_DECLS #ifdef BIND_4_COMPAT diff --git a/freebsd/include/arpa/nameser_compat.h b/freebsd/include/arpa/nameser_compat.h index 1853bc08..a10d0353 100644 --- a/freebsd/include/arpa/nameser_compat.h +++ b/freebsd/include/arpa/nameser_compat.h @@ -28,7 +28,7 @@ /*% * from nameser.h 8.1 (Berkeley) 6/2/93 - * $Id: nameser_compat.h,v 1.5.18.3 2006/05/19 02:36:00 marka Exp $ + * $Id: nameser_compat.h,v 1.8 2006/05/19 02:33:40 marka Exp $ * $FreeBSD$ */ diff --git a/freebsd/include/res_update.h b/freebsd/include/res_update.h index 704a9490..7f281e5b 100644 --- a/freebsd/include/res_update.h +++ b/freebsd/include/res_update.h @@ -16,7 +16,7 @@ */ /* - * $Id: res_update.h,v 1.2.18.1 2005/04/27 05:00:49 sra Exp $ + * $Id: res_update.h,v 1.3 2005/04/27 04:56:15 sra Exp $ * $FreeBSD$ */ diff --git a/freebsd/include/resolv.h b/freebsd/include/resolv.h index 7aa61f62..9e8ad3b1 100644 --- a/freebsd/include/resolv.h +++ b/freebsd/include/resolv.h @@ -1,7 +1,24 @@ +/* + * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1995-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + /* * Copyright (c) 1983, 1987, 1989 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +30,7 @@ * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -27,26 +44,9 @@ * SUCH DAMAGE. */ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - /*% * @(#)resolv.h 8.1 (Berkeley) 6/2/93 - * $Id: resolv.h,v 1.19.18.4 2008/04/03 23:15:15 marka Exp $ + * $Id: resolv.h,v 1.30 2009/03/03 01:52:48 each Exp $ * $FreeBSD$ */ @@ -68,7 +68,7 @@ * is new enough to contain a certain feature. */ -#define __RES 20030124 +#define __RES 20090302 /*% * This used to be defined in res_query.c, now it's in herror.c. @@ -179,7 +179,7 @@ struct __res_state { u_int _pad; /*%< make _u 64 bit aligned */ union { /* On an 32-bit arch this means 512b total. */ - char pad[72 - 4*sizeof (int) - 2*sizeof (void *)]; + char pad[72 - 4*sizeof (int) - 3*sizeof (void *)]; struct { u_int16_t nscount; u_int16_t nstimes[MAXNS]; /*%< ms. */ @@ -187,6 +187,7 @@ struct __res_state { struct __res_state_ext *ext; /*%< extention for IPv6 */ } _ext; } _u; + u_char *_rnd; /*%< PRIVATE: random state */ }; typedef struct __res_state *res_state; @@ -320,7 +321,7 @@ __END_DECLS #if !defined(SHARED_LIBBIND) || defined(LIB) /* * If libbind is a shared object (well, DLL anyway) - * these externs break the linker when resolv.h is + * these externs break the linker when resolv.h is * included by a lib client (like named) * Make them go away if a client is including this * @@ -378,7 +379,9 @@ extern const struct res_sym __p_rcode_syms[]; #define res_nisourserver __res_nisourserver #define res_ownok __res_ownok #define res_queriesmatch __res_queriesmatch +#define res_rndinit __res_rndinit #define res_randomid __res_randomid +#define res_nrandomid __res_nrandomid #define sym_ntop __sym_ntop #define sym_ntos __sym_ntos #define sym_ston __sym_ston @@ -441,7 +444,9 @@ int dn_count_labels(const char *); int dn_comp(const char *, u_char *, int, u_char **, u_char **); int dn_expand(const u_char *, const u_char *, const u_char *, char *, int); +void res_rndinit(res_state); u_int res_randomid(void); +u_int res_nrandomid(res_state); int res_nameinquery(const char *, int, int, const u_char *, const u_char *); int res_queriesmatch(const u_char *, const u_char *, diff --git a/freebsd/lib/libc/include/isc/eventlib.h b/freebsd/lib/libc/include/isc/eventlib.h index 9713be3c..d303bf39 100644 --- a/freebsd/lib/libc/include/isc/eventlib.h +++ b/freebsd/lib/libc/include/isc/eventlib.h @@ -1,24 +1,24 @@ /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1995-1999 by Internet Software Consortium + * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1995-1999, 2001, 2003 Internet Software Consortium. * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ /* eventlib.h - exported interfaces for eventlib * vix 09sep95 [initial] * - * $Id: eventlib.h,v 1.3.18.3 2008/01/23 02:12:01 marka Exp $ + * $Id: eventlib.h,v 1.7 2008/11/14 02:36:51 marka Exp $ */ #ifndef _EVENTLIB_H diff --git a/freebsd/lib/libc/include/isc/list.h b/freebsd/lib/libc/include/isc/list.h index fef631b4..ffd0c511 100644 --- a/freebsd/lib/libc/include/isc/list.h +++ b/freebsd/lib/libc/include/isc/list.h @@ -38,7 +38,8 @@ } while (0) #define INIT_LINK(elt, link) \ INIT_LINK_TYPE(elt, link, void) -#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1)) +#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1) && \ + (void *)((elt)->link.next) != (void *)(-1)) #define HEAD(list) ((list).head) #define TAIL(list) ((list).tail) diff --git a/freebsd/lib/libc/include/port_before.h b/freebsd/lib/libc/include/port_before.h index 304dd66d..4b6e3590 100644 --- a/freebsd/lib/libc/include/port_before.h +++ b/freebsd/lib/libc/include/port_before.h @@ -6,6 +6,7 @@ #define _LIBC 1 #define DO_PTHREADS 1 #define USE_KQUEUE 1 +#define HAVE_MD5 1 #define ISC_SOCKLEN_T socklen_t #define ISC_FORMAT_PRINTF(fmt, args) \ diff --git a/freebsd/lib/libc/inet/inet_addr.c b/freebsd/lib/libc/inet/inet_addr.c index e5041aa1..eab1a42e 100644 --- a/freebsd/lib/libc/inet/inet_addr.c +++ b/freebsd/lib/libc/inet/inet_addr.c @@ -68,7 +68,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; -static const char rcsid[] = "$Id: inet_addr.c,v 1.4.18.1 2005/04/27 05:00:52 sra Exp $"; +static const char rcsid[] = "$Id: inet_addr.c,v 1.5 2005/04/27 04:56:19 sra Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/inet_cidr_ntop.c b/freebsd/lib/libc/inet/inet_cidr_ntop.c index fe83a000..2c999096 100644 --- a/freebsd/lib/libc/inet/inet_cidr_ntop.c +++ b/freebsd/lib/libc/inet/inet_cidr_ntop.c @@ -18,8 +18,10 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 1.4.18.3 2006/10/11 02:32:47 marka Exp $"; +static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 1.7 2006/10/11 02:18:18 marka Exp $"; #endif +#include +__FBSDID("$FreeBSD$"); #include "port_before.h" diff --git a/freebsd/lib/libc/inet/inet_cidr_pton.c b/freebsd/lib/libc/inet/inet_cidr_pton.c index 746ac954..b6513f78 100644 --- a/freebsd/lib/libc/inet/inet_cidr_pton.c +++ b/freebsd/lib/libc/inet/inet_cidr_pton.c @@ -18,7 +18,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.5.18.1 2005/04/27 05:00:53 sra Exp $"; +static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.6 2005/04/27 04:56:19 sra Exp $"; #endif #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/inet_net_ntop.c b/freebsd/lib/libc/inet/inet_net_ntop.c index 78eade0b..998e0fc8 100644 --- a/freebsd/lib/libc/inet/inet_net_ntop.c +++ b/freebsd/lib/libc/inet/inet_net_ntop.c @@ -18,7 +18,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.3.18.2 2006/06/20 02:51:32 marka Exp $"; +static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.5 2006/06/20 02:50:14 marka Exp $"; #endif #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/inet_net_pton.c b/freebsd/lib/libc/inet/inet_net_pton.c index 9179dce4..29f9ca03 100644 --- a/freebsd/lib/libc/inet/inet_net_pton.c +++ b/freebsd/lib/libc/inet/inet_net_pton.c @@ -1,24 +1,24 @@ #include /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996,1999 by Internet Software Consortium. + * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1996, 1998, 1999, 2001, 2003 Internet Software Consortium. * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_pton.c,v 1.7.18.2 2008/08/26 04:42:43 marka Exp $"; +static const char rcsid[] = "$Id: inet_net_pton.c,v 1.10 2008/11/14 02:36:51 marka Exp $"; #endif #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/inet_neta.c b/freebsd/lib/libc/inet/inet_neta.c index 11cc18d7..69c129d2 100644 --- a/freebsd/lib/libc/inet/inet_neta.c +++ b/freebsd/lib/libc/inet/inet_neta.c @@ -18,7 +18,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_neta.c,v 1.2.18.1 2005/04/27 05:00:53 sra Exp $"; +static const char rcsid[] = "$Id: inet_neta.c,v 1.3 2005/04/27 04:56:20 sra Exp $"; #endif #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/inet_ntoa.c b/freebsd/lib/libc/inet/inet_ntoa.c index 36d85c18..1097fc72 100644 --- a/freebsd/lib/libc/inet/inet_ntoa.c +++ b/freebsd/lib/libc/inet/inet_ntoa.c @@ -31,7 +31,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: inet_ntoa.c,v 1.1.352.1 2005/04/27 05:00:54 sra Exp $"; +static const char rcsid[] = "$Id: inet_ntoa.c,v 1.2 2005/04/27 04:56:21 sra Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/inet_ntop.c b/freebsd/lib/libc/inet/inet_ntop.c index df3deb14..879b2504 100644 --- a/freebsd/lib/libc/inet/inet_ntop.c +++ b/freebsd/lib/libc/inet/inet_ntop.c @@ -18,7 +18,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_ntop.c,v 1.3.18.2 2005/11/03 23:02:22 marka Exp $"; +static const char rcsid[] = "$Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/inet_pton.c b/freebsd/lib/libc/inet/inet_pton.c index 1a89732a..b02dd7f1 100644 --- a/freebsd/lib/libc/inet/inet_pton.c +++ b/freebsd/lib/libc/inet/inet_pton.c @@ -18,7 +18,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_pton.c,v 1.3.18.2 2005/07/28 07:38:07 marka Exp $"; +static const char rcsid[] = "$Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/inet/nsap_addr.c b/freebsd/lib/libc/inet/nsap_addr.c index a7aba040..3bbb3962 100644 --- a/freebsd/lib/libc/inet/nsap_addr.c +++ b/freebsd/lib/libc/inet/nsap_addr.c @@ -18,7 +18,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nsap_addr.c,v 1.3.18.2 2005/07/28 07:38:08 marka Exp $"; +static const char rcsid[] = "$Id: nsap_addr.c,v 1.5 2005/07/28 06:51:48 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/isc/ev_streams.c b/freebsd/lib/libc/isc/ev_streams.c index 2edfc2ca..83fd4a1e 100644 --- a/freebsd/lib/libc/isc/ev_streams.c +++ b/freebsd/lib/libc/isc/ev_streams.c @@ -22,7 +22,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_streams.c,v 1.4.18.1 2005/04/27 05:01:06 sra Exp $"; +static const char rcsid[] = "$Id: ev_streams.c,v 1.5 2005/04/27 04:56:36 sra Exp $"; #endif #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/isc/ev_timers.c b/freebsd/lib/libc/isc/ev_timers.c index 5b1b226f..74dda8ea 100644 --- a/freebsd/lib/libc/isc/ev_timers.c +++ b/freebsd/lib/libc/isc/ev_timers.c @@ -22,7 +22,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_timers.c,v 1.5.18.1 2005/04/27 05:01:06 sra Exp $"; +static const char rcsid[] = "$Id: ev_timers.c,v 1.6 2005/04/27 04:56:36 sra Exp $"; #endif #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/isc/eventlib_p.h b/freebsd/lib/libc/isc/eventlib_p.h index aea5bd6a..b27ab54d 100644 --- a/freebsd/lib/libc/isc/eventlib_p.h +++ b/freebsd/lib/libc/isc/eventlib_p.h @@ -19,7 +19,7 @@ * \brief private interfaces for eventlib * \author vix 09sep95 [initial] * - * $Id: eventlib_p.h,v 1.5.18.4 2006/03/10 00:20:08 marka Exp $ + * $Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp $ * $FreeBSD$ */ diff --git a/freebsd/lib/libc/nameser/ns_name.c b/freebsd/lib/libc/nameser/ns_name.c index 181a9756..fa1a32e3 100644 --- a/freebsd/lib/libc/nameser/ns_name.c +++ b/freebsd/lib/libc/nameser/ns_name.c @@ -18,8 +18,10 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_name.c,v 1.8.18.2 2005/04/27 05:01:08 sra Exp $"; +static const char rcsid[] = "$Id: ns_name.c,v 1.11 2009/01/23 19:59:16 each Exp $"; #endif +#include +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -123,7 +125,7 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) } if ((l = labellen(cp - 1)) < 0) { errno = EMSGSIZE; /*%< XXX */ - return(-1); + return (-1); } if (dn + l >= eom) { errno = EMSGSIZE; @@ -135,12 +137,12 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) if (n != DNS_LABELTYPE_BITSTRING) { /* XXX: labellen should reject this case */ errno = EINVAL; - return(-1); + return (-1); } if ((m = decode_bitstring(&cp, dn, eom)) < 0) { errno = EMSGSIZE; - return(-1); + return (-1); } dn += m; continue; @@ -199,10 +201,25 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) * notes: *\li Enforces label and domain length limits. */ +int +ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { + return (ns_name_pton2(src, dst, dstsiz, NULL)); +} +/* + * ns_name_pton2(src, dst, dstsiz, *dstlen) + * Convert a ascii string into an encoded domain name as per RFC1035. + * return: + * -1 if it fails + * 1 if string was fully qualified + * 0 is string was not fully qualified + * side effects: + * fills in *dstlen (if non-NULL) + * notes: + * Enforces label and domain length limits. + */ int -ns_name_pton(const char *src, u_char *dst, size_t dstsiz) -{ +ns_name_pton2(const char *src, u_char *dst, size_t dstsiz, size_t *dstlen) { u_char *label, *bp, *eom; int c, n, escaped, e = 0; char *cp; @@ -217,13 +234,13 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) if (c == '[') { /*%< start a bit string label */ if ((cp = strchr(src, ']')) == NULL) { errno = EINVAL; /*%< ??? */ - return(-1); + return (-1); } if ((e = encode_bitsring(&src, cp + 2, &label, &bp, eom)) != 0) { errno = e; - return(-1); + return (-1); } escaped = 0; label = bp++; @@ -231,7 +248,7 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) goto done; else if (c != '.') { errno = EINVAL; - return(-1); + return (-1); } continue; } @@ -283,6 +300,8 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) errno = EMSGSIZE; return (-1); } + if (dstlen != NULL) + *dstlen = (bp - dst); return (1); } if (c == 0 || *src == '.') { @@ -320,6 +339,8 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) errno = EMSGSIZE; return (-1); } + if (dstlen != NULL) + *dstlen = (bp - dst); return (0); } @@ -367,7 +388,7 @@ ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) } for ((void)NULL; l > 0; l--) { c = *cp++; - if (isupper(c)) + if (isascii(c) && isupper(c)) *dn++ = tolower(c); else *dn++ = c; @@ -386,6 +407,21 @@ ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, u_char *dst, size_t dstsiz) +{ + return (ns_name_unpack2(msg, eom, src, dst, dstsiz, NULL)); +} + +/* + * ns_name_unpack2(msg, eom, src, dst, dstsiz, *dstlen) + * Unpack a domain name from a message, source may be compressed. + * return: + * -1 if it fails, or consumed octets if it succeeds. + * side effect: + * fills in *dstlen (if non-NULL). + */ +int +ns_name_unpack2(const u_char *msg, const u_char *eom, const u_char *src, + u_char *dst, size_t dstsiz, size_t *dstlen) { const u_char *srcp, *dstlim; u_char *dstp; @@ -409,7 +445,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, /* Limit checks. */ if ((l = labellen(srcp - 1)) < 0) { errno = EMSGSIZE; - return(-1); + return (-1); } if (dstp + l + 1 >= dstlim || srcp + l >= eom) { errno = EMSGSIZE; @@ -429,11 +465,12 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, } if (len < 0) len = srcp - src + 1; - srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); - if (srcp < msg || srcp >= eom) { /*%< Out of range. */ + l = ((n & 0x3f) << 8) | (*srcp & 0xff); + if (l >= eom - msg) { /*%< Out of range. */ errno = EMSGSIZE; return (-1); } + srcp = msg + l; checked += 2; /* * Check for loops in the compressed name; @@ -451,7 +488,9 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, return (-1); /*%< flag error */ } } - *dstp = '\0'; + *dstp++ = 0; + if (dstlen != NULL) + *dstlen = dstp - dst; if (len < 0) len = srcp - src; return (len); @@ -510,7 +549,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, } if ((l0 = labellen(srcp)) < 0) { errno = EINVAL; - return(-1); + return (-1); } l += l0 + 1; if (l > MAXCDNAME) { @@ -657,7 +696,7 @@ ns_name_skip(const u_char **ptrptr, const u_char *eom) case NS_TYPE_ELT: /*%< EDNS0 extended label */ if ((l = labellen(cp - 1)) < 0) { errno = EMSGSIZE; /*%< XXX */ - return(-1); + return (-1); } cp += l; continue; @@ -678,6 +717,150 @@ ns_name_skip(const u_char **ptrptr, const u_char *eom) return (0); } +/* Find the number of octets an nname takes up, including the root label. + * (This is basically ns_name_skip() without compression-pointer support.) + * ((NOTE: can only return zero if passed-in namesiz argument is zero.)) + */ +ssize_t +ns_name_length(ns_nname_ct nname, size_t namesiz) { + ns_nname_ct orig = nname; + u_int n; + + while (namesiz-- > 0 && (n = *nname++) != 0) { + if ((n & NS_CMPRSFLGS) != 0) { + errno = EISDIR; + return (-1); + } + if (n > namesiz) { + errno = EMSGSIZE; + return (-1); + } + nname += n; + namesiz -= n; + } + return (nname - orig); +} + +/* Compare two nname's for equality. Return -1 on error (setting errno). + */ +int +ns_name_eq(ns_nname_ct a, size_t as, ns_nname_ct b, size_t bs) { + ns_nname_ct ae = a + as, be = b + bs; + int ac, bc; + + while (ac = *a, bc = *b, ac != 0 && bc != 0) { + if ((ac & NS_CMPRSFLGS) != 0 || (bc & NS_CMPRSFLGS) != 0) { + errno = EISDIR; + return (-1); + } + if (a + ac >= ae || b + bc >= be) { + errno = EMSGSIZE; + return (-1); + } + if (ac != bc || strncasecmp((const char *) ++a, + (const char *) ++b, ac) != 0) + return (0); + a += ac, b += bc; + } + return (ac == 0 && bc == 0); +} + +/* Is domain "A" owned by (at or below) domain "B"? + */ +int +ns_name_owned(ns_namemap_ct a, int an, ns_namemap_ct b, int bn) { + /* If A is shorter, it cannot be owned by B. */ + if (an < bn) + return (0); + + /* If they are unequal before the length of the shorter, A cannot... */ + while (bn > 0) { + if (a->len != b->len || + strncasecmp((const char *) a->base, + (const char *) b->base, a->len) != 0) + return (0); + a++, an--; + b++, bn--; + } + + /* A might be longer or not, but either way, B owns it. */ + return (1); +} + +/* Build an array of tuples from an nname, top-down order. + * Return the number of tuples (labels) thus discovered. + */ +int +ns_name_map(ns_nname_ct nname, size_t namelen, ns_namemap_t map, int mapsize) { + u_int n; + int l; + + n = *nname++; + namelen--; + + /* Root zone? */ + if (n == 0) { + /* Extra data follows name? */ + if (namelen > 0) { + errno = EMSGSIZE; + return (-1); + } + return (0); + } + + /* Compression pointer? */ + if ((n & NS_CMPRSFLGS) != 0) { + errno = EISDIR; + return (-1); + } + + /* Label too long? */ + if (n > namelen) { + errno = EMSGSIZE; + return (-1); + } + + /* Recurse to get rest of name done first. */ + l = ns_name_map(nname + n, namelen - n, map, mapsize); + if (l < 0) + return (-1); + + /* Too many labels? */ + if (l >= mapsize) { + errno = ENAMETOOLONG; + return (-1); + } + + /* We're on our way back up-stack, store current map data. */ + map[l].base = nname; + map[l].len = n; + return (l + 1); +} + +/* Count the labels in a domain name. Root counts, so COM. has two. This + * is to make the result comparable to the result of ns_name_map(). + */ +int +ns_name_labels(ns_nname_ct nname, size_t namesiz) { + int ret = 0; + u_int n; + + while (namesiz-- > 0 && (n = *nname++) != 0) { + if ((n & NS_CMPRSFLGS) != 0) { + errno = EISDIR; + return (-1); + } + if (n > namesiz) { + errno = EMSGSIZE; + return (-1); + } + nname += n; + namesiz -= n; + ret++; + } + return (ret + 1); +} + /* Private. */ /*% @@ -808,7 +991,7 @@ decode_bitstring(const unsigned char **cpp, char *dn, const char *eom) plen = (blen + 3) / 4; plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); if (dn + plen >= eom) - return(-1); + return (-1); cp++; i = SPRINTF((dn, "\\[x")); @@ -841,12 +1024,12 @@ decode_bitstring(const unsigned char **cpp, char *dn, const char *eom) dn += i; *cpp = cp; - return(dn - beg); + return (dn - beg); } static int encode_bitsring(const char **bp, const char *end, unsigned char **labelp, - unsigned char ** dst, unsigned const char *eom) + unsigned char ** dst, unsigned const char *eom) { int afterslash = 0; const char *cp = *bp; @@ -860,23 +1043,23 @@ encode_bitsring(const char **bp, const char *end, unsigned char **labelp, /* a bitstring must contain at least 2 characters */ if (end - cp < 2) - return(EINVAL); + return (EINVAL); /* XXX: currently, only hex strings are supported */ if (*cp++ != 'x') - return(EINVAL); + return (EINVAL); if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */ - return(EINVAL); + return (EINVAL); for (tp = *dst + 1; cp < end && tp < eom; cp++) { switch((c = *cp)) { case ']': /*%< end of the bitstring */ if (afterslash) { if (beg_blen == NULL) - return(EINVAL); + return (EINVAL); blen = (int)strtol(beg_blen, &end_blen, 10); if (*end_blen != ']') - return(EINVAL); + return (EINVAL); } if (count) *tp++ = ((value << 4) & 0xff); @@ -888,24 +1071,24 @@ encode_bitsring(const char **bp, const char *end, unsigned char **labelp, default: if (afterslash) { if (!isdigit(c&0xff)) - return(EINVAL); + return (EINVAL); if (beg_blen == NULL) { if (c == '0') { /* blen never begings with 0 */ - return(EINVAL); + return (EINVAL); } beg_blen = cp; } } else { if (!isxdigit(c&0xff)) - return(EINVAL); + return (EINVAL); value <<= 4; value += digitvalue[(int)c]; count += 4; tbcount += 4; if (tbcount > 256) - return(EINVAL); + return (EINVAL); if (count == 8) { *tp++ = value; count = 0; @@ -916,7 +1099,7 @@ encode_bitsring(const char **bp, const char *end, unsigned char **labelp, } done: if (cp >= end || tp >= eom) - return(EMSGSIZE); + return (EMSGSIZE); /* * bit length validation: @@ -930,10 +1113,10 @@ encode_bitsring(const char **bp, const char *end, unsigned char **labelp, int traillen; if (((blen + 3) & ~3) != tbcount) - return(EINVAL); + return (EINVAL); traillen = tbcount - blen; /*%< between 0 and 3 */ if (((value << (8 - traillen)) & 0xff) != 0) - return(EINVAL); + return (EINVAL); } else blen = tbcount; @@ -947,7 +1130,7 @@ encode_bitsring(const char **bp, const char *end, unsigned char **labelp, *bp = cp; *dst = tp; - return(0); + return (0); } static int @@ -958,18 +1141,18 @@ labellen(const u_char *lp) if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* should be avoided by the caller */ - return(-1); + return (-1); } if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) { if (l == DNS_LABELTYPE_BITSTRING) { if ((bitlen = *(lp + 1)) == 0) bitlen = 256; - return((bitlen + 7 ) / 8 + 1); + return ((bitlen + 7 ) / 8 + 1); } - return(-1); /*%< unknwon ELT */ + return (-1); /*%< unknwon ELT */ } - return(l); + return (l); } /*! \file */ diff --git a/freebsd/lib/libc/nameser/ns_netint.c b/freebsd/lib/libc/nameser/ns_netint.c index d13abe17..887bdc44 100644 --- a/freebsd/lib/libc/nameser/ns_netint.c +++ b/freebsd/lib/libc/nameser/ns_netint.c @@ -18,8 +18,10 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_netint.c,v 1.2.18.1 2005/04/27 05:01:08 sra Exp $"; +static const char rcsid[] = "$Id: ns_netint.c,v 1.3 2005/04/27 04:56:40 sra Exp $"; #endif +#include +__FBSDID("$FreeBSD$"); /* Import. */ diff --git a/freebsd/lib/libc/nameser/ns_parse.c b/freebsd/lib/libc/nameser/ns_parse.c index ad1e7652..80325e7c 100644 --- a/freebsd/lib/libc/nameser/ns_parse.c +++ b/freebsd/lib/libc/nameser/ns_parse.c @@ -18,8 +18,10 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_parse.c,v 1.5.18.4 2007/08/27 03:34:24 marka Exp $"; +static const char rcsid[] = "$Id: ns_parse.c,v 1.10 2009/01/23 19:59:16 each Exp $"; #endif +#include +__FBSDID("$FreeBSD$"); /* Import. */ @@ -49,6 +51,9 @@ static void setsection(ns_msg *msg, ns_sect sect); do { errno = (err); if (errno == errno) return (-1); } while (0) #endif +#define PARSE_FMT_PRESO 0 /* Parse using presentation-format names */ +#define PARSE_FMT_WIRE 1 /* Parse using network-format names */ + /* Public. */ /* These need to be in the same order as the nres.h:ns_flag enum. */ @@ -104,7 +109,6 @@ ns_initparse(const u_char *msg, int msglen, ns_msg *handle) { const u_char *eom = msg + msglen; int i; - memset(handle, 0x5e, sizeof *handle); handle->_msg = msg; handle->_eom = eom; if (msg + NS_INT16SZ > eom) @@ -196,6 +200,68 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { return (0); } +/* + * This is identical to the above but uses network-format (uncompressed) names. + */ +int +ns_parserr2(ns_msg *handle, ns_sect section, int rrnum, ns_rr2 *rr) { + int b; + int tmp; + + /* Make section right. */ + if ((tmp = section) < 0 || section >= ns_s_max) + RETERR(ENODEV); + if (section != handle->_sect) + setsection(handle, section); + + /* Make rrnum right. */ + if (rrnum == -1) + rrnum = handle->_rrnum; + if (rrnum < 0 || rrnum >= handle->_counts[(int)section]) + RETERR(ENODEV); + if (rrnum < handle->_rrnum) + setsection(handle, section); + if (rrnum > handle->_rrnum) { + b = ns_skiprr(handle->_msg_ptr, handle->_eom, section, + rrnum - handle->_rrnum); + + if (b < 0) + return (-1); + handle->_msg_ptr += b; + handle->_rrnum = rrnum; + } + + /* Do the parse. */ + b = ns_name_unpack2(handle->_msg, handle->_eom, handle->_msg_ptr, + rr->nname, NS_MAXNNAME, &rr->nnamel); + if (b < 0) + return (-1); + handle->_msg_ptr += b; + if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) + RETERR(EMSGSIZE); + NS_GET16(rr->type, handle->_msg_ptr); + NS_GET16(rr->rr_class, handle->_msg_ptr); + if (section == ns_s_qd) { + rr->ttl = 0; + rr->rdlength = 0; + rr->rdata = NULL; + } else { + if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) + RETERR(EMSGSIZE); + NS_GET32(rr->ttl, handle->_msg_ptr); + NS_GET16(rr->rdlength, handle->_msg_ptr); + if (handle->_msg_ptr + rr->rdlength > handle->_eom) + RETERR(EMSGSIZE); + rr->rdata = handle->_msg_ptr; + handle->_msg_ptr += rr->rdlength; + } + if (++handle->_rrnum > handle->_counts[(int)section]) + setsection(handle, (ns_sect)((int)section + 1)); + + /* All done. */ + return (0); +} + /* Private. */ static void diff --git a/freebsd/lib/libc/nameser/ns_print.c b/freebsd/lib/libc/nameser/ns_print.c index e4b78599..8f797962 100644 --- a/freebsd/lib/libc/nameser/ns_print.c +++ b/freebsd/lib/libc/nameser/ns_print.c @@ -18,7 +18,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_print.c,v 1.6.18.4 2005/04/27 05:01:09 sra Exp $"; +static const char rcsid[] = "$Id: ns_print.c,v 1.12 2009/03/03 05:29:58 each Exp $"; #endif #include __FBSDID("$FreeBSD$"); @@ -76,6 +76,9 @@ static int addtab(size_t len, size_t target, int spaced, return (-1); \ } while (0) +static const char base32hex[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUV=0123456789abcdefghijklmnopqrstuv"; + /* Public. */ /*% @@ -259,7 +262,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_mx: case ns_t_afsdb: - case ns_t_rt: { + case ns_t_rt: + case ns_t_kx: { u_int t; if (rdlen < (size_t)NS_INT16SZ) @@ -307,6 +311,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, break; case ns_t_txt: + case ns_t_spf: while (rdata < edata) { T(len = charstr(rdata, edata, &buf, &buflen)); if (len == 0) @@ -453,7 +458,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen, break; } - case ns_t_key: { + case ns_t_key: + case ns_t_dnskey: { char base64_key[NS_MD5RSA_MAX_BASE64]; u_int keyflags, protocol, algorithm, key_id; const char *leader; @@ -499,7 +505,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen, break; } - case ns_t_sig: { + case ns_t_sig: + case ns_t_rrsig: { char base64_key[NS_MD5RSA_MAX_BASE64]; u_int type, algorithm, labels, footprint; const char *leader; @@ -510,7 +517,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, goto formerr; /* Type covered, Algorithm, Label count, Original TTL. */ - type = ns_get16(rdata); rdata += NS_INT16SZ; + type = ns_get16(rdata); rdata += NS_INT16SZ; algorithm = *rdata++; labels = *rdata++; t = ns_get32(rdata); rdata += NS_INT32SZ; @@ -704,6 +711,345 @@ ns_sprintrrf(const u_char *msg, size_t msglen, break; } + case ns_t_ds: + case ns_t_dlv: + case ns_t_sshfp: { + u_int t; + + if (type == ns_t_ds || type == ns_t_dlv) { + if (rdlen < 4U) goto formerr; + t = ns_get16(rdata); + rdata += NS_INT16SZ; + len = SPRINTF((tmp, "%u ", t)); + T(addstr(tmp, len, &buf, &buflen)); + } else + if (rdlen < 2U) goto formerr; + + len = SPRINTF((tmp, "%u ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + + len = SPRINTF((tmp, "%u ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + + while (rdata < edata) { + len = SPRINTF((tmp, "%02X", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + } + break; + } + + case ns_t_nsec3: + case ns_t_nsec3param: { + u_int t, w, l, j, k, c; + + len = SPRINTF((tmp, "%u ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + + len = SPRINTF((tmp, "%u ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + + t = ns_get16(rdata); + rdata += NS_INT16SZ; + len = SPRINTF((tmp, "%u ", t)); + T(addstr(tmp, len, &buf, &buflen)); + + t = *rdata++; + if (t == 0) { + T(addstr("-", 1, &buf, &buflen)); + } else { + while (t-- > 0) { + len = SPRINTF((tmp, "%02X", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + } + } + if (type == ns_t_nsec3param) + break; + T(addstr(" ", 1, &buf, &buflen)); + + t = *rdata++; + while (t > 0) { + switch (t) { + case 1: + tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; + tmp[1] = base32hex[((rdata[0]<<2)&0x1c)]; + tmp[2] = tmp[3] = tmp[4] = '='; + tmp[5] = tmp[6] = tmp[7] = '='; + break; + case 2: + tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; + tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| + ((rdata[1]>>6)&0x03)]; + tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; + tmp[3] = base32hex[((rdata[1]<<4)&0x10)]; + tmp[4] = tmp[5] = tmp[6] = tmp[7] = '='; + break; + case 3: + tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; + tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| + ((rdata[1]>>6)&0x03)]; + tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; + tmp[3] = base32hex[((rdata[1]<<4)&0x10)| + ((rdata[2]>>4)&0x0f)]; + tmp[4] = base32hex[((rdata[2]<<1)&0x1e)]; + tmp[5] = tmp[6] = tmp[7] = '='; + break; + case 4: + tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; + tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| + ((rdata[1]>>6)&0x03)]; + tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; + tmp[3] = base32hex[((rdata[1]<<4)&0x10)| + ((rdata[2]>>4)&0x0f)]; + tmp[4] = base32hex[((rdata[2]<<1)&0x1e)| + ((rdata[3]>>7)&0x01)]; + tmp[5] = base32hex[((rdata[3]>>2)&0x1f)]; + tmp[6] = base32hex[(rdata[3]<<3)&0x18]; + tmp[7] = '='; + break; + default: + tmp[0] = base32hex[((rdata[0]>>3)&0x1f)]; + tmp[1] = base32hex[((rdata[0]<<2)&0x1c)| + ((rdata[1]>>6)&0x03)]; + tmp[2] = base32hex[((rdata[1]>>1)&0x1f)]; + tmp[3] = base32hex[((rdata[1]<<4)&0x10)| + ((rdata[2]>>4)&0x0f)]; + tmp[4] = base32hex[((rdata[2]<<1)&0x1e)| + ((rdata[3]>>7)&0x01)]; + tmp[5] = base32hex[((rdata[3]>>2)&0x1f)]; + tmp[6] = base32hex[((rdata[3]<<3)&0x18)| + ((rdata[4]>>5)&0x07)]; + tmp[7] = base32hex[(rdata[4]&0x1f)]; + break; + } + T(addstr(tmp, 8, &buf, &buflen)); + if (t >= 5) { + rdata += 5; + t -= 5; + } else { + rdata += t; + t -= t; + } + } + + while (rdata < edata) { + w = *rdata++; + l = *rdata++; + for (j = 0; j < l; j++) { + if (rdata[j] == 0) + continue; + for (k = 0; k < 8; k++) { + if ((rdata[j] & (0x80 >> k)) == 0) + continue; + c = w * 256 + j * 8 + k; + len = SPRINTF((tmp, " %s", p_type(c))); + T(addstr(tmp, len, &buf, &buflen)); + } + } + rdata += l; + } + break; + } + + case ns_t_nsec: { + u_int w, l, j, k, c; + + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); + + while (rdata < edata) { + w = *rdata++; + l = *rdata++; + for (j = 0; j < l; j++) { + if (rdata[j] == 0) + continue; + for (k = 0; k < 8; k++) { + if ((rdata[j] & (0x80 >> k)) == 0) + continue; + c = w * 256 + j * 8 + k; + len = SPRINTF((tmp, " %s", p_type(c))); + T(addstr(tmp, len, &buf, &buflen)); + } + } + rdata += l; + } + break; + } + + case ns_t_dhcid: { + int n; + unsigned int siz; + char base64_dhcid[8192]; + const char *leader; + + siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ + if (siz > sizeof(base64_dhcid) * 3/4) { + const char *str = "record too long to print"; + T(addstr(str, strlen(str), &buf, &buflen)); + } else { + len = b64_ntop(rdata, edata-rdata, base64_dhcid, siz); + + if (len < 0) + goto formerr; + + else if (len > 15) { + T(addstr(" (", 2, &buf, &buflen)); + leader = "\n\t\t"; + spaced = 0; + } + else + leader = " "; + + for (n = 0; n < len; n += 48) { + T(addstr(leader, strlen(leader), + &buf, &buflen)); + T(addstr(base64_dhcid + n, MIN(len - n, 48), + &buf, &buflen)); + } + if (len > 15) + T(addstr(" )", 2, &buf, &buflen)); + } + break; + } + + case ns_t_ipseckey: { + int n; + unsigned int siz; + char base64_key[8192]; + const char *leader; + + if (rdlen < 2) + goto formerr; + + switch (rdata[1]) { + case 0: + case 3: + if (rdlen < 3) + goto formerr; + break; + case 1: + if (rdlen < 7) + goto formerr; + break; + case 2: + if (rdlen < 19) + goto formerr; + break; + default: + comment = "unknown IPSECKEY gateway type"; + goto hexify; + } + + len = SPRINTF((tmp, "%u ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + + len = SPRINTF((tmp, "%u ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + + len = SPRINTF((tmp, "%u ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + + switch (rdata[-2]) { + case 0: + T(addstr(".", 1, &buf, &buflen)); + break; + case 1: + (void) inet_ntop(AF_INET, rdata, buf, buflen); + addlen(strlen(buf), &buf, &buflen); + rdata += 4; + break; + case 2: + (void) inet_ntop(AF_INET6, rdata, buf, buflen); + addlen(strlen(buf), &buf, &buflen); + rdata += 16; + break; + case 3: + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); + break; + } + + if (rdata >= edata) + break; + + siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ + if (siz > sizeof(base64_key) * 3/4) { + const char *str = "record too long to print"; + T(addstr(str, strlen(str), &buf, &buflen)); + } else { + len = b64_ntop(rdata, edata-rdata, base64_key, siz); + + if (len < 0) + goto formerr; + + else if (len > 15) { + T(addstr(" (", 2, &buf, &buflen)); + leader = "\n\t\t"; + spaced = 0; + } + else + leader = " "; + + for (n = 0; n < len; n += 48) { + T(addstr(leader, strlen(leader), + &buf, &buflen)); + T(addstr(base64_key + n, MIN(len - n, 48), + &buf, &buflen)); + } + if (len > 15) + T(addstr(" )", 2, &buf, &buflen)); + } + } + + case ns_t_hip: { + unsigned int i, hip_len, algorithm, key_len; + char base64_key[NS_MD5RSA_MAX_BASE64]; + unsigned int siz; + const char *leader = "\n\t\t\t\t\t"; + + hip_len = *rdata++; + algorithm = *rdata++; + key_len = ns_get16(rdata); + rdata += NS_INT16SZ; + + siz = key_len*4/3 + 4; /* "+4" accounts for trailing \0 */ + if (siz > sizeof(base64_key) * 3/4) { + const char *str = "record too long to print"; + T(addstr(str, strlen(str), &buf, &buflen)); + } else { + len = sprintf(tmp, "( %u ", algorithm); + T(addstr(tmp, len, &buf, &buflen)); + + for (i = 0; i < hip_len; i++) { + len = sprintf(tmp, "%02X", *rdata); + T(addstr(tmp, len, &buf, &buflen)); + rdata++; + } + T(addstr(leader, strlen(leader), &buf, &buflen)); + + len = b64_ntop(rdata, key_len, base64_key, siz); + if (len < 0) + goto formerr; + + T(addstr(base64_key, len, &buf, &buflen)); + + rdata += key_len; + while (rdata < edata) { + T(addstr(leader, strlen(leader), &buf, &buflen)); + T(addname(msg, msglen, &rdata, origin, + &buf, &buflen)); + } + T(addstr(" )", 2, &buf, &buflen)); + } + break; + } + default: comment = "unknown RR type"; goto hexify; diff --git a/freebsd/lib/libc/nameser/ns_samedomain.c b/freebsd/lib/libc/nameser/ns_samedomain.c index 7a404bdc..b10b5707 100644 --- a/freebsd/lib/libc/nameser/ns_samedomain.c +++ b/freebsd/lib/libc/nameser/ns_samedomain.c @@ -18,7 +18,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_samedomain.c,v 1.5.18.1 2005/04/27 05:01:09 sra Exp $"; +static const char rcsid[] = "$Id: ns_samedomain.c,v 1.6 2005/04/27 04:56:40 sra Exp $"; #endif #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/nameser/ns_ttl.c b/freebsd/lib/libc/nameser/ns_ttl.c index 795427a6..5a5aa169 100644 --- a/freebsd/lib/libc/nameser/ns_ttl.c +++ b/freebsd/lib/libc/nameser/ns_ttl.c @@ -18,8 +18,10 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_ttl.c,v 1.2.18.2 2005/07/28 07:38:10 marka Exp $"; +static const char rcsid[] = "$Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp $"; #endif +#include +__FBSDID("$FreeBSD$"); /* Import. */ diff --git a/freebsd/lib/libc/resolv/herror.c b/freebsd/lib/libc/resolv/herror.c index d87548a6..67ddc51e 100644 --- a/freebsd/lib/libc/resolv/herror.c +++ b/freebsd/lib/libc/resolv/herror.c @@ -48,7 +48,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: herror.c,v 1.3.18.1 2005/04/27 05:01:09 sra Exp $"; +static const char rcsid[] = "$Id: herror.c,v 1.4 2005/04/27 04:56:41 sra Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/resolv/res_comp.c b/freebsd/lib/libc/resolv/res_comp.c index 27d613e6..c31537e9 100644 --- a/freebsd/lib/libc/resolv/res_comp.c +++ b/freebsd/lib/libc/resolv/res_comp.c @@ -68,7 +68,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_comp.c,v 1.3.18.2 2005/07/28 07:38:11 marka Exp $"; +static const char rcsid[] = "$Id: res_comp.c,v 1.5 2005/07/28 06:51:50 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/resolv/res_data.c b/freebsd/lib/libc/resolv/res_data.c index 0ce0c143..a5164c44 100644 --- a/freebsd/lib/libc/resolv/res_data.c +++ b/freebsd/lib/libc/resolv/res_data.c @@ -18,7 +18,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: res_data.c,v 1.3.18.2 2007/09/14 05:35:47 marka Exp $"; +static const char rcsid[] = "$Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -109,13 +109,6 @@ res_init(void) { if (!(_res.options & RES_INIT)) _res.options = RES_DEFAULT; - /* - * This one used to initialize implicitly to zero, so unless the app - * has set it to something in particular, we can randomize it now. - */ - if (!_res.id) - _res.id = res_randomid(); - return (__res_vinit(&_res, 1)); } @@ -266,6 +259,16 @@ res_querydomain(const char *name, answer, anslen)); } +u_int +res_randomid(void) { + if ((_res.options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + return (-1); + } + + return (res_nrandomid(&_res)); +} + int res_opt(int n0, u_char *buf, int buflen, int anslen) { diff --git a/freebsd/lib/libc/resolv/res_debug.c b/freebsd/lib/libc/resolv/res_debug.c index 1bc32a05..b8e68891 100644 --- a/freebsd/lib/libc/resolv/res_debug.c +++ b/freebsd/lib/libc/resolv/res_debug.c @@ -1,9 +1,26 @@ #include +/* + * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1996-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + /* * Copyright (c) 1985 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +32,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,14 +48,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -74,26 +91,9 @@ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_debug.c,v 1.10.18.6 2008/04/03 23:15:15 marka Exp $"; +static const char rcsid[] = "$Id: res_debug.c,v 1.19 2009/02/26 11:20:20 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -329,7 +329,7 @@ res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { fprintf(file, ", %s: %d", p_section(ns_s_ar, opcode), arcount); } - if ((!statp->pfcode) || (statp->pfcode & + if ((!statp->pfcode) || (statp->pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { putc('\n',file); } @@ -496,6 +496,24 @@ const struct res_sym __p_type_syms[] = { {ns_t_nimloc, "NIMLOC", "NIMROD locator (unimplemented)"}, {ns_t_srv, "SRV", "server selection"}, {ns_t_atma, "ATMA", "ATM address (unimplemented)"}, + {ns_t_naptr, "NAPTR", "naptr"}, + {ns_t_kx, "KX", "key exchange"}, + {ns_t_cert, "CERT", "certificate"}, + {ns_t_a6, "A", "IPv6 address (experminental)"}, + {ns_t_dname, "DNAME", "non-terminal redirection"}, + {ns_t_opt, "OPT", "opt"}, + {ns_t_apl, "apl", "apl"}, + {ns_t_ds, "DS", "delegation signer"}, + {ns_t_sshfp, "SSFP", "SSH fingerprint"}, + {ns_t_ipseckey, "IPSECKEY", "IPSEC key"}, + {ns_t_rrsig, "RRSIG", "rrsig"}, + {ns_t_nsec, "NSEC", "nsec"}, + {ns_t_dnskey, "DNSKEY", "DNS key"}, + {ns_t_dhcid, "DHCID", "dynamic host configuration identifier"}, + {ns_t_nsec3, "NSEC3", "nsec3"}, + {ns_t_nsec3param, "NSEC3PARAM", "NSEC3 parameters"}, + {ns_t_hip, "HIP", "host identity protocol"}, + {ns_t_spf, "SPF", "sender policy framework"}, {ns_t_tkey, "TKEY", "tkey"}, {ns_t_tsig, "TSIG", "transaction signature"}, {ns_t_ixfr, "IXFR", "incremental zone transfer"}, @@ -511,6 +529,7 @@ const struct res_sym __p_type_syms[] = { {ns_t_sink, "SINK", "Kitchen Sink (experimental)"}, {ns_t_opt, "OPT", "EDNS Options"}, {ns_t_any, "ANY", "\"any\""}, + {ns_t_dlv, "DLV", "DNSSEC look-aside validation"}, {0, NULL, NULL} }; @@ -938,7 +957,7 @@ loc_aton(ascii, binary) altsign = -1; cp++; } - + if (*cp == '+') cp++; @@ -967,7 +986,7 @@ loc_aton(ascii, binary) goto defaults; siz = precsize_aton(&cp); - + while (!isspace((unsigned char)*cp) && (cp < maxcp)) /*%< if trailing garbage or m */ cp++; @@ -1000,7 +1019,7 @@ loc_aton(ascii, binary) PUTLONG(latit,bcp); PUTLONG(longit,bcp); PUTLONG(alt,bcp); - + return (16); /*%< size of RR in octets */ } @@ -1026,7 +1045,7 @@ loc_ntoa(binary, ascii) int32_t latval, longval, altval; u_int32_t templ; u_int8_t sizeval, hpval, vpval, versionval; - + char *sizestr, *hpstr, *vpstr; versionval = *cp++; @@ -1140,7 +1159,7 @@ dn_count_labels(const char *name) { } /*% - * Make dates expressed in seconds-since-Jan-1-1970 easy to read. + * Make dates expressed in seconds-since-Jan-1-1970 easy to read. * SIG records are required to be printed like this, by the Secure DNS RFC. */ char * @@ -1150,7 +1169,7 @@ p_secstodate (u_long secs) { struct tm *time; #ifdef HAVE_TIME_R struct tm res; - + time = gmtime_r(&clock, &res); #else time = gmtime(&clock); diff --git a/freebsd/lib/libc/resolv/res_findzonecut.c b/freebsd/lib/libc/resolv/res_findzonecut.c index 2c570556..aa6efcf1 100644 --- a/freebsd/lib/libc/resolv/res_findzonecut.c +++ b/freebsd/lib/libc/resolv/res_findzonecut.c @@ -1,7 +1,7 @@ #include #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_findzonecut.c,v 1.7.18.3 2005/10/11 00:25:11 marka Exp $"; +static const char rcsid[] = "$Id: res_findzonecut.c,v 1.10 2005/10/11 00:10:16 marka Exp $"; #endif /* not lint */ /* diff --git a/freebsd/lib/libc/resolv/res_init.c b/freebsd/lib/libc/resolv/res_init.c index 83da2548..cf6449f3 100644 --- a/freebsd/lib/libc/resolv/res_init.c +++ b/freebsd/lib/libc/resolv/res_init.c @@ -68,7 +68,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; -static const char rcsid[] = "$Id: res_init.c,v 1.16.18.7 2007/07/09 01:52:58 marka Exp $"; +static const char rcsid[] = "$Id: res_init.c,v 1.26 2008/12/11 09:59:00 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -93,6 +93,19 @@ __FBSDID("$FreeBSD$"); #include #include +#ifndef HAVE_MD5 +# include "../dst/md5.h" +#else +# ifdef SOLARIS2 +# include +# elif _LIBC +# include +# endif +#endif +#ifndef _MD5_H_ +# define _MD5_H_ 1 /*%< make sure we do not include rsaref md5.h file */ +#endif + #include "un-namespace.h" #include "port_after.h" @@ -180,9 +193,12 @@ __res_vinit(res_state statp, int preinit) { statp->retrans = RES_TIMEOUT; statp->retry = RES_DFLRETRY; statp->options = RES_DEFAULT; - statp->id = res_randomid(); } + statp->_rnd = malloc(16); + res_rndinit(statp); + statp->id = res_nrandomid(statp); + memset(u, 0, sizeof(u)); #ifdef USELOOPBACK u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); @@ -717,12 +733,48 @@ net_mask(in) /*!< XXX - should really use system's version of this */ } #endif +static u_char srnd[16]; + +void +res_rndinit(res_state statp) +{ + struct timeval now; + u_int32_t u32; + u_int16_t u16; + u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; + + gettimeofday(&now, NULL); + u32 = now.tv_sec; + memcpy(rnd, &u32, 4); + u32 = now.tv_usec; + memcpy(rnd + 4, &u32, 4); + u32 += now.tv_sec; + memcpy(rnd + 8, &u32, 4); + u16 = getpid(); + memcpy(rnd + 12, &u16, 2); +} + u_int -res_randomid(void) { +res_nrandomid(res_state statp) { struct timeval now; + u_int16_t u16; + MD5_CTX ctx; + u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; gettimeofday(&now, NULL); - return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid())); + u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec); + memcpy(rnd + 14, &u16, 2); +#ifndef HAVE_MD5 + MD5_Init(&ctx); + MD5_Update(&ctx, rnd, 16); + MD5_Final(rnd, &ctx); +#else + MD5Init(&ctx); + MD5Update(&ctx, rnd, 16); + MD5Final(rnd, &ctx); +#endif + memcpy(&u16, rnd + 14, 2); + return ((u_int) u16); } /*% @@ -752,10 +804,15 @@ res_nclose(res_state statp) { void res_ndestroy(res_state statp) { res_nclose(statp); - if (statp->_u._ext.ext != NULL) + if (statp->_u._ext.ext != NULL) { free(statp->_u._ext.ext); + statp->_u._ext.ext = NULL; + } + if (statp->_rnd != NULL) { + free(statp->_rnd); + statp->_rnd = NULL; + } statp->options &= ~RES_INIT; - statp->_u._ext.ext = NULL; } #ifndef _LIBC diff --git a/freebsd/lib/libc/resolv/res_mkquery.c b/freebsd/lib/libc/resolv/res_mkquery.c index 8fa9c3b8..eb4df45d 100644 --- a/freebsd/lib/libc/resolv/res_mkquery.c +++ b/freebsd/lib/libc/resolv/res_mkquery.c @@ -1,9 +1,26 @@ #include +/* + * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + /* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +32,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,14 +48,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -49,26 +66,9 @@ * SOFTWARE. */ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_mkquery.c,v 1.5.18.2 2008/04/03 23:15:15 marka Exp $"; +static const char rcsid[] = "$Id: res_mkquery.c,v 1.10 2008/12/11 09:59:00 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -123,7 +123,8 @@ res_nmkquery(res_state statp, return (-1); memset(buf, 0, HFIXEDSZ); hp = (HEADER *) buf; - hp->id = htons(++statp->id); + statp->id = res_nrandomid(statp); + hp->id = htons(statp->id); hp->opcode = op; hp->rd = (statp->options & RES_RECURSE) != 0U; hp->rcode = NOERROR; diff --git a/freebsd/lib/libc/resolv/res_mkupdate.c b/freebsd/lib/libc/resolv/res_mkupdate.c index 880f46aa..e486e31a 100644 --- a/freebsd/lib/libc/resolv/res_mkupdate.c +++ b/freebsd/lib/libc/resolv/res_mkupdate.c @@ -24,7 +24,7 @@ */ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_mkupdate.c,v 1.4.18.4 2005/10/14 05:44:12 marka Exp $"; +static const char rcsid[] = "$Id: res_mkupdate.c,v 1.10 2008/12/11 09:59:00 marka Exp $"; #endif /* not lint */ #include __FBSDID("$FreeBSD$"); @@ -118,7 +118,8 @@ res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) { return (-1); memset(buf, 0, HFIXEDSZ); hp = (HEADER *) buf; - hp->id = htons(++statp->id); + statp->id = res_nrandomid(statp); + hp->id = htons(statp->id); hp->opcode = ns_o_update; hp->rcode = NOERROR; cp = buf + HFIXEDSZ; diff --git a/freebsd/lib/libc/resolv/res_query.c b/freebsd/lib/libc/resolv/res_query.c index 15c39a03..5a5acef1 100644 --- a/freebsd/lib/libc/resolv/res_query.c +++ b/freebsd/lib/libc/resolv/res_query.c @@ -1,9 +1,26 @@ #include +/* + * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1996-2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +32,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,14 +48,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -49,26 +66,9 @@ * SOFTWARE. */ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_query.c,v 1.7.18.2 2008/04/03 23:15:15 marka Exp $"; +static const char rcsid[] = "$Id: res_query.c,v 1.11 2008/11/14 02:36:51 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); diff --git a/freebsd/lib/libc/resolv/res_send.c b/freebsd/lib/libc/resolv/res_send.c index 51bca770..68961132 100644 --- a/freebsd/lib/libc/resolv/res_send.c +++ b/freebsd/lib/libc/resolv/res_send.c @@ -1,9 +1,26 @@ #include +/* + * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1996-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + /* * Copyright (c) 1985, 1989, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +32,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,14 +48,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -49,26 +66,9 @@ * SOFTWARE. */ -/* - * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_send.c,v 1.9.18.10 2008/01/27 02:06:26 marka Exp $"; +static const char rcsid[] = "$Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); @@ -355,7 +355,7 @@ res_nsend(res_state statp, if (EXT(statp).nssocks[ns] == -1) continue; peerlen = sizeof(peer); - if (_getsockname(EXT(statp).nssocks[ns], + if (_getpeername(EXT(statp).nssocks[ns], (struct sockaddr *)&peer, &peerlen) < 0) { needclose++; break; @@ -406,7 +406,7 @@ res_nsend(res_state statp, nstime = EXT(statp).nstimes[0]; for (ns = 0; ns < lastns; ns++) { if (EXT(statp).ext != NULL) - EXT(statp).ext->nsaddrs[ns] = + EXT(statp).ext->nsaddrs[ns] = EXT(statp).ext->nsaddrs[ns + 1]; statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; @@ -688,12 +688,12 @@ send_vc(res_state statp, /* * Disable generation of SIGPIPE when writing to a closed * socket. Write should return -1 and set errno to EPIPE - * instead. + * instead. * * Push on even if setsockopt(SO_NOSIGPIPE) fails. */ (void)_setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on, - sizeof(on)); + sizeof(on)); #endif errno = 0; if (_connect(statp->_vcsock, nsap, nsaplen) < 0) { diff --git a/freebsd/lib/libc/resolv/res_update.c b/freebsd/lib/libc/resolv/res_update.c index 1e46429c..cd3abbd8 100644 --- a/freebsd/lib/libc/resolv/res_update.c +++ b/freebsd/lib/libc/resolv/res_update.c @@ -1,7 +1,7 @@ #include #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_update.c,v 1.12.18.1 2005/04/27 05:01:12 sra Exp $"; +static const char rcsid[] = "$Id: res_update.c,v 1.13 2005/04/27 04:56:43 sra Exp $"; #endif /* not lint */ /* diff --git a/freebsd/sbin/ifconfig/af_inet6.c b/freebsd/sbin/ifconfig/af_inet6.c index f74d3e8b..0e099ada 100644 --- a/freebsd/sbin/ifconfig/af_inet6.c +++ b/freebsd/sbin/ifconfig/af_inet6.c @@ -290,6 +290,8 @@ in6_status(int s __unused, const struct ifaddrs *ifa) printf("autoconf "); if ((flags6 & IN6_IFF_TEMPORARY) != 0) printf("temporary "); + if ((flags6 & IN6_IFF_PREFER_SOURCE) != 0) + printf("prefer_source "); if (scopeid) printf("scopeid 0x%x ", scopeid); @@ -509,6 +511,8 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-deprecated", -IN6_IFF_DEPRECATED, setip6flags), DEF_CMD("autoconf", IN6_IFF_AUTOCONF, setip6flags), DEF_CMD("-autoconf", -IN6_IFF_AUTOCONF, setip6flags), + DEF_CMD("prefer_source",IN6_IFF_PREFER_SOURCE, setip6flags), + DEF_CMD("-prefer_source",-IN6_IFF_PREFER_SOURCE,setip6flags), DEF_CMD("accept_rtadv", ND6_IFF_ACCEPT_RTADV, setnd6flags), DEF_CMD("-accept_rtadv",-ND6_IFF_ACCEPT_RTADV, setnd6flags), DEF_CMD("no_radr", ND6_IFF_NO_RADR, setnd6flags), @@ -519,8 +523,6 @@ static struct cmd inet6_cmds[] = { DEF_CMD("-ifdisabled", -ND6_IFF_IFDISABLED, setnd6flags), DEF_CMD("nud", ND6_IFF_PERFORMNUD, setnd6flags), DEF_CMD("-nud", -ND6_IFF_PERFORMNUD, setnd6flags), - DEF_CMD("prefer_source",ND6_IFF_PREFER_SOURCE, setnd6flags), - DEF_CMD("-prefer_source",-ND6_IFF_PREFER_SOURCE,setnd6flags), DEF_CMD("auto_linklocal",ND6_IFF_AUTO_LINKLOCAL,setnd6flags), DEF_CMD("-auto_linklocal",-ND6_IFF_AUTO_LINKLOCAL,setnd6flags), DEF_CMD("no_prefer_iface",ND6_IFF_NO_PREFER_IFACE,setnd6flags), diff --git a/freebsd/sbin/ifconfig/ifconfig.c b/freebsd/sbin/ifconfig/ifconfig.c index 74800e85..8fc53f6f 100644 --- a/freebsd/sbin/ifconfig/ifconfig.c +++ b/freebsd/sbin/ifconfig/ifconfig.c @@ -86,7 +86,7 @@ static const char rcsid[] = /* * Since "struct ifreq" is composed of various union members, callers - * should pay special attention to interprete the value. + * should pay special attention to interpret the value. * (.e.g. little/big endian difference in the structure.) */ struct ifreq ifr; diff --git a/freebsd/sbin/ping6/ping6.c b/freebsd/sbin/ping6/ping6.c index 9553890c..2067b54b 100644 --- a/freebsd/sbin/ping6/ping6.c +++ b/freebsd/sbin/ping6/ping6.c @@ -1165,8 +1165,14 @@ main(int argc, char *argv[]) /* signal handling */ if (seenalrm) { /* last packet sent, timeout reached? */ - if (npackets && ntransmitted >= npackets) - break; + if (npackets && ntransmitted >= npackets) { + struct timeval zerotime = {0, 0}; + itimer.it_value = zerotime; + itimer.it_interval = zerotime; + (void)setitimer(ITIMER_REAL, &itimer, NULL); + seenalrm = 0; /* clear flag */ + continue; + } retransmit(); seenalrm = 0; continue; diff --git a/freebsd/sys/cam/cam.h b/freebsd/sys/cam/cam.h index 499fffa3..ba0e43c7 100644 --- a/freebsd/sys/cam/cam.h +++ b/freebsd/sys/cam/cam.h @@ -119,7 +119,8 @@ enum { SF_QUIET_IR = 0x04, /* Be quiet about Illegal Request reponses */ SF_PRINT_ALWAYS = 0x08, /* Always print error status. */ SF_NO_RECOVERY = 0x10, /* Don't do active error recovery. */ - SF_NO_RETRY = 0x20 /* Don't do any retries. */ + SF_NO_RETRY = 0x20, /* Don't do any retries. */ + SF_RETRY_BUSY = 0x40 /* Retry BUSY status. */ }; /* CAM Status field values */ diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c index 4cad972d..7e268bb1 100644 --- a/freebsd/sys/cam/scsi/scsi_all.c +++ b/freebsd/sys/cam/scsi/scsi_all.c @@ -1110,13 +1110,13 @@ static struct asc_table_entry asc_table[] = { { SST(0x04, 0x09, SS_RDEF, /* XXX TBD */ "Logical unit not ready, self-test in progress") }, /* DTLPWROMAEBKVF */ - { SST(0x04, 0x0A, SS_RDEF, /* XXX TBD */ + { SST(0x04, 0x0A, SS_TUR | SSQ_MANY | SSQ_DECREMENT_COUNT | ENXIO, "Logical unit not accessible, asymmetric access state transition")}, /* DTLPWROMAEBKVF */ - { SST(0x04, 0x0B, SS_RDEF, /* XXX TBD */ + { SST(0x04, 0x0B, SS_FATAL | ENXIO, "Logical unit not accessible, target port in standby state") }, /* DTLPWROMAEBKVF */ - { SST(0x04, 0x0C, SS_RDEF, /* XXX TBD */ + { SST(0x04, 0x0C, SS_FATAL | ENXIO, "Logical unit not accessible, target port in unavailable state") }, /* F */ { SST(0x04, 0x0D, SS_RDEF, /* XXX TBD */ @@ -5158,7 +5158,7 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data) { u_int8_t type; char *dtype, *qtype; - char vendor[16], product[48], revision[16], rstr[4]; + char vendor[16], product[48], revision[16], rstr[12]; type = SID_TYPE(inq_data); @@ -5166,7 +5166,7 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data) * Figure out basic device type and qualifier. */ if (SID_QUAL_IS_VENDOR_UNIQUE(inq_data)) { - qtype = "(vendor-unique qualifier)"; + qtype = " (vendor-unique qualifier)"; } else { switch (SID_QUAL(inq_data)) { case SID_QUAL_LU_CONNECTED: @@ -5174,15 +5174,15 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data) break; case SID_QUAL_LU_OFFLINE: - qtype = "(offline)"; + qtype = " (offline)"; break; case SID_QUAL_RSVD: - qtype = "(reserved qualifier)"; + qtype = " (reserved qualifier)"; break; default: case SID_QUAL_BAD_LU: - qtype = "(LUN not supported)"; + qtype = " (LUN not supported)"; break; } } @@ -5251,11 +5251,16 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data) cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), sizeof(revision)); - if (SID_ANSI_REV(inq_data) == SCSI_REV_CCS) - bcopy("CCS", rstr, 4); - else - snprintf(rstr, sizeof (rstr), "%d", SID_ANSI_REV(inq_data)); - printf("<%s %s %s> %s %s SCSI-%s device %s\n", + if (SID_ANSI_REV(inq_data) == SCSI_REV_0) + snprintf(rstr, sizeof(rstr), "SCSI"); + else if (SID_ANSI_REV(inq_data) <= SCSI_REV_SPC) { + snprintf(rstr, sizeof(rstr), "SCSI-%d", + SID_ANSI_REV(inq_data)); + } else { + snprintf(rstr, sizeof(rstr), "SPC-%d SCSI", + SID_ANSI_REV(inq_data) - 2); + } + printf("<%s %s %s> %s %s %s device%s\n", vendor, product, revision, SID_IS_REMOVABLE(inq_data) ? "Removable" : "Fixed", dtype, rstr, qtype); diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h index cf84d396..326ce990 100644 --- a/freebsd/sys/cam/scsi/scsi_all.h +++ b/freebsd/sys/cam/scsi/scsi_all.h @@ -1132,7 +1132,7 @@ struct scsi_inquiry_data * reserved for this peripheral * qualifier. */ -#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) +#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x04) != 0) u_int8_t dev_qual2; #define SID_QUAL2 0x7F #define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0) diff --git a/freebsd/sys/dev/bce/if_bcefw.h b/freebsd/sys/dev/bce/if_bcefw.h index fa0d528a..cae01fea 100644 --- a/freebsd/sys/dev/bce/if_bcefw.h +++ b/freebsd/sys/dev/bce/if_bcefw.h @@ -7997,7 +7997,7 @@ const u32 bce_TPAT_b09FwBss[(0x12b4/4) + 1] = { 0x0 }; const u32 bce_TPAT_b09FwSbss[(0x3c/4) + 1] = { 0x0 }; const u32 bce_TPAT_b09FwSdata[(0x0/4) + 1] = { 0x0 }; - + int bce_COM_b09FwReleaseMajor = 0x6; int bce_COM_b09FwReleaseMinor = 0x0; int bce_COM_b09FwReleaseFix = 0x11; @@ -11727,8 +11727,8 @@ const u32 bce_RXP_b09FwText[(0x9090/4) + 1] = { 0x90cf0009, 0x240d0004, 0x31ee00ff, 0x11cdfd85, 0x24020001, 0x3c010801, 0xa022950d, 0xa002154, 0x0, 0x0 }; -u32 bce_RXP_b09FwData[(0x0/4) + 1] = { 0x0 }; -u32 bce_RXP_b09FwRodata[(0x33c/4) + 1] = { +const u32 bce_RXP_b09FwData[(0x0/4) + 1] = { 0x0 }; +const u32 bce_RXP_b09FwRodata[(0x33c/4) + 1] = { 0x8003344, 0x8003344, 0x8003420, 0x80033f4, 0x80033d8, 0x8003328, 0x8003328, 0x8003328, 0x800334c, diff --git a/freebsd/sys/dev/bce/if_bcereg.h b/freebsd/sys/dev/bce/if_bcereg.h index 00903562..1058c14a 100644 --- a/freebsd/sys/dev/bce/if_bcereg.h +++ b/freebsd/sys/dev/bce/if_bcereg.h @@ -465,7 +465,7 @@ /* Returns FALSE in "defects" per 2^31 - 1 calls, otherwise returns TRUE. */ #define DB_RANDOMFALSE(defects) (random() > defects) #define DB_OR_RANDOMFALSE(defects) || (random() > defects) -#define DB_AND_RANDOMFALSE(defects) && (random() > ddfects) +#define DB_AND_RANDOMFALSE(defects) && (random() > defects) /* Returns TRUE in "defects" per 2^31 - 1 calls, otherwise returns FALSE. */ #define DB_RANDOMTRUE(defects) (random() < defects) diff --git a/freebsd/sys/dev/bge/if_bge.c b/freebsd/sys/dev/bge/if_bge.c index c0f78a78..5456f3d5 100644 --- a/freebsd/sys/dev/bge/if_bge.c +++ b/freebsd/sys/dev/bge/if_bge.c @@ -1939,11 +1939,9 @@ bge_chipinit(struct bge_softc *sc) /* * Disable memory write invalidate. Apparently it is not supported - * properly by these devices. Also ensure that INTx isn't disabled, - * as these chips need it even when using MSI. + * properly by these devices. */ - PCI_CLRBIT(sc->bge_dev, BGE_PCI_CMD, - PCIM_CMD_INTxDIS | PCIM_CMD_MWIEN, 4); + PCI_CLRBIT(sc->bge_dev, BGE_PCI_CMD, PCIM_CMD_MWIEN, 4); /* Set the timer prescaler (always 66 MHz). */ CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ); diff --git a/freebsd/sys/dev/e1000/e1000_80003es2lan.c b/freebsd/sys/dev/e1000/e1000_80003es2lan.c index ea5e88c1..62e9fc42 100644 --- a/freebsd/sys/dev/e1000/e1000_80003es2lan.c +++ b/freebsd/sys/dev/e1000/e1000_80003es2lan.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2013, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -34,16 +34,12 @@ ******************************************************************************/ /*$FreeBSD$*/ -/* - * 80003ES2LAN Gigabit Ethernet Controller (Copper) +/* 80003ES2LAN Gigabit Ethernet Controller (Copper) * 80003ES2LAN Gigabit Ethernet Controller (Serdes) */ #include "e1000_api.h" -static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw); -static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw); -static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw); static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw); static void e1000_release_phy_80003es2lan(struct e1000_hw *hw); static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); @@ -73,14 +69,12 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data); static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data); -static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw); static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); -/* - * A table for the GG82563 cable length where the range is defined +/* A table for the GG82563 cable length where the range is defined * with a lower bound at "index" and the upper bound at * "index + 5". */ @@ -97,13 +91,13 @@ static const u16 e1000_gg82563_cable_length_table[] = { static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_init_phy_params_80003es2lan"); if (hw->phy.media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; - goto out; + return E1000_SUCCESS; } else { phy->ops.power_up = e1000_power_up_phy_copper; phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan; @@ -135,12 +129,9 @@ static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) ret_val = e1000_get_phy_id(hw); /* Verify phy id */ - if (phy->id != GG82563_E_PHY_ID) { - ret_val = -E1000_ERR_PHY; - goto out; - } + if (phy->id != GG82563_E_PHY_ID) + return -E1000_ERR_PHY; -out: return ret_val; } @@ -178,8 +169,7 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); - /* - * Added to a constant, "size" becomes the left-shift value + /* Added to a constant, "size" becomes the left-shift value * for setting word_size. */ size += NVM_WORD_SIZE_BASE_SHIFT; @@ -236,8 +226,8 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) /* FWSM register */ mac->has_fwsm = TRUE; /* ARC supported; valid only if manageability features are enabled. */ - mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) & - E1000_FWSM_MODE_MASK) ? TRUE : FALSE; + mac->arc_subsystem_valid = !!(E1000_READ_REG(hw, E1000_FWSM) & + E1000_FWSM_MODE_MASK); /* Adaptive IFS not supported */ mac->adaptive_ifs = FALSE; @@ -379,14 +369,13 @@ static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); if (ret_val) - goto out; + return ret_val; ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); -out: return ret_val; } @@ -417,23 +406,20 @@ static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) u32 swfw_sync; u32 swmask = mask; u32 fwmask = mask << 16; - s32 ret_val = E1000_SUCCESS; - s32 i = 0, timeout = 50; + s32 i = 0; + s32 timeout = 50; DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan"); while (i < timeout) { - if (e1000_get_hw_semaphore_generic(hw)) { - ret_val = -E1000_ERR_SWFW_SYNC; - goto out; - } + if (e1000_get_hw_semaphore_generic(hw)) + return -E1000_ERR_SWFW_SYNC; swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); if (!(swfw_sync & (fwmask | swmask))) break; - /* - * Firmware currently using resource (fwmask) + /* Firmware currently using resource (fwmask) * or other software thread using resource (swmask) */ e1000_put_hw_semaphore_generic(hw); @@ -443,8 +429,7 @@ static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) if (i == timeout) { DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); - ret_val = -E1000_ERR_SWFW_SYNC; - goto out; + return -E1000_ERR_SWFW_SYNC; } swfw_sync |= swmask; @@ -452,8 +437,7 @@ static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) e1000_put_hw_semaphore_generic(hw); -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -499,14 +483,13 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ret_val = e1000_acquire_phy_80003es2lan(hw); if (ret_val) - goto out; + return ret_val; /* Select Configuration Page */ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { page_select = GG82563_PHY_PAGE_SELECT; } else { - /* - * Use Alternative Page Select register to access + /* Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; @@ -516,12 +499,11 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); if (ret_val) { e1000_release_phy_80003es2lan(hw); - goto out; + return ret_val; } - if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { - /* - * The "ready" bit in the MDIC register may be incorrectly set + if (hw->dev_spec._80003es2lan.mdic_wa_enable) { + /* The "ready" bit in the MDIC register may be incorrectly set * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ @@ -531,9 +513,8 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { - ret_val = -E1000_ERR_PHY; e1000_release_phy_80003es2lan(hw); - goto out; + return -E1000_ERR_PHY; } usec_delay(200); @@ -551,7 +532,6 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, e1000_release_phy_80003es2lan(hw); -out: return ret_val; } @@ -574,14 +554,13 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ret_val = e1000_acquire_phy_80003es2lan(hw); if (ret_val) - goto out; + return ret_val; /* Select Configuration Page */ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { page_select = GG82563_PHY_PAGE_SELECT; } else { - /* - * Use Alternative Page Select register to access + /* Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; @@ -591,12 +570,11 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); if (ret_val) { e1000_release_phy_80003es2lan(hw); - goto out; + return ret_val; } - if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { - /* - * The "ready" bit in the MDIC register may be incorrectly set + if (hw->dev_spec._80003es2lan.mdic_wa_enable) { + /* The "ready" bit in the MDIC register may be incorrectly set * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ @@ -606,9 +584,8 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { - ret_val = -E1000_ERR_PHY; e1000_release_phy_80003es2lan(hw); - goto out; + return -E1000_ERR_PHY; } usec_delay(200); @@ -626,7 +603,6 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, e1000_release_phy_80003es2lan(hw); -out: return ret_val; } @@ -657,7 +633,6 @@ static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; - s32 ret_val = E1000_SUCCESS; u32 mask = E1000_NVM_CFG_DONE_PORT_0; DEBUGFUNC("e1000_get_cfg_done_80003es2lan"); @@ -673,12 +648,10 @@ static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) } if (!timeout) { DEBUGOUT("MNG configuration cycle has not completed.\n"); - ret_val = -E1000_ERR_RESET; - goto out; + return -E1000_ERR_RESET; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -690,33 +663,32 @@ out: **/ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u16 phy_data; bool link; DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan"); if (!(hw->phy.ops.read_reg)) - goto out; + return E1000_SUCCESS; - /* - * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI + /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed and duplex are forced. */ ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); if (ret_val) - goto out; + return ret_val; DEBUGOUT1("GG82563 PSCR: %X\n", phy_data); ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) - goto out; + return ret_val; e1000_phy_force_speed_duplex_setup(hw, &phy_data); @@ -725,7 +697,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data); if (ret_val) - goto out; + return ret_val; usec_delay(1); @@ -735,32 +707,30 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 100000, &link); if (ret_val) - goto out; + return ret_val; if (!link) { - /* - * We didn't get link. + /* We didn't get link. * Reset the DSP and cross our fingers. */ ret_val = e1000_phy_reset_dsp_generic(hw); if (ret_val) - goto out; + return ret_val; } /* Try once more */ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 100000, &link); if (ret_val) - goto out; + return ret_val; } ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; - /* - * Resetting the phy means we need to verify the TX_CLK corresponds + /* Resetting the phy means we need to verify the TX_CLK corresponds * to the link speed. 10Mbps -> 2.5MHz, else 25MHz. */ phy_data &= ~GG82563_MSCR_TX_CLK_MASK; @@ -769,15 +739,13 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) else phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25; - /* - * In addition, we must re-enable CRS on Tx for both half and full + /* In addition, we must re-enable CRS on Tx for both half and full * duplex. */ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); -out: return ret_val; } @@ -791,32 +759,29 @@ out: static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u16 phy_data, index; DEBUGFUNC("e1000_get_cable_length_80003es2lan"); if (!(hw->phy.ops.read_reg)) - goto out; + return E1000_SUCCESS; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); if (ret_val) - goto out; + return ret_val; index = phy_data & GG82563_DSPD_CABLE_LENGTH; - if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) { - ret_val = -E1000_ERR_PHY; - goto out; - } + if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) + return -E1000_ERR_PHY; phy->min_cable_length = e1000_gg82563_cable_length_table[index]; phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5]; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -857,11 +822,11 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; + u16 kum_reg_data; DEBUGFUNC("e1000_reset_hw_80003es2lan"); - /* - * Prevent the PCI-E bus from sticking if there is no TLP connection + /* Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); @@ -880,23 +845,30 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) ctrl = E1000_READ_REG(hw, E1000_CTRL); ret_val = e1000_acquire_phy_80003es2lan(hw); + if (ret_val) + return ret_val; + DEBUGOUT("Issuing a global reset to MAC\n"); E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); e1000_release_phy_80003es2lan(hw); + /* Disable IBIST slave mode (far-end loopback) */ + e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, + &kum_reg_data); + kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE; + e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, + kum_reg_data); + ret_val = e1000_get_auto_rd_done_generic(hw); if (ret_val) /* We don't want to continue accessing MAC registers. */ - goto out; + return ret_val; /* Clear any pending interrupt events. */ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); E1000_READ_REG(hw, E1000_ICR); - ret_val = e1000_check_alt_mac_addr_generic(hw); - -out: - return ret_val; + return e1000_check_alt_mac_addr_generic(hw); } /** @@ -919,9 +891,9 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Initialize identification LED */ ret_val = mac->ops.id_led_init(hw); + /* An error is not fatal and we should not stop init due to this */ if (ret_val) DEBUGOUT("Error initializing identification LED\n"); - /* This is not fatal and we should not stop init due to this */ /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); @@ -937,6 +909,8 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = mac->ops.setup_link(hw); + if (ret_val) + return ret_val; /* Disable IBIST slave mode (far-end loopback) */ e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, @@ -947,14 +921,14 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Set the transmit descriptor write-back policy */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); /* ...for both queues. */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); /* Enable retransmit on late collisions */ @@ -981,18 +955,16 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* default to TRUE to enable the MDIC W/A */ hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE; - ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET >> - E1000_KMRNCTRLSTA_OFFSET_SHIFT, - &i); + ret_val = + e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET >> + E1000_KMRNCTRLSTA_OFFSET_SHIFT, &i); if (!ret_val) { if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE; } - /* - * Clear all of the statistics registers (clear on read). It is + /* Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. @@ -1039,6 +1011,13 @@ static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) reg |= (1 << 28); E1000_WRITE_REG(hw, E1000_TARC(1), reg); + /* Disable IPv6 extension header parsing because some malformed + * IPv6 headers can hang the Rx. + */ + reg = E1000_READ_REG(hw, E1000_RFCTL); + reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); + E1000_WRITE_REG(hw, E1000_RFCTL, reg); + return; } @@ -1052,14 +1031,14 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; - u32 ctrl_ext; + u32 reg; u16 data; DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &data); if (ret_val) - goto out; + return ret_val; data |= GG82563_MSCR_ASSERT_CRS_ON_TX; /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ @@ -1067,10 +1046,9 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, data); if (ret_val) - goto out; + return ret_val; - /* - * Options: + /* Options: * MDI/MDI-X = 0 (default) * 0 - Auto for all speeds * 1 - MDI mode @@ -1079,7 +1057,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) */ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); if (ret_val) - goto out; + return ret_val; data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; @@ -1096,8 +1074,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) break; } - /* - * Options: + /* Options: * disable_polarity_correction = 0 (default) * Automatic Correction for Reversed Cable Polarity * 0 - Disabled @@ -1109,90 +1086,86 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); if (ret_val) - goto out; + return ret_val; /* SW Reset the PHY so all changes take effect */ ret_val = hw->phy.ops.commit(hw); if (ret_val) { DEBUGOUT("Error Resetting the PHY\n"); - goto out; + return ret_val; } /* Bypass Rx and Tx FIFO's */ - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, - E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | - E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); + reg = E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL; + data = (E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | + E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data); if (ret_val) - goto out; + return ret_val; - ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, &data); + reg = E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE; + ret_val = e1000_read_kmrn_reg_80003es2lan(hw, reg, &data); if (ret_val) - goto out; + return ret_val; data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, data); + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, reg, data); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data); if (ret_val) - goto out; + return ret_val; data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data); if (ret_val) - goto out; + return ret_val; - ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); - ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); - E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); + reg = E1000_READ_REG(hw, E1000_CTRL_EXT); + reg &= ~E1000_CTRL_EXT_LINK_MODE_MASK; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); if (ret_val) - goto out; + return ret_val; - /* - * Do not init these registers when the HW is in IAMT mode, since the + /* Do not init these registers when the HW is in IAMT mode, since the * firmware will have already initialized them. We only initialize * them if the HW is not in IAMT mode. */ - if (!(hw->mac.ops.check_mng_mode(hw))) { + if (!hw->mac.ops.check_mng_mode(hw)) { /* Enable Electrical Idle on the PHY */ data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, data); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &data); if (ret_val) - goto out; + return ret_val; data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, data); if (ret_val) - goto out; + return ret_val; } - /* - * Workaround: Disable padding in Kumeran interface in the MAC + /* Workaround: Disable padding in Kumeran interface in the MAC * and in the PHY to avoid CRC errors. */ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data); if (ret_val) - goto out; + return ret_val; data |= GG82563_ICR_DIS_PADDING; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data); if (ret_val) - goto out; + return ret_val; -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1215,42 +1188,42 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - /* - * Set the mac to wait the maximum time between each + /* Set the mac to wait the maximum time between each * iteration and increase the max iterations when * polling the phy; this fixes erroneous timeouts at 10Mbps. */ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4), 0xFFFF); if (ret_val) - goto out; + return ret_val; ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), ®_data); if (ret_val) - goto out; + return ret_val; reg_data |= 0x3F; ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), reg_data); if (ret_val) - goto out; - ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, ®_data); + return ret_val; + ret_val = + e1000_read_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, + ®_data); if (ret_val) - goto out; + return ret_val; reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, reg_data); + ret_val = + e1000_write_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, + reg_data); if (ret_val) - goto out; + return ret_val; ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw); if (ret_val) - goto out; - - ret_val = e1000_setup_copper_link_generic(hw); + return ret_val; -out: - return ret_val; + return e1000_setup_copper_link_generic(hw); } /** @@ -1273,7 +1246,7 @@ static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) ret_val = e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex); if (ret_val) - goto out; + return ret_val; if (speed == SPEED_1000) ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); @@ -1281,7 +1254,6 @@ static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex); } -out: return ret_val; } @@ -1295,7 +1267,7 @@ out: **/ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u32 tipg; u32 i = 0; u16 reg_data, reg_data2; @@ -1303,11 +1275,12 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) DEBUGFUNC("e1000_configure_kmrn_for_10_100"); reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, - reg_data); + ret_val = + e1000_write_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, + reg_data); if (ret_val) - goto out; + return ret_val; /* Configure Transmit Inter-Packet Gap */ tipg = E1000_READ_REG(hw, E1000_TIPG); @@ -1319,12 +1292,12 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); if (ret_val) - goto out; + return ret_val; i++; } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); @@ -1333,11 +1306,7 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) else reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - reg_data); - -out: - return ret_val; + return hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); } /** @@ -1349,7 +1318,7 @@ out: **/ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u16 reg_data, reg_data2; u32 tipg; u32 i = 0; @@ -1357,10 +1326,12 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_configure_kmrn_for_1000"); reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; - ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, reg_data); + ret_val = + e1000_write_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, + reg_data); if (ret_val) - goto out; + return ret_val; /* Configure Transmit Inter-Packet Gap */ tipg = E1000_READ_REG(hw, E1000_TIPG); @@ -1372,21 +1343,18 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); if (ret_val) - goto out; + return ret_val; i++; } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - reg_data); -out: - return ret_val; + return hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); } /** @@ -1403,13 +1371,13 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data) { u32 kmrnctrlsta; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan"); ret_val = e1000_acquire_mac_csr_80003es2lan(hw); if (ret_val) - goto out; + return ret_val; kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; @@ -1423,7 +1391,6 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, e1000_release_mac_csr_80003es2lan(hw); -out: return ret_val; } @@ -1441,13 +1408,13 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data) { u32 kmrnctrlsta; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan"); ret_val = e1000_acquire_mac_csr_80003es2lan(hw); if (ret_val) - goto out; + return ret_val; kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | data; @@ -1458,7 +1425,6 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, e1000_release_mac_csr_80003es2lan(hw); -out: return ret_val; } @@ -1468,23 +1434,19 @@ out: **/ static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_read_mac_addr_80003es2lan"); - /* - * If there's an alternate MAC address place it in RAR0 + /* If there's an alternate MAC address place it in RAR0 * so that it will override the Si installed default perm * address. */ ret_val = e1000_check_alt_mac_addr_generic(hw); if (ret_val) - goto out; - - ret_val = e1000_read_mac_addr_generic(hw); + return ret_val; -out: - return ret_val; + return e1000_read_mac_addr_generic(hw); } /** diff --git a/freebsd/sys/dev/e1000/e1000_80003es2lan.h b/freebsd/sys/dev/e1000/e1000_80003es2lan.h index 157468e4..3807e463 100644 --- a/freebsd/sys/dev/e1000/e1000_80003es2lan.h +++ b/freebsd/sys/dev/e1000/e1000_80003es2lan.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2013, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -51,34 +51,32 @@ #define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C #define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004 -#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ +#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gig Carry Extend Padding */ #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 #define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8 #define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9 /* GG82563 PHY Specific Status Register (Page 0, Register 16 */ -#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disabled */ +#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Dis */ #define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060 #define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */ #define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */ #define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */ /* PHY Specific Control Register 2 (Page 0, Register 26) */ -#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Nego */ +#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Neg */ /* MAC Specific Control Register (Page 2, Register 21) */ /* Tx clock speed for Link Down and 1000BASE-T for the following speeds */ #define GG82563_MSCR_TX_CLK_MASK 0x0007 #define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004 #define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005 -#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006 #define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007 #define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ -/* DSP Distance Register (Page 5, Register 26) */ -/* +/* DSP Distance Register (Page 5, Register 26) * 0 = <50M * 1 = 50-80M * 2 = 80-100M diff --git a/freebsd/sys/dev/e1000/e1000_82542.c b/freebsd/sys/dev/e1000/e1000_82542.c index 8b4ce19f..95323394 100644 --- a/freebsd/sys/dev/e1000/e1000_82542.c +++ b/freebsd/sys/dev/e1000/e1000_82542.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2010, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,7 +49,7 @@ static s32 e1000_init_hw_82542(struct e1000_hw *hw); static s32 e1000_setup_link_82542(struct e1000_hw *hw); static s32 e1000_led_on_82542(struct e1000_hw *hw); static s32 e1000_led_off_82542(struct e1000_hw *hw); -static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index); +static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index); static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw); static s32 e1000_read_mac_addr_82542(struct e1000_hw *hw); @@ -411,7 +411,7 @@ static s32 e1000_led_off_82542(struct e1000_hw *hw) * Sets the receive address array register at index to the address passed * in by addr. **/ -static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index) +static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index) { u32 rar_low, rar_high; @@ -433,6 +433,7 @@ static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index) E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); + return E1000_SUCCESS; } /** diff --git a/freebsd/sys/dev/e1000/e1000_82571.c b/freebsd/sys/dev/e1000/e1000_82571.c index e64e8fa6..dadd3a82 100644 --- a/freebsd/sys/dev/e1000/e1000_82571.c +++ b/freebsd/sys/dev/e1000/e1000_82571.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -929,9 +929,9 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, } for (i = 0; i < words; i++) { - eewr = (data[i] << E1000_NVM_RW_REG_DATA) | - ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | - E1000_NVM_RW_REG_START; + eewr = ((data[i] << E1000_NVM_RW_REG_DATA) | + ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) | + E1000_NVM_RW_REG_START); ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); if (ret_val) @@ -1103,8 +1103,6 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) default: break; } - if (ret_val) - DEBUGOUT("Cannot acquire MDIO ownership\n"); ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -1113,9 +1111,16 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) /* Must release MDIO ownership and mutex after MAC reset. */ switch (hw->mac.type) { + case e1000_82573: + /* Release mutex only if the hw semaphore is acquired */ + if (!ret_val) + e1000_put_hw_semaphore_82573(hw); + break; case e1000_82574: case e1000_82583: - e1000_put_hw_semaphore_82574(hw); + /* Release mutex only if the hw semaphore is acquired */ + if (!ret_val) + e1000_put_hw_semaphore_82574(hw); break; default: break; @@ -1224,8 +1229,8 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) /* Set the transmit descriptor write-back policy */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC); E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); /* ...for both queues. */ @@ -1241,9 +1246,9 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) break; default: reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); - reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB | - E1000_TXDCTL_COUNT_DESC; + reg_data = ((reg_data & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB | + E1000_TXDCTL_COUNT_DESC); E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); break; } @@ -1450,10 +1455,14 @@ static void e1000_clear_vfta_82571(struct e1000_hw *hw) static bool e1000_check_mng_mode_82574(struct e1000_hw *hw) { u16 data; + s32 ret_val; DEBUGFUNC("e1000_check_mng_mode_82574"); - hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data); + ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data); + if (ret_val) + return FALSE; + return (data & E1000_NVM_INIT_CTRL2_MNGM) != 0; } diff --git a/freebsd/sys/dev/e1000/e1000_82571.h b/freebsd/sys/dev/e1000/e1000_82571.h index c76f16fe..41d5df0e 100644 --- a/freebsd/sys/dev/e1000/e1000_82571.h +++ b/freebsd/sys/dev/e1000/e1000_82571.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2010, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,29 +35,30 @@ #ifndef _E1000_82571_H_ #define _E1000_82571_H_ -#define ID_LED_RESERVED_F746 0xF746 -#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \ - (ID_LED_OFF1_ON2 << 8) | \ - (ID_LED_DEF1_DEF2 << 4) | \ - (ID_LED_DEF1_DEF2)) +#define ID_LED_RESERVED_F746 0xF746 +#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \ + (ID_LED_OFF1_ON2 << 8) | \ + (ID_LED_DEF1_DEF2 << 4) | \ + (ID_LED_DEF1_DEF2)) -#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 -#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */ +#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 +#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */ /* Intr Throttling - RW */ -#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n))) +#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n))) -#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */ -#define E1000_EIAC_MASK_82574 0x01F00000 +#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */ +#define E1000_EIAC_MASK_82574 0x01F00000 -#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */ +#define E1000_IVAR_INT_ALLOC_VALID 0x8 -#define E1000_RXCFGL 0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */ +/* Manageability Operation Mode mask */ +#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 -#define E1000_BASE1000T_STATUS 10 -#define E1000_IDLE_ERROR_COUNT_MASK 0xFF -#define E1000_RECEIVE_ERROR_COUNTER 21 -#define E1000_RECEIVE_ERROR_MAX 0xFFFF +#define E1000_BASE1000T_STATUS 10 +#define E1000_IDLE_ERROR_COUNT_MASK 0xFF +#define E1000_RECEIVE_ERROR_COUNTER 21 +#define E1000_RECEIVE_ERROR_MAX 0xFFFF bool e1000_check_phy_82574(struct e1000_hw *hw); bool e1000_get_laa_state_82571(struct e1000_hw *hw); void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state); diff --git a/freebsd/sys/dev/e1000/e1000_82575.c b/freebsd/sys/dev/e1000/e1000_82575.c index b6356b05..0e06471f 100644 --- a/freebsd/sys/dev/e1000/e1000_82575.c +++ b/freebsd/sys/dev/e1000/e1000_82575.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -54,10 +54,10 @@ static void e1000_release_phy_82575(struct e1000_hw *hw); static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw); static void e1000_release_nvm_82575(struct e1000_hw *hw); static s32 e1000_check_for_link_82575(struct e1000_hw *hw); +static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw); static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw); static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, u16 *duplex); -static s32 e1000_init_hw_82575(struct e1000_hw *hw); static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw); static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 *data); @@ -121,7 +121,8 @@ static bool e1000_get_i2c_data(u32 *i2cctl); static const u16 e1000_82580_rxpbs_table[] = { 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 }; #define E1000_82580_RXPBS_TABLE_SIZE \ - (sizeof(e1000_82580_rxpbs_table)/sizeof(u16)) + (sizeof(e1000_82580_rxpbs_table) / \ + sizeof(e1000_82580_rxpbs_table[0])) /** @@ -146,6 +147,7 @@ static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw) break; case e1000_82580: case e1000_i350: + case e1000_i354: case e1000_i210: case e1000_i211: reg = E1000_READ_REG(hw, E1000_MDICNFG); @@ -209,6 +211,7 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82580: case e1000_i350: + case e1000_i354: phy->ops.read_reg = e1000_read_phy_reg_82580; phy->ops.write_reg = e1000_write_phy_reg_82580; break; @@ -228,6 +231,8 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) /* Verify phy id and set remaining function pointers */ switch (phy->id) { + case M88E1543_E_PHY_ID: + case M88E1512_E_PHY_ID: case I347AT4_E_PHY_ID: case M88E1112_E_PHY_ID: case M88E1340M_E_PHY_ID: @@ -240,9 +245,41 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) phy->id == M88E1340M_E_PHY_ID) phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2; + else if (phy->id == M88E1543_E_PHY_ID || + phy->id == M88E1512_E_PHY_ID) + phy->ops.get_cable_length = + e1000_get_cable_length_m88_gen2; else phy->ops.get_cable_length = e1000_get_cable_length_m88; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + /* Check if this PHY is confgured for media swap. */ + if (phy->id == M88E1112_E_PHY_ID) { + u16 data; + + ret_val = phy->ops.write_reg(hw, + E1000_M88E1112_PAGE_ADDR, + 2); + if (ret_val) + goto out; + + ret_val = phy->ops.read_reg(hw, + E1000_M88E1112_MAC_CTRL_1, + &data); + if (ret_val) + goto out; + + data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >> + E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT; + if (data == E1000_M88E1112_AUTO_COPPER_SGMII || + data == E1000_M88E1112_AUTO_COPPER_BASEX) + hw->mac.ops.check_for_link = + e1000_check_for_link_media_swap; + } + if (phy->id == M88E1512_E_PHY_ID) { + ret_val = e1000_initialize_M88E1512_phy(hw); + if (ret_val) + goto out; + } break; case IGP03E1000_E_PHY_ID: case IGP04E1000_E_PHY_ID: @@ -357,6 +394,7 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw) nvm->ops.update = e1000_update_nvm_checksum_82580; break; case e1000_i350: + case e1000_i354: nvm->ops.validate = e1000_validate_nvm_checksum_i350; nvm->ops.update = e1000_update_nvm_checksum_i350; break; @@ -390,7 +428,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES_82576; if (mac->type == e1000_82580) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; - if (mac->type == e1000_i350) + if (mac->type == e1000_i350 || mac->type == e1000_i354) mac->rar_entry_count = E1000_RAR_ENTRIES_I350; /* Enable EEE default settings for EEE supported devices */ @@ -419,6 +457,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) else mac->ops.reset_hw = e1000_reset_hw_82575; /* hw initialization */ + if ((mac->type == e1000_i210) || (mac->type == e1000_i211)) + mac->ops.init_hw = e1000_init_hw_i210; + else mac->ops.init_hw = e1000_init_hw_82575; /* link setup */ mac->ops.setup_link = e1000_setup_link_generic; @@ -438,7 +479,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) mac->ops.config_collision_dist = e1000_config_collision_dist_82575; /* multicast address update */ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; - if (mac->type == e1000_i350) { + if (hw->mac.type == e1000_i350 || mac->type == e1000_i354) { /* writing VFTA */ mac->ops.write_vfta = e1000_write_vfta_i350; /* clearing VFTA */ @@ -624,6 +665,10 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_get_phy_id_82575"); + /* some i354 devices need an extra read for phy id */ + if (hw->mac.type == e1000_i354) + e1000_get_phy_id(hw); + /* * For SGMII PHYs, we try the list of possible addresses until * we find one that works. For non-SGMII PHYs @@ -647,6 +692,7 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) break; case e1000_82580: case e1000_i350: + case e1000_i354: case e1000_i210: case e1000_i211: mdic = E1000_READ_REG(hw, E1000_MDICNFG); @@ -714,6 +760,7 @@ out: static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; + struct e1000_phy_info *phy = &hw->phy; DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575"); @@ -736,7 +783,11 @@ static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw) goto out; ret_val = hw->phy.ops.commit(hw); + if (ret_val) + goto out; + if (phy->id == M88E1512_E_PHY_ID) + ret_val = e1000_initialize_M88E1512_phy(hw); out: return ret_val; } @@ -843,7 +894,6 @@ out: static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; u32 data; DEBUGFUNC("e1000_set_d0_lplu_state_82580"); @@ -871,7 +921,7 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) } E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data); - return ret_val; + return E1000_SUCCESS; } /** @@ -891,7 +941,6 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; u32 data; DEBUGFUNC("e1000_set_d3_lplu_state_82580"); @@ -919,7 +968,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) } E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data); - return ret_val; + return E1000_SUCCESS; } /** @@ -933,7 +982,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) **/ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_acquire_nvm_82575"); @@ -955,6 +1004,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) DEBUGOUT("Nvm bit banging access error detected and cleared.\n"); } } + if (hw->mac.type == e1000_82580) { u32 eecd = E1000_READ_REG(hw, E1000_EECD); if (eecd & E1000_EECD_BLOCKED) { @@ -965,7 +1015,6 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) } } - ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); @@ -1079,7 +1128,6 @@ static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; - s32 ret_val = E1000_SUCCESS; u32 mask = E1000_NVM_CFG_DONE_PORT_0; DEBUGFUNC("e1000_get_cfg_done_82575"); @@ -1104,7 +1152,7 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw) (hw->phy.type == e1000_phy_igp_3)) e1000_phy_init_script_igp3(hw); - return ret_val; + return E1000_SUCCESS; } /** @@ -1174,6 +1222,61 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw) return ret_val; } +/** + * e1000_check_for_link_media_swap - Check which M88E1112 interface linked + * @hw: pointer to the HW structure + * + * Poll the M88E1112 interfaces to see which interface achieved link. + */ +static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 data; + u8 port = 0; + + DEBUGFUNC("e1000_check_for_link_media_swap"); + + /* Check the copper medium. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0); + if (ret_val) + return ret_val; + + ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data); + if (ret_val) + return ret_val; + + if (data & E1000_M88E1112_STATUS_LINK) + port = E1000_MEDIA_PORT_COPPER; + + /* Check the other medium. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1); + if (ret_val) + return ret_val; + + ret_val = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data); + if (ret_val) + return ret_val; + + /* reset page to 0 */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0); + if (ret_val) + return ret_val; + + if (data & E1000_M88E1112_STATUS_LINK) + port = E1000_MEDIA_PORT_OTHER; + + /* Determine if a swap needs to happen. */ + if (port && (hw->dev_spec._82575.media_port != port)) { + hw->dev_spec._82575.media_port = port; + hw->dev_spec._82575.media_changed = TRUE; + } else { + ret_val = e1000_check_for_link_82575(hw); + } + + return E1000_SUCCESS; +} + /** * e1000_power_up_serdes_link_82575 - Power up the serdes link after shutdown * @hw: pointer to the HW structure @@ -1217,6 +1320,7 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, { struct e1000_mac_info *mac = &hw->mac; u32 pcs; + u32 status; DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575"); @@ -1247,6 +1351,18 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, else *duplex = HALF_DUPLEX; + /* Check if it is an I354 2.5Gb backplane connection. */ + if (mac->type == e1000_i354) { + status = E1000_READ_REG(hw, E1000_STATUS); + if ((status & E1000_STATUS_2P5_SKU) && + !(status & E1000_STATUS_2P5_SKU_OVER)) { + *speed = SPEED_2500; + *duplex = FULL_DUPLEX; + DEBUGOUT("2500 Mbs, "); + DEBUGOUT("Full Duplex\n"); + } + } + } else { mac->serdes_has_link = FALSE; *speed = 0; @@ -1362,7 +1478,7 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw) * * This inits the hardware readying it for operation. **/ -static s32 e1000_init_hw_82575(struct e1000_hw *hw) +s32 e1000_init_hw_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; @@ -1432,11 +1548,18 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - /* Clear Go Link Disconnect bit */ - if (hw->mac.type >= e1000_82580) { + /* Clear Go Link Disconnect bit on supported devices */ + switch (hw->mac.type) { + case e1000_82580: + case e1000_i350: + case e1000_i210: + case e1000_i211: phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT); phpm_reg &= ~E1000_82580_PM_GO_LINKD; E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg); + break; + default: + break; } ret_val = e1000_setup_serdes_link_82575(hw); @@ -1460,6 +1583,8 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) case I347AT4_E_PHY_ID: case M88E1112_E_PHY_ID: case M88E1340M_E_PHY_ID: + case M88E1543_E_PHY_ID: + case M88E1512_E_PHY_ID: case I210_I_PHY_ID: ret_val = e1000_copper_link_setup_m88_gen2(hw); break; @@ -1872,7 +1997,7 @@ static s32 e1000_reset_init_script_82575(struct e1000_hw *hw) **/ static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_read_mac_addr_82575"); @@ -2134,42 +2259,33 @@ out: **/ void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf) { - u32 dtxswc; + u32 reg_val, reg_offset; switch (hw->mac.type) { case e1000_82576: - dtxswc = E1000_READ_REG(hw, E1000_DTXSWC); - if (enable) { - dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); - /* The PF can spoof - it has to in order to - * support emulation mode NICs */ - dtxswc ^= (1 << pf | 1 << (pf + - E1000_DTXSWC_VLAN_SPOOF_SHIFT)); - } else { - dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); - } - E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc); + reg_offset = E1000_DTXSWC; break; case e1000_i350: - dtxswc = E1000_READ_REG(hw, E1000_TXSWC); - if (enable) { - dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); - /* The PF can spoof - it has to in order to - * support emulation mode NICs - */ - dtxswc ^= (1 << pf | 1 << (pf + - E1000_DTXSWC_VLAN_SPOOF_SHIFT)); - } else { - dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); - } - E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc); - default: + case e1000_i354: + reg_offset = E1000_TXSWC; break; + default: + return; } + + reg_val = E1000_READ_REG(hw, reg_offset); + if (enable) { + reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + /* The PF can spoof - it has to in order to + * support emulation mode NICs + */ + reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS)); + } else { + reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + } + E1000_WRITE_REG(hw, reg_offset, reg_val); } /** @@ -2193,6 +2309,7 @@ void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable) E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc); break; case e1000_i350: + case e1000_i354: dtxswc = E1000_READ_REG(hw, E1000_TXSWC); if (enable) dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN; @@ -2373,11 +2490,17 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw) ctrl |= E1000_CTRL_RST; E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - E1000_WRITE_FLUSH(hw); - /* Add delay to insure DEV_RST has time to complete */ - if (global_device_reset) - msec_delay(5); + switch (hw->device_id) { + case E1000_DEV_ID_DH89XXCC_SGMII: + break; + default: + E1000_WRITE_FLUSH(hw); + break; + } + + /* Add delay to insure DEV_RST or RST has time to complete */ + msec_delay(5); ret_val = e1000_get_auto_rd_done_generic(hw); if (ret_val) { @@ -2389,10 +2512,6 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw) DEBUGOUT("Auto Read Done did not complete\n"); } - /* If EEPROM is not present, run manual init scripts */ - if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES)) - e1000_reset_init_script_82575(hw); - /* clear global device reset status bit */ E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET); @@ -2516,7 +2635,7 @@ out: **/ static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u16 eeprom_regions_count = 1; u16 j, nvm_data; u16 nvm_offset; @@ -2646,6 +2765,134 @@ out: return ret_val; } +/** + * __e1000_access_emi_reg - Read/write EMI register + * @hw: pointer to the HW structure + * @addr: EMI address to program + * @data: pointer to value to read/write from/to the EMI address + * @read: boolean flag to indicate read or write + **/ +static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address, + u16 *data, bool read) +{ + s32 ret_val; + + DEBUGFUNC("__e1000_access_emi_reg"); + + ret_val = hw->phy.ops.write_reg(hw, E1000_EMIADD, address); + if (ret_val) + return ret_val; + + if (read) + ret_val = hw->phy.ops.read_reg(hw, E1000_EMIDATA, data); + else + ret_val = hw->phy.ops.write_reg(hw, E1000_EMIDATA, *data); + + return ret_val; +} + +/** + * e1000_read_emi_reg - Read Extended Management Interface register + * @hw: pointer to the HW structure + * @addr: EMI address to program + * @data: value to be read from the EMI address + **/ +s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data) +{ + DEBUGFUNC("e1000_read_emi_reg"); + + return __e1000_access_emi_reg(hw, addr, data, TRUE); +} + +/** + * e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY + * @hw: pointer to the HW structure + * + * Initialize Marverl 1512 to work correctly with Avoton. + **/ +s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_initialize_M88E1512_phy"); + + /* Check if this is correct PHY. */ + if (phy->id != M88E1512_E_PHY_ID) + goto out; + + /* Switch to PHY page 0xFF. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159); + if (ret_val) + goto out; + + /* Switch to PHY page 0xFB. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D); + if (ret_val) + goto out; + + /* Switch to PHY page 0x12. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12); + if (ret_val) + goto out; + + /* Change mode to SGMII-to-Copper */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001); + if (ret_val) + goto out; + + /* Return the PHY to page 0. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0); + if (ret_val) + goto out; + + ret_val = phy->ops.commit(hw); + if (ret_val) { + DEBUGOUT("Error committing the PHY changes\n"); + return ret_val; + } + + msec_delay(1000); +out: + return ret_val; +} + /** * e1000_set_eee_i350 - Enable/disable EEE support * @hw: pointer to the HW structure @@ -2655,7 +2902,6 @@ out: **/ s32 e1000_set_eee_i350(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; u32 ipcnfg, eeer; DEBUGFUNC("e1000_set_eee_i350"); @@ -2688,6 +2934,114 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw) E1000_READ_REG(hw, E1000_EEER); out: + return E1000_SUCCESS; +} + +/** + * e1000_set_eee_i354 - Enable/disable EEE support + * @hw: pointer to the HW structure + * + * Enable/disable EEE legacy mode based on setting in dev_spec structure. + * + **/ +s32 e1000_set_eee_i354(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val = E1000_SUCCESS; + u16 phy_data; + + DEBUGFUNC("e1000_set_eee_i354"); + + if ((hw->phy.media_type != e1000_media_type_copper) || + ((phy->id != M88E1543_E_PHY_ID) && + (phy->id != M88E1512_E_PHY_ID))) + goto out; + + if (!hw->dev_spec._82575.eee_disable) { + /* Switch to PHY page 18. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18); + if (ret_val) + goto out; + + ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1, + &phy_data); + if (ret_val) + goto out; + + phy_data |= E1000_M88E1543_EEE_CTRL_1_MS; + ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1, + phy_data); + if (ret_val) + goto out; + + /* Return the PHY to page 0. */ + ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0); + if (ret_val) + goto out; + + /* Turn on EEE advertisement. */ + ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354, + E1000_EEE_ADV_DEV_I354, + &phy_data); + if (ret_val) + goto out; + + phy_data |= E1000_EEE_ADV_100_SUPPORTED | + E1000_EEE_ADV_1000_SUPPORTED; + ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354, + E1000_EEE_ADV_DEV_I354, + phy_data); + } else { + /* Turn off EEE advertisement. */ + ret_val = e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354, + E1000_EEE_ADV_DEV_I354, + &phy_data); + if (ret_val) + goto out; + + phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED | + E1000_EEE_ADV_1000_SUPPORTED); + ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354, + E1000_EEE_ADV_DEV_I354, + phy_data); + } + +out: + return ret_val; +} + +/** + * e1000_get_eee_status_i354 - Get EEE status + * @hw: pointer to the HW structure + * @status: EEE status + * + * Get EEE status by guessing based on whether Tx or Rx LPI indications have + * been received. + **/ +s32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val = E1000_SUCCESS; + u16 phy_data; + + DEBUGFUNC("e1000_get_eee_status_i354"); + + /* Check if EEE is supported on this device. */ + if ((hw->phy.media_type != e1000_media_type_copper) || + ((phy->id != M88E1543_E_PHY_ID) && + (phy->id != M88E1512_E_PHY_ID))) + goto out; + + ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354, + E1000_PCS_STATUS_DEV_I354, + &phy_data); + if (ret_val) + goto out; + + *status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD | + E1000_PCS_STATUS_RX_LPI_RCVD) ? TRUE : FALSE; + +out: return ret_val; } @@ -3288,4 +3642,3 @@ void e1000_i2c_bus_clear(struct e1000_hw *hw) e1000_i2c_stop(hw); } - diff --git a/freebsd/sys/dev/e1000/e1000_82575.h b/freebsd/sys/dev/e1000/e1000_82575.h index c6bbe186..6569b988 100644 --- a/freebsd/sys/dev/e1000/e1000_82575.h +++ b/freebsd/sys/dev/e1000/e1000_82575.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -245,6 +245,8 @@ union e1000_adv_rx_desc { #define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009 /* RSS Packet Types as indicated in the receive descriptor */ +#define E1000_RXDADV_PKTTYPE_ILMASK 0x000000F0 +#define E1000_RXDADV_PKTTYPE_TLMASK 0x00000F00 #define E1000_RXDADV_PKTTYPE_NONE 0x00000000 #define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */ #define E1000_RXDADV_PKTTYPE_IPV4_EX 0x00000020 /* IPV4 hdr + extensions */ @@ -478,6 +480,7 @@ void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable); void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf); void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable); s32 e1000_init_nvm_params_82575(struct e1000_hw *hw); +s32 e1000_init_hw_82575(struct e1000_hw *hw); enum e1000_promisc_type { e1000_promisc_disabled = 0, /* all promisc modes disabled */ @@ -491,7 +494,11 @@ void e1000_vfta_set_vf(struct e1000_hw *, u16, bool); void e1000_rlpml_set_vf(struct e1000_hw *, u16); s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type); u16 e1000_rxpbs_adjust_82580(u32 data); +s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data); s32 e1000_set_eee_i350(struct e1000_hw *); +s32 e1000_set_eee_i354(struct e1000_hw *); +s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *); +s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw); /* I2C SDA and SCL timing parameters for standard mode */ #define E1000_I2C_T_HD_STA 4 diff --git a/freebsd/sys/dev/e1000/e1000_api.c b/freebsd/sys/dev/e1000/e1000_api.c index 3c0eb4f4..71315bde 100644 --- a/freebsd/sys/dev/e1000/e1000_api.c +++ b/freebsd/sys/dev/e1000/e1000_api.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -295,6 +295,10 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_PCH_LPT_I217_V: case E1000_DEV_ID_PCH_LPTLP_I218_LM: case E1000_DEV_ID_PCH_LPTLP_I218_V: + case E1000_DEV_ID_PCH_I218_LM2: + case E1000_DEV_ID_PCH_I218_V2: + case E1000_DEV_ID_PCH_I218_LM3: + case E1000_DEV_ID_PCH_I218_V3: mac->type = e1000_pch_lpt; break; case E1000_DEV_ID_82575EB_COPPER: @@ -331,9 +335,8 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_I350_DA4: mac->type = e1000_i350; break; -#if defined(QV_RELEASE) && defined(SPRINGVILLE_FLASHLESS_HW) - case E1000_DEV_ID_I210_NVMLESS: -#endif /* QV_RELEASE && SPRINGVILLE_FLASHLESS_HW */ + case E1000_DEV_ID_I210_COPPER_FLASHLESS: + case E1000_DEV_ID_I210_SERDES_FLASHLESS: case E1000_DEV_ID_I210_COPPER: case E1000_DEV_ID_I210_COPPER_OEM1: case E1000_DEV_ID_I210_COPPER_IT: @@ -354,6 +357,11 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) mac->type = e1000_vfadapt_i350; break; + case E1000_DEV_ID_I354_BACKPLANE_1GBPS: + case E1000_DEV_ID_I354_SGMII: + case E1000_DEV_ID_I354_BACKPLANE_2_5GBPS: + mac->type = e1000_i354; + break; default: /* Should never have loaded on this device */ ret_val = -E1000_ERR_MAC_INIT; @@ -449,6 +457,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) case e1000_82576: case e1000_82580: case e1000_i350: + case e1000_i354: e1000_init_function_pointers_82575(hw); break; case e1000_i210: @@ -825,10 +834,12 @@ void e1000_config_collision_dist(struct e1000_hw *hw) * * Sets a Receive Address Register (RAR) to the specified address. **/ -void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) +int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) { if (hw->mac.ops.rar_set) - hw->mac.ops.rar_set(hw, addr, index); + return hw->mac.ops.rar_set(hw, addr, index); + + return E1000_SUCCESS; } /** diff --git a/freebsd/sys/dev/e1000/e1000_api.h b/freebsd/sys/dev/e1000/e1000_api.h index 69db1be9..a2ffa169 100644 --- a/freebsd/sys/dev/e1000/e1000_api.h +++ b/freebsd/sys/dev/e1000/e1000_api.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -69,7 +69,7 @@ s32 e1000_setup_link(struct e1000_hw *hw); s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex); s32 e1000_disable_pcie_master(struct e1000_hw *hw); void e1000_config_collision_dist(struct e1000_hw *hw); -void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); +int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr); void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count); diff --git a/freebsd/sys/dev/e1000/e1000_defines.h b/freebsd/sys/dev/e1000/e1000_defines.h index 0815ea8e..72a8b14f 100644 --- a/freebsd/sys/dev/e1000/e1000_defines.h +++ b/freebsd/sys/dev/e1000/e1000_defines.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -43,6 +43,8 @@ /* Wake Up Control */ #define E1000_WUC_APME 0x00000001 /* APM Enable */ #define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ +#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */ +#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */ #define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */ /* Wake Up Filter Control */ @@ -75,6 +77,7 @@ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ /* Physical Func Reset Done Indication */ #define E1000_CTRL_EXT_PFRSTD 0x00004000 +#define E1000_CTRL_EXT_SDLPE 0X00040000 /* SerDes Low Power Enable */ #define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clk Gating */ @@ -129,7 +132,7 @@ #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ -#define E1000_RXDEXT_STATERR_TST 0x00010000 /* Time Stamp taken */ +#define E1000_RXDEXT_STATERR_TST 0x00000100 /* Time Stamp taken */ #define E1000_RXDEXT_STATERR_LB 0x00040000 #define E1000_RXDEXT_STATERR_CE 0x01000000 #define E1000_RXDEXT_STATERR_SE 0x02000000 @@ -155,6 +158,7 @@ E1000_RXDEXT_STATERR_CXE | \ E1000_RXDEXT_STATERR_RXE) +#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001 #define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000 #define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 #define E1000_MRQC_RSS_FIELD_IPV4 0x00020000 @@ -287,7 +291,10 @@ #define E1000_CONNSW_ENRGSRC 0x4 #define E1000_CONNSW_PHYSD 0x400 +#define E1000_CONNSW_PHY_PDN 0x800 #define E1000_CONNSW_SERDESD 0x200 +#define E1000_CONNSW_AUTOSENSE_CONF 0x2 +#define E1000_CONNSW_AUTOSENSE_EN 0x1 #define E1000_PCS_CFG_PCS_EN 8 #define E1000_PCS_LCTL_FLV_LINK_UP 1 #define E1000_PCS_LCTL_FSV_10 0 @@ -325,6 +332,8 @@ #define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master request status */ #define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ +#define E1000_STATUS_2P5_SKU 0x00001000 /* Val of 2.5GBE SKU strap */ +#define E1000_STATUS_2P5_SKU_OVER 0x00002000 /* Val of 2.5GBE SKU Over */ #define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ #define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */ @@ -336,6 +345,7 @@ #define SPEED_10 10 #define SPEED_100 100 #define SPEED_1000 1000 +#define SPEED_2500 2500 #define HALF_DUPLEX 1 #define FULL_DUPLEX 2 @@ -456,6 +466,7 @@ #define ETHERNET_FCS_SIZE 4 #define MAX_JUMBO_FRAME_SIZE 0x3F00 +#define E1000_TX_PTR_GAP 0x1F /* Extended Configuration Control and Size */ #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 @@ -650,6 +661,7 @@ #define E1000_EITR_ITR_INT_MASK 0x0000FFFF /* E1000_EITR_CNT_IGNR is only for 82576 and newer */ #define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */ +#define E1000_EITR_INTERVAL 0x00007FFC /* Transmit Descriptor Control */ #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ @@ -805,6 +817,17 @@ #define E1000_MDICNFG_PHY_MASK 0x03E00000 #define E1000_MDICNFG_PHY_SHIFT 21 +#define E1000_MEDIA_PORT_COPPER 1 +#define E1000_MEDIA_PORT_OTHER 2 +#define E1000_M88E1112_AUTO_COPPER_SGMII 0x2 +#define E1000_M88E1112_AUTO_COPPER_BASEX 0x3 +#define E1000_M88E1112_STATUS_LINK 0x0004 /* Interface Link Bit */ +#define E1000_M88E1112_MAC_CTRL_1 0x10 +#define E1000_M88E1112_MAC_CTRL_1_MODE_MASK 0x0380 /* Mode Select */ +#define E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT 7 +#define E1000_M88E1112_PAGE_ADDR 0x16 +#define E1000_M88E1112_STATUS 0x01 + #define E1000_THSTAT_LOW_EVENT 0x20000000 /* Low thermal threshold */ #define E1000_THSTAT_MID_EVENT 0x00200000 /* Mid thermal threshold */ #define E1000_THSTAT_HIGH_EVENT 0x00002000 /* High thermal threshold */ @@ -821,7 +844,25 @@ #define E1000_EEER_EEE_NEG 0x20000000 /* EEE capability nego */ #define E1000_EEER_RX_LPI_STATUS 0x40000000 /* Rx in LPI state */ #define E1000_EEER_TX_LPI_STATUS 0x80000000 /* Tx in LPI state */ +#define E1000_EEE_LP_ADV_ADDR_I350 0x040F /* EEE LP Advertisement */ +#define E1000_M88E1543_PAGE_ADDR 0x16 /* Page Offset Register */ +#define E1000_M88E1543_EEE_CTRL_1 0x0 +#define E1000_M88E1543_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */ +#define E1000_EEE_ADV_DEV_I354 7 +#define E1000_EEE_ADV_ADDR_I354 60 +#define E1000_EEE_ADV_100_SUPPORTED (1 << 1) /* 100BaseTx EEE Supported */ +#define E1000_EEE_ADV_1000_SUPPORTED (1 << 2) /* 1000BaseT EEE Supported */ +#define E1000_PCS_STATUS_DEV_I354 3 +#define E1000_PCS_STATUS_ADDR_I354 1 +#define E1000_PCS_STATUS_RX_LPI_RCVD 0x0400 +#define E1000_PCS_STATUS_TX_LPI_RCVD 0x0800 +#define E1000_M88E1512_CFG_REG_1 0x0010 +#define E1000_M88E1512_CFG_REG_2 0x0011 +#define E1000_M88E1512_CFG_REG_3 0x0007 +#define E1000_M88E1512_MODE 0x0014 #define E1000_EEE_SU_LPI_CLK_STP 0x00800000 /* EEE LPI Clock Stop */ +#define E1000_EEE_LP_ADV_DEV_I210 7 /* EEE LP Adv Device */ +#define E1000_EEE_LP_ADV_ADDR_I210 61 /* EEE LP Adv Register */ /* PCI Express Control */ #define E1000_GCR_RXD_NO_SNOOP 0x00000001 #define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002 @@ -841,6 +882,8 @@ E1000_GCR_TXDSCW_NO_SNOOP | \ E1000_GCR_TXDSCR_NO_SNOOP) +#define E1000_MMDAC_FUNC_DATA 0x4000 /* Data, no post increment */ + /* mPHY address control and data registers */ #define E1000_MPHY_ADDR_CTL 0x0024 /* Address Control Reg */ #define E1000_MPHY_ADDR_CTL_OFFSET_MASK 0xFFFF0000 @@ -1169,6 +1212,8 @@ #define M88E1011_I_PHY_ID 0x01410C20 #define IGP01E1000_I_PHY_ID 0x02A80380 #define M88E1111_I_PHY_ID 0x01410CC0 +#define M88E1543_E_PHY_ID 0x01410EA0 +#define M88E1512_E_PHY_ID 0x01410DD0 #define M88E1112_E_PHY_ID 0x01410C90 #define I347AT4_E_PHY_ID 0x01410DC0 #define M88E1340M_E_PHY_ID 0x01410DF0 @@ -1391,6 +1436,9 @@ #define E1000_RXPBS_CFG_TS_EN 0x80000000 /* Timestamp in Rx buffer */ #define E1000_RXPBS_SIZE_I210_MASK 0x0000003F /* Rx packet buffer size */ #define E1000_TXPB0S_SIZE_I210_MASK 0x0000003F /* Tx packet buffer 0 size */ +#define I210_RXPBSIZE_DEFAULT 0x000000A2 /* RXPBSIZE default */ +#define I210_TXPBSIZE_DEFAULT 0x04000014 /* TXPBSIZE default */ + #define E1000_DOBFFCTL_OBFFTHR_MASK 0x000000FF /* OBFF threshold */ #define E1000_DOBFFCTL_EXIT_ACT_MASK 0x01000000 /* Exit active CB */ @@ -1416,4 +1464,8 @@ /* Lan ID bit field offset in status register */ #define E1000_STATUS_LAN_ID_OFFSET 2 #define E1000_VFTA_ENTRIES 128 +#define E1000_UNUSEDARG +#ifndef ERROR_REPORT +#define ERROR_REPORT(fmt) do { } while (0) +#endif /* ERROR_REPORT */ #endif /* _E1000_DEFINES_H_ */ diff --git a/freebsd/sys/dev/e1000/e1000_hw.h b/freebsd/sys/dev/e1000/e1000_hw.h index e8a8c174..faf64a37 100644 --- a/freebsd/sys/dev/e1000/e1000_hw.h +++ b/freebsd/sys/dev/e1000/e1000_hw.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -133,6 +133,10 @@ struct e1000_hw; #define E1000_DEV_ID_PCH_LPT_I217_V 0x153B #define E1000_DEV_ID_PCH_LPTLP_I218_LM 0x155A #define E1000_DEV_ID_PCH_LPTLP_I218_V 0x1559 +#define E1000_DEV_ID_PCH_I218_LM2 0x15A0 +#define E1000_DEV_ID_PCH_I218_V2 0x15A1 +#define E1000_DEV_ID_PCH_I218_LM3 0x15A2 /* Wildcat Point PCH */ +#define E1000_DEV_ID_PCH_I218_V3 0x15A3 /* Wildcat Point PCH */ #define E1000_DEV_ID_82576 0x10C9 #define E1000_DEV_ID_82576_FIBER 0x10E6 #define E1000_DEV_ID_82576_SERDES 0x10E7 @@ -165,7 +169,12 @@ struct e1000_hw; #define E1000_DEV_ID_I210_FIBER 0x1536 #define E1000_DEV_ID_I210_SERDES 0x1537 #define E1000_DEV_ID_I210_SGMII 0x1538 +#define E1000_DEV_ID_I210_COPPER_FLASHLESS 0x157B +#define E1000_DEV_ID_I210_SERDES_FLASHLESS 0x157C #define E1000_DEV_ID_I211_COPPER 0x1539 +#define E1000_DEV_ID_I354_BACKPLANE_1GBPS 0x1F40 +#define E1000_DEV_ID_I354_SGMII 0x1F41 +#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS 0x1F45 #define E1000_DEV_ID_DH89XXCC_SGMII 0x0438 #define E1000_DEV_ID_DH89XXCC_SERDES 0x043A #define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C @@ -217,6 +226,7 @@ enum e1000_mac_type { e1000_82576, e1000_82580, e1000_i350, + e1000_i354, e1000_i210, e1000_i211, e1000_vfadapt, @@ -238,6 +248,7 @@ enum e1000_nvm_type { e1000_nvm_eeprom_spi, e1000_nvm_eeprom_microwire, e1000_nvm_flash_hw, + e1000_nvm_invm, e1000_nvm_flash_sw }; @@ -391,6 +402,10 @@ union e1000_rx_desc_extended { }; #define MAX_PS_BUFFERS 4 + +/* Number of packet split data buffers (not including the header buffer) */ +#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1) + /* Receive Descriptor - Packet Split */ union e1000_rx_desc_packet_split { struct { @@ -415,7 +430,8 @@ union e1000_rx_desc_packet_split { } middle; struct { __le16 header_status; - __le16 length[3]; /* length of buffers 1-3 */ + /* length of buffers 1-3 */ + __le16 length[PS_PAGE_BUFFERS]; } upper; __le64 reserved; } wb; /* writeback */ @@ -684,7 +700,7 @@ struct e1000_mac_operations { s32 (*setup_led)(struct e1000_hw *); void (*write_vfta)(struct e1000_hw *, u32, u32); void (*config_collision_dist)(struct e1000_hw *); - void (*rar_set)(struct e1000_hw *, u8*, u32); + int (*rar_set)(struct e1000_hw *, u8*, u32); s32 (*read_mac_addr)(struct e1000_hw *); s32 (*validate_mdi_setting)(struct e1000_hw *); s32 (*set_obff_timer)(struct e1000_hw *, u32); @@ -922,6 +938,13 @@ struct e1000_shadow_ram { #define E1000_SHADOW_RAM_WORDS 2048 +/* I218 PHY Ultra Low Power (ULP) states */ +enum e1000_ulp_state { + e1000_ulp_state_unknown, + e1000_ulp_state_off, + e1000_ulp_state_on, +}; + struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS]; @@ -930,6 +953,7 @@ struct e1000_dev_spec_ich8lan { bool nvm_k1_enabled; bool eee_disable; u16 eee_lp_ability; + enum e1000_ulp_state ulp_state; }; struct e1000_dev_spec_82575 { @@ -940,6 +964,8 @@ struct e1000_dev_spec_82575 { bool clear_semaphore_once; u32 mtu; struct sfp_e1000_flags eth_flags; + u8 media_port; + bool media_changed; }; struct e1000_dev_spec_vf { diff --git a/freebsd/sys/dev/e1000/e1000_i210.h b/freebsd/sys/dev/e1000/e1000_i210.h index d7711fe0..2a20ca1e 100644 --- a/freebsd/sys/dev/e1000/e1000_i210.h +++ b/freebsd/sys/dev/e1000/e1000_i210.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,6 +35,7 @@ #ifndef _E1000_I210_H_ #define _E1000_I210_H_ +bool e1000_get_flash_presence_i210(struct e1000_hw *hw); s32 e1000_update_flash_i210(struct e1000_hw *hw); s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw); s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw); @@ -42,9 +43,13 @@ s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data); s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask); void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); +s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, + u16 *data); +s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, + u16 data); +s32 e1000_init_hw_i210(struct e1000_hw *hw); #define E1000_STM_OPCODE 0xDB00 #define E1000_EEPROM_FLASH_SIZE_WORD 0x11 @@ -82,11 +87,23 @@ enum E1000_INVM_STRUCTURE_TYPE { (ID_LED_OFF1_OFF2)) #define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \ (ID_LED_DEF1_DEF2 << 4) | \ - (ID_LED_DEF1_DEF2)) + (ID_LED_OFF1_ON2)) /* NVM offset defaults for I211 devices */ #define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243 #define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1 #define NVM_LED_1_CFG_DEFAULT_I211 0x0184 #define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C + +/* PLL Defines */ +#define E1000_PCI_PMCSR 0x44 +#define E1000_PCI_PMCSR_D3 0x03 +#define E1000_MAX_PLL_TRIES 5 +#define E1000_PHY_PLL_UNCONF 0xFF +#define E1000_PHY_PLL_FREQ_PAGE 0xFC0000 +#define E1000_PHY_PLL_FREQ_REG 0x000E +#define E1000_INVM_DEFAULT_AL 0x202F +#define E1000_INVM_AUTOLOAD 0x0A +#define E1000_INVM_PLL_WO_VAL 0x0010 + #endif diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.c b/freebsd/sys/dev/e1000/e1000_ich8lan.c index e843527e..b5c75f26 100644 --- a/freebsd/sys/dev/e1000/e1000_ich8lan.c +++ b/freebsd/sys/dev/e1000/e1000_ich8lan.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -61,6 +61,14 @@ * 82578DC Gigabit Network Connection * 82579LM Gigabit Network Connection * 82579V Gigabit Network Connection + * Ethernet Connection I217-LM + * Ethernet Connection I217-V + * Ethernet Connection I218-V + * Ethernet Connection I218-LM + * Ethernet Connection (2) I218-LM + * Ethernet Connection (2) I218-V + * Ethernet Connection (3) I218-LM + * Ethernet Connection (3) I218-V */ #include "e1000_api.h" @@ -71,8 +79,9 @@ static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw); static void e1000_release_nvm_ich8lan(struct e1000_hw *hw); static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); -static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index); -static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index); +static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index); +static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index); +static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw); static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count); @@ -183,8 +192,9 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) { u16 phy_reg = 0; u32 phy_id = 0; - s32 ret_val; + s32 ret_val = 0; u16 retry_count; + u32 mac_reg = 0; for (retry_count = 0; retry_count < 2; retry_count++) { ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_reg); @@ -203,23 +213,84 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) if (hw->phy.id) { if (hw->phy.id == phy_id) - return TRUE; + goto out; } else if (phy_id) { hw->phy.id = phy_id; hw->phy.revision = (u32)(phy_reg & ~PHY_REVISION_MASK); - return TRUE; + goto out; } /* In case the PHY needs to be in mdio slow mode, * set slow mode and try to get the PHY id again. */ - hw->phy.ops.release(hw); - ret_val = e1000_set_mdio_slow_mode_hv(hw); - if (!ret_val) - ret_val = e1000_get_phy_id(hw); - hw->phy.ops.acquire(hw); + if (hw->mac.type < e1000_pch_lpt) { + hw->phy.ops.release(hw); + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (!ret_val) + ret_val = e1000_get_phy_id(hw); + hw->phy.ops.acquire(hw); + } + + if (ret_val) + return FALSE; +out: + if (hw->mac.type == e1000_pch_lpt) { + /* Unforce SMBus mode in PHY */ + hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg); + phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS; + hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg); + + /* Unforce SMBus mode in MAC */ + mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); + mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); + } + + return TRUE; +} + +/** + * e1000_toggle_lanphypc_pch_lpt - toggle the LANPHYPC pin value + * @hw: pointer to the HW structure + * + * Toggling the LANPHYPC pin value fully power-cycles the PHY and is + * used to reset the PHY to a quiescent state when necessary. + **/ +static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw) +{ + u32 mac_reg; + + DEBUGFUNC("e1000_toggle_lanphypc_pch_lpt"); + + /* Set Phy Config Counter to 50msec */ + mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM3); + mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; + mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; + E1000_WRITE_REG(hw, E1000_FEXTNVM3, mac_reg); + + /* Toggle LANPHYPC Value bit */ + mac_reg = E1000_READ_REG(hw, E1000_CTRL); + mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE; + mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE; + E1000_WRITE_REG(hw, E1000_CTRL, mac_reg); + E1000_WRITE_FLUSH(hw); + usec_delay(10); + mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; + E1000_WRITE_REG(hw, E1000_CTRL, mac_reg); + E1000_WRITE_FLUSH(hw); + + if (hw->mac.type < e1000_pch_lpt) { + msec_delay(50); + } else { + u16 count = 20; + + do { + msec_delay(5); + } while (!(E1000_READ_REG(hw, E1000_CTRL_EXT) & + E1000_CTRL_EXT_LPCD) && count--); - return !ret_val; + msec_delay(30); + } } /** @@ -233,7 +304,6 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) { u32 mac_reg, fwsm = E1000_READ_REG(hw, E1000_FWSM); s32 ret_val; - u16 phy_reg; DEBUGFUNC("e1000_init_phy_workarounds_pchlan"); @@ -242,6 +312,12 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) */ e1000_gate_hw_phy_config_ich8lan(hw, TRUE); + /* It is not possible to be certain of the current state of ULP + * so forcibly disable it. + */ + hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown; + e1000_disable_ulp_lpt_lp(hw, TRUE); + ret_val = hw->phy.ops.acquire(hw); if (ret_val) { DEBUGOUT("Failed to initialize PHY flow\n"); @@ -264,24 +340,16 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); + /* Wait 50 milliseconds for MAC to finish any retries + * that it might be trying to perform from previous + * attempts to acknowledge any phy read requests. + */ + msec_delay(50); + /* fall-through */ case e1000_pch2lan: - if (e1000_phy_is_accessible_pchlan(hw)) { - if (hw->mac.type == e1000_pch_lpt) { - /* Unforce SMBus mode in PHY */ - hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, - &phy_reg); - phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS; - hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, - phy_reg); - - /* Unforce SMBus mode in MAC */ - mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); - mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; - E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); - } + if (e1000_phy_is_accessible_pchlan(hw)) break; - } /* fall-through */ case e1000_pchlan: @@ -291,44 +359,27 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) if (hw->phy.ops.check_reset_block(hw)) { DEBUGOUT("Required LANPHYPC toggle blocked by ME\n"); + ret_val = -E1000_ERR_PHY; break; } - DEBUGOUT("Toggling LANPHYPC\n"); - - /* Set Phy Config Counter to 50msec */ - mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM3); - mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; - mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; - E1000_WRITE_REG(hw, E1000_FEXTNVM3, mac_reg); + /* Toggle LANPHYPC Value bit */ + e1000_toggle_lanphypc_pch_lpt(hw); + if (hw->mac.type >= e1000_pch_lpt) { + if (e1000_phy_is_accessible_pchlan(hw)) + break; - if (hw->mac.type == e1000_pch_lpt) { /* Toggling LANPHYPC brings the PHY out of SMBus mode - * So ensure that the MAC is also out of SMBus mode + * so ensure that the MAC is also out of SMBus mode */ mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); - } - /* Toggle LANPHYPC Value bit */ - mac_reg = E1000_READ_REG(hw, E1000_CTRL); - mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE; - mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE; - E1000_WRITE_REG(hw, E1000_CTRL, mac_reg); - E1000_WRITE_FLUSH(hw); - usec_delay(10); - mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; - E1000_WRITE_REG(hw, E1000_CTRL, mac_reg); - E1000_WRITE_FLUSH(hw); - if (hw->mac.type < e1000_pch_lpt) { - msec_delay(50); - } else { - u16 count = 20; - do { - msec_delay(5); - } while (!(E1000_READ_REG(hw, E1000_CTRL_EXT) & - E1000_CTRL_EXT_LPCD) && count--); + if (e1000_phy_is_accessible_pchlan(hw)) + break; + + ret_val = -E1000_ERR_PHY; } break; default: @@ -336,13 +387,33 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) } hw->phy.ops.release(hw); + if (!ret_val) { - /* Reset the PHY before any access to it. Doing so, ensures - * that the PHY is in a known good state before we read/write - * PHY registers. The generic reset is sufficient here, - * because we haven't determined the PHY type yet. - */ - ret_val = e1000_phy_hw_reset_generic(hw); + /* Check to see if able to reset PHY. Print error if not */ + if (hw->phy.ops.check_reset_block(hw)) { + ERROR_REPORT("Reset blocked by ME\n"); + goto out; + } + + /* Reset the PHY before any access to it. Doing so, ensures + * that the PHY is in a known good state before we read/write + * PHY registers. The generic reset is sufficient here, + * because we haven't determined the PHY type yet. + */ + ret_val = e1000_phy_hw_reset_generic(hw); + if (ret_val) + goto out; + + /* On a successful reset, possibly need to wait for the PHY + * to quiesce to an accessible state before returning control + * to the calling function. If the PHY does not quiesce, then + * return E1000E_BLK_PHY_RESET, as this is the condition that + * the PHY is in. + */ + ret_val = hw->phy.ops.check_reset_block(hw); + if (ret_val) + ERROR_REPORT("ME blocked access to PHY after reset\n"); + } out: /* Ungate automatic PHY configuration on non-managed 82579 */ @@ -552,13 +623,12 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) DEBUGFUNC("e1000_init_nvm_params_ich8lan"); /* Can't read flash registers if the register set isn't mapped. */ + nvm->type = e1000_nvm_flash_sw; if (!hw->flash_address) { DEBUGOUT("ERROR: Flash registers not mapped\n"); return -E1000_ERR_CONFIG; } - nvm->type = e1000_nvm_flash_sw; - gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG); /* sector_X_addr is a "sector"-aligned address (4096 bytes) @@ -574,8 +644,8 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) /* find total size of the NVM, then cut in half since the total * size represents two separate NVM banks. */ - nvm->flash_bank_size = (sector_end_addr - sector_base_addr) - << FLASH_SECTOR_ADDR_SHIFT; + nvm->flash_bank_size = ((sector_end_addr - sector_base_addr) + << FLASH_SECTOR_ADDR_SHIFT); nvm->flash_bank_size /= 2; /* Adjust to word count */ nvm->flash_bank_size /= sizeof(u16); @@ -768,7 +838,7 @@ s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data) * * Assumes the SW/FW/HW Semaphore is already acquired. **/ -static s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data) +s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data) { DEBUGFUNC("e1000_read_emi_reg_locked"); @@ -782,18 +852,35 @@ static s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data) * Enable/disable EEE based on setting in dev_spec structure, the duplex of * the link and the EEE capabilities of the link partner. The LPI Control * register bits will remain set only if/when link is up. + * + * EEE LPI must not be asserted earlier than one second after link is up. + * On 82579, EEE LPI should not be enabled until such time otherwise there + * can be link issues with some switches. Other devices can have EEE LPI + * enabled immediately upon link up since they have a timer in hardware which + * prevents LPI from being asserted too early. **/ -static s32 e1000_set_eee_pchlan(struct e1000_hw *hw) +s32 e1000_set_eee_pchlan(struct e1000_hw *hw) { struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; s32 ret_val; - u16 lpi_ctrl; + u16 lpa, pcs_status, adv, adv_addr, lpi_ctrl, data; DEBUGFUNC("e1000_set_eee_pchlan"); - if ((hw->phy.type != e1000_phy_82579) && - (hw->phy.type != e1000_phy_i217)) + switch (hw->phy.type) { + case e1000_phy_82579: + lpa = I82579_EEE_LP_ABILITY; + pcs_status = I82579_EEE_PCS_STATUS; + adv_addr = I82579_EEE_ADVERTISEMENT; + break; + case e1000_phy_i217: + lpa = I217_EEE_LP_ABILITY; + pcs_status = I217_EEE_PCS_STATUS; + adv_addr = I217_EEE_ADVERTISEMENT; + break; + default: return E1000_SUCCESS; + } ret_val = hw->phy.ops.acquire(hw); if (ret_val) @@ -808,34 +895,24 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw) /* Enable EEE if not disabled by user */ if (!dev_spec->eee_disable) { - u16 lpa, pcs_status, data; - /* Save off link partner's EEE ability */ - switch (hw->phy.type) { - case e1000_phy_82579: - lpa = I82579_EEE_LP_ABILITY; - pcs_status = I82579_EEE_PCS_STATUS; - break; - case e1000_phy_i217: - lpa = I217_EEE_LP_ABILITY; - pcs_status = I217_EEE_PCS_STATUS; - break; - default: - ret_val = -E1000_ERR_PHY; - goto release; - } ret_val = e1000_read_emi_reg_locked(hw, lpa, &dev_spec->eee_lp_ability); if (ret_val) goto release; + /* Read EEE advertisement */ + ret_val = e1000_read_emi_reg_locked(hw, adv_addr, &adv); + if (ret_val) + goto release; + /* Enable EEE only for speeds in which the link partner is - * EEE capable. + * EEE capable and for which we advertise EEE. */ - if (dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED) + if (adv & dev_spec->eee_lp_ability & I82579_EEE_1000_SUPPORTED) lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE; - if (dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) { + if (adv & dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) { hw->phy.ops.read_reg_locked(hw, PHY_LP_ABILITY, &data); if (data & NWAY_LPAR_100TX_FD_CAPS) lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE; @@ -847,13 +924,24 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw) dev_spec->eee_lp_ability &= ~I82579_EEE_100_SUPPORTED; } + } - /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */ - ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data); + if (hw->phy.type == e1000_phy_82579) { + ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT, + &data); if (ret_val) goto release; + + data &= ~I82579_LPI_100_PLL_SHUT; + ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT, + data); } + /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */ + ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_LPI_CTRL, lpi_ctrl); release: hw->phy.ops.release(hw); @@ -869,30 +957,31 @@ release: * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications * preventing further DMA write requests. Workaround the issue by disabling * the de-assertion of the clock request when in 1Gpbs mode. + * Also, set appropriate Tx re-transmission timeouts for 10 and 100Half link + * speeds in order to avoid Tx hangs. **/ static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) { u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6); + u32 status = E1000_READ_REG(hw, E1000_STATUS); s32 ret_val = E1000_SUCCESS; + u16 reg; - if (link && (E1000_READ_REG(hw, E1000_STATUS) & - E1000_STATUS_SPEED_1000)) { - u16 kmrn_reg; - + if (link && (status & E1000_STATUS_SPEED_1000)) { ret_val = hw->phy.ops.acquire(hw); if (ret_val) return ret_val; ret_val = e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, - &kmrn_reg); + ®); if (ret_val) goto release; ret_val = e1000_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, - kmrn_reg & + reg & ~E1000_KMRNCTRLSTA_K1_ENABLE); if (ret_val) goto release; @@ -905,13 +994,45 @@ static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) ret_val = e1000_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, - kmrn_reg); + reg); release: hw->phy.ops.release(hw); } else { /* clear FEXTNVM6 bit 8 on link down or 10/100 */ - E1000_WRITE_REG(hw, E1000_FEXTNVM6, - fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); + fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK; + + if (!link || ((status & E1000_STATUS_SPEED_100) && + (status & E1000_STATUS_FD))) + goto update_fextnvm6; + + ret_val = hw->phy.ops.read_reg(hw, I217_INBAND_CTRL, ®); + if (ret_val) + return ret_val; + + /* Clear link status transmit timeout */ + reg &= ~I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK; + + if (status & E1000_STATUS_SPEED_100) { + /* Set inband Tx timeout to 5x10us for 100Half */ + reg |= 5 << I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT; + + /* Do not extend the K1 entry latency for 100Half */ + fextnvm6 &= ~E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION; + } else { + /* Set inband Tx timeout to 50x10us for 10Full/Half */ + reg |= 50 << + I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT; + + /* Extend the K1 entry latency for 10 Mbps */ + fextnvm6 |= E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION; + } + + ret_val = hw->phy.ops.write_reg(hw, I217_INBAND_CTRL, reg); + if (ret_val) + return ret_val; + +update_fextnvm6: + E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6); } return ret_val; @@ -1020,7 +1141,6 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link) lat_ns /= 1000000000; obff_hwm = (s32)(rxa - lat_ns); } - if ((obff_hwm < 0) || (obff_hwm > E1000_SVT_OFF_HWM_MASK)) { DEBUGOUT1("Invalid high water mark %d\n", obff_hwm); return -E1000_ERR_CONFIG; @@ -1080,6 +1200,256 @@ static s32 e1000_set_obff_timer_pch_lpt(struct e1000_hw *hw, u32 itr) return E1000_SUCCESS; } +/** + * e1000_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP + * @hw: pointer to the HW structure + * @to_sx: boolean indicating a system power state transition to Sx + * + * When link is down, configure ULP mode to significantly reduce the power + * to the PHY. If on a Manageability Engine (ME) enabled system, tell the + * ME firmware to start the ULP configuration. If not on an ME enabled + * system, configure the ULP mode by software. + */ +s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) +{ + u32 mac_reg; + s32 ret_val = E1000_SUCCESS; + u16 phy_reg; + + if ((hw->mac.type < e1000_pch_lpt) || + (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) || + (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V) || + (hw->device_id == E1000_DEV_ID_PCH_I218_LM2) || + (hw->device_id == E1000_DEV_ID_PCH_I218_V2) || + (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_on)) + return 0; + + if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) { + /* Request ME configure ULP mode in the PHY */ + mac_reg = E1000_READ_REG(hw, E1000_H2ME); + mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS; + E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); + + goto out; + } + + if (!to_sx) { + int i = 0; + + /* Poll up to 5 seconds for Cable Disconnected indication */ + while (!(E1000_READ_REG(hw, E1000_FEXT) & + E1000_FEXT_PHY_CABLE_DISCONNECTED)) { + /* Bail if link is re-acquired */ + if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU) + return -E1000_ERR_PHY; + + if (i++ == 100) + break; + + msec_delay(50); + } + DEBUGOUT2("CABLE_DISCONNECTED %s set after %dmsec\n", + (E1000_READ_REG(hw, E1000_FEXT) & + E1000_FEXT_PHY_CABLE_DISCONNECTED) ? "" : "not", + i * 50); + } + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + + /* Force SMBus mode in PHY */ + ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); + if (ret_val) + goto release; + phy_reg |= CV_SMB_CTRL_FORCE_SMBUS; + e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg); + + /* Force SMBus mode in MAC */ + mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); + mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); + + /* Set Inband ULP Exit, Reset to SMBus mode and + * Disable SMBus Release on PERST# in PHY + */ + ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); + if (ret_val) + goto release; + phy_reg |= (I218_ULP_CONFIG1_RESET_TO_SMBUS | + I218_ULP_CONFIG1_DISABLE_SMB_PERST); + if (to_sx) { + if (E1000_READ_REG(hw, E1000_WUFC) & E1000_WUFC_LNKC) + phy_reg |= I218_ULP_CONFIG1_WOL_HOST; + + phy_reg |= I218_ULP_CONFIG1_STICKY_ULP; + } else { + phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT; + } + e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); + + /* Set Disable SMBus Release on PERST# in MAC */ + mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); + mac_reg |= E1000_FEXTNVM7_DISABLE_SMB_PERST; + E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); + + /* Commit ULP changes in PHY by starting auto ULP configuration */ + phy_reg |= I218_ULP_CONFIG1_START; + e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); +release: + hw->phy.ops.release(hw); +out: + if (ret_val) { + DEBUGOUT1("Error in ULP enable flow: %d\n", ret_val); + } else + hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_on; + + return ret_val; +} + +/** + * e1000_disable_ulp_lpt_lp - unconfigure Ultra Low Power mode for LynxPoint-LP + * @hw: pointer to the HW structure + * @force: boolean indicating whether or not to force disabling ULP + * + * Un-configure ULP mode when link is up, the system is transitioned from + * Sx or the driver is unloaded. If on a Manageability Engine (ME) enabled + * system, poll for an indication from ME that ULP has been un-configured. + * If not on an ME enabled system, un-configure the ULP mode by software. + * + * During nominal operation, this function is called when link is acquired + * to disable ULP mode (force=FALSE); otherwise, for example when unloading + * the driver or during Sx->S0 transitions, this is called with force=TRUE + * to forcibly disable ULP. + */ +s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) +{ + s32 ret_val = E1000_SUCCESS; + u32 mac_reg; + u16 phy_reg; + int i = 0; + + if ((hw->mac.type < e1000_pch_lpt) || + (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) || + (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V) || + (hw->device_id == E1000_DEV_ID_PCH_I218_LM2) || + (hw->device_id == E1000_DEV_ID_PCH_I218_V2) || + (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_off)) + return 0; + + if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) { + if (force) { + /* Request ME un-configure ULP mode in the PHY */ + mac_reg = E1000_READ_REG(hw, E1000_H2ME); + mac_reg &= ~E1000_H2ME_ULP; + mac_reg |= E1000_H2ME_ENFORCE_SETTINGS; + E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); + } + + /* Poll up to 100msec for ME to clear ULP_CFG_DONE */ + while (E1000_READ_REG(hw, E1000_FWSM) & + E1000_FWSM_ULP_CFG_DONE) { + if (i++ == 10) { + ret_val = -E1000_ERR_PHY; + goto out; + } + + msec_delay(10); + } + DEBUGOUT1("ULP_CONFIG_DONE cleared after %dmsec\n", i * 10); + + if (force) { + mac_reg = E1000_READ_REG(hw, E1000_H2ME); + mac_reg &= ~E1000_H2ME_ENFORCE_SETTINGS; + E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); + } else { + /* Clear H2ME.ULP after ME ULP configuration */ + mac_reg = E1000_READ_REG(hw, E1000_H2ME); + mac_reg &= ~E1000_H2ME_ULP; + E1000_WRITE_REG(hw, E1000_H2ME, mac_reg); + } + + goto out; + } + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + + if (force) + /* Toggle LANPHYPC Value bit */ + e1000_toggle_lanphypc_pch_lpt(hw); + + /* Unforce SMBus mode in PHY */ + ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); + if (ret_val) { + /* The MAC might be in PCIe mode, so temporarily force to + * SMBus mode in order to access the PHY. + */ + mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); + mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); + + msec_delay(50); + + ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, + &phy_reg); + if (ret_val) + goto release; + } + phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS; + e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg); + + /* Unforce SMBus mode in MAC */ + mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT); + mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg); + + /* When ULP mode was previously entered, K1 was disabled by the + * hardware. Re-Enable K1 in the PHY when exiting ULP. + */ + ret_val = e1000_read_phy_reg_hv_locked(hw, HV_PM_CTRL, &phy_reg); + if (ret_val) + goto release; + phy_reg |= HV_PM_CTRL_K1_ENABLE; + e1000_write_phy_reg_hv_locked(hw, HV_PM_CTRL, phy_reg); + + /* Clear ULP enabled configuration */ + ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); + if (ret_val) + goto release; + phy_reg &= ~(I218_ULP_CONFIG1_IND | + I218_ULP_CONFIG1_STICKY_ULP | + I218_ULP_CONFIG1_RESET_TO_SMBUS | + I218_ULP_CONFIG1_WOL_HOST | + I218_ULP_CONFIG1_INBAND_EXIT | + I218_ULP_CONFIG1_DISABLE_SMB_PERST); + e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); + + /* Commit ULP changes by starting auto ULP configuration */ + phy_reg |= I218_ULP_CONFIG1_START; + e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); + + /* Clear Disable SMBus Release on PERST# in MAC */ + mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); + mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST; + E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); + +release: + hw->phy.ops.release(hw); + if (force) { + hw->phy.ops.reset(hw); + msec_delay(50); + } +out: + if (ret_val) { + DEBUGOUT1("Error in ULP disable flow: %d\n", ret_val); + } else + hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_off; + + return ret_val; +} + /** * e1000_check_for_copper_link_ich8lan - Check for link (Copper) * @hw: pointer to the HW structure @@ -1105,13 +1475,13 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (!mac->get_link_status) return E1000_SUCCESS; - /* First we want to see if the MII Status Register reports - * link. If so, then we want to get the current speed/duplex - * of the PHY. - */ - ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); - if (ret_val) - return ret_val; + /* First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex + * of the PHY. + */ + ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) + return ret_val; if (hw->mac.type == e1000_pchlan) { ret_val = e1000_k1_gig_workaround_hv(hw, link); @@ -1119,14 +1489,17 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) return ret_val; } - /* When connected at 10Mbps half-duplex, 82579 parts are excessively + /* When connected at 10Mbps half-duplex, some parts are excessively * aggressive resulting in many collisions. To avoid this, increase * the IPG and reduce Rx latency in the PHY. */ - if ((hw->mac.type == e1000_pch2lan) && link) { + if (((hw->mac.type == e1000_pch2lan) || + (hw->mac.type == e1000_pch_lpt)) && link) { u32 reg; reg = E1000_READ_REG(hw, E1000_STATUS); if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) { + u16 emi_addr; + reg = E1000_READ_REG(hw, E1000_TIPG); reg &= ~E1000_TIPG_IPGT_MASK; reg |= 0xFF; @@ -1137,7 +1510,11 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (ret_val) return ret_val; - ret_val = e1000_write_emi_reg_locked(hw, I82579_RX_CONFIG, 0); + if (hw->mac.type == e1000_pch2lan) + emi_addr = I82579_RX_CONFIG; + else + emi_addr = I217_RX_CONFIG; + ret_val = e1000_write_emi_reg_locked(hw, emi_addr, 0); hw->phy.ops.release(hw); @@ -1148,15 +1525,17 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) /* Work-around I218 hang issue */ if ((hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || - (hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) { + (hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) || + (hw->device_id == E1000_DEV_ID_PCH_I218_LM3) || + (hw->device_id == E1000_DEV_ID_PCH_I218_V3)) { ret_val = e1000_k1_workaround_lpt_lp(hw, link); if (ret_val) return ret_val; } - if (hw->mac.type == e1000_pch_lpt) { - /* Set platform power management values for Latency Tolerance - * Reporting (LTR) and Optimized Buffer Flush/Fill (OBFF). + /* Set platform power management values for + * Latency Tolerance Reporting (LTR) + * Optimized Buffer Flush/Fill (OBFF) */ ret_val = e1000_platform_pm_pch_lpt(hw, link); if (ret_val) @@ -1208,9 +1587,11 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) e1000_check_downshift_generic(hw); /* Enable/Disable EEE after link up */ - ret_val = e1000_set_eee_pchlan(hw); - if (ret_val) - return ret_val; + if (hw->phy.type > e1000_phy_82579) { + ret_val = e1000_set_eee_pchlan(hw); + if (ret_val) + return ret_val; + } /* If we are forcing speed/duplex, then we simply return since * we have already determined whether we have link or not. @@ -1434,7 +1815,7 @@ static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw) * contain the MAC address but RAR[1-6] are reserved for manageability (ME). * Use SHRA[0-3] in place of those reserved for ME. **/ -static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) +static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) { u32 rar_low, rar_high; @@ -1458,10 +1839,13 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) E1000_WRITE_FLUSH(hw); E1000_WRITE_REG(hw, E1000_RAH(index), rar_high); E1000_WRITE_FLUSH(hw); - return; + return E1000_SUCCESS; } - if (index < hw->mac.rar_entry_count) { + /* RAR[1-6] are owned by manageability. Skip those and program the + * next address into the SHRA register array. + */ + if (index < (u32) (hw->mac.rar_entry_count)) { s32 ret_val; ret_val = e1000_acquire_swflag_ich8lan(hw); @@ -1478,7 +1862,7 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) /* verify the register updates */ if ((E1000_READ_REG(hw, E1000_SHRAL(index - 1)) == rar_low) && (E1000_READ_REG(hw, E1000_SHRAH(index - 1)) == rar_high)) - return; + return E1000_SUCCESS; DEBUGOUT2("SHRA[%d] might be locked by ME - FWSM=0x%8.8x\n", (index - 1), E1000_READ_REG(hw, E1000_FWSM)); @@ -1486,6 +1870,7 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) out: DEBUGOUT1("Failed to write receive address at index %d\n", index); + return -E1000_ERR_CONFIG; } /** @@ -1499,7 +1884,7 @@ out: * contain the MAC address. SHRA[0-10] are the shared receive address * registers that are shared between the Host and manageability engine (ME). **/ -static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index) +static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index) { u32 rar_low, rar_high; u32 wlock_mac; @@ -1523,7 +1908,7 @@ static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index) E1000_WRITE_FLUSH(hw); E1000_WRITE_REG(hw, E1000_RAH(index), rar_high); E1000_WRITE_FLUSH(hw); - return; + return E1000_SUCCESS; } /* The manageability engine (ME) can lock certain SHRAR registers that @@ -1558,12 +1943,13 @@ static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index) /* verify the register updates */ if ((E1000_READ_REG(hw, E1000_SHRAL_PCH_LPT(index - 1)) == rar_low) && (E1000_READ_REG(hw, E1000_SHRAH_PCH_LPT(index - 1)) == rar_high)) - return; + return E1000_SUCCESS; } } out: DEBUGOUT1("Failed to write receive address at index %d\n", index); + return -E1000_ERR_CONFIG; } /** @@ -1621,13 +2007,21 @@ release: static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) { u32 fwsm; + bool blocked = FALSE; + int i = 0; DEBUGFUNC("e1000_check_reset_block_ich8lan"); - fwsm = E1000_READ_REG(hw, E1000_FWSM); - - return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS - : E1000_BLK_PHY_RESET; + do { + fwsm = E1000_READ_REG(hw, E1000_FWSM); + if (!(fwsm & E1000_ICH_FWSM_RSPCIPHY)) { + blocked = TRUE; + msec_delay(10); + continue; + } + blocked = FALSE; + } while (blocked && (i++ < 10)); + return blocked ? E1000_BLK_PHY_RESET : E1000_SUCCESS; } /** @@ -1827,9 +2221,9 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) if (ret_val) goto release; - status_reg &= BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; + status_reg &= (BM_CS_STATUS_LINK_UP | + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK); if (status_reg == (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | @@ -1843,9 +2237,9 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) if (ret_val) goto release; - status_reg &= HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_MASK; + status_reg &= (HV_M_STATUS_LINK_UP | + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_MASK); if (status_reg == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE | @@ -2127,8 +2521,8 @@ void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw) if (ret_val) goto release; - /* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */ - for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) { + /* Copy both RAL/H (rar_entry_count) and SHRAL/H to PHY */ + for (i = 0; i < (hw->mac.rar_entry_count); i++) { mac_reg = E1000_READ_REG(hw, E1000_RAL(i)); hw->phy.ops.write_reg_page(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF)); @@ -2193,10 +2587,10 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) return ret_val; if (enable) { - /* Write Rx addresses (rar_entry_count for RAL/H, +4 for + /* Write Rx addresses (rar_entry_count for RAL/H, and * SHRAL/H) and initial CRC values to the MAC */ - for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) { + for (i = 0; i < hw->mac.rar_entry_count; i++) { u8 mac_addr[ETH_ADDR_LEN] = {0}; u32 addr_high, addr_low; @@ -2265,7 +2659,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) return ret_val; hw->phy.ops.read_reg(hw, PHY_REG(776, 20), &data); data &= ~(0x3FF << 2); - data |= (0x1A << 2); + data |= (E1000_TX_PTR_GAP << 2); ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 20), data); if (ret_val) return ret_val; @@ -2379,55 +2773,47 @@ release: * e1000_k1_gig_workaround_lv - K1 Si workaround * @hw: pointer to the HW structure * - * Workaround to set the K1 beacon duration for 82579 parts + * Workaround to set the K1 beacon duration for 82579 parts in 10Mbps + * Disable K1 for 1000 and 100 speeds **/ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 status_reg = 0; - u32 mac_reg; - u16 phy_reg; DEBUGFUNC("e1000_k1_workaround_lv"); if (hw->mac.type != e1000_pch2lan) return E1000_SUCCESS; - /* Set K1 beacon duration based on 1Gbps speed or otherwise */ + /* Set K1 beacon duration based on 10Mbs speed */ ret_val = hw->phy.ops.read_reg(hw, HV_M_STATUS, &status_reg); if (ret_val) return ret_val; if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { - mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4); - mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; - - ret_val = hw->phy.ops.read_reg(hw, I82579_LPI_CTRL, &phy_reg); - if (ret_val) - return ret_val; - - if (status_reg & HV_M_STATUS_SPEED_1000) { + if (status_reg & + (HV_M_STATUS_SPEED_1000 | HV_M_STATUS_SPEED_100)) { u16 pm_phy_reg; - mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; - phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; - /* LV 1G Packet drop issue wa */ + /* LV 1G/100 Packet drop issue wa */ ret_val = hw->phy.ops.read_reg(hw, HV_PM_CTRL, &pm_phy_reg); if (ret_val) return ret_val; - pm_phy_reg &= ~HV_PM_CTRL_PLL_STOP_IN_K1_GIGA; + pm_phy_reg &= ~HV_PM_CTRL_K1_ENABLE; ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, pm_phy_reg); if (ret_val) return ret_val; } else { + u32 mac_reg; + mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4); + mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; - phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; + E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg); } - E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg); - ret_val = hw->phy.ops.write_reg(hw, I82579_LPI_CTRL, phy_reg); } return ret_val; @@ -2964,7 +3350,6 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) /* Clear FCERR and DAEL in hw status by writing 1 */ hsfsts.hsf_status.flcerr = 1; hsfsts.hsf_status.dael = 1; - E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval); /* Either we should have a hardware SPI cycle in progress @@ -3031,6 +3416,7 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */ hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); hsflctl.hsf_ctrl.flcgo = 1; + E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); /* wait till FDONE bit is set to 1 */ @@ -3085,6 +3471,7 @@ static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u16 word = 0; ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word); + if (ret_val) return ret_val; @@ -3114,11 +3501,10 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, DEBUGFUNC("e1000_read_flash_data_ich8lan"); - if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) + if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) return -E1000_ERR_NVM; - - flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + - hw->nvm.flash_base_addr; + flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + + hw->nvm.flash_base_addr); do { usec_delay(1); @@ -3126,13 +3512,12 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val != E1000_SUCCESS) break; - hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); + /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ hsflctl.hsf_ctrl.fldbcount = size - 1; hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ; E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); - E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); ret_val = e1000_flash_cycle_ich8lan(hw, @@ -3171,6 +3556,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, return ret_val; } + /** * e1000_write_nvm_ich8lan - Write word(s) to the NVM * @hw: pointer to the HW structure @@ -3224,7 +3610,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; u32 i, act_offset, new_bank_offset, old_bank_offset, bank; s32 ret_val; - u16 data; + u16 data = 0; DEBUGFUNC("e1000_update_nvm_checksum_ich8lan"); @@ -3260,12 +3646,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (ret_val) goto release; } - for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { - /* Determine whether to write the value stored - * in the other NVM bank or a modified value stored - * in the shadow RAM - */ if (dev_spec->shadow_ram[i].modified) { data = dev_spec->shadow_ram[i].value; } else { @@ -3275,7 +3656,6 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (ret_val) break; } - /* If the word is 0x13, then make sure the signature bits * (15:14) are 11b until the commit has completed. * This will allow us to write 10b which indicates the @@ -3290,6 +3670,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) act_offset = (i + new_bank_offset) << 1; usec_delay(100); + /* Write the bytes to the new bank. */ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, @@ -3303,7 +3684,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) (u8)(data >> 8)); if (ret_val) break; - } + } /* Don't bother writing the segment valid bits if sector * programming failed. @@ -3324,8 +3705,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) goto release; data &= 0xBFFF; - ret_val = e1000_retry_write_flash_byte_ich8lan(hw, - act_offset * 2 + 1, + ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset * 2 + 1, (u8)(data >> 8)); if (ret_val) goto release; @@ -3336,7 +3716,9 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) * to 1's. We can write 1's to 0's without an erase */ act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; + ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); + if (ret_val) goto release; @@ -3435,12 +3817,11 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, DEBUGFUNC("e1000_write_ich8_data"); - if (size < 1 || size > 2 || data > size * 0xff || - offset > ICH_FLASH_LINEAR_ADDR_MASK) + if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) return -E1000_ERR_NVM; - flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + - hw->nvm.flash_base_addr; + flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) + + hw->nvm.flash_base_addr); do { usec_delay(1); @@ -3448,8 +3829,8 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val != E1000_SUCCESS) break; - hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); + /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ hsflctl.hsf_ctrl.fldbcount = size - 1; hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE; @@ -3467,8 +3848,9 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* check if FCERR is set to 1 , if set to 1, clear it * and try the whole sequence a few more times else done */ - ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_WRITE_COMMAND_TIMEOUT); + ret_val = + e1000_flash_cycle_ich8lan(hw, + ICH_FLASH_WRITE_COMMAND_TIMEOUT); if (ret_val == E1000_SUCCESS) break; @@ -3490,6 +3872,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, return ret_val; } + /** * e1000_write_flash_byte_ich8lan - Write a single byte to NVM * @hw: pointer to the HW structure @@ -3508,6 +3891,8 @@ static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, return e1000_write_flash_data_ich8lan(hw, offset, 1, word); } + + /** * e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM * @hw: pointer to the HW structure @@ -3604,8 +3989,10 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) flash_linear_addr = hw->nvm.flash_base_addr; flash_linear_addr += (bank) ? flash_bank_size : 0; - for (j = 0; j < iteration ; j++) { + for (j = 0; j < iteration; j++) { do { + u32 timeout = ICH_FLASH_ERASE_COMMAND_TIMEOUT; + /* Steps */ ret_val = e1000_flash_cycle_init_ich8lan(hw); if (ret_val) @@ -3614,8 +4001,9 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) /* Write a value 11 (block Erase) in Flash * Cycle field in hw flash control */ - hsflctl.regval = E1000_READ_FLASH_REG16(hw, - ICH_FLASH_HSFCTL); + hsflctl.regval = + E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); + hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE; E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); @@ -3628,8 +4016,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); - ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_ERASE_COMMAND_TIMEOUT); + ret_val = e1000_flash_cycle_ich8lan(hw, timeout); if (ret_val == E1000_SUCCESS) break; @@ -3949,16 +4336,16 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) /* Set the transmit descriptor write-back policy for both queues */ txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); - txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB; - txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | - E1000_TXDCTL_MAX_TX_DESC_PREFETCH; + txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB); + txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) | + E1000_TXDCTL_MAX_TX_DESC_PREFETCH); E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); txdctl = E1000_READ_REG(hw, E1000_TXDCTL(1)); - txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB; - txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | - E1000_TXDCTL_MAX_TX_DESC_PREFETCH; + txdctl = ((txdctl & ~E1000_TXDCTL_WTHRESH) | + E1000_TXDCTL_FULL_TX_DESC_WB); + txdctl = ((txdctl & ~E1000_TXDCTL_PTHRESH) | + E1000_TXDCTL_MAX_TX_DESC_PREFETCH); E1000_WRITE_REG(hw, E1000_TXDCTL(1), txdctl); /* ICH8 has opposite polarity of no_snoop bits. @@ -4043,6 +4430,7 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) */ reg = E1000_READ_REG(hw, E1000_RFCTL); reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); + /* Disable IPv6 extension header parsing because some malformed * IPv6 headers can hang the Rx. */ @@ -4481,7 +4869,9 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) u16 phy_reg, device_id = hw->device_id; if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || - (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) { + (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) || + (device_id == E1000_DEV_ID_PCH_I218_LM3) || + (device_id == E1000_DEV_ID_PCH_I218_V3)) { u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6); E1000_WRITE_REG(hw, E1000_FEXTNVM6, @@ -4504,14 +4894,25 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) /* Disable LPLU if both link partners support 100BaseT * EEE and 100Full is advertised on both ends of the - * link. + * link, and enable Auto Enable LPI since there will + * be no driver to enable LPI while in Sx. */ if ((eee_advert & I82579_EEE_100_SUPPORTED) && (dev_spec->eee_lp_ability & I82579_EEE_100_SUPPORTED) && - (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)) + (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)) { phy_ctrl &= ~(E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_NOND0A_LPLU); + + /* Set Auto Enable LPI after link up */ + hw->phy.ops.read_reg_locked(hw, + I217_LPI_GPIO_CTRL, + &phy_reg); + phy_reg |= I217_LPI_GPIO_CTRL_AUTO_EN_LPI; + hw->phy.ops.write_reg_locked(hw, + I217_LPI_GPIO_CTRL, + phy_reg); + } } /* For i217 Intel Rapid Start Technology support, @@ -4522,7 +4923,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) * The SMBus release must also be disabled on LCD reset. */ if (!(E1000_READ_REG(hw, E1000_FWSM) & - E1000_ICH_FWSM_FW_VALID)) { + E1000_ICH_FWSM_FW_VALID)) { /* Enable proxy to reset only on power good. */ hw->phy.ops.read_reg_locked(hw, I217_PROXY_CTRL, &phy_reg); @@ -4615,6 +5016,11 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) return; } + /* Clear Auto Enable LPI after link up */ + hw->phy.ops.read_reg_locked(hw, I217_LPI_GPIO_CTRL, &phy_reg); + phy_reg &= ~I217_LPI_GPIO_CTRL_AUTO_EN_LPI; + hw->phy.ops.write_reg_locked(hw, I217_LPI_GPIO_CTRL, phy_reg); + if (!(E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID)) { /* Restore clear on SMB if no manageability engine diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.h b/freebsd/sys/dev/e1000/e1000_ich8lan.h index bf928981..999e856b 100644 --- a/freebsd/sys/dev/e1000/e1000_ich8lan.h +++ b/freebsd/sys/dev/e1000/e1000_ich8lan.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -60,21 +60,26 @@ #define ICH_FLASH_SEG_SIZE_8K 8192 #define ICH_FLASH_SEG_SIZE_64K 65536 -#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ +#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ /* FW established a valid mode */ -#define E1000_ICH_FWSM_FW_VALID 0x00008000 -#define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */ +#define E1000_ICH_FWSM_FW_VALID 0x00008000 +#define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */ #define E1000_ICH_FWSM_PCIM2PCI_COUNT 2000 #define E1000_ICH_MNG_IAMT_MODE 0x2 #define E1000_FWSM_WLOCK_MAC_MASK 0x0380 #define E1000_FWSM_WLOCK_MAC_SHIFT 7 +#define E1000_FWSM_ULP_CFG_DONE 0x00000400 /* Low power cfg done */ /* Shared Receive Address Registers */ #define E1000_SHRAL_PCH_LPT(_i) (0x05408 + ((_i) * 8)) #define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8)) +#define E1000_H2ME 0x05B50 /* Host to ME */ +#define E1000_H2ME_ULP 0x00000800 /* ULP Indication Bit */ +#define E1000_H2ME_ENFORCE_SETTINGS 0x00001000 /* Enforce Settings */ + #define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ (ID_LED_OFF1_OFF2 << 8) | \ (ID_LED_OFF1_ON2 << 4) | \ @@ -87,8 +92,11 @@ #define E1000_ICH8_LAN_INIT_TIMEOUT 1500 +/* FEXT register bit definition */ +#define E1000_FEXT_PHY_CABLE_DISCONNECTED 0x00000004 + #define E1000_FEXTNVM_SW_CONFIG 1 -#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */ +#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* different on ICH8M */ #define E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK 0x0C000000 #define E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC 0x08000000 @@ -98,6 +106,9 @@ #define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 #define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100 +#define E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION 0x00000200 + +#define E1000_FEXTNVM7_DISABLE_SMB_PERST 0x00000020 #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL @@ -108,8 +119,8 @@ #define PHY_PAGE_SHIFT 5 #define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ ((reg) & MAX_PHY_REG_ADDRESS)) -#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */ -#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */ +#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */ +#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */ #define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 #define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 @@ -140,19 +151,20 @@ #define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400 #define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004 #define HV_STATS_PAGE 778 -#define HV_SCC_UPPER PHY_REG(HV_STATS_PAGE, 16) /* Single Collision Count */ +/* Half-duplex collision counts */ +#define HV_SCC_UPPER PHY_REG(HV_STATS_PAGE, 16) /* Single Collision */ #define HV_SCC_LOWER PHY_REG(HV_STATS_PAGE, 17) -#define HV_ECOL_UPPER PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. Count */ +#define HV_ECOL_UPPER PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. */ #define HV_ECOL_LOWER PHY_REG(HV_STATS_PAGE, 19) -#define HV_MCC_UPPER PHY_REG(HV_STATS_PAGE, 20) /* Multiple Coll. Count */ +#define HV_MCC_UPPER PHY_REG(HV_STATS_PAGE, 20) /* Multiple Collision */ #define HV_MCC_LOWER PHY_REG(HV_STATS_PAGE, 21) -#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision Count */ +#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision */ #define HV_LATECOL_LOWER PHY_REG(HV_STATS_PAGE, 24) -#define HV_COLC_UPPER PHY_REG(HV_STATS_PAGE, 25) /* Collision Count */ +#define HV_COLC_UPPER PHY_REG(HV_STATS_PAGE, 25) /* Collision */ #define HV_COLC_LOWER PHY_REG(HV_STATS_PAGE, 26) #define HV_DC_UPPER PHY_REG(HV_STATS_PAGE, 27) /* Defer Count */ #define HV_DC_LOWER PHY_REG(HV_STATS_PAGE, 28) -#define HV_TNCRS_UPPER PHY_REG(HV_STATS_PAGE, 29) /* Transmit with no CRS */ +#define HV_TNCRS_UPPER PHY_REG(HV_STATS_PAGE, 29) /* Tx with no CRS */ #define HV_TNCRS_LOWER PHY_REG(HV_STATS_PAGE, 30) #define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ @@ -164,6 +176,16 @@ #define CV_SMB_CTRL PHY_REG(769, 23) #define CV_SMB_CTRL_FORCE_SMBUS 0x0001 +/* I218 Ultra Low Power Configuration 1 Register */ +#define I218_ULP_CONFIG1 PHY_REG(779, 16) +#define I218_ULP_CONFIG1_START 0x0001 /* Start auto ULP config */ +#define I218_ULP_CONFIG1_IND 0x0004 /* Pwr up from ULP indication */ +#define I218_ULP_CONFIG1_STICKY_ULP 0x0010 /* Set sticky ULP mode */ +#define I218_ULP_CONFIG1_INBAND_EXIT 0x0020 /* Inband on ULP exit */ +#define I218_ULP_CONFIG1_WOL_HOST 0x0040 /* WoL Host on ULP exit */ +#define I218_ULP_CONFIG1_RESET_TO_SMBUS 0x0100 /* Reset to SMBus mode */ +#define I218_ULP_CONFIG1_DISABLE_SMB_PERST 0x1000 /* Disable on PERST# */ + /* SMBus Address Phy Register */ #define HV_SMB_ADDR PHY_REG(768, 26) #define HV_SMB_ADDR_MASK 0x007F @@ -198,15 +220,28 @@ /* PHY Power Management Control */ #define HV_PM_CTRL PHY_REG(770, 17) #define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100 +#define HV_PM_CTRL_K1_ENABLE 0x4000 #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */ +/* Inband Control */ +#define I217_INBAND_CTRL PHY_REG(770, 18) +#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK 0x3F00 +#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT 8 + +/* Low Power Idle GPIO Control */ +#define I217_LPI_GPIO_CTRL PHY_REG(772, 18) +#define I217_LPI_GPIO_CTRL_AUTO_EN_LPI 0x0800 + /* PHY Low Power Idle Control */ #define I82579_LPI_CTRL PHY_REG(772, 20) #define I82579_LPI_CTRL_100_ENABLE 0x2000 #define I82579_LPI_CTRL_1000_ENABLE 0x4000 #define I82579_LPI_CTRL_ENABLE_MASK 0x6000 -#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80 + +/* 82579 DFT Control */ +#define I82579_DFT_CTRL PHY_REG(769, 20) +#define I82579_DFT_CTRL_GATE_PHY_RESET 0x0040 /* Gate PHY Reset on MAC Reset */ /* Extended Management Interface (EMI) Registers */ #define I82579_EMI_ADDR 0x10 @@ -216,16 +251,19 @@ #define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */ #define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ #define I82579_RX_CONFIG 0x3412 /* Receive configuration */ -#define I82579_EEE_PCS_STATUS 0x182D /* IEEE MMD Register 3.1 >> 8 */ +#define I82579_LPI_PLL_SHUT 0x4412 /* LPI PLL Shut Enable */ +#define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */ #define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */ #define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */ #define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */ -#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE supported */ -#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE supported */ +#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */ +#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */ +#define I82579_LPI_100_PLL_SHUT (1 << 2) /* 100M LPI PLL Shut Enabled */ #define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */ #define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */ #define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */ #define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */ +#define I217_RX_CONFIG 0xB20C /* Receive configuration */ #define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */ #define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */ @@ -274,4 +312,8 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw); s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable); s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data); +s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data); +s32 e1000_set_eee_pchlan(struct e1000_hw *hw); +s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx); +s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force); #endif /* _E1000_ICH8LAN_H_ */ diff --git a/freebsd/sys/dev/e1000/e1000_mac.c b/freebsd/sys/dev/e1000/e1000_mac.c index b9bf8dc4..3967a25a 100644 --- a/freebsd/sys/dev/e1000/e1000_mac.c +++ b/freebsd/sys/dev/e1000/e1000_mac.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -39,7 +39,7 @@ static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw); static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw); static void e1000_config_collision_dist_generic(struct e1000_hw *hw); -static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); +static int e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); /** * e1000_init_mac_ops_generic - Initialize MAC function pointers @@ -87,7 +87,7 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw) * e1000_null_ops_generic - No-op function, returns 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_ops_generic(struct e1000_hw *hw) +s32 e1000_null_ops_generic(struct e1000_hw E1000_UNUSEDARG *hw) { DEBUGFUNC("e1000_null_ops_generic"); return E1000_SUCCESS; @@ -97,7 +97,7 @@ s32 e1000_null_ops_generic(struct e1000_hw *hw) * e1000_null_mac_generic - No-op function, return void * @hw: pointer to the HW structure **/ -void e1000_null_mac_generic(struct e1000_hw *hw) +void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw) { DEBUGFUNC("e1000_null_mac_generic"); return; @@ -107,7 +107,8 @@ void e1000_null_mac_generic(struct e1000_hw *hw) * e1000_null_link_info - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d) +s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw, + u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d) { DEBUGFUNC("e1000_null_link_info"); return E1000_SUCCESS; @@ -117,7 +118,8 @@ s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d) * e1000_null_mng_mode - No-op function, return FALSE * @hw: pointer to the HW structure **/ -bool e1000_null_mng_mode(struct e1000_hw *hw) { +bool e1000_null_mng_mode(struct e1000_hw E1000_UNUSEDARG *hw) +{ DEBUGFUNC("e1000_null_mng_mode"); return FALSE; } @@ -126,7 +128,8 @@ bool e1000_null_mng_mode(struct e1000_hw *hw) { * e1000_null_update_mc - No-op function, return void * @hw: pointer to the HW structure **/ -void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a) +void e1000_null_update_mc(struct e1000_hw E1000_UNUSEDARG *hw, + u8 E1000_UNUSEDARG *h, u32 E1000_UNUSEDARG a) { DEBUGFUNC("e1000_null_update_mc"); return; @@ -136,27 +139,30 @@ void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a) * e1000_null_write_vfta - No-op function, return void * @hw: pointer to the HW structure **/ -void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b) +void e1000_null_write_vfta(struct e1000_hw E1000_UNUSEDARG *hw, + u32 E1000_UNUSEDARG a, u32 E1000_UNUSEDARG b) { DEBUGFUNC("e1000_null_write_vfta"); return; } /** - * e1000_null_rar_set - No-op function, return void + * e1000_null_rar_set - No-op function, return 0 * @hw: pointer to the HW structure **/ -void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a) +int e1000_null_rar_set(struct e1000_hw E1000_UNUSEDARG *hw, + u8 E1000_UNUSEDARG *h, u32 E1000_UNUSEDARG a) { DEBUGFUNC("e1000_null_rar_set"); - return; + return E1000_SUCCESS; } /** * e1000_null_set_obff_timer - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a) +s32 e1000_null_set_obff_timer(struct e1000_hw E1000_UNUSEDARG *hw, + u32 E1000_UNUSEDARG a) { DEBUGFUNC("e1000_null_set_obff_timer"); return E1000_SUCCESS; @@ -471,7 +477,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) * Sets the receive address array register at index to the address passed * in by addr. **/ -static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) +static int e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) { u32 rar_low, rar_high; @@ -497,6 +503,8 @@ static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) E1000_WRITE_FLUSH(hw); E1000_WRITE_REG(hw, E1000_RAH(index), rar_high); E1000_WRITE_FLUSH(hw); + + return E1000_SUCCESS; } /** @@ -942,6 +950,7 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw) { s32 ret_val; u16 nvm_data; + u16 nvm_offset = 0; DEBUGFUNC("e1000_set_default_fc_generic"); @@ -953,7 +962,18 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw) * control setting, then the variable hw->fc will * be initialized based on a value in the EEPROM. */ - ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); + if (hw->mac.type == e1000_i350) { + nvm_offset = NVM_82580_LAN_FUNC_OFFSET(hw->bus.func); + ret_val = hw->nvm.ops.read(hw, + NVM_INIT_CONTROL2_REG + + nvm_offset, + 1, &nvm_data); + } else { + ret_val = hw->nvm.ops.read(hw, + NVM_INIT_CONTROL2_REG, + 1, &nvm_data); + } + if (ret_val) { DEBUGOUT("NVM Read Error\n"); @@ -1677,7 +1697,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, * Sets the speed and duplex to gigabit full duplex (the only possible option) * for fiber/serdes links. **/ -s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, +s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw, u16 *speed, u16 *duplex) { DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic"); @@ -2080,7 +2100,8 @@ s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw) while (timeout) { if (!(E1000_READ_REG(hw, E1000_STATUS) & - E1000_STATUS_GIO_MASTER_ENABLE)) + E1000_STATUS_GIO_MASTER_ENABLE) || + E1000_REMOVED(hw->hw_addr)) break; usec_delay(100); timeout--; @@ -2189,7 +2210,7 @@ static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw) * Validate the MDI/MDIx setting, allowing for auto-crossover during forced * operation. **/ -s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw *hw) +s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw E1000_UNUSEDARG *hw) { DEBUGFUNC("e1000_validate_mdi_setting_crossover_generic"); diff --git a/freebsd/sys/dev/e1000/e1000_mac.h b/freebsd/sys/dev/e1000/e1000_mac.h index 3e2ccded..2c1bfe32 100644 --- a/freebsd/sys/dev/e1000/e1000_mac.h +++ b/freebsd/sys/dev/e1000/e1000_mac.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,13 +36,16 @@ #define _E1000_MAC_H_ void e1000_init_mac_ops_generic(struct e1000_hw *hw); +#ifndef E1000_REMOVED +#define E1000_REMOVED(a) (0) +#endif /* E1000_REMOVED */ void e1000_null_mac_generic(struct e1000_hw *hw); s32 e1000_null_ops_generic(struct e1000_hw *hw); s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d); bool e1000_null_mng_mode(struct e1000_hw *hw); void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a); void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b); -void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a); +int e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a); s32 e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a); s32 e1000_blink_led_generic(struct e1000_hw *hw); s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw); diff --git a/freebsd/sys/dev/e1000/e1000_manage.c b/freebsd/sys/dev/e1000/e1000_manage.c index e33ff560..0648ac9d 100644 --- a/freebsd/sys/dev/e1000/e1000_manage.c +++ b/freebsd/sys/dev/e1000/e1000_manage.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -366,9 +366,12 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) } else if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) { u16 data; + s32 ret_val; factps = E1000_READ_REG(hw, E1000_FACTPS); - e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); + ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); + if (ret_val) + return FALSE; if (!(factps & E1000_FACTPS_MNGCG) && ((data & E1000_NVM_INIT_CTRL2_MNGM) == @@ -376,7 +379,7 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) return TRUE; } else if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) { - return TRUE; + return TRUE; } return FALSE; diff --git a/freebsd/sys/dev/e1000/e1000_mbx.c b/freebsd/sys/dev/e1000/e1000_mbx.c index 8028487b..1b5bb70d 100644 --- a/freebsd/sys/dev/e1000/e1000_mbx.c +++ b/freebsd/sys/dev/e1000/e1000_mbx.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2010, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -40,7 +40,8 @@ * e1000_null_mbx_check_for_flag - No-op function, return 0 * @hw: pointer to the HW structure **/ -static s32 e1000_null_mbx_check_for_flag(struct e1000_hw *hw, u16 mbx_id) +static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw, + u16 E1000_UNUSEDARG mbx_id) { DEBUGFUNC("e1000_null_mbx_check_flag"); @@ -51,8 +52,10 @@ static s32 e1000_null_mbx_check_for_flag(struct e1000_hw *hw, u16 mbx_id) * e1000_null_mbx_transact - No-op function, return 0 * @hw: pointer to the HW structure **/ -static s32 e1000_null_mbx_transact(struct e1000_hw *hw, u32 *msg, u16 size, - u16 mbx_id) +static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw, + u32 E1000_UNUSEDARG *msg, + u16 E1000_UNUSEDARG size, + u16 E1000_UNUSEDARG mbx_id) { DEBUGFUNC("e1000_null_mbx_rw_msg"); @@ -356,7 +359,8 @@ static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask) * * returns SUCCESS if the PF has set the Status bit or else ERR_MBX **/ -static s32 e1000_check_for_msg_vf(struct e1000_hw *hw, u16 mbx_id) +static s32 e1000_check_for_msg_vf(struct e1000_hw *hw, + u16 E1000_UNUSEDARG mbx_id) { s32 ret_val = -E1000_ERR_MBX; @@ -377,7 +381,8 @@ static s32 e1000_check_for_msg_vf(struct e1000_hw *hw, u16 mbx_id) * * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX **/ -static s32 e1000_check_for_ack_vf(struct e1000_hw *hw, u16 mbx_id) +static s32 e1000_check_for_ack_vf(struct e1000_hw *hw, + u16 E1000_UNUSEDARG mbx_id) { s32 ret_val = -E1000_ERR_MBX; @@ -398,14 +403,15 @@ static s32 e1000_check_for_ack_vf(struct e1000_hw *hw, u16 mbx_id) * * returns TRUE if the PF has set the reset done bit or else FALSE **/ -static s32 e1000_check_for_rst_vf(struct e1000_hw *hw, u16 mbx_id) +static s32 e1000_check_for_rst_vf(struct e1000_hw *hw, + u16 E1000_UNUSEDARG mbx_id) { s32 ret_val = -E1000_ERR_MBX; DEBUGFUNC("e1000_check_for_rst_vf"); if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD | - E1000_V2PMAILBOX_RSTI))) { + E1000_V2PMAILBOX_RSTI))) { ret_val = E1000_SUCCESS; hw->mbx.stats.rsts++; } @@ -445,7 +451,7 @@ static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw) * returns SUCCESS if it successfully copied message into the buffer **/ static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size, - u16 mbx_id) + u16 E1000_UNUSEDARG mbx_id) { s32 ret_val; u16 i; @@ -486,7 +492,7 @@ out_no_write: * returns SUCCESS if it successfuly read message from buffer **/ static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size, - u16 mbx_id) + u16 E1000_UNUSEDARG mbx_id) { s32 ret_val = E1000_SUCCESS; u16 i; @@ -659,7 +665,7 @@ static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) * returns SUCCESS if it successfully copied message into the buffer **/ static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, - u16 vf_number) + u16 vf_number) { s32 ret_val; u16 i; @@ -702,7 +708,7 @@ out_no_write: * a message due to a VF request so no polling for message is needed. **/ static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, - u16 vf_number) + u16 vf_number) { s32 ret_val; u16 i; @@ -741,6 +747,7 @@ s32 e1000_init_mbx_params_pf(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82576: case e1000_i350: + case e1000_i354: mbx->timeout = 0; mbx->usec_delay = 0; diff --git a/freebsd/sys/dev/e1000/e1000_mbx.h b/freebsd/sys/dev/e1000/e1000_mbx.h index 206f00c5..d2aea5c4 100644 --- a/freebsd/sys/dev/e1000/e1000_mbx.h +++ b/freebsd/sys/dev/e1000/e1000_mbx.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2010, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -38,59 +38,59 @@ #include "e1000_api.h" /* Define mailbox register bits */ -#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */ -#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */ -#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ -#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ -#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */ -#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */ -#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */ -#define E1000_V2PMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */ +#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */ +#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */ +#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ +#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ +#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */ +#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */ +#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */ +#define E1000_V2PMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */ #define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */ -#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */ -#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */ -#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ -#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ -#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */ +#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */ +#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */ +#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ +#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ +#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */ #define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */ -#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */ +#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */ #define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */ -#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */ +#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */ -#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ +#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ /* If it's a E1000_VF_* msg then it originates in the VF and is sent to the * PF. The reverse is TRUE if it is E1000_PF_*. * Message ACK's are the value or'd with 0xF0000000 */ -#define E1000_VT_MSGTYPE_ACK 0x80000000 /* Messages below or'd with - * this are the ACK */ -#define E1000_VT_MSGTYPE_NACK 0x40000000 /* Messages below or'd with - * this are the NACK */ -#define E1000_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still - clear to send requests */ -#define E1000_VT_MSGINFO_SHIFT 16 -/* bits 23:16 are used for exra info for certain messages */ -#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT) +/* Msgs below or'd with this are the ACK */ +#define E1000_VT_MSGTYPE_ACK 0x80000000 +/* Msgs below or'd with this are the NACK */ +#define E1000_VT_MSGTYPE_NACK 0x40000000 +/* Indicates that VF is still clear to send requests */ +#define E1000_VT_MSGTYPE_CTS 0x20000000 +#define E1000_VT_MSGINFO_SHIFT 16 +/* bits 23:16 are used for extra info for certain messages */ +#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT) -#define E1000_VF_RESET 0x01 /* VF requests reset */ -#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */ -#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */ +#define E1000_VF_RESET 0x01 /* VF requests reset */ +#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */ +#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */ #define E1000_VF_SET_MULTICAST_COUNT_MASK (0x1F << E1000_VT_MSGINFO_SHIFT) -#define E1000_VF_SET_MULTICAST_OVERFLOW (0x80 << E1000_VT_MSGINFO_SHIFT) -#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */ -#define E1000_VF_SET_VLAN_ADD (0x01 << E1000_VT_MSGINFO_SHIFT) -#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LPE */ -#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.ROPE/MPME*/ -#define E1000_VF_SET_PROMISC_UNICAST (0x01 << E1000_VT_MSGINFO_SHIFT) -#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT) +#define E1000_VF_SET_MULTICAST_OVERFLOW (0x80 << E1000_VT_MSGINFO_SHIFT) +#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */ +#define E1000_VF_SET_VLAN_ADD (0x01 << E1000_VT_MSGINFO_SHIFT) +#define E1000_VF_SET_LPE 0x05 /* reqs to set VMOLR.LPE */ +#define E1000_VF_SET_PROMISC 0x06 /* reqs to clear VMOLR.ROPE/MPME*/ +#define E1000_VF_SET_PROMISC_UNICAST (0x01 << E1000_VT_MSGINFO_SHIFT) +#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT) -#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */ +#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */ -#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */ -#define E1000_VF_MBX_INIT_DELAY 500 /* microseconds between retries */ +#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */ +#define E1000_VF_MBX_INIT_DELAY 500 /* microseconds between retries */ s32 e1000_read_mbx(struct e1000_hw *, u32 *, u16, u16); s32 e1000_write_mbx(struct e1000_hw *, u32 *, u16, u16); diff --git a/freebsd/sys/dev/e1000/e1000_nvm.c b/freebsd/sys/dev/e1000/e1000_nvm.c index 9b9333c6..ad0c9544 100644 --- a/freebsd/sys/dev/e1000/e1000_nvm.c +++ b/freebsd/sys/dev/e1000/e1000_nvm.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -65,7 +65,9 @@ void e1000_init_nvm_ops_generic(struct e1000_hw *hw) * e1000_null_nvm_read - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c) +s32 e1000_null_read_nvm(struct e1000_hw E1000_UNUSEDARG *hw, + u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b, + u16 E1000_UNUSEDARG *c) { DEBUGFUNC("e1000_null_read_nvm"); return E1000_SUCCESS; @@ -75,7 +77,7 @@ s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c) * e1000_null_nvm_generic - No-op function, return void * @hw: pointer to the HW structure **/ -void e1000_null_nvm_generic(struct e1000_hw *hw) +void e1000_null_nvm_generic(struct e1000_hw E1000_UNUSEDARG *hw) { DEBUGFUNC("e1000_null_nvm_generic"); return; @@ -85,7 +87,8 @@ void e1000_null_nvm_generic(struct e1000_hw *hw) * e1000_null_led_default - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data) +s32 e1000_null_led_default(struct e1000_hw E1000_UNUSEDARG *hw, + u16 E1000_UNUSEDARG *data) { DEBUGFUNC("e1000_null_led_default"); return E1000_SUCCESS; @@ -95,7 +98,9 @@ s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data) * e1000_null_write_nvm - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c) +s32 e1000_null_write_nvm(struct e1000_hw E1000_UNUSEDARG *hw, + u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b, + u16 E1000_UNUSEDARG *c) { DEBUGFUNC("e1000_null_write_nvm"); return E1000_SUCCESS; @@ -579,6 +584,9 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) E1000_NVM_RW_REG_DATA); } + if (ret_val) + DEBUGOUT1("NVM read error: %d\n", ret_val); + return ret_val; } @@ -769,6 +777,12 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, DEBUGFUNC("e1000_read_pba_string_generic"); + if ((hw->mac.type >= e1000_i210) && + !e1000_get_flash_presence_i210(hw)) { + DEBUGOUT("Flashless no PBA string\n"); + return -E1000_ERR_NVM_PBA_SECTION; + } + if (pba_num == NULL) { DEBUGOUT("PBA string buffer was null\n"); return -E1000_ERR_INVALID_ARGUMENT; @@ -976,7 +990,7 @@ s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf, return ret_val; } else { if (eeprom_buf_size > (u32)(pba->word[1] + - pba->pba_block[0])) { + pba_block_size)) { memcpy(pba->pba_block, &eeprom_buf[pba->word[1]], pba_block_size * sizeof(u16)); diff --git a/freebsd/sys/dev/e1000/e1000_osdep.h b/freebsd/sys/dev/e1000/e1000_osdep.h index 7253969b..b331bdc1 100644 --- a/freebsd/sys/dev/e1000/e1000_osdep.h +++ b/freebsd/sys/dev/e1000/e1000_osdep.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -60,14 +60,13 @@ #define ASSERT(x) if(!(x)) panic("EM: x") #define usec_delay(x) DELAY(x) +#define usec_delay_irq(x) DELAY(x) #define msec_delay(x) DELAY(1000*(x)) #define msec_delay_irq(x) DELAY(1000*(x)) -#define MSGOUT(S, A, B) printf(S "\n", A, B) #define DEBUGFUNC(F) DEBUGOUT(F); #define DEBUGOUT(S) do {} while (0) -/* This define is needed or shared code will not build */ -#define DEBUGOUT1(S,A) if (0) printf(S,A); +#define DEBUGOUT1(S,A) do {} while (0) #define DEBUGOUT2(S,A,B) do {} while (0) #define DEBUGOUT3(S,A,B,C) do {} while (0) #define DEBUGOUT7(S,A,B,C,D,E,F,G) do {} while (0) @@ -76,7 +75,7 @@ #define FALSE 0 #define TRUE 1 #ifndef __bool_true_false_are_defined -#define false FALSE +#define false FALSE #define true TRUE #endif #define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */ @@ -86,7 +85,7 @@ #define E1000_MUTEX struct mtx #define E1000_MUTEX_INIT(mutex) mtx_init((mutex), #mutex, \ MTX_NETWORK_LOCK, \ - MTX_DEF | MTX_DUPOK) + MTX_DEF | MTX_DUPOK) #define E1000_MUTEX_DESTROY(mutex) mtx_destroy(mutex) #define E1000_MUTEX_LOCK(mutex) mtx_lock(mutex) #define E1000_MUTEX_TRYLOCK(mutex) mtx_trylock(mutex) @@ -108,7 +107,7 @@ typedef boolean_t bool; #define __le32 u32 #define __le64 u64 -#if __FreeBSD_version < 800000 /* Now in HEAD */ +#if __FreeBSD_version < 800000 #if defined(__i386__) || defined(__amd64__) #define mb() __asm volatile("mfence" ::: "memory") #define wmb() __asm volatile("sfence" ::: "memory") diff --git a/freebsd/sys/dev/e1000/e1000_phy.c b/freebsd/sys/dev/e1000/e1000_phy.c index 9f955089..cb92973b 100644 --- a/freebsd/sys/dev/e1000/e1000_phy.c +++ b/freebsd/sys/dev/e1000/e1000_phy.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -106,7 +106,8 @@ void e1000_init_phy_ops_generic(struct e1000_hw *hw) * e1000_null_set_page - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_set_page(struct e1000_hw *hw, u16 data) +s32 e1000_null_set_page(struct e1000_hw E1000_UNUSEDARG *hw, + u16 E1000_UNUSEDARG data) { DEBUGFUNC("e1000_null_set_page"); return E1000_SUCCESS; @@ -116,7 +117,8 @@ s32 e1000_null_set_page(struct e1000_hw *hw, u16 data) * e1000_null_read_reg - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_null_read_reg(struct e1000_hw E1000_UNUSEDARG *hw, + u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG *data) { DEBUGFUNC("e1000_null_read_reg"); return E1000_SUCCESS; @@ -126,7 +128,7 @@ s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data) * e1000_null_phy_generic - No-op function, return void * @hw: pointer to the HW structure **/ -void e1000_null_phy_generic(struct e1000_hw *hw) +void e1000_null_phy_generic(struct e1000_hw E1000_UNUSEDARG *hw) { DEBUGFUNC("e1000_null_phy_generic"); return; @@ -136,7 +138,8 @@ void e1000_null_phy_generic(struct e1000_hw *hw) * e1000_null_lplu_state - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active) +s32 e1000_null_lplu_state(struct e1000_hw E1000_UNUSEDARG *hw, + bool E1000_UNUSEDARG active) { DEBUGFUNC("e1000_null_lplu_state"); return E1000_SUCCESS; @@ -146,7 +149,8 @@ s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active) * e1000_null_write_reg - No-op function, return 0 * @hw: pointer to the HW structure **/ -s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_null_write_reg(struct e1000_hw E1000_UNUSEDARG *hw, + u32 E1000_UNUSEDARG offset, u16 E1000_UNUSEDARG data) { DEBUGFUNC("e1000_null_write_reg"); return E1000_SUCCESS; @@ -160,8 +164,10 @@ s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data) * @data: data value read * **/ -s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset, - u8 dev_addr, u8 *data) +s32 e1000_read_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw, + u8 E1000_UNUSEDARG byte_offset, + u8 E1000_UNUSEDARG dev_addr, + u8 E1000_UNUSEDARG *data) { DEBUGFUNC("e1000_read_i2c_byte_null"); return E1000_SUCCESS; @@ -175,10 +181,10 @@ s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset, * @data: data value to write * **/ -s32 e1000_write_i2c_byte_null(struct e1000_hw *hw, - u8 byte_offset, - u8 dev_addr, - u8 data) +s32 e1000_write_i2c_byte_null(struct e1000_hw E1000_UNUSEDARG *hw, + u8 E1000_UNUSEDARG byte_offset, + u8 E1000_UNUSEDARG dev_addr, + u8 E1000_UNUSEDARG data) { DEBUGFUNC("e1000_write_i2c_byte_null"); return E1000_SUCCESS; @@ -304,7 +310,7 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) * the lower time out */ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { - usec_delay(50); + usec_delay_irq(50); mdic = E1000_READ_REG(hw, E1000_MDIC); if (mdic & E1000_MDIC_READY) break; @@ -329,7 +335,7 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) * reading duplicate data in the next MDIC transaction. */ if (hw->mac.type == e1000_pch2lan) - usec_delay(100); + usec_delay_irq(100); return E1000_SUCCESS; } @@ -370,7 +376,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) * the lower time out */ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { - usec_delay(50); + usec_delay_irq(50); mdic = E1000_READ_REG(hw, E1000_MDIC); if (mdic & E1000_MDIC_READY) break; @@ -394,7 +400,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) * reading duplicate data in the next MDIC transaction. */ if (hw->mac.type == e1000_pch2lan) - usec_delay(100); + usec_delay_irq(100); return E1000_SUCCESS; } @@ -1056,16 +1062,12 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) } } - /* Enable CRS on Tx. This must be set for half-duplex operation. - * Not required on some PHYs. - */ + /* Enable CRS on Tx. This must be set for half-duplex operation. */ ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data); if (ret_val) return ret_val; - if ((hw->phy.type != e1000_phy_82579) && - (hw->phy.type != e1000_phy_i217)) - phy_data |= I82577_CFG_ASSERT_CRS_ON_TX; + phy_data |= I82577_CFG_ASSERT_CRS_ON_TX; /* Enable downshift */ phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; @@ -1251,12 +1253,6 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) return ret_val; } - if (phy->type == e1000_phy_i210) { - ret_val = e1000_set_master_slave_mode(hw); - if (ret_val) - return ret_val; - } - return E1000_SUCCESS; } @@ -1320,6 +1316,20 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw) phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; /* Enable downshift and setting it to X6 */ + if (phy->id == M88E1543_E_PHY_ID) { + phy_data &= ~I347AT4_PSCR_DOWNSHIFT_ENABLE; + ret_val = + phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + if (ret_val) + return ret_val; + + ret_val = phy->ops.commit(hw); + if (ret_val) { + DEBUGOUT("Error committing the PHY changes\n"); + return ret_val; + } + } + phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK; phy_data |= I347AT4_PSCR_DOWNSHIFT_6X; phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE; @@ -1335,6 +1345,10 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw) return ret_val; } + ret_val = e1000_set_master_slave_mode(hw); + if (ret_val) + return ret_val; + return E1000_SUCCESS; } @@ -1849,6 +1863,8 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) case I347AT4_E_PHY_ID: case M88E1340M_E_PHY_ID: case M88E1112_E_PHY_ID: + case M88E1543_E_PHY_ID: + case M88E1512_E_PHY_ID: case I210_I_PHY_ID: reset_dsp = FALSE; break; @@ -1891,6 +1907,9 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) return E1000_SUCCESS; if (hw->phy.id == I210_I_PHY_ID) return E1000_SUCCESS; + if ((hw->phy.id == M88E1543_E_PHY_ID) || + (hw->phy.id == M88E1512_E_PHY_ID)) + return E1000_SUCCESS; ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) return ret_val; @@ -2196,9 +2215,9 @@ s32 e1000_check_polarity_m88(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data); if (!ret_val) - phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & M88E1000_PSSR_REV_POLARITY) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); return ret_val; } @@ -2242,9 +2261,9 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, offset, &data); if (!ret_val) - phy->cable_polarity = (data & mask) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & mask) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); return ret_val; } @@ -2276,9 +2295,9 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, offset, &phy_data); if (!ret_val) - phy->cable_polarity = (phy_data & mask) + phy->cable_polarity = ((phy_data & mask) ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + : e1000_rev_polarity_normal); return ret_val; } @@ -2345,19 +2364,23 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, * it across the board. */ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); - if (ret_val) + if (ret_val) { /* If the first read fails, another entity may have * ownership of the resources, wait and try again to * see if they have relinquished the resources yet. */ - usec_delay(usec_interval); + if (usec_interval >= 1000) + msec_delay(usec_interval/1000); + else + usec_delay(usec_interval); + } ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val) break; if (phy_status & MII_SR_LINK_STATUS) break; if (usec_interval >= 1000) - msec_delay_irq(usec_interval/1000); + msec_delay(usec_interval/1000); else usec_delay(usec_interval); } @@ -2394,8 +2417,8 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw) if (ret_val) return ret_val; - index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> - M88E1000_PSSR_CABLE_LENGTH_SHIFT; + index = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >> + M88E1000_PSSR_CABLE_LENGTH_SHIFT); if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) return -E1000_ERR_PHY; @@ -2439,6 +2462,8 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw) phy->max_cable_length = phy_data / (is_cm ? 100 : 1); phy->cable_length = phy_data / (is_cm ? 100 : 1); break; + case M88E1543_E_PHY_ID: + case M88E1512_E_PHY_ID: case M88E1340M_E_PHY_ID: case I347AT4_E_PHY_ID: /* Remember the original page select and set it to 7 */ @@ -2556,8 +2581,8 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) * that can be put into the lookup table to obtain the * approximate cable length. */ - cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & - IGP02E1000_AGC_LENGTH_MASK; + cur_agc_index = ((phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & + IGP02E1000_AGC_LENGTH_MASK); /* Array index bound check. */ if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) || @@ -2580,8 +2605,8 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2); /* Calculate cable length with the error range of +/- 10 meters. */ - phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ? - (agc_value - IGP02E1000_AGC_RANGE) : 0; + phy->min_cable_length = (((agc_value - IGP02E1000_AGC_RANGE) > 0) ? + (agc_value - IGP02E1000_AGC_RANGE) : 0); phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; @@ -2765,9 +2790,9 @@ s32 e1000_get_phy_info_ife(struct e1000_hw *hw) return ret_val; } else { /* Polarity is forced */ - phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & IFE_PSC_FORCE_POLARITY) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); } ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); @@ -2865,7 +2890,7 @@ s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) * Generic function to wait 10 milli-seconds for configuration to complete * and return success. **/ -s32 e1000_get_cfg_done_generic(struct e1000_hw *hw) +s32 e1000_get_cfg_done_generic(struct e1000_hw E1000_UNUSEDARG *hw) { DEBUGFUNC("e1000_get_cfg_done_generic"); @@ -2972,6 +2997,8 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id) case M88E1000_E_PHY_ID: case M88E1111_I_PHY_ID: case M88E1011_I_PHY_ID: + case M88E1543_E_PHY_ID: + case M88E1512_E_PHY_ID: case I347AT4_E_PHY_ID: case M88E1112_E_PHY_ID: case M88E1340M_E_PHY_ID: @@ -3404,11 +3431,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data, bool read, bool page_set) { s32 ret_val; - u16 reg = BM_PHY_REG_NUM(offset); - u16 page = BM_PHY_REG_PAGE(offset); + u16 reg, page; u16 phy_reg = 0; DEBUGFUNC("e1000_access_phy_wakeup_reg_bm"); + reg = BM_PHY_REG_NUM(offset); + page = BM_PHY_REG_PAGE(offset); /* Gig must be disabled for MDIO accesses to Host Wakeup reg page */ if ((hw->mac.type == e1000_pchlan) && @@ -3466,16 +3494,10 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, void e1000_power_up_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; - u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg &= ~MII_CR_POWER_DOWN; - if (hw->phy.type == e1000_phy_i210) { - hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); - power_reg &= ~GS40G_CS_POWER_DOWN; - hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); - } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); } @@ -3490,17 +3512,10 @@ void e1000_power_up_phy_copper(struct e1000_hw *hw) void e1000_power_down_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; - u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; - /* i210 Phy requires an additional bit for power up/down */ - if (hw->phy.type == e1000_phy_i210) { - hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); - power_reg |= GS40G_CS_POWER_DOWN; - hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); - } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); msec_delay(1); } @@ -3778,8 +3793,8 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, DEBUGFUNC("e1000_access_phy_debug_regs_hv"); /* This takes care of the difference with desktop vs mobile phy */ - addr_reg = (hw->phy.type == e1000_phy_82578) ? - I82578_ADDR_REG : I82577_ADDR_REG; + addr_reg = ((hw->phy.type == e1000_phy_82578) ? + I82578_ADDR_REG : I82577_ADDR_REG); data_reg = addr_reg + 1; /* All operations in this function are phy address 2 */ @@ -3835,8 +3850,8 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) if (ret_val) return ret_val; - data &= BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; + data &= (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK); if (data != (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | BM_CS_STATUS_SPEED_1000)) @@ -3874,9 +3889,9 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data); if (!ret_val) - phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + phy->cable_polarity = ((data & I82577_PHY_STATUS2_REV_POLARITY) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal); return ret_val; } @@ -4011,8 +4026,8 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw) if (ret_val) return ret_val; - length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >> - I82577_DSTATUS_CABLE_LENGTH_SHIFT; + length = ((phy_data & I82577_DSTATUS_CABLE_LENGTH) >> + I82577_DSTATUS_CABLE_LENGTH_SHIFT); if (length == E1000_CABLE_LENGTH_UNDEFINED) return -E1000_ERR_PHY; @@ -4085,3 +4100,157 @@ release: return ret_val; } +/** + * e1000_read_phy_reg_mphy - Read mPHY control register + * @hw: pointer to the HW structure + * @address: address to be read + * @data: pointer to the read data + * + * Reads the mPHY control register in the PHY at offset and stores the + * information read to data. + **/ +s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data) +{ + u32 mphy_ctrl = 0; + bool locked = FALSE; + bool ready; + + DEBUGFUNC("e1000_read_phy_reg_mphy"); + + /* Check if mPHY is ready to read/write operations */ + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + + /* Check if mPHY access is disabled and enable it if so */ + mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL); + if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) { + locked = TRUE; + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + mphy_ctrl |= E1000_MPHY_ENA_ACCESS; + E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl); + } + + /* Set the address that we want to read */ + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + + /* We mask address, because we want to use only current lane */ + mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK & + ~E1000_MPHY_ADDRESS_FNC_OVERRIDE) | + (address & E1000_MPHY_ADDRESS_MASK); + E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl); + + /* Read data from the address */ + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + *data = E1000_READ_REG(hw, E1000_MPHY_DATA); + + /* Disable access to mPHY if it was originally disabled */ + if (locked) + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, + E1000_MPHY_DIS_ACCESS); + + return E1000_SUCCESS; +} + +/** + * e1000_write_phy_reg_mphy - Write mPHY control register + * @hw: pointer to the HW structure + * @address: address to write to + * @data: data to write to register at offset + * @line_override: used when we want to use different line than default one + * + * Writes data to mPHY control register. + **/ +s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data, + bool line_override) +{ + u32 mphy_ctrl = 0; + bool locked = FALSE; + bool ready; + + DEBUGFUNC("e1000_write_phy_reg_mphy"); + + /* Check if mPHY is ready to read/write operations */ + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + + /* Check if mPHY access is disabled and enable it if so */ + mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL); + if (mphy_ctrl & E1000_MPHY_DIS_ACCESS) { + locked = TRUE; + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + mphy_ctrl |= E1000_MPHY_ENA_ACCESS; + E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl); + } + + /* Set the address that we want to read */ + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + + /* We mask address, because we want to use only current lane */ + if (line_override) + mphy_ctrl |= E1000_MPHY_ADDRESS_FNC_OVERRIDE; + else + mphy_ctrl &= ~E1000_MPHY_ADDRESS_FNC_OVERRIDE; + mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK) | + (address & E1000_MPHY_ADDRESS_MASK); + E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl); + + /* Read data from the address */ + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + E1000_WRITE_REG(hw, E1000_MPHY_DATA, data); + + /* Disable access to mPHY if it was originally disabled */ + if (locked) + ready = e1000_is_mphy_ready(hw); + if (!ready) + return -E1000_ERR_PHY; + E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, + E1000_MPHY_DIS_ACCESS); + + return E1000_SUCCESS; +} + +/** + * e1000_is_mphy_ready - Check if mPHY control register is not busy + * @hw: pointer to the HW structure + * + * Returns mPHY control register status. + **/ +bool e1000_is_mphy_ready(struct e1000_hw *hw) +{ + u16 retry_count = 0; + u32 mphy_ctrl = 0; + bool ready = FALSE; + + while (retry_count < 2) { + mphy_ctrl = E1000_READ_REG(hw, E1000_MPHY_ADDR_CTRL); + if (mphy_ctrl & E1000_MPHY_BUSY) { + usec_delay(20); + retry_count++; + continue; + } + ready = TRUE; + break; + } + + if (!ready) + DEBUGOUT("ERROR READING mPHY control register, phy is busy.\n"); + + return ready; +} diff --git a/freebsd/sys/dev/e1000/e1000_phy.h b/freebsd/sys/dev/e1000/e1000_phy.h index 9911df77..0e5b2e6a 100644 --- a/freebsd/sys/dev/e1000/e1000_phy.h +++ b/freebsd/sys/dev/e1000/e1000_phy.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -116,6 +116,10 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw); s32 e1000_get_cable_length_82577(struct e1000_hw *hw); s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); +s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data); +s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data, + bool line_override); +bool e1000_is_mphy_ready(struct e1000_hw *hw); #define E1000_MAX_PHY_ADDR 8 @@ -140,7 +144,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); #define GS40G_MAC_LB 0x4140 #define GS40G_MAC_SPEED_1G 0X0006 #define GS40G_COPPER_SPEC 0x0010 -#define GS40G_CS_POWER_DOWN 0x0002 /* BM/HV Specific Registers */ #define BM_PORT_CTRL_PAGE 769 @@ -170,7 +173,7 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); #define I82577_ADDR_REG 16 #define I82577_CFG_REG 22 #define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) -#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ +#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift */ #define I82577_CTRL_REG 23 /* 82577 specific PHY registers */ @@ -201,6 +204,12 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); #define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */ #define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect */ +#define E1000_MPHY_DIS_ACCESS 0x80000000 /* disable_access bit */ +#define E1000_MPHY_ENA_ACCESS 0x40000000 /* enable_access bit */ +#define E1000_MPHY_BUSY 0x00010000 /* busy bit */ +#define E1000_MPHY_ADDRESS_FNC_OVERRIDE 0x20000000 /* fnc_override bit */ +#define E1000_MPHY_ADDRESS_MASK 0x0000FFFF /* address mask */ + /* BM PHY Copper Specific Control 1 */ #define BM_CS_CTRL1 16 @@ -216,6 +225,7 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); #define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 #define HV_M_STATUS_SPEED_MASK 0x0300 #define HV_M_STATUS_SPEED_1000 0x0200 +#define HV_M_STATUS_SPEED_100 0x0100 #define HV_M_STATUS_LINK_UP 0x0040 #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 @@ -247,7 +257,7 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); #define IGP02E1000_PHY_AGC_C 0x14B1 #define IGP02E1000_PHY_AGC_D 0x18B1 -#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */ +#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course=15:13, Fine=12:9 */ #define IGP02E1000_AGC_LENGTH_MASK 0x7F #define IGP02E1000_AGC_RANGE 15 @@ -267,8 +277,8 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data); #define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */ #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 -#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ -#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */ +#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Ctrl */ +#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Ctrl */ #define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */ /* IFE PHY Extended Status Control */ diff --git a/freebsd/sys/dev/e1000/e1000_regs.h b/freebsd/sys/dev/e1000/e1000_regs.h index 516d377a..5c2e3f78 100644 --- a/freebsd/sys/dev/e1000/e1000_regs.h +++ b/freebsd/sys/dev/e1000/e1000_regs.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,11 +50,16 @@ #define E1000_BARCTRL 0x5BBC /* BAR ctrl reg */ #define E1000_BARCTRL_FLSIZE 0x0700 /* BAR ctrl Flsize */ #define E1000_BARCTRL_CSRSIZE 0x2000 /* BAR ctrl CSR size */ +#define E1000_MPHY_ADDR_CTRL 0x0024 /* GbE MPHY Address Control */ +#define E1000_MPHY_DATA 0x0E10 /* GBE MPHY Data */ +#define E1000_MPHY_STAT 0x0E0C /* GBE MPHY Statistics */ +#define E1000_PPHY_CTRL 0x5b48 /* PCIe PHY Control */ #define E1000_I350_BARCTRL 0x5BFC /* BAR ctrl reg */ #define E1000_I350_DTXMXPKTSZ 0x355C /* Maximum sent packet size reg*/ #define E1000_SCTL 0x00024 /* SerDes Control - RW */ #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ +#define E1000_FEXT 0x0002C /* Future Extended - RW */ #define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */ #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ @@ -94,6 +99,7 @@ #define E1000_TBT 0x00448 /* Tx Burst Timer - RW */ #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ #define E1000_LEDCTL 0x00E00 /* LED Control - RW */ +#define E1000_LEDMUX 0x08130 /* LED MUX Control */ #define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ #define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ #define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */ @@ -103,6 +109,7 @@ #define E1000_PBECCSTS 0x0100C /* Packet Buffer ECC Status - RW */ #define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ #define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ +#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */ #define E1000_FLASHT 0x01028 /* FLASH Timer Register */ #define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ #define E1000_FLSWCTL 0x01030 /* FLASH control register */ @@ -152,6 +159,8 @@ #define E1000_PBRWAC 0x024E8 /* Rx packet buffer wrap around counter - RO */ #define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */ #define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */ +#define E1000_EMIADD 0x10 /* Extended Memory Indirect Address */ +#define E1000_EMIDATA 0x11 /* Extended Memory Indirect Data */ #define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */ #define E1000_I210_FLMNGCTL 0x12038 #define E1000_I210_FLMNGDATA 0x1203C @@ -208,6 +217,9 @@ /* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */ #define E1000_I210_TXPBS_SIZE(_n, _s) ((_s) << (6 * _n)) +#define E1000_MMDAC 13 /* MMD Access Control */ +#define E1000_MMDAAD 14 /* MMD Access Address/Data */ + /* Convenience macros * * Note: "_n" is the queue number of the register to be written to. @@ -484,8 +496,6 @@ #define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */ #define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ #define E1000_HOST_IF 0x08800 /* Host Interface */ -#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ -#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ #define E1000_HIBBA 0x8F40 /* Host Interface Buffer Base Address */ /* Flexible Host Filter Table */ #define E1000_FHFT(_n) (0x09000 + ((_n) * 0x100)) diff --git a/freebsd/sys/dev/e1000/e1000_vf.c b/freebsd/sys/dev/e1000/e1000_vf.c index e525795d..17fd7cb0 100644 --- a/freebsd/sys/dev/e1000/e1000_vf.c +++ b/freebsd/sys/dev/e1000/e1000_vf.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -51,7 +51,7 @@ static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, static s32 e1000_init_hw_vf(struct e1000_hw *hw); static s32 e1000_reset_hw_vf(struct e1000_hw *hw); static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32); -static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32); +static int e1000_rar_set_vf(struct e1000_hw *, u8 *, u32); static s32 e1000_read_mac_addr_vf(struct e1000_hw *); /** @@ -161,7 +161,7 @@ void e1000_init_function_pointers_vf(struct e1000_hw *hw) * In addition, the MAC registers to access PHY/NVM don't exist so we don't * even want any SW to attempt to use them. **/ -static s32 e1000_acquire_vf(struct e1000_hw *hw) +static s32 e1000_acquire_vf(struct e1000_hw E1000_UNUSEDARG *hw) { return -E1000_ERR_PHY; } @@ -174,7 +174,7 @@ static s32 e1000_acquire_vf(struct e1000_hw *hw) * In addition, the MAC registers to access PHY/NVM don't exist so we don't * even want any SW to attempt to use them. **/ -static void e1000_release_vf(struct e1000_hw *hw) +static void e1000_release_vf(struct e1000_hw E1000_UNUSEDARG *hw) { return; } @@ -185,7 +185,7 @@ static void e1000_release_vf(struct e1000_hw *hw) * * Virtual functions cannot change link. **/ -static s32 e1000_setup_link_vf(struct e1000_hw *hw) +static s32 e1000_setup_link_vf(struct e1000_hw E1000_UNUSEDARG *hw) { DEBUGFUNC("e1000_setup_link_vf"); @@ -322,7 +322,8 @@ static s32 e1000_init_hw_vf(struct e1000_hw *hw) * @addr: pointer to the receive address * @index receive address array register **/ -static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index) +static int e1000_rar_set_vf(struct e1000_hw *hw, u8 *addr, + u32 E1000_UNUSEDARG index) { struct e1000_mbx_info *mbx = &hw->mbx; u32 msgbuf[3]; @@ -343,6 +344,8 @@ static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index) if (!ret_val && (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK))) e1000_read_mac_addr_vf(hw); + + return E1000_SUCCESS; } /** diff --git a/freebsd/sys/dev/e1000/e1000_vf.h b/freebsd/sys/dev/e1000/e1000_vf.h index 0ee73aec..2a780741 100644 --- a/freebsd/sys/dev/e1000/e1000_vf.h +++ b/freebsd/sys/dev/e1000/e1000_vf.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2010, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -41,48 +41,50 @@ struct e1000_hw; -#define E1000_DEV_ID_82576_VF 0x10CA -#define E1000_DEV_ID_I350_VF 0x1520 +#define E1000_DEV_ID_82576_VF 0x10CA +#define E1000_DEV_ID_I350_VF 0x1520 -#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */ +#define E1000_VF_INIT_TIMEOUT 200 /* Num of retries to clear RSTI */ /* Additional Descriptor Control definitions */ -#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */ -#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */ +#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */ +#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */ /* SRRCTL bit definitions */ -#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */ -#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00 -#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */ -#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000 -#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 -#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000 -#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 -#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000 +#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \ + (0x0C00C + ((_n) * 0x40))) +#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */ +#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00 +#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */ +#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000 +#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 +#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000 +#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 +#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000 #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 -#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 -#define E1000_SRRCTL_DROP_EN 0x80000000 +#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 +#define E1000_SRRCTL_DROP_EN 0x80000000 -#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F -#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 +#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F +#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 /* Interrupt Defines */ -#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ -#define E1000_EITR(_n) (0x01680 + ((_n) << 2)) -#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ -#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ -#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ -#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */ -#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */ -#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */ -#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */ -#define E1000_IVAR_VALID 0x80 +#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ +#define E1000_EITR(_n) (0x01680 + ((_n) << 2)) +#define E1000_EICS 0x01520 /* Ext. Intr Cause Set -W0 */ +#define E1000_EIMS 0x01524 /* Ext. Intr Mask Set/Read -RW */ +#define E1000_EIMC 0x01528 /* Ext. Intr Mask Clear -WO */ +#define E1000_EIAC 0x0152C /* Ext. Intr Auto Clear -RW */ +#define E1000_EIAM 0x01530 /* Ext. Intr Ack Auto Clear Mask -RW */ +#define E1000_IVAR0 0x01700 /* Intr Vector Alloc (array) -RW */ +#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes -RW */ +#define E1000_IVAR_VALID 0x80 /* Receive Descriptor - Advanced */ union e1000_adv_rx_desc { struct { - u64 pkt_addr; /* Packet buffer address */ - u64 hdr_addr; /* Header buffer address */ + u64 pkt_addr; /* Packet buffer address */ + u64 hdr_addr; /* Header buffer address */ } read; struct { struct { @@ -96,23 +98,23 @@ union e1000_adv_rx_desc { } hs_rss; } lo_dword; union { - u32 rss; /* RSS Hash */ + u32 rss; /* RSS Hash */ struct { - u16 ip_id; /* IP id */ - u16 csum; /* Packet Checksum */ + u16 ip_id; /* IP id */ + u16 csum; /* Packet Checksum */ } csum_ip; } hi_dword; } lower; struct { - u32 status_error; /* ext status/error */ - u16 length; /* Packet length */ - u16 vlan; /* VLAN tag */ + u32 status_error; /* ext status/error */ + u16 length; /* Packet length */ + u16 vlan; /* VLAN tag */ } upper; } wb; /* writeback */ }; -#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 -#define E1000_RXDADV_HDRBUFLEN_SHIFT 5 +#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 +#define E1000_RXDADV_HDRBUFLEN_SHIFT 5 /* Transmit Descriptor - Advanced */ union e1000_adv_tx_desc { @@ -129,15 +131,15 @@ union e1000_adv_tx_desc { }; /* Adv Transmit Descriptor Config Masks */ -#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */ -#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ -#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */ -#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */ -#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */ -#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */ -#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */ -#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */ +#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */ +#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ +#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */ +#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ +#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */ +#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */ +#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */ +#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */ +#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */ /* Context descriptors */ struct e1000_adv_tx_context_desc { @@ -147,11 +149,11 @@ struct e1000_adv_tx_context_desc { u32 mss_l4len_idx; }; -#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ -#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ -#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ -#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ -#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ +#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ +#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ +#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ +#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ +#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ enum e1000_mac_type { e1000_undefined = 0, @@ -206,7 +208,7 @@ struct e1000_mac_operations { s32 (*init_hw)(struct e1000_hw *); s32 (*setup_link)(struct e1000_hw *); void (*write_vfta)(struct e1000_hw *, u32, u32); - void (*rar_set)(struct e1000_hw *, u8*, u32); + int (*rar_set)(struct e1000_hw *, u8*, u32); s32 (*read_mac_addr)(struct e1000_hw *); }; diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c index 2a3fe54a..05d7fbc2 100644 --- a/freebsd/sys/dev/e1000/if_em.c +++ b/freebsd/sys/dev/e1000/if_em.c @@ -2,7 +2,7 @@ /****************************************************************************** - Copyright (c) 2001-2013, Intel Corporation + Copyright (c) 2001-2014, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -97,7 +97,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "7.3.8"; +char em_driver_version[] = "7.4.2"; /********************************************************************* * PCI Device ID Table @@ -181,6 +181,10 @@ static em_vendor_info_t em_vendor_info_array[] = PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_PCH_LPTLP_I218_V, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_I218_LM2, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_I218_V2, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_I218_LM3, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_PCH_I218_V3, PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ { 0, 0, 0, 0, 0} }; @@ -699,6 +703,9 @@ em_attach(device_t dev) goto err_late; } + /* Disable ULP support */ + e1000_disable_ulp_lpt_lp(hw, TRUE); + /* ** Do interrupt configuration */ @@ -1825,7 +1832,6 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp) int nsegs, i, j, first, last = 0; int error, do_tso, tso_desc = 0, remap = 1; -retry: m_head = *m_headp; txd_upper = txd_lower = txd_used = txd_saved = 0; do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0); @@ -1951,6 +1957,7 @@ retry: tx_buffer_mapped = tx_buffer; map = tx_buffer->map; +retry: error = bus_dmamap_load_mbuf_sg(txr->txtag, map, *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); @@ -4060,8 +4067,7 @@ em_allocate_receive_buffers(struct rx_ring *rxr) rxbuf = rxr->rx_buffers; for (int i = 0; i < adapter->num_rx_desc; i++, rxbuf++) { rxbuf = &rxr->rx_buffers[i]; - error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT, - &rxbuf->map); + error = bus_dmamap_create(rxr->rxtag, 0, &rxbuf->map); if (error) { device_printf(dev, "%s: bus_dmamap_create failed: %d\n", __func__, error); @@ -4468,6 +4474,7 @@ em_rxeof(struct rx_ring *rxr, int count, int *done) em_rx_discard(rxr, i); goto next_desc; } + bus_dmamap_unload(rxr->rxtag, rxr->rx_buffers[i].map); /* Assign correct length to the current fragment */ mp = rxr->rx_buffers[i].m_head; @@ -4554,6 +4561,8 @@ em_rx_discard(struct rx_ring *rxr, int i) struct em_buffer *rbuf; rbuf = &rxr->rx_buffers[i]; + bus_dmamap_unload(rxr->rxtag, rbuf->map); + /* Free any previous pieces */ if (rxr->fmp != NULL) { rxr->fmp->m_flags |= M_PKTHDR; @@ -5673,7 +5682,7 @@ em_set_sysctl_value(struct adapter *adapter, const char *name, *limit = value; SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), - OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); + OID_AUTO, name, CTLFLAG_RW, limit, value, description); } diff --git a/freebsd/sys/dev/e1000/if_igb.c b/freebsd/sys/dev/e1000/if_igb.c index 09da15ca..27ae386c 100644 --- a/freebsd/sys/dev/e1000/if_igb.c +++ b/freebsd/sys/dev/e1000/if_igb.c @@ -103,7 +103,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 2.3.10"; +char igb_driver_version[] = "version - 2.4.0"; /********************************************************************* @@ -157,10 +157,19 @@ static igb_vendor_info_t igb_vendor_info_array[] = { 0x8086, E1000_DEV_ID_I210_COPPER_IT, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_I210_COPPER_OEM1, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_COPPER_FLASHLESS, + PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_SERDES_FLASHLESS, + PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_I210_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_I210_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_I210_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_I211_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I354_BACKPLANE_1GBPS, + PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I354_BACKPLANE_2_5GBPS, + PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I354_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ { 0, 0, 0, 0, 0} }; @@ -235,9 +244,10 @@ static __inline void igb_rx_input(struct rx_ring *, static bool igb_rxeof(struct igb_queue *, int, int *); static void igb_rx_checksum(u32, struct mbuf *, u32); -static bool igb_tx_ctx_setup(struct tx_ring *, struct mbuf *); -static bool igb_tso_setup(struct tx_ring *, struct mbuf *, int, - struct ip *, struct tcphdr *); +static int igb_tx_ctx_setup(struct tx_ring *, + struct mbuf *, u32 *, u32 *); +static int igb_tso_setup(struct tx_ring *, + struct mbuf *, u32 *, u32 *); static void igb_set_promisc(struct adapter *); static void igb_disable_promisc(struct adapter *); static void igb_set_multi(struct adapter *); @@ -353,7 +363,7 @@ TUNABLE_INT("hw.igb.max_interrupt_rate", &igb_max_interrupt_rate); SYSCTL_INT(_hw_igb, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN, &igb_max_interrupt_rate, 0, "Maximum interrupts per second"); -#if __FreeBSD_version >= 800000 +#ifndef IGB_LEGACY_TX /* ** Tuneable number of buffers in the buf-ring (drbr_xxx) */ @@ -559,7 +569,6 @@ igb_attach(device_t dev) * standard ethernet sized frames. */ adapter->max_frame_size = ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE; - adapter->min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE; /* ** Allocate and Setup Queues @@ -605,8 +614,12 @@ igb_attach(device_t dev) OID_AUTO, "eee_disabled", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, igb_sysctl_eee, "I", "Disable Energy Efficient Ethernet"); - if (adapter->hw.phy.media_type == e1000_media_type_copper) - e1000_set_eee_i350(&adapter->hw); + if (adapter->hw.phy.media_type == e1000_media_type_copper) { + if (adapter->hw.mac.type == e1000_i354) + e1000_set_eee_i354(&adapter->hw); + else + e1000_set_eee_i350(&adapter->hw); + } } /* @@ -977,12 +990,12 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m) if (err) return (err); if (IGB_TX_TRYLOCK(txr)) { - err = igb_mq_start_locked(ifp, txr); + igb_mq_start_locked(ifp, txr); IGB_TX_UNLOCK(txr); } else taskqueue_enqueue(que->tq, &txr->txq_task); - return (err); + return (0); } static int @@ -990,7 +1003,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) { struct adapter *adapter = txr->adapter; struct mbuf *next; - int err = 0, enq; + int err = 0, enq = 0; IGB_TX_LOCK_ASSERT(txr); @@ -998,7 +1011,6 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) adapter->link_active == 0) return (ENETDOWN); - enq = 0; /* Process the queue */ while ((next = drbr_peek(ifp, txr->br)) != NULL) { @@ -1226,6 +1238,10 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_capenable ^= IFCAP_TSO4; reinit = 1; } + if (mask & IFCAP_TSO6) { + ifp->if_capenable ^= IFCAP_TSO6; + reinit = 1; + } if (mask & IFCAP_VLAN_HWTAGGING) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; reinit = 1; @@ -1303,7 +1319,7 @@ igb_init_locked(struct adapter *adapter) #endif } - if (ifp->if_capenable & IFCAP_TSO4) + if (ifp->if_capenable & IFCAP_TSO) ifp->if_hwassist |= CSUM_TSO; /* Configure for OS presence */ @@ -1367,8 +1383,12 @@ igb_init_locked(struct adapter *adapter) } /* Set Energy Efficient Ethernet */ - if (adapter->hw.phy.media_type == e1000_media_type_copper) - e1000_set_eee_i350(&adapter->hw); + if (adapter->hw.phy.media_type == e1000_media_type_copper) { + if (adapter->hw.mac.type == e1000_i354) + e1000_set_eee_i354(&adapter->hw); + else + e1000_set_eee_i350(&adapter->hw); + } } static void @@ -1736,6 +1756,9 @@ igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) case 1000: ifmr->ifm_active |= IFM_1000_T; break; + case 2500: + ifmr->ifm_active |= IFM_2500_SX; + break; } if (adapter->link_duplex == FULL_DUPLEX) @@ -1812,273 +1835,142 @@ igb_media_change(struct ifnet *ifp) static int igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) { - struct adapter *adapter = txr->adapter; - bus_dma_segment_t segs[IGB_MAX_SCATTER]; - bus_dmamap_t map; - struct igb_tx_buffer *tx_buffer, *tx_buffer_mapped; - union e1000_adv_tx_desc *txd = NULL; - struct mbuf *m_head = *m_headp; - struct ether_vlan_header *eh = NULL; - struct ip *ip = NULL; - struct tcphdr *th = NULL; - u32 hdrlen, cmd_type_len, olinfo_status = 0; - int ehdrlen, poff; - int nsegs, i, first, last = 0; - int error, do_tso, remap = 1; - - /* Set basic descriptor constants */ - cmd_type_len = E1000_ADVTXD_DTYP_DATA; - cmd_type_len |= E1000_ADVTXD_DCMD_IFCS | E1000_ADVTXD_DCMD_DEXT; - if (m_head->m_flags & M_VLANTAG) - cmd_type_len |= E1000_ADVTXD_DCMD_VLE; + struct adapter *adapter = txr->adapter; + u32 olinfo_status = 0, cmd_type_len; + int i, j, error, nsegs; + int first; + bool remap = TRUE; + struct mbuf *m_head; + bus_dma_segment_t segs[IGB_MAX_SCATTER]; + bus_dmamap_t map; + struct igb_tx_buf *txbuf; + union e1000_adv_tx_desc *txd = NULL; -retry: m_head = *m_headp; - do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0); - hdrlen = ehdrlen = poff = 0; - /* - * Intel recommends entire IP/TCP header length reside in a single - * buffer. If multiple descriptors are used to describe the IP and - * TCP header, each descriptor should describe one or more - * complete headers; descriptors referencing only parts of headers - * are not supported. If all layer headers are not coalesced into - * a single buffer, each buffer should not cross a 4KB boundary, - * or be larger than the maximum read request size. - * Controller also requires modifing IP/TCP header to make TSO work - * so we firstly get a writable mbuf chain then coalesce ethernet/ - * IP/TCP header into a single buffer to meet the requirement of - * controller. This also simplifies IP/TCP/UDP checksum offloading - * which also has similiar restrictions. - */ - if (do_tso || m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) { - if (do_tso || (m_head->m_next != NULL && - m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)) { - if (M_WRITABLE(*m_headp) == 0) { - m_head = m_dup(*m_headp, M_NOWAIT); - m_freem(*m_headp); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - *m_headp = m_head; - } - } - /* - * Assume IPv4, we don't have TSO/checksum offload support - * for IPv6 yet. - */ - ehdrlen = sizeof(struct ether_header); - m_head = m_pullup(m_head, ehdrlen); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - eh = mtod(m_head, struct ether_vlan_header *); - if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { - ehdrlen = sizeof(struct ether_vlan_header); - m_head = m_pullup(m_head, ehdrlen); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - } - m_head = m_pullup(m_head, ehdrlen + sizeof(struct ip)); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - ip = (struct ip *)(mtod(m_head, char *) + ehdrlen); - poff = ehdrlen + (ip->ip_hl << 2); - if (do_tso) { - m_head = m_pullup(m_head, poff + sizeof(struct tcphdr)); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - /* - * The pseudo TCP checksum does not include TCP payload - * length so driver should recompute the checksum here - * what hardware expect to see. This is adherence of - * Microsoft's Large Send specification. - */ - th = (struct tcphdr *)(mtod(m_head, char *) + poff); - th->th_sum = in_pseudo(ip->ip_src.s_addr, - ip->ip_dst.s_addr, htons(IPPROTO_TCP)); - /* Keep track of the full header length */ - hdrlen = poff + (th->th_off << 2); - } else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) { - m_head = m_pullup(m_head, poff + sizeof(struct tcphdr)); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - th = (struct tcphdr *)(mtod(m_head, char *) + poff); - m_head = m_pullup(m_head, poff + (th->th_off << 2)); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - ip = (struct ip *)(mtod(m_head, char *) + ehdrlen); - th = (struct tcphdr *)(mtod(m_head, char *) + poff); - } else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) { - m_head = m_pullup(m_head, poff + sizeof(struct udphdr)); - if (m_head == NULL) { - *m_headp = NULL; - return (ENOBUFS); - } - ip = (struct ip *)(mtod(m_head, char *) + ehdrlen); - } - *m_headp = m_head; - } + /* Basic descriptor defines */ + cmd_type_len = (E1000_ADVTXD_DTYP_DATA | + E1000_ADVTXD_DCMD_IFCS | E1000_ADVTXD_DCMD_DEXT); + + if (m_head->m_flags & M_VLANTAG) + cmd_type_len |= E1000_ADVTXD_DCMD_VLE; + + /* + * Important to capture the first descriptor + * used because it will contain the index of + * the one we tell the hardware to report back + */ + first = txr->next_avail_desc; + txbuf = &txr->tx_buffers[first]; + map = txbuf->map; /* - * Map the packet for DMA - * - * Capture the first descriptor index, - * this descriptor will have the index - * of the EOP which is the only one that - * now gets a DONE bit writeback. + * Map the packet for DMA. */ - first = txr->next_avail_desc; - tx_buffer = &txr->tx_buffers[first]; - tx_buffer_mapped = tx_buffer; - map = tx_buffer->map; - +retry: error = bus_dmamap_load_mbuf_sg(txr->txtag, map, *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); - /* - * There are two types of errors we can (try) to handle: - * - EFBIG means the mbuf chain was too long and bus_dma ran - * out of segments. Defragment the mbuf chain and try again. - * - ENOMEM means bus_dma could not obtain enough bounce buffers - * at this point in time. Defer sending and try again later. - * All other errors, in particular EINVAL, are fatal and prevent the - * mbuf chain from ever going through. Drop it and report error. - */ - if (error == EFBIG && remap) { + if (__predict_false(error)) { struct mbuf *m; - m = m_defrag(*m_headp, M_NOWAIT); - if (m == NULL) { - adapter->mbuf_defrag_failed++; + switch (error) { + case EFBIG: + /* Try it again? - one try */ + if (remap == TRUE) { + remap = FALSE; + m = m_defrag(*m_headp, M_NOWAIT); + if (m == NULL) { + adapter->mbuf_defrag_failed++; + m_freem(*m_headp); + *m_headp = NULL; + return (ENOBUFS); + } + *m_headp = m; + goto retry; + } else + return (error); + case ENOMEM: + txr->no_tx_dma_setup++; + return (error); + default: + txr->no_tx_dma_setup++; m_freem(*m_headp); *m_headp = NULL; - return (ENOBUFS); + return (error); } - *m_headp = m; - - /* Try it again, but only once */ - remap = 0; - goto retry; - } else if (error == ENOMEM) { - adapter->no_tx_dma_setup++; - return (error); - } else if (error != 0) { - adapter->no_tx_dma_setup++; - m_freem(*m_headp); - *m_headp = NULL; - return (error); } - /* - ** Make sure we don't overrun the ring, - ** we need nsegs descriptors and one for - ** the context descriptor used for the - ** offloads. - */ - if ((nsegs + 1) > (txr->tx_avail - 2)) { - txr->no_desc_avail++; + /* Make certain there are enough descriptors */ + if (nsegs > txr->tx_avail - 2) { + txr->no_desc_avail++; bus_dmamap_unload(txr->txtag, map); return (ENOBUFS); - } + } m_head = *m_headp; - /* Do hardware assists: - * Set up the context descriptor, used - * when any hardware offload is done. - * This includes CSUM, VLAN, and TSO. - * It will use the first descriptor. - */ - - if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { - if (igb_tso_setup(txr, m_head, ehdrlen, ip, th)) { - cmd_type_len |= E1000_ADVTXD_DCMD_TSE; - olinfo_status |= E1000_TXD_POPTS_IXSM << 8; - olinfo_status |= E1000_TXD_POPTS_TXSM << 8; - } else - return (ENXIO); - } else if (igb_tx_ctx_setup(txr, m_head)) - olinfo_status |= E1000_TXD_POPTS_TXSM << 8; - - /* Calculate payload length */ - olinfo_status |= ((m_head->m_pkthdr.len - hdrlen) - << E1000_ADVTXD_PAYLEN_SHIFT); + /* + ** Set up the appropriate offload context + ** this will consume the first descriptor + */ + error = igb_tx_ctx_setup(txr, m_head, &cmd_type_len, &olinfo_status); + if (__predict_false(error)) { + m_freem(*m_headp); + *m_headp = NULL; + return (error); + } /* 82575 needs the queue index added */ if (adapter->hw.mac.type == e1000_82575) olinfo_status |= txr->me << 4; - /* Set up our transmit descriptors */ i = txr->next_avail_desc; - for (int j = 0; j < nsegs; j++) { - bus_size_t seg_len; - bus_addr_t seg_addr; - - tx_buffer = &txr->tx_buffers[i]; - txd = (union e1000_adv_tx_desc *)&txr->tx_base[i]; - seg_addr = segs[j].ds_addr; - seg_len = segs[j].ds_len; - - txd->read.buffer_addr = htole64(seg_addr); - txd->read.cmd_type_len = htole32(cmd_type_len | seg_len); + for (j = 0; j < nsegs; j++) { + bus_size_t seglen; + bus_addr_t segaddr; + + txbuf = &txr->tx_buffers[i]; + txd = &txr->tx_base[i]; + seglen = segs[j].ds_len; + segaddr = htole64(segs[j].ds_addr); + + txd->read.buffer_addr = segaddr; + txd->read.cmd_type_len = htole32(E1000_TXD_CMD_IFCS | + cmd_type_len | seglen); txd->read.olinfo_status = htole32(olinfo_status); - last = i; - if (++i == adapter->num_tx_desc) + + if (++i == txr->num_desc) i = 0; - tx_buffer->m_head = NULL; - tx_buffer->next_eop = -1; } - txr->next_avail_desc = i; + txd->read.cmd_type_len |= + htole32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS); txr->tx_avail -= nsegs; - tx_buffer->m_head = m_head; + txr->next_avail_desc = i; + txbuf->m_head = m_head; /* ** Here we swap the map so the last descriptor, ** which gets the completion interrupt has the ** real map, and the first descriptor gets the ** unused map from this descriptor. */ - tx_buffer_mapped->map = tx_buffer->map; - tx_buffer->map = map; - bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE); + txr->tx_buffers[first].map = txbuf->map; + txbuf->map = map; + bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE); - /* - * Last Descriptor of Packet - * needs End Of Packet (EOP) - * and Report Status (RS) - */ - txd->read.cmd_type_len |= - htole32(E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS); - /* - * Keep track in the first buffer which - * descriptor will be written back - */ - tx_buffer = &txr->tx_buffers[first]; - tx_buffer->next_eop = last; - /* Update the watchdog time early and often */ - txr->watchdog_time = ticks; + /* Set the EOP descriptor that will be marked done */ + txbuf = &txr->tx_buffers[first]; + txbuf->eop = txd; + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* - * Advance the Transmit Descriptor Tail (TDT), this tells the E1000 - * that this frame is available to transmit. + * Advance the Transmit Descriptor Tail (Tdt), this tells the + * hardware that this frame is available to transmit. */ - bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + ++txr->total_packets; E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), i); - ++txr->tx_packets; return (0); } @@ -2347,6 +2239,17 @@ igb_update_link_status(struct adapter *adapter) if ((ctrl & E1000_CTRL_EXT_LINK_MODE_GMII) && (thstat & E1000_THSTAT_LINK_THROTTLE)) device_printf(dev, "Link: thermal downshift\n"); + /* Delay Link Up for Phy update */ + if (((hw->mac.type == e1000_i210) || + (hw->mac.type == e1000_i211)) && + (hw->phy.id == I210_I_PHY_ID)) + msec_delay(I210_LINK_DELAY); + /* Reset if the media type changed. */ + if (hw->dev_spec._82575.media_changed) { + hw->dev_spec._82575.media_changed = false; + adapter->flags |= IGB_MEDIA_RESET; + igb_reset(adapter); + } /* This can sleep */ if_link_state_change(ifp, LINK_STATE_UP); } else if (!link_check && (adapter->link_active == 1)) { @@ -2479,6 +2382,9 @@ igb_allocate_legacy(struct adapter *adapter) { device_t dev = adapter->dev; struct igb_queue *que = adapter->queues; +#ifndef IGB_LEGACY_TX + struct tx_ring *txr = adapter->tx_rings; +#endif int error, rid = 0; /* Turn off all interrupts */ @@ -2498,7 +2404,7 @@ igb_allocate_legacy(struct adapter *adapter) } #ifndef IGB_LEGACY_TX - TASK_INIT(&que->txr->txq_task, 0, igb_deferred_mq_start, que->txr); + TASK_INIT(&txr->txq_task, 0, igb_deferred_mq_start, txr); #endif /* @@ -2635,6 +2541,7 @@ igb_configure_queues(struct adapter *adapter) switch (adapter->hw.mac.type) { case e1000_82580: case e1000_i350: + case e1000_i354: case e1000_i210: case e1000_i211: case e1000_vfadapt: @@ -2820,7 +2727,7 @@ mem: if (adapter->msix_mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, - PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem); + adapter->memrid, adapter->msix_mem); if (adapter->pci_mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, @@ -2834,8 +2741,8 @@ mem: static int igb_setup_msix(struct adapter *adapter) { - device_t dev = adapter->dev; - int rid, want, queues, msgs, maxqueues; + device_t dev = adapter->dev; + int bar, want, queues, msgs, maxqueues; /* tuneable override */ if (igb_enable_msix == 0) @@ -2845,9 +2752,17 @@ igb_setup_msix(struct adapter *adapter) msgs = pci_msix_count(dev); if (msgs == 0) goto msi; - rid = PCIR_BAR(IGB_MSIX_BAR); + /* + ** Some new devices, as with ixgbe, now may + ** use a different BAR, so we need to keep + ** track of which is used. + */ + adapter->memrid = PCIR_BAR(IGB_MSIX_BAR); + bar = pci_read_config(dev, adapter->memrid, 4); + if (bar == 0) /* use next bar */ + adapter->memrid += 4; adapter->msix_mem = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE); + SYS_RES_MEMORY, &adapter->memrid, RF_ACTIVE); if (adapter->msix_mem == NULL) { /* May not be enabled */ device_printf(adapter->dev, @@ -2870,6 +2785,7 @@ igb_setup_msix(struct adapter *adapter) case e1000_82576: case e1000_82580: case e1000_i350: + case e1000_i354: maxqueues = 8; break; case e1000_i210: @@ -2885,8 +2801,9 @@ igb_setup_msix(struct adapter *adapter) if (queues > maxqueues) queues = maxqueues; - /* reflect correct sysctl value */ - igb_num_queues = queues; + /* Manual override */ + if (igb_num_queues != 0) + queues = igb_num_queues; /* ** One vector (RX/TX pair) per queue @@ -2929,6 +2846,129 @@ msi: return (0); } +/********************************************************************* + * + * Initialize the DMA Coalescing feature + * + **********************************************************************/ +static void +igb_init_dmac(struct adapter *adapter, u32 pba) +{ + device_t dev = adapter->dev; + struct e1000_hw *hw = &adapter->hw; + u32 dmac, reg = ~E1000_DMACR_DMAC_EN; + u16 hwm; + + if (hw->mac.type == e1000_i211) + return; + + if (hw->mac.type > e1000_82580) { + + if (adapter->dmac == 0) { /* Disabling it */ + E1000_WRITE_REG(hw, E1000_DMACR, reg); + return; + } else + device_printf(dev, "DMA Coalescing enabled\n"); + + /* Set starting threshold */ + E1000_WRITE_REG(hw, E1000_DMCTXTH, 0); + + hwm = 64 * pba - adapter->max_frame_size / 16; + if (hwm < 64 * (pba - 6)) + hwm = 64 * (pba - 6); + reg = E1000_READ_REG(hw, E1000_FCRTC); + reg &= ~E1000_FCRTC_RTH_COAL_MASK; + reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT) + & E1000_FCRTC_RTH_COAL_MASK); + E1000_WRITE_REG(hw, E1000_FCRTC, reg); + + + dmac = pba - adapter->max_frame_size / 512; + if (dmac < pba - 10) + dmac = pba - 10; + reg = E1000_READ_REG(hw, E1000_DMACR); + reg &= ~E1000_DMACR_DMACTHR_MASK; + reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT) + & E1000_DMACR_DMACTHR_MASK); + + /* transition to L0x or L1 if available..*/ + reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK); + + /* Check if status is 2.5Gb backplane connection + * before configuration of watchdog timer, which is + * in msec values in 12.8usec intervals + * watchdog timer= msec values in 32usec intervals + * for non 2.5Gb connection + */ + if (hw->mac.type == e1000_i354) { + int status = E1000_READ_REG(hw, E1000_STATUS); + if ((status & E1000_STATUS_2P5_SKU) && + (!(status & E1000_STATUS_2P5_SKU_OVER))) + reg |= ((adapter->dmac * 5) >> 6); + else + reg |= (adapter->dmac >> 5); + } else { + reg |= (adapter->dmac >> 5); + } + + E1000_WRITE_REG(hw, E1000_DMACR, reg); + +#ifdef I210_OBFF_SUPPORT + /* + * Set the OBFF Rx threshold to DMA Coalescing Rx + * threshold - 2KB and enable the feature in the + * hardware for I210. + */ + if (hw->mac.type == e1000_i210) { + int obff = dmac - 2; + reg = E1000_READ_REG(hw, E1000_DOBFFCTL); + reg &= ~E1000_DOBFFCTL_OBFFTHR_MASK; + reg |= (obff & E1000_DOBFFCTL_OBFFTHR_MASK) + | E1000_DOBFFCTL_EXIT_ACT_MASK; + E1000_WRITE_REG(hw, E1000_DOBFFCTL, reg); + } +#endif + E1000_WRITE_REG(hw, E1000_DMCRTRH, 0); + + /* Set the interval before transition */ + reg = E1000_READ_REG(hw, E1000_DMCTLX); + if (hw->mac.type == e1000_i350) + reg |= IGB_DMCTLX_DCFLUSH_DIS; + /* + ** in 2.5Gb connection, TTLX unit is 0.4 usec + ** which is 0x4*2 = 0xA. But delay is still 4 usec + */ + if (hw->mac.type == e1000_i354) { + int status = E1000_READ_REG(hw, E1000_STATUS); + if ((status & E1000_STATUS_2P5_SKU) && + (!(status & E1000_STATUS_2P5_SKU_OVER))) + reg |= 0xA; + else + reg |= 0x4; + } else { + reg |= 0x4; + } + + E1000_WRITE_REG(hw, E1000_DMCTLX, reg); + + /* free space in tx packet buffer to wake from DMA coal */ + E1000_WRITE_REG(hw, E1000_DMCTXTH, (IGB_TXPBSIZE - + (2 * adapter->max_frame_size)) >> 6); + + /* make low power state decision controlled by DMA coal */ + reg = E1000_READ_REG(hw, E1000_PCIEMISC); + reg &= ~E1000_PCIEMISC_LX_DECISION; + E1000_WRITE_REG(hw, E1000_PCIEMISC, reg); + + } else if (hw->mac.type == e1000_82580) { + u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC); + E1000_WRITE_REG(hw, E1000_PCIEMISC, + reg & ~E1000_PCIEMISC_LX_DECISION); + E1000_WRITE_REG(hw, E1000_DMACR, 0); + } +} + + /********************************************************************* * * Set up an fresh starting state @@ -2965,6 +3005,7 @@ igb_reset(struct adapter *adapter) break; case e1000_82580: case e1000_i350: + case e1000_i354: case e1000_vfadapt_i350: pba = E1000_READ_REG(hw, E1000_RXPBS); pba = e1000_rxpbs_adjust_82580(pba); @@ -3035,70 +3076,19 @@ igb_reset(struct adapter *adapter) e1000_reset_hw(hw); E1000_WRITE_REG(hw, E1000_WUC, 0); + /* Reset for AutoMediaDetect */ + if (adapter->flags & IGB_MEDIA_RESET) { + e1000_setup_init_funcs(hw, TRUE); + e1000_get_bus_info(hw); + adapter->flags &= ~IGB_MEDIA_RESET; + } + if (e1000_init_hw(hw) < 0) device_printf(dev, "Hardware Initialization Failed\n"); /* Setup DMA Coalescing */ - if ((hw->mac.type > e1000_82580) && - (hw->mac.type != e1000_i211)) { - u32 dmac; - u32 reg = ~E1000_DMACR_DMAC_EN; - - if (adapter->dmac == 0) { /* Disabling it */ - E1000_WRITE_REG(hw, E1000_DMACR, reg); - goto reset_out; - } + igb_init_dmac(adapter, pba); - /* Set starting thresholds */ - E1000_WRITE_REG(hw, E1000_DMCTXTH, 0); - E1000_WRITE_REG(hw, E1000_DMCRTRH, 0); - - hwm = 64 * pba - adapter->max_frame_size / 16; - if (hwm < 64 * (pba - 6)) - hwm = 64 * (pba - 6); - reg = E1000_READ_REG(hw, E1000_FCRTC); - reg &= ~E1000_FCRTC_RTH_COAL_MASK; - reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT) - & E1000_FCRTC_RTH_COAL_MASK); - E1000_WRITE_REG(hw, E1000_FCRTC, reg); - - - dmac = pba - adapter->max_frame_size / 512; - if (dmac < pba - 10) - dmac = pba - 10; - reg = E1000_READ_REG(hw, E1000_DMACR); - reg &= ~E1000_DMACR_DMACTHR_MASK; - reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT) - & E1000_DMACR_DMACTHR_MASK); - /* transition to L0x or L1 if available..*/ - reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK); - /* timer = value in adapter->dmac in 32usec intervals */ - reg |= (adapter->dmac >> 5); - E1000_WRITE_REG(hw, E1000_DMACR, reg); - - /* Set the interval before transition */ - reg = E1000_READ_REG(hw, E1000_DMCTLX); - reg |= 0x80000004; - E1000_WRITE_REG(hw, E1000_DMCTLX, reg); - - /* free space in tx packet buffer to wake from DMA coal */ - E1000_WRITE_REG(hw, E1000_DMCTXTH, - (20480 - (2 * adapter->max_frame_size)) >> 6); - - /* make low power state decision controlled by DMA coal */ - reg = E1000_READ_REG(hw, E1000_PCIEMISC); - reg &= ~E1000_PCIEMISC_LX_DECISION; - E1000_WRITE_REG(hw, E1000_PCIEMISC, reg); - device_printf(dev, "DMA Coalescing enabled\n"); - - } else if (hw->mac.type == e1000_82580) { - u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC); - E1000_WRITE_REG(hw, E1000_DMACR, 0); - E1000_WRITE_REG(hw, E1000_PCIEMISC, - reg & ~E1000_PCIEMISC_LX_DECISION); - } - -reset_out: E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); e1000_get_phy_info(hw); e1000_check_for_link(hw); @@ -3142,7 +3132,7 @@ igb_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capabilities = ifp->if_capenable = 0; ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; - ifp->if_capabilities |= IFCAP_TSO4; + ifp->if_capabilities |= IFCAP_TSO; ifp->if_capabilities |= IFCAP_JUMBO_MTU; ifp->if_capenable = ifp->if_capabilities; @@ -3348,6 +3338,7 @@ igb_allocate_queues(struct adapter *adapter) txr = &adapter->tx_rings[i]; txr->adapter = adapter; txr->me = i; + txr->num_desc = adapter->num_tx_desc; /* Initialize the TX lock */ snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)", @@ -3361,7 +3352,7 @@ igb_allocate_queues(struct adapter *adapter) error = ENOMEM; goto err_tx_desc; } - txr->tx_base = (struct e1000_tx_desc *)txr->txdma.dma_vaddr; + txr->tx_base = (union e1000_adv_tx_desc *)txr->txdma.dma_vaddr; bzero((void *)txr->tx_base, tsize); /* Now allocate transmit buffers for the ring */ @@ -3454,7 +3445,7 @@ igb_allocate_transmit_buffers(struct tx_ring *txr) { struct adapter *adapter = txr->adapter; device_t dev = adapter->dev; - struct igb_tx_buffer *txbuf; + struct igb_tx_buf *txbuf; int error, i; /* @@ -3477,7 +3468,7 @@ igb_allocate_transmit_buffers(struct tx_ring *txr) } if (!(txr->tx_buffers = - (struct igb_tx_buffer *) malloc(sizeof(struct igb_tx_buffer) * + (struct igb_tx_buf *) malloc(sizeof(struct igb_tx_buf) * adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO))) { device_printf(dev, "Unable to allocate tx_buffer memory\n"); error = ENOMEM; @@ -3510,7 +3501,7 @@ static void igb_setup_transmit_ring(struct tx_ring *txr) { struct adapter *adapter = txr->adapter; - struct igb_tx_buffer *txbuf; + struct igb_tx_buf *txbuf; int i; #ifdef DEV_NETMAP struct netmap_adapter *na = NA(adapter->ifp); @@ -3546,7 +3537,7 @@ igb_setup_transmit_ring(struct tx_ring *txr) } #endif /* DEV_NETMAP */ /* clear the watch index */ - txbuf->next_eop = -1; + txbuf->eop = NULL; } /* Set number of descriptors available */ @@ -3660,7 +3651,7 @@ static void igb_free_transmit_buffers(struct tx_ring *txr) { struct adapter *adapter = txr->adapter; - struct igb_tx_buffer *tx_buffer; + struct igb_tx_buf *tx_buffer; int i; INIT_DEBUGOUT("free_transmit_ring: begin"); @@ -3707,44 +3698,100 @@ igb_free_transmit_buffers(struct tx_ring *txr) /********************************************************************** * - * Setup work for hardware segmentation offload (TSO) + * Setup work for hardware segmentation offload (TSO) on + * adapters using advanced tx descriptors * **********************************************************************/ -static bool -igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, int ehdrlen, - struct ip *ip, struct tcphdr *th) +static int +igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, + u32 *cmd_type_len, u32 *olinfo_status) { struct adapter *adapter = txr->adapter; struct e1000_adv_tx_context_desc *TXD; - struct igb_tx_buffer *tx_buffer; u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; - u32 mss_l4len_idx = 0; - u16 vtag = 0; - int ctxd, ip_hlen, tcp_hlen; + u32 mss_l4len_idx = 0, paylen; + u16 vtag = 0, eh_type; + int ctxd, ehdrlen, ip_hlen, tcp_hlen; + struct ether_vlan_header *eh; +#ifdef INET6 + struct ip6_hdr *ip6; +#endif +#ifdef INET + struct ip *ip; +#endif + struct tcphdr *th; + + + /* + * Determine where frame payload starts. + * Jump over vlan headers if already present + */ + eh = mtod(mp, struct ether_vlan_header *); + if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { + ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; + eh_type = eh->evl_proto; + } else { + ehdrlen = ETHER_HDR_LEN; + eh_type = eh->evl_encap_proto; + } + + switch (ntohs(eh_type)) { +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); + /* XXX-BZ For now we do not pretend to support ext. hdrs. */ + if (ip6->ip6_nxt != IPPROTO_TCP) + return (ENXIO); + ip_hlen = sizeof(struct ip6_hdr); + ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); + th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen); + th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); + type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6; + break; +#endif +#ifdef INET + case ETHERTYPE_IP: + ip = (struct ip *)(mp->m_data + ehdrlen); + if (ip->ip_p != IPPROTO_TCP) + return (ENXIO); + ip->ip_sum = 0; + ip_hlen = ip->ip_hl << 2; + th = (struct tcphdr *)((caddr_t)ip + ip_hlen); + th->th_sum = in_pseudo(ip->ip_src.s_addr, + ip->ip_dst.s_addr, htons(IPPROTO_TCP)); + type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4; + /* Tell transmit desc to also do IPv4 checksum. */ + *olinfo_status |= E1000_TXD_POPTS_IXSM << 8; + break; +#endif + default: + panic("%s: CSUM_TSO but no supported IP version (0x%04x)", + __func__, ntohs(eh_type)); + break; + } ctxd = txr->next_avail_desc; - tx_buffer = &txr->tx_buffers[ctxd]; TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[ctxd]; - ip->ip_sum = 0; - ip_hlen = ip->ip_hl << 2; tcp_hlen = th->th_off << 2; + /* This is used in the transmit desc in encap */ + paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen; + /* VLAN MACLEN IPLEN */ if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); - vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT); + vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT); } - vlan_macip_lens |= (ehdrlen << E1000_ADVTXD_MACLEN_SHIFT); + vlan_macip_lens |= ehdrlen << E1000_ADVTXD_MACLEN_SHIFT; vlan_macip_lens |= ip_hlen; - TXD->vlan_macip_lens |= htole32(vlan_macip_lens); + TXD->vlan_macip_lens = htole32(vlan_macip_lens); /* ADV DTYPE TUCMD */ type_tucmd_mlhl |= E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DTYP_CTXT; type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_TCP; - type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4; - TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl); + TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl); /* MSS L4LEN IDX */ mss_l4len_idx |= (mp->m_pkthdr.tso_segsz << E1000_ADVTXD_MSS_SHIFT); @@ -3755,57 +3802,65 @@ igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, int ehdrlen, TXD->mss_l4len_idx = htole32(mss_l4len_idx); TXD->seqnum_seed = htole32(0); - tx_buffer->m_head = NULL; - tx_buffer->next_eop = -1; - if (++ctxd == adapter->num_tx_desc) + if (++ctxd == txr->num_desc) ctxd = 0; txr->tx_avail--; txr->next_avail_desc = ctxd; - return TRUE; + *cmd_type_len |= E1000_ADVTXD_DCMD_TSE; + *olinfo_status |= E1000_TXD_POPTS_TXSM << 8; + *olinfo_status |= paylen << E1000_ADVTXD_PAYLEN_SHIFT; + ++txr->tso_tx; + return (0); } - /********************************************************************* * - * Context Descriptor setup for VLAN or CSUM + * Advanced Context Descriptor setup for VLAN, CSUM or TSO * **********************************************************************/ -static bool -igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) +static int +igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, + u32 *cmd_type_len, u32 *olinfo_status) { - struct adapter *adapter = txr->adapter; struct e1000_adv_tx_context_desc *TXD; - struct igb_tx_buffer *tx_buffer; - u32 vlan_macip_lens, type_tucmd_mlhl, mss_l4len_idx; + struct adapter *adapter = txr->adapter; struct ether_vlan_header *eh; - struct ip *ip = NULL; + struct ip *ip; struct ip6_hdr *ip6; - int ehdrlen, ctxd, ip_hlen = 0; - u16 etype, vtag = 0; + u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0, mss_l4len_idx = 0; + int ehdrlen, ip_hlen = 0; + u16 etype; u8 ipproto = 0; - bool offload = TRUE; + int offload = TRUE; + int ctxd = txr->next_avail_desc; + u16 vtag = 0; + + /* First check if TSO is to be used */ + if (mp->m_pkthdr.csum_flags & CSUM_TSO) + return (igb_tso_setup(txr, mp, cmd_type_len, olinfo_status)); if ((mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) == 0) offload = FALSE; - vlan_macip_lens = type_tucmd_mlhl = mss_l4len_idx = 0; - ctxd = txr->next_avail_desc; - tx_buffer = &txr->tx_buffers[ctxd]; + /* Indicate the whole packet as payload when not doing TSO */ + *olinfo_status |= mp->m_pkthdr.len << E1000_ADVTXD_PAYLEN_SHIFT; + + /* Now ready a context descriptor */ TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[ctxd]; /* ** In advanced descriptors the vlan tag must - ** be placed into the context descriptor, thus - ** we need to be here just for that setup. + ** be placed into the context descriptor. Hence + ** we need to make one even if not doing offloads. */ if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT); - } else if (offload == FALSE) - return FALSE; + } else if (offload == FALSE) /* ... no offload to do */ + return (0); /* * Determine where frame payload starts. @@ -3828,16 +3883,13 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) case ETHERTYPE_IP: ip = (struct ip *)(mp->m_data + ehdrlen); ip_hlen = ip->ip_hl << 2; - if (mp->m_len < ehdrlen + ip_hlen) { - offload = FALSE; - break; - } ipproto = ip->ip_p; type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4; break; case ETHERTYPE_IPV6: ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); ip_hlen = sizeof(struct ip6_hdr); + /* XXX-BZ this will go badly in case of ext hdrs. */ ipproto = ip6->ip6_nxt; type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6; break; @@ -3858,6 +3910,7 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) if (mp->m_pkthdr.csum_flags & CSUM_UDP) type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_UDP; break; + #if __FreeBSD_version >= 800000 case IPPROTO_SCTP: if (mp->m_pkthdr.csum_flags & CSUM_SCTP) @@ -3869,29 +3922,28 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) break; } + if (offload) /* For the TX descriptor setup */ + *olinfo_status |= E1000_TXD_POPTS_TXSM << 8; + /* 82575 needs the queue index added */ if (adapter->hw.mac.type == e1000_82575) mss_l4len_idx = txr->me << 4; /* Now copy bits into descriptor */ - TXD->vlan_macip_lens |= htole32(vlan_macip_lens); - TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl); + TXD->vlan_macip_lens = htole32(vlan_macip_lens); + TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl); TXD->seqnum_seed = htole32(0); TXD->mss_l4len_idx = htole32(mss_l4len_idx); - tx_buffer->m_head = NULL; - tx_buffer->next_eop = -1; - /* We've consumed the first desc, adjust counters */ - if (++ctxd == adapter->num_tx_desc) + if (++ctxd == txr->num_desc) ctxd = 0; txr->next_avail_desc = ctxd; --txr->tx_avail; - return (offload); + return (0); } - /********************************************************************** * * Examine each tx_buffer in the used queue. If the hardware is done @@ -3903,89 +3955,103 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) static bool igb_txeof(struct tx_ring *txr) { - struct adapter *adapter = txr->adapter; - int first, last, done, processed; - struct igb_tx_buffer *tx_buffer; - struct e1000_tx_desc *tx_desc, *eop_desc; - struct ifnet *ifp = adapter->ifp; + struct adapter *adapter = txr->adapter; + struct ifnet *ifp = adapter->ifp; + u32 work, processed = 0; + u16 limit = txr->process_limit; + struct igb_tx_buf *buf; + union e1000_adv_tx_desc *txd; - IGB_TX_LOCK_ASSERT(txr); + mtx_assert(&txr->tx_mtx, MA_OWNED); #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, txr->me )) + if (netmap_tx_irq(ifp, txr->me)) return (FALSE); #endif /* DEV_NETMAP */ - if (txr->tx_avail == adapter->num_tx_desc) { + + if (txr->tx_avail == txr->num_desc) { txr->queue_status = IGB_QUEUE_IDLE; - return FALSE; + return FALSE; } - processed = 0; - first = txr->next_to_clean; - tx_desc = &txr->tx_base[first]; - tx_buffer = &txr->tx_buffers[first]; - last = tx_buffer->next_eop; - eop_desc = &txr->tx_base[last]; - - /* - * What this does is get the index of the - * first descriptor AFTER the EOP of the - * first packet, that way we can do the - * simple comparison on the inner while loop. - */ - if (++last == adapter->num_tx_desc) - last = 0; - done = last; - + /* Get work starting point */ + work = txr->next_to_clean; + buf = &txr->tx_buffers[work]; + txd = &txr->tx_base[work]; + work -= txr->num_desc; /* The distance to ring end */ bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + do { + union e1000_adv_tx_desc *eop = buf->eop; + if (eop == NULL) /* No work */ + break; - while (eop_desc->upper.fields.status & E1000_TXD_STAT_DD) { - /* We clean the range of the packet */ - while (first != done) { - tx_desc->upper.data = 0; - tx_desc->lower.data = 0; - tx_desc->buffer_addr = 0; - ++txr->tx_avail; - ++processed; + if ((eop->wb.status & E1000_TXD_STAT_DD) == 0) + break; /* I/O not complete */ - if (tx_buffer->m_head) { + if (buf->m_head) { + txr->bytes += + buf->m_head->m_pkthdr.len; + bus_dmamap_sync(txr->txtag, + buf->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(txr->txtag, + buf->map); + m_freem(buf->m_head); + buf->m_head = NULL; + } + buf->eop = NULL; + ++txr->tx_avail; + + /* We clean the range if multi segment */ + while (txd != eop) { + ++txd; + ++buf; + ++work; + /* wrap the ring? */ + if (__predict_false(!work)) { + work -= txr->num_desc; + buf = txr->tx_buffers; + txd = txr->tx_base; + } + if (buf->m_head) { txr->bytes += - tx_buffer->m_head->m_pkthdr.len; + buf->m_head->m_pkthdr.len; bus_dmamap_sync(txr->txtag, - tx_buffer->map, + buf->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(txr->txtag, - tx_buffer->map); - - m_freem(tx_buffer->m_head); - tx_buffer->m_head = NULL; - } - tx_buffer->next_eop = -1; - txr->watchdog_time = ticks; - - if (++first == adapter->num_tx_desc) - first = 0; + buf->map); + m_freem(buf->m_head); + buf->m_head = NULL; + } + ++txr->tx_avail; + buf->eop = NULL; - tx_buffer = &txr->tx_buffers[first]; - tx_desc = &txr->tx_base[first]; } ++txr->packets; + ++processed; ++ifp->if_opackets; - /* See if we can continue to the next packet */ - last = tx_buffer->next_eop; - if (last != -1) { - eop_desc = &txr->tx_base[last]; - /* Get new done point */ - if (++last == adapter->num_tx_desc) last = 0; - done = last; - } else - break; - } - bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + txr->watchdog_time = ticks; + + /* Try the next packet */ + ++txd; + ++buf; + ++work; + /* reset with a wrap */ + if (__predict_false(!work)) { + work -= txr->num_desc; + buf = txr->tx_buffers; + txd = txr->tx_base; + } + prefetch(txd); + } while (__predict_true(--limit)); + + bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - txr->next_to_clean = first; + work += txr->num_desc; + txr->next_to_clean = work; /* ** Watchdog calculation, we know there's @@ -3995,18 +4061,14 @@ igb_txeof(struct tx_ring *txr) */ if ((!processed) && ((ticks - txr->watchdog_time) > IGB_WATCHDOG)) txr->queue_status |= IGB_QUEUE_HUNG; - /* - * If we have a minimum free, - * clear depleted state bit - */ - if (txr->tx_avail >= IGB_QUEUE_THRESHOLD) - txr->queue_status &= ~IGB_QUEUE_DEPLETED; - /* All clean, turn off the watchdog */ - if (txr->tx_avail == adapter->num_tx_desc) { + if (txr->tx_avail >= IGB_QUEUE_THRESHOLD) + txr->queue_status &= ~IGB_QUEUE_DEPLETED; + + if (txr->tx_avail == txr->num_desc) { txr->queue_status = IGB_QUEUE_IDLE; return (FALSE); - } + } return (TRUE); } @@ -4169,15 +4231,13 @@ igb_allocate_receive_buffers(struct rx_ring *rxr) for (i = 0; i < adapter->num_rx_desc; i++) { rxbuf = &rxr->rx_buffers[i]; - error = bus_dmamap_create(rxr->htag, - BUS_DMA_NOWAIT, &rxbuf->hmap); + error = bus_dmamap_create(rxr->htag, 0, &rxbuf->hmap); if (error) { device_printf(dev, "Unable to create RX head DMA maps\n"); goto fail; } - error = bus_dmamap_create(rxr->ptag, - BUS_DMA_NOWAIT, &rxbuf->pmap); + error = bus_dmamap_create(rxr->ptag, 0, &rxbuf->pmap); if (error) { device_printf(dev, "Unable to create RX packet DMA maps\n"); @@ -4697,11 +4757,13 @@ igb_rx_discard(struct rx_ring *rxr, int i) if (rbuf->m_head) { m_free(rbuf->m_head); rbuf->m_head = NULL; + bus_dmamap_unload(rxr->htag, rbuf->hmap); } if (rbuf->m_pack) { m_free(rbuf->m_pack); rbuf->m_pack = NULL; + bus_dmamap_unload(rxr->ptag, rbuf->pmap); } return; @@ -4792,7 +4854,8 @@ igb_rxeof(struct igb_queue *que, int count, int *done) rxbuf = &rxr->rx_buffers[i]; plen = le16toh(cur->wb.upper.length); ptype = le32toh(cur->wb.lower.lo_dword.data) & IGB_PKTTYPE_MASK; - if ((adapter->hw.mac.type == e1000_i350) && + if (((adapter->hw.mac.type == e1000_i350) || + (adapter->hw.mac.type == e1000_i354)) && (staterr & E1000_RXDEXT_STATERR_LB)) vtag = be16toh(cur->wb.upper.vlan); else @@ -4825,6 +4888,7 @@ igb_rxeof(struct igb_queue *que, int count, int *done) ** case only the first header is valid. */ if (rxr->hdr_split && rxr->fmp == NULL) { + bus_dmamap_unload(rxr->htag, rxbuf->hmap); hlen = (hdr & E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; if (hlen > IGB_HDR_BUF) @@ -4857,6 +4921,7 @@ igb_rxeof(struct igb_queue *que, int count, int *done) /* clear buf info for refresh */ rxbuf->m_pack = NULL; } + bus_dmamap_unload(rxr->ptag, rxbuf->pmap); ++processed; /* So we know when to refresh */ @@ -4987,7 +5052,7 @@ igb_rx_checksum(u32 staterr, struct mbuf *mp, u32 ptype) } if (status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) { - u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); + u64 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); #if __FreeBSD_version >= 800000 if (sctp) /* reassign */ type = CSUM_SCTP_VALID; @@ -5347,8 +5412,14 @@ igb_update_stats_counters(struct adapter *adapter) stats->roc += E1000_READ_REG(hw, E1000_ROC); stats->rjc += E1000_READ_REG(hw, E1000_RJC); - stats->tor += E1000_READ_REG(hw, E1000_TORH); - stats->tot += E1000_READ_REG(hw, E1000_TOTH); + stats->mgprc += E1000_READ_REG(hw, E1000_MGTPRC); + stats->mgpdc += E1000_READ_REG(hw, E1000_MGTPDC); + stats->mgptc += E1000_READ_REG(hw, E1000_MGTPTC); + + stats->tor += E1000_READ_REG(hw, E1000_TORL) + + ((u64)E1000_READ_REG(hw, E1000_TORH) << 32); + stats->tot += E1000_READ_REG(hw, E1000_TOTL) + + ((u64)E1000_READ_REG(hw, E1000_TOTH) << 32); stats->tpr += E1000_READ_REG(hw, E1000_TPR); stats->tpt += E1000_READ_REG(hw, E1000_TPT); @@ -5527,8 +5598,8 @@ igb_add_hw_stats(struct adapter *adapter) char namebuf[QUEUE_NAME_LEN]; /* Driver Statistics */ - SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "link_irq", - CTLFLAG_RD, &adapter->link_irq, 0, + SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq", + CTLFLAG_RD, &adapter->link_irq, "Link MSIX IRQ Handled"); SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped", CTLFLAG_RD, &adapter->dropped_pkts, @@ -5577,32 +5648,32 @@ igb_add_hw_stats(struct adapter *adapter) queue_list = SYSCTL_CHILDREN(queue_node); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "interrupt_rate", - CTLFLAG_RD, &adapter->queues[i], + CTLTYPE_UINT | CTLFLAG_RD, &adapter->queues[i], sizeof(&adapter->queues[i]), igb_sysctl_interrupt_rate_handler, "IU", "Interrupt Rate"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head", - CTLFLAG_RD, adapter, E1000_TDH(txr->me), + CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDH(txr->me), igb_sysctl_reg_handler, "IU", "Transmit Descriptor Head"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_tail", - CTLFLAG_RD, adapter, E1000_TDT(txr->me), + CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_TDT(txr->me), igb_sysctl_reg_handler, "IU", "Transmit Descriptor Tail"); SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "no_desc_avail", CTLFLAG_RD, &txr->no_desc_avail, "Queue No Descriptor Available"); - SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "tx_packets", - CTLFLAG_RD, &txr->tx_packets, + SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets", + CTLFLAG_RD, &txr->total_packets, "Queue Packets Transmitted"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_head", - CTLFLAG_RD, adapter, E1000_RDH(rxr->me), + CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDH(rxr->me), igb_sysctl_reg_handler, "IU", "Receive Descriptor Head"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_tail", - CTLFLAG_RD, adapter, E1000_RDT(rxr->me), + CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RDT(rxr->me), igb_sysctl_reg_handler, "IU", "Receive Descriptor Tail"); SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "rx_packets", @@ -5675,6 +5746,9 @@ igb_add_hw_stats(struct adapter *adapter) SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "missed_packets", CTLFLAG_RD, &stats->mpc, "Missed Packets"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_length_errors", + CTLFLAG_RD, &stats->rlec, + "Receive Length Errors"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_no_buff", CTLFLAG_RD, &stats->rnbc, "Receive No Buffers"); @@ -5683,7 +5757,7 @@ igb_add_hw_stats(struct adapter *adapter) "Receive Undersize"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_fragmented", CTLFLAG_RD, &stats->rfc, - "Fragmented Packets Received "); + "Fragmented Packets Received"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_oversize", CTLFLAG_RD, &stats->roc, "Oversized Packets Received"); @@ -5699,6 +5773,9 @@ igb_add_hw_stats(struct adapter *adapter) SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "alignment_errs", CTLFLAG_RD, &stats->algnerrc, "Alignment Errors"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_no_crs", + CTLFLAG_RD, &stats->tncrs, + "Transmit with No CRS"); /* On 82575 these are collision counts */ SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs", CTLFLAG_RD, &stats->cexterr, @@ -5715,10 +5792,22 @@ igb_add_hw_stats(struct adapter *adapter) SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "xoff_txd", CTLFLAG_RD, &stats->xofftxc, "XOFF Transmitted"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "unsupported_fc_recvd", + CTLFLAG_RD, &stats->fcruc, + "Unsupported Flow Control Received"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mgmt_pkts_recvd", + CTLFLAG_RD, &stats->mgprc, + "Management Packets Received"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mgmt_pkts_drop", + CTLFLAG_RD, &stats->mgpdc, + "Management Packets Dropped"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mgmt_pkts_txd", + CTLFLAG_RD, &stats->mgptc, + "Management Packets Transmitted"); /* Packet Reception Stats */ SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd", CTLFLAG_RD, &stats->tpr, - "Total Packets Received "); + "Total Packets Received"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd", CTLFLAG_RD, &stats->gprc, "Good Packets Received"); @@ -5730,7 +5819,7 @@ igb_add_hw_stats(struct adapter *adapter) "Multicast Packets Received"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_64", CTLFLAG_RD, &stats->prc64, - "64 byte frames received "); + "64 byte frames received"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127", CTLFLAG_RD, &stats->prc127, "65-127 byte frames received"); @@ -5748,12 +5837,18 @@ igb_add_hw_stats(struct adapter *adapter) "1023-1522 byte frames received"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd", CTLFLAG_RD, &stats->gorc, - "Good Octets Received"); + "Good Octets Received"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_octets_recvd", + CTLFLAG_RD, &stats->tor, + "Total Octets Received"); /* Packet Transmission Stats */ SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", CTLFLAG_RD, &stats->gotc, "Good Octets Transmitted"); + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_octets_txd", + CTLFLAG_RD, &stats->tot, + "Total Octets Transmitted"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd", CTLFLAG_RD, &stats->tpt, "Total Packets Transmitted"); @@ -5768,7 +5863,7 @@ igb_add_hw_stats(struct adapter *adapter) "Multicast Packets Transmitted"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_64", CTLFLAG_RD, &stats->ptc64, - "64 byte frames transmitted "); + "64 byte frames transmitted"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127", CTLFLAG_RD, &stats->ptc127, "65-127 byte frames transmitted"); @@ -5952,7 +6047,7 @@ igb_set_sysctl_value(struct adapter *adapter, const char *name, *limit = value; SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), - OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); + OID_AUTO, name, CTLFLAG_RW, limit, value, description); } /* @@ -6035,7 +6130,7 @@ igb_sysctl_dmac(SYSCTL_HANDLER_ARGS) default: /* Do nothing, illegal value */ adapter->dmac = 0; - return (error); + return (EINVAL); } /* Reinit the interface */ igb_init(adapter); diff --git a/freebsd/sys/dev/e1000/if_igb.h b/freebsd/sys/dev/e1000/if_igb.h index 6f3a3a54..0c447412 100644 --- a/freebsd/sys/dev/e1000/if_igb.h +++ b/freebsd/sys/dev/e1000/if_igb.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2013, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -162,6 +162,9 @@ /* PHY master/slave setting */ #define IGB_MASTER_SLAVE e1000_ms_hw_default +/* Support AutoMediaDetect for Marvell M88 PHY in i354 */ +#define IGB_MEDIA_RESET (1 << 0) + /* * Micellaneous constants */ @@ -173,11 +176,13 @@ #define IGB_SMARTSPEED_MAX 15 #define IGB_MAX_LOOP 10 -#define IGB_RX_PTHRESH (hw->mac.type <= e1000_82576 ? 16 : 8) +#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : \ + ((hw->mac.type <= e1000_82576) ? 16 : 8)) #define IGB_RX_HTHRESH 8 -#define IGB_RX_WTHRESH 1 +#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \ + adapter->msix_mem) ? 1 : 4) -#define IGB_TX_PTHRESH 8 +#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8) #define IGB_TX_HTHRESH 1 #define IGB_TX_WTHRESH ((hw->mac.type != e1000_82575 && \ adapter->msix_mem) ? 1 : 16) @@ -190,11 +195,6 @@ #define IGB_EEPROM_APME 0x400; /* Queue minimum free for use */ #define IGB_QUEUE_THRESHOLD (adapter->num_tx_desc / 8) -/* Queue bit defines */ -#define IGB_QUEUE_IDLE 1 -#define IGB_QUEUE_WORKING 2 -#define IGB_QUEUE_HUNG 4 -#define IGB_QUEUE_DEPLETED 8 /* * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be @@ -228,8 +228,10 @@ #define IGB_BR_SIZE 4096 /* ring buf size */ #define IGB_TSO_SIZE (65535 + sizeof(struct ether_vlan_header)) #define IGB_TSO_SEG_SIZE 4096 /* Max dma segment size */ +#define IGB_TXPBSIZE 20408 #define IGB_HDR_BUF 128 #define IGB_PKTTYPE_MASK 0x0000FFF0 +#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coalesce Flush */ #define ETH_ZLEN 60 #define ETH_ADDR_LEN 6 @@ -245,6 +247,7 @@ #define IGB_DEFAULT_ITR ((1000000/IGB_INTS_PER_SEC) << 2) #define IGB_LINK_ITR 2000 +#define I210_LINK_DELAY 1000 /* Precision Time Sync (IEEE 1588) defines */ #define ETHERTYPE_IEEE1588 0x88F7 @@ -284,34 +287,42 @@ struct igb_queue { }; /* - * Transmit ring: one per queue + * The transmit ring, one per queue */ struct tx_ring { - struct adapter *adapter; - u32 me; + struct adapter *adapter; struct mtx tx_mtx; - char mtx_name[16]; + u32 me; + int watchdog_time; + union e1000_adv_tx_desc *tx_base; + struct igb_tx_buf *tx_buffers; struct igb_dma_alloc txdma; - struct e1000_tx_desc *tx_base; - u32 next_avail_desc; - u32 next_to_clean; volatile u16 tx_avail; - struct igb_tx_buffer *tx_buffers; + u16 next_avail_desc; + u16 next_to_clean; + u16 process_limit; + u16 num_desc; + enum { + IGB_QUEUE_IDLE = 1, + IGB_QUEUE_WORKING = 2, + IGB_QUEUE_HUNG = 4, + IGB_QUEUE_DEPLETED = 8, + } queue_status; + u32 txd_cmd; + bus_dma_tag_t txtag; + char mtx_name[16]; #ifndef IGB_LEGACY_TX struct buf_ring *br; struct task txq_task; #endif - bus_dma_tag_t txtag; - - u32 bytes; + u32 bytes; /* used for AIM */ u32 packets; - - int queue_status; - int watchdog_time; - int tdt; - int tdh; + /* Soft Stats */ + unsigned long tso_tx; + unsigned long no_tx_map_avail; + unsigned long no_tx_dma_setup; u64 no_desc_avail; - u64 tx_packets; + u64 total_packets; }; /* @@ -353,43 +364,38 @@ struct rx_ring { }; struct adapter { - struct ifnet *ifp; - struct e1000_hw hw; - - struct e1000_osdep osdep; - struct device *dev; - struct cdev *led_dev; - - struct resource *pci_mem; - struct resource *msix_mem; - struct resource *res; - void *tag; - u32 que_mask; - - int linkvec; - int link_mask; - struct task link_task; - int link_irq; - - struct ifmedia media; - struct callout timer; - int msix; /* total vectors allocated */ - int if_flags; - int max_frame_size; - int min_frame_size; - int pause_frames; - struct mtx core_mtx; - int igb_insert_vlan_header; - u16 num_queues; - u16 vf_ifp; /* a VF interface */ - - eventhandler_tag vlan_attach; - eventhandler_tag vlan_detach; - u32 num_vlans; - - /* Management and WOL features */ - int wol; - int has_manage; + struct ifnet *ifp; + struct e1000_hw hw; + + struct e1000_osdep osdep; + struct device *dev; + struct cdev *led_dev; + + struct resource *pci_mem; + struct resource *msix_mem; + int memrid; + + /* + * Interrupt resources: this set is + * either used for legacy, or for Link + * when doing MSIX + */ + void *tag; + struct resource *res; + + struct ifmedia media; + struct callout timer; + int msix; + int if_flags; + int pause_frames; + + struct mtx core_mtx; + + eventhandler_tag vlan_attach; + eventhandler_tag vlan_detach; + + u16 num_vlans; + u16 num_queues; /* ** Shadow VFTA table, this is needed because @@ -397,66 +403,86 @@ struct adapter { ** a soft reset and the driver needs to be able ** to repopulate it. */ - u32 shadow_vfta[IGB_VFTA_SIZE]; + u32 shadow_vfta[IGB_VFTA_SIZE]; /* Info about the interface */ - u16 link_active; - u16 fc; - u16 link_speed; - u16 link_duplex; - u32 smartspeed; - u32 dmac; - int enable_aim; - - /* Interface queues */ + u32 optics; + u32 fc; /* local flow ctrl setting */ + int advertise; /* link speeds */ + bool link_active; + u16 max_frame_size; + u16 num_segs; + u16 link_speed; + bool link_up; + u32 linkvec; + u16 link_duplex; + u32 dmac; + int link_mask; + + /* Flags */ + u32 flags; + + /* Mbuf cluster size */ + u32 rx_mbuf_sz; + + /* Support for pluggable optics */ + bool sfp_probe; + struct task link_task; /* Link tasklet */ + struct task mod_task; /* SFP tasklet */ + struct task msf_task; /* Multispeed Fiber */ + struct taskqueue *tq; + + /* + ** Queues: + ** This is the irq holder, it has + ** and RX/TX pair or rings associated + ** with it. + */ struct igb_queue *queues; /* - * Transmit rings + * Transmit rings: + * Allocated at run time, an array of rings. */ struct tx_ring *tx_rings; - u16 num_tx_desc; - - /* Multicast array pointer */ - u8 *mta; + u32 num_tx_desc; - /* - * Receive rings + /* + * Receive rings: + * Allocated at run time, an array of rings. */ struct rx_ring *rx_rings; - bool rx_hdr_split; - u16 num_rx_desc; - int rx_process_limit; - u32 rx_mbuf_sz; - u32 rx_mask; + u64 que_mask; + u32 num_rx_desc; + + /* Multicast array memory */ + u8 *mta; /* Misc stats maintained by the driver */ - unsigned long dropped_pkts; - unsigned long mbuf_defrag_failed; - unsigned long mbuf_header_failed; - unsigned long mbuf_packet_failed; - unsigned long no_tx_map_avail; - unsigned long no_tx_dma_setup; - unsigned long watchdog_events; - unsigned long rx_overruns; - unsigned long device_control; - unsigned long rx_control; - unsigned long int_mask; - unsigned long eint_mask; - unsigned long packet_buf_alloc_rx; - unsigned long packet_buf_alloc_tx; - - boolean_t in_detach; - -#ifdef IGB_IEEE1588 - /* IEEE 1588 precision time support */ - struct cyclecounter cycles; - struct nettimer clock; - struct nettime_compare compare; - struct hwtstamp_ctrl hwtstamp; -#endif + unsigned long dropped_pkts; + unsigned long mbuf_defrag_failed; + unsigned long mbuf_header_failed; + unsigned long mbuf_packet_failed; + unsigned long no_tx_dma_setup; + unsigned long watchdog_events; + unsigned long link_irq; + unsigned long rx_overruns; + unsigned long device_control; + unsigned long rx_control; + unsigned long int_mask; + unsigned long eint_mask; + unsigned long packet_buf_alloc_rx; + unsigned long packet_buf_alloc_tx; + /* Used in pf and vf */ + void *stats; + + int enable_aim; + int has_manage; + int wol; + int rx_process_limit; + u16 vf_ifp; /* a VF interface */ + bool in_detach; /* Used only in igb_ioctl */ - void *stats; }; /* ****************************************************************************** @@ -474,11 +500,10 @@ typedef struct _igb_vendor_info_t { unsigned int index; } igb_vendor_info_t; - -struct igb_tx_buffer { - int next_eop; /* Index of the desc to watch */ - struct mbuf *m_head; - bus_dmamap_t map; /* bus_dma map for packet */ +struct igb_tx_buf { + union e1000_adv_tx_desc *eop; + struct mbuf *m_head; + bus_dmamap_t map; }; struct igb_rx_buf { diff --git a/freebsd/sys/dev/e1000/if_lem.c b/freebsd/sys/dev/e1000/if_lem.c index 64a1bcc0..7c22200d 100644 --- a/freebsd/sys/dev/e1000/if_lem.c +++ b/freebsd/sys/dev/e1000/if_lem.c @@ -4650,7 +4650,7 @@ lem_set_flow_cntrl(struct adapter *adapter, const char *name, *limit = value; SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), - OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); + OID_AUTO, name, CTLFLAG_RW, limit, value, description); } static void @@ -4660,5 +4660,5 @@ lem_add_rx_process_limit(struct adapter *adapter, const char *name, *limit = value; SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), - OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); + OID_AUTO, name, CTLFLAG_RW, limit, value, description); } diff --git a/freebsd/sys/dev/mii/e1000phy.c b/freebsd/sys/dev/mii/e1000phy.c index 822ebce4..47f77d15 100644 --- a/freebsd/sys/dev/mii/e1000phy.c +++ b/freebsd/sys/dev/mii/e1000phy.c @@ -169,8 +169,12 @@ e1000phy_attach(device_t dev) PHY_RESET(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask; - if (sc->mii_capabilities & BMSR_EXTSTAT) + if (sc->mii_capabilities & BMSR_EXTSTAT) { sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); + if ((sc->mii_extcapabilities & + (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) + sc->mii_flags |= MIIF_HAVE_GTCR; + } device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); @@ -321,8 +325,7 @@ e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) speed = 0; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_1000_T: - if ((sc->mii_extcapabilities & - (EXTSR_1000TFDX | EXTSR_1000THDX)) == 0) + if ((sc->mii_flags & MIIF_HAVE_GTCR) == 0) return (EINVAL); speed = E1000_CR_SPEED_1000; break; @@ -359,10 +362,9 @@ e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { gig |= E1000_1GCR_MS_ENABLE; - if ((ife->ifm_media & IFM_ETH_MASTER) != 0) + if ((ife->ifm_media & IFM_ETH_MASTER) != 0) gig |= E1000_1GCR_MS_VALUE; - } else if ((sc->mii_extcapabilities & - (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) + } else if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) gig = 0; PHY_WRITE(sc, E1000_1GCR, gig); PHY_WRITE(sc, E1000_AR, E1000_AR_SELECTOR_FIELD); @@ -493,9 +495,14 @@ e1000phy_mii_phy_auto(struct mii_softc *sc, int media) PHY_WRITE(sc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD); } else PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X); - if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) - PHY_WRITE(sc, E1000_1GCR, - E1000_1GCR_1000T_FD | E1000_1GCR_1000T); + if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) { + reg = 0; + if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0) + reg |= E1000_1GCR_1000T_FD; + if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0) + reg |= E1000_1GCR_1000T; + PHY_WRITE(sc, E1000_1GCR, reg); + } PHY_WRITE(sc, E1000_CR, E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG); diff --git a/freebsd/sys/dev/mii/micphy.c b/freebsd/sys/dev/mii/micphy.c index 501f7f19..ab40dab5 100644 --- a/freebsd/sys/dev/mii/micphy.c +++ b/freebsd/sys/dev/mii/micphy.c @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include diff --git a/freebsd/sys/dev/mii/ukphy.c b/freebsd/sys/dev/mii/ukphy.c index 960c797f..57958cac 100644 --- a/freebsd/sys/dev/mii/ukphy.c +++ b/freebsd/sys/dev/mii/ukphy.c @@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c index 7dcaa0d5..426d06a2 100644 --- a/freebsd/sys/dev/pci/pci.c +++ b/freebsd/sys/dev/pci/pci.c @@ -211,6 +211,7 @@ struct pci_quirk { #define PCI_QUIRK_ENABLE_MSI_VM 3 /* Older chipset in VM where MSI works */ #define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */ #define PCI_QUIRK_DISABLE_MSIX 5 /* MSI-X doesn't work */ +#define PCI_QUIRK_MSI_INTX_BUG 6 /* PCIM_CMD_INTxDIS disables MSI */ int arg1; int arg2; }; @@ -270,6 +271,26 @@ static const struct pci_quirk pci_quirks[] = { */ { 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 }, + /* + * Atheros AR8161/AR8162/E2200 Ethernet controllers have a bug that + * MSI interrupt does not assert if PCIM_CMD_INTxDIS bit of the + * command register is set. + */ + { 0x10911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, + { 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, + { 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, + + /* + * Broadcom BCM5714(S)/BCM5715(S)/BCM5780(S) Ethernet MACs don't + * issue MSI interrupts with PCIM_CMD_INTxDIS set either. + */ + { 0x166814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714 */ + { 0x166914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714S */ + { 0x166a14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780 */ + { 0x166b14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780S */ + { 0x167814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715 */ + { 0x167914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715S */ + { 0 } }; @@ -3567,8 +3588,16 @@ pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, mte->mte_handlers++; } - /* Make sure that INTx is disabled if we are using MSI/MSIX */ - pci_set_command_bit(dev, child, PCIM_CMD_INTxDIS); + /* + * Make sure that INTx is disabled if we are using MSI/MSI-X, + * unless the device is affected by PCI_QUIRK_MSI_INTX_BUG, + * in which case we "enable" INTx so MSI/MSI-X actually works. + */ + if (!pci_has_quirk(pci_get_devid(child), + PCI_QUIRK_MSI_INTX_BUG)) + pci_set_command_bit(dev, child, PCIM_CMD_INTxDIS); + else + pci_clear_command_bit(dev, child, PCIM_CMD_INTxDIS); bad: if (error) { (void)bus_generic_teardown_intr(dev, child, irq, diff --git a/freebsd/sys/dev/re/if_re.c b/freebsd/sys/dev/re/if_re.c index 99751374..b574f9a2 100644 --- a/freebsd/sys/dev/re/if_re.c +++ b/freebsd/sys/dev/re/if_re.c @@ -704,6 +704,12 @@ re_set_rxmode(struct rl_softc *sc) rxfilt |= RL_RXCFG_RX_MULTI; } + if (sc->rl_hwrev->rl_rev == RL_HWREV_8168F) { + /* Disable multicast filtering due to silicon bug. */ + hashes[0] = 0xffffffff; + hashes[1] = 0xffffffff; + } + done: CSR_WRITE_4(sc, RL_MAR0, hashes[0]); CSR_WRITE_4(sc, RL_MAR4, hashes[1]); diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c index 86c75b27..bf637c20 100644 --- a/freebsd/sys/dev/sdhci/sdhci.c +++ b/freebsd/sys/dev/sdhci/sdhci.c @@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$"); #include #ifndef __rtems__ -#include +#include "sdhci.h" #else /* __rtems__ */ #include #endif /* __rtems__ */ diff --git a/freebsd/sys/dev/usb/controller/ehci.c b/freebsd/sys/dev/usb/controller/ehci.c index 730fd666..3eb63c60 100644 --- a/freebsd/sys/dev/usb/controller/ehci.c +++ b/freebsd/sys/dev/usb/controller/ehci.c @@ -214,7 +214,7 @@ ehci_reset(ehci_softc_t *sc) return (0); } } - device_printf(sc->sc_bus.bdev, "Reset timeout\n"); + device_printf(sc->sc_bus.bdev, "reset timeout\n"); return (USB_ERR_IOERROR); } @@ -289,7 +289,7 @@ ehci_init_sub(struct ehci_softc *sc) } } if (hcr) { - device_printf(sc->sc_bus.bdev, "Run timeout\n"); + device_printf(sc->sc_bus.bdev, "run timeout\n"); return (USB_ERR_IOERROR); } return (USB_ERR_NORMAL_COMPLETION); diff --git a/freebsd/sys/dev/usb/controller/usb_controller.c b/freebsd/sys/dev/usb/controller/usb_controller.c index c0fda652..90e09bb5 100644 --- a/freebsd/sys/dev/usb/controller/usb_controller.c +++ b/freebsd/sys/dev/usb/controller/usb_controller.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -130,7 +131,7 @@ DRIVER_MODULE(usbus, xhci, usb_driver, usb_devclass, 0, 0); /* Device Only Drivers */ DRIVER_MODULE(usbus, at91_udp, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, musbotg, usb_driver, usb_devclass, 0, 0); -DRIVER_MODULE(usbus, uss820, usb_driver, usb_devclass, 0, 0); +DRIVER_MODULE(usbus, uss820dci, usb_driver, usb_devclass, 0, 0); /*------------------------------------------------------------------------* * usb_probe @@ -213,6 +214,11 @@ usb_detach(device_t dev) usb_proc_mwait(&bus->explore_proc, &bus->detach_msg[0], &bus->detach_msg[1]); +#if USB_HAVE_UGEN + /* Wait for cleanup to complete */ + usb_proc_mwait(&bus->explore_proc, + &bus->cleanup_msg[0], &bus->cleanup_msg[1]); +#endif USB_BUS_UNLOCK(bus); /* Get rid of USB callback processes */ @@ -324,7 +330,7 @@ usb_shutdown(device_t dev) return (0); } - device_printf(bus->bdev, "Controller shutdown\n"); + DPRINTF("%s: Controller shutdown\n", device_get_nameunit(bus->bdev)); USB_BUS_LOCK(bus); #ifndef __rtems__ @@ -338,7 +344,8 @@ usb_shutdown(device_t dev) #endif /* __rtems__ */ USB_BUS_UNLOCK(bus); - device_printf(bus->bdev, "Controller shutdown complete\n"); + DPRINTF("%s: Controller shutdown complete\n", + device_get_nameunit(bus->bdev)); return (0); } @@ -624,6 +631,32 @@ usb_bus_shutdown(struct usb_proc_msg *pm) USB_BUS_LOCK(bus); } +/*------------------------------------------------------------------------* + * usb_bus_cleanup + * + * This function is used to cleanup leftover USB character devices. + *------------------------------------------------------------------------*/ +#if USB_HAVE_UGEN +static void +usb_bus_cleanup(struct usb_proc_msg *pm) +{ + struct usb_bus *bus; + struct usb_fs_privdata *pd; + + bus = ((struct usb_bus_msg *)pm)->bus; + + while ((pd = LIST_FIRST(&bus->pd_cleanup_list)) != NULL) { + + LIST_REMOVE(pd, pd_next); + USB_BUS_UNLOCK(bus); + + usb_destroy_dev_sync(pd); + + USB_BUS_LOCK(bus); + } +} +#endif + static void usb_power_wdog(void *arg) { @@ -804,6 +837,14 @@ usb_attach_sub(device_t dev, struct usb_bus *bus) bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown; bus->shutdown_msg[1].bus = bus; +#if USB_HAVE_UGEN + LIST_INIT(&bus->pd_cleanup_list); + bus->cleanup_msg[0].hdr.pm_callback = &usb_bus_cleanup; + bus->cleanup_msg[0].bus = bus; + bus->cleanup_msg[1].hdr.pm_callback = &usb_bus_cleanup; + bus->cleanup_msg[1].bus = bus; +#endif + /* Create USB explore and callback processes */ if (usb_proc_create(&bus->giant_callback_proc, @@ -901,7 +942,7 @@ usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, #if USB_HAVE_BUSDMA usb_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags, - dmat, &bus->bus_mtx, NULL, 32, USB_BUS_DMA_TAG_MAX); + dmat, &bus->bus_mtx, NULL, bus->dma_bits, USB_BUS_DMA_TAG_MAX); #endif if ((bus->devices_max > USB_MAX_DEVICES) || (bus->devices_max < USB_MIN_DEVICES) || diff --git a/freebsd/sys/dev/usb/controller/xhcireg.h b/freebsd/sys/dev/usb/controller/xhcireg.h index bd1d635c..a0b73971 100644 --- a/freebsd/sys/dev/usb/controller/xhcireg.h +++ b/freebsd/sys/dev/usb/controller/xhcireg.h @@ -35,7 +35,9 @@ #define PCI_XHCI_FLADJ 0x61 /* RW frame length adjust */ #define PCI_XHCI_INTEL_XUSB2PR 0xD0 /* Intel USB2 Port Routing */ +#define PCI_XHCI_INTEL_USB2PRM 0xD4 /* Intel USB2 Port Routing Mask */ #define PCI_XHCI_INTEL_USB3_PSSEN 0xD8 /* Intel USB3 Port SuperSpeed Enable */ +#define PCI_XHCI_INTEL_USB3PRM 0xDC /* Intel USB3 Port Routing Mask */ /* XHCI capability registers */ #define XHCI_CAPLENGTH 0x00 /* RO capability */ diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c index 2f7ea792..7447ea80 100644 --- a/freebsd/sys/dev/usb/quirk/usb_quirk.c +++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c @@ -61,7 +61,7 @@ MODULE_DEPEND(usb_quirk, usb, 1, 1, 1); MODULE_VERSION(usb_quirk, 1); -#define USB_DEV_QUIRKS_MAX 256 +#define USB_DEV_QUIRKS_MAX 384 #define USB_SUB_QUIRKS_MAX 8 struct usb_quirk_entry { @@ -132,6 +132,8 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(MICROSOFT, WLINTELLIMOUSE, 0x0000, 0xffff, UQ_MS_LEADING_BYTE), /* Quirk for Corsair Vengeance K60 keyboard */ USB_QUIRK(CORSAIR, K60, 0x0000, 0xffff, UQ_KBD_BOOTPROTO), + /* Quirk for Corsair Vengeance K70 keyboard */ + USB_QUIRK(CORSAIR, K70, 0x0000, 0xffff, UQ_KBD_BOOTPROTO), /* umodem(4) device quirks */ USB_QUIRK(METRICOM, RICOCHET_GS, 0x100, 0x100, UQ_ASSUME_CM_OVER_DATA), USB_QUIRK(SANYO, SCP4900, 0x000, 0x000, UQ_ASSUME_CM_OVER_DATA), @@ -252,6 +254,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(LEXAR, CF_READER, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), USB_QUIRK(LEXAR, JUMPSHOT, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), + USB_QUIRK(LEXAR, JUMPDRIVE, 0x0000, 0xffff, UQ_MSC_NO_INQUIRY), USB_QUIRK(LOGITEC, LDR_H443SU2, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), USB_QUIRK(LOGITEC, LDR_H443U2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI,), @@ -436,8 +439,28 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(WESTERN, MYBOOK, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_SYNC_CACHE), - USB_QUIRK(WESTERN, MYPASSWORD, 0x0000, 0xffff, UQ_MSC_FORCE_SHORT_INQ), - USB_QUIRK(WESTERN, MYPASSPORT, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_00, 0x0000, 0xffff, UQ_MSC_FORCE_SHORT_INQ), + USB_QUIRK(WESTERN, MYPASSPORT_01, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_02, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_03, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_04, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_05, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_06, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_07, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_08, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_09, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_10, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_11, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_00, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_01, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_02, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_03, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_04, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_05, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_06, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_07, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_08, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORTES_09, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WINMAXGROUP, FLASH64MC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), USB_QUIRK(YANO, FW800HD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, @@ -458,10 +481,11 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { UQ_MSC_FORCE_PROTO_ATAPI), USB_QUIRK(MEIZU, M6_SL, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY, UQ_MSC_NO_SYNC_CACHE), - - USB_QUIRK(TOSHIBA, TRANSMEMORY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(TOSHIBA, TRANSMEMORY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, + UQ_MSC_NO_PREVENT_ALLOW), USB_QUIRK(VIALABS, USB30SATABRIDGE, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), - + USB_QUIRK(QUALCOMMINC, ZTE_MF730M, 0x0000, 0xffff, UQ_MSC_NO_GETMAXLUN, + UQ_MSC_NO_INQUIRY, UQ_CFG_INDEX_0), /* Non-standard USB MIDI devices */ USB_QUIRK(ROLAND, UM1, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), USB_QUIRK(ROLAND, SC8850, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS), @@ -565,6 +589,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = { [UQ_MSC_EJECT_WAIT] = "UQ_MSC_EJECT_WAIT", [UQ_MSC_EJECT_SAEL_M460] = "UQ_MSC_EJECT_SAEL_M460", [UQ_MSC_EJECT_HUAWEISCSI] = "UQ_MSC_EJECT_HUAWEISCSI", + [UQ_MSC_EJECT_HUAWEISCSI2] = "UQ_MSC_EJECT_HUAWEISCSI2", [UQ_MSC_EJECT_TCT] = "UQ_MSC_EJECT_TCT", [UQ_BAD_MIDI] = "UQ_BAD_MIDI", [UQ_AU_VENDOR_CLASS] = "UQ_AU_VENDOR_CLASS", diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.h b/freebsd/sys/dev/usb/quirk/usb_quirk.h index 32a60a10..bddc2c55 100644 --- a/freebsd/sys/dev/usb/quirk/usb_quirk.h +++ b/freebsd/sys/dev/usb/quirk/usb_quirk.h @@ -103,6 +103,7 @@ enum { UQ_MSC_EJECT_WAIT, /* wait for the device to eject */ UQ_MSC_EJECT_SAEL_M460, /* ejects after Sael USB commands */ UQ_MSC_EJECT_HUAWEISCSI, /* ejects after Huawei SCSI command */ + UQ_MSC_EJECT_HUAWEISCSI2, /* ejects after Huawei SCSI 2 command */ UQ_MSC_EJECT_TCT, /* ejects after TCT SCSI command */ UQ_BAD_MIDI, /* device claims MIDI class, but isn't */ diff --git a/freebsd/sys/dev/usb/usb_bus.h b/freebsd/sys/dev/usb/usb_bus.h index 702f623d..0a7350c9 100644 --- a/freebsd/sys/dev/usb/usb_bus.h +++ b/freebsd/sys/dev/usb/usb_bus.h @@ -27,6 +27,8 @@ #ifndef _USB_BUS_H_ #define _USB_BUS_H_ +struct usb_fs_privdata; + /* * The following structure defines the USB explore message sent to the USB * explore process. @@ -75,6 +77,10 @@ struct usb_bus { struct usb_bus_msg resume_msg[2]; struct usb_bus_msg reset_msg[2]; struct usb_bus_msg shutdown_msg[2]; +#if USB_HAVE_UGEN + struct usb_bus_msg cleanup_msg[2]; + LIST_HEAD(,usb_fs_privdata) pd_cleanup_list; +#endif /* * This mutex protects the USB hardware: */ @@ -106,6 +112,7 @@ struct usb_bus { uint8_t devices_max; /* maximum number of USB devices */ uint8_t do_probe; /* set if USB should be re-probed */ uint8_t no_explore; /* don't explore USB ports */ + uint8_t dma_bits; /* number of DMA address lines */ }; #endif /* _USB_BUS_H_ */ diff --git a/freebsd/sys/dev/usb/usb_busdma.h b/freebsd/sys/dev/usb/usb_busdma.h index 6b6e4039..ee420bc6 100644 --- a/freebsd/sys/dev/usb/usb_busdma.h +++ b/freebsd/sys/dev/usb/usb_busdma.h @@ -60,7 +60,7 @@ typedef void (usb_dma_callback_t)(struct usb_dma_parent_tag *udpt); */ struct usb_page { #if USB_HAVE_BUSDMA - bus_size_t physaddr; + bus_addr_t physaddr; void *buffer; /* non Kernel Virtual Address */ #endif }; @@ -73,7 +73,7 @@ struct usb_page { struct usb_page_search { void *buffer; #if USB_HAVE_BUSDMA - bus_size_t physaddr; + bus_addr_t physaddr; #endif usb_size_t length; }; diff --git a/freebsd/sys/dev/usb/usb_core.h b/freebsd/sys/dev/usb/usb_core.h index 48e5ee83..287e69f2 100644 --- a/freebsd/sys/dev/usb/usb_core.h +++ b/freebsd/sys/dev/usb/usb_core.h @@ -97,6 +97,7 @@ struct usb_xfer_flags_int { * sent */ uint8_t control_act:1; /* set if control transfer is active */ uint8_t control_stall:1; /* set if control transfer should be stalled */ + uint8_t control_did_data:1; /* set if control DATA has been transferred */ uint8_t short_frames_ok:1; /* filtered version */ uint8_t short_xfer_ok:1; /* filtered version */ diff --git a/freebsd/sys/dev/usb/usb_dev.c b/freebsd/sys/dev/usb/usb_dev.c index 3ff064ee..ce107cf3 100644 --- a/freebsd/sys/dev/usb/usb_dev.c +++ b/freebsd/sys/dev/usb/usb_dev.c @@ -292,11 +292,15 @@ error: usbd_enum_unlock(cpd->udev); if (crd->is_uref) { - cpd->udev->refcount--; - cv_broadcast(&cpd->udev->ref_cv); + if (--(cpd->udev->refcount) == 0) + cv_broadcast(&cpd->udev->ref_cv); } mtx_unlock(&usb_ref_lock); DPRINTFN(2, "fail\n"); + + /* clear all refs */ + memset(crd, 0, sizeof(*crd)); + return (USB_ERR_INVAL); } @@ -360,8 +364,8 @@ usb_unref_device(struct usb_cdev_privdata *cpd, } if (crd->is_uref) { crd->is_uref = 0; - cpd->udev->refcount--; - cv_broadcast(&cpd->udev->ref_cv); + if (--(cpd->udev->refcount) == 0) + cv_broadcast(&cpd->udev->ref_cv); } mtx_unlock(&usb_ref_lock); } @@ -587,12 +591,12 @@ usb_fifo_free(struct usb_fifo *f) /* decrease refcount */ f->refcount--; - /* prevent any write flush */ - f->flag_iserror = 1; /* need to wait until all callers have exited */ while (f->refcount != 0) { mtx_unlock(&usb_ref_lock); /* avoid LOR */ mtx_lock(f->priv_mtx); + /* prevent write flush, if any */ + f->flag_iserror = 1; /* get I/O thread out of any sleep state */ if (f->flag_sleeping) { f->flag_sleeping = 0; @@ -1092,8 +1096,8 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* goto done; if (usb_usb_ref_device(cpd, &refs)) { - err = ENXIO; - goto done; + /* we lost the reference */ + return (ENXIO); } err = (f->methods->f_ioctl_post) (f, cmd, addr, fflags); @@ -1116,9 +1120,8 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* while (usb_ref_device(cpd, &refs, 1 /* need uref */)) { if (usb_ref_device(cpd, &refs, 0)) { - /* device no longer exits */ - err = ENXIO; - goto done; + /* device no longer exists */ + return (ENXIO); } usb_unref_device(cpd, &refs); usb_pause_mtx(NULL, hz / 128); @@ -1410,9 +1413,9 @@ usb_read(struct cdev *dev, struct uio *uio, int ioflag) return (err); err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); - if (err) { + if (err) return (ENXIO); - } + fflags = cpd->fflags; f = refs.rxfifo; @@ -1536,9 +1539,9 @@ usb_write(struct cdev *dev, struct uio *uio, int ioflag) return (err); err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); - if (err) { + if (err) return (ENXIO); - } + fflags = cpd->fflags; f = refs.txfifo; diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c index e18c32df..8e0144cc 100644 --- a/freebsd/sys/dev/usb/usb_device.c +++ b/freebsd/sys/dev/usb/usb_device.c @@ -437,60 +437,28 @@ usb_endpoint_foreach(struct usb_device *udev, struct usb_endpoint *ep) } /*------------------------------------------------------------------------* - * usb_wait_pending_ref_locked + * usb_wait_pending_refs * * This function will wait for any USB references to go away before - * returning and disable further USB device refcounting on the - * specified USB device. This function is used when detaching a USB - * device. + * returning. This function is used before freeing a USB device. *------------------------------------------------------------------------*/ static void -usb_wait_pending_ref_locked(struct usb_device *udev) +usb_wait_pending_refs(struct usb_device *udev) { #if USB_HAVE_UGEN - const uint16_t refcount = - usb_proc_is_called_from( - &udev->bus->explore_proc) ? 1 : 2; - - DPRINTF("Refcount = %d\n", (int)refcount); + DPRINTF("Refcount = %d\n", (int)udev->refcount); + mtx_lock(&usb_ref_lock); + udev->refcount--; while (1) { /* wait for any pending references to go away */ - mtx_lock(&usb_ref_lock); - if (udev->refcount == refcount) { - /* prevent further refs being taken */ + if (udev->refcount == 0) { + /* prevent further refs being taken, if any */ udev->refcount = USB_DEV_REF_MAX; - mtx_unlock(&usb_ref_lock); break; } - usbd_enum_unlock(udev); cv_wait(&udev->ref_cv, &usb_ref_lock); - mtx_unlock(&usb_ref_lock); - (void) usbd_enum_lock(udev); } -#endif -} - -/*------------------------------------------------------------------------* - * usb_ref_restore_locked - * - * This function will restore the reference count value after a call - * to "usb_wait_pending_ref_locked()". - *------------------------------------------------------------------------*/ -static void -usb_ref_restore_locked(struct usb_device *udev) -{ -#if USB_HAVE_UGEN - const uint16_t refcount = - usb_proc_is_called_from( - &udev->bus->explore_proc) ? 1 : 2; - - DPRINTF("Refcount = %d\n", (int)refcount); - - /* restore reference count and wakeup waiters, if any */ - mtx_lock(&usb_ref_lock); - udev->refcount = refcount; - cv_broadcast(&udev->ref_cv); mtx_unlock(&usb_ref_lock); #endif } @@ -844,9 +812,6 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd) /* find maximum number of endpoints */ if (ep_max < temp) ep_max = temp; - - /* optimalisation */ - id = (struct usb_interface_descriptor *)ed; } } @@ -1100,10 +1065,12 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev, */ *ppdev = NULL; - device_printf(dev, "at %s, port %d, addr %d " - "(disconnected)\n", - device_get_nameunit(udev->parent_dev), - udev->port_no, udev->address); + if (!rebooting) { + device_printf(dev, "at %s, port %d, addr %d " + "(disconnected)\n", + device_get_nameunit(udev->parent_dev), + udev->port_no, udev->address); + } if (device_is_attached(dev)) { if (udev->flags.peer_suspended) { @@ -1156,9 +1123,6 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index, sx_assert(&udev->enum_sx, SA_LOCKED); - /* wait for pending refs to go away */ - usb_wait_pending_ref_locked(udev); - /* * First detach the child to give the child's detach routine a * chance to detach the sub-devices in the correct order. @@ -1185,8 +1149,6 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index, usb_detach_device_sub(udev, &iface->subdev, &iface->pnpinfo, flag); } - - usb_ref_restore_locked(udev); } /*------------------------------------------------------------------------* @@ -1998,15 +1960,47 @@ usb_make_dev(struct usb_device *udev, const char *devname, int ep, return (pd); } +void +usb_destroy_dev_sync(struct usb_fs_privdata *pd) +{ + DPRINTFN(1, "Destroying device at ugen%d.%d\n", + pd->bus_index, pd->dev_index); + + /* + * Destroy character device synchronously. After this + * all system calls are returned. Can block. + */ + destroy_dev(pd->cdev); + + free(pd, M_USBDEV); +} + void usb_destroy_dev(struct usb_fs_privdata *pd) { + struct usb_bus *bus; + if (pd == NULL) return; - destroy_dev(pd->cdev); + mtx_lock(&usb_ref_lock); + bus = devclass_get_softc(usb_devclass_ptr, pd->bus_index); + mtx_unlock(&usb_ref_lock); - free(pd, M_USBDEV); + if (bus == NULL) { + usb_destroy_dev_sync(pd); + return; + } + + /* make sure we can re-use the device name */ + delist_dev(pd->cdev); + + USB_BUS_LOCK(bus); + LIST_INSERT_HEAD(&bus->pd_cleanup_list, pd, pd_next); + /* get cleanup going */ + usb_proc_msignal(&bus->explore_proc, + &bus->cleanup_msg[0], &bus->cleanup_msg[1]); + USB_BUS_UNLOCK(bus); } static void @@ -2115,8 +2109,10 @@ usb_free_device(struct usb_device *udev, uint8_t flag) #endif #if USB_HAVE_UGEN - printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name, - usb_get_manufacturer(udev), device_get_nameunit(bus->bdev)); + if (!rebooting) { + printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name, + usb_get_manufacturer(udev), device_get_nameunit(bus->bdev)); + } /* Destroy UGEN symlink, if any */ if (udev->ugen_symlink) { @@ -2155,6 +2151,9 @@ usb_free_device(struct usb_device *udev, uint8_t flag) &udev->cs_msg[0], &udev->cs_msg[1]); USB_BUS_UNLOCK(udev->bus); + /* wait for all references to go away */ + usb_wait_pending_refs(udev); + sx_destroy(&udev->enum_sx); sx_destroy(&udev->sr_sx); @@ -2640,14 +2639,8 @@ usb_fifo_free_wrap(struct usb_device *udev, /* no need to free this FIFO */ continue; } - /* wait for pending refs to go away */ - usb_wait_pending_ref_locked(udev); - /* free this FIFO */ usb_fifo_free(f); - - /* restore refcount */ - usb_ref_restore_locked(udev); } } #endif diff --git a/freebsd/sys/dev/usb/usb_device.h b/freebsd/sys/dev/usb/usb_device.h index 361f5c3c..309bd057 100644 --- a/freebsd/sys/dev/usb/usb_device.h +++ b/freebsd/sys/dev/usb/usb_device.h @@ -281,6 +281,7 @@ struct usb_device *usb_alloc_device(device_t parent_dev, struct usb_bus *bus, struct usb_fs_privdata *usb_make_dev(struct usb_device *, const char *, int, int, int, uid_t, gid_t, int); void usb_destroy_dev(struct usb_fs_privdata *); +void usb_destroy_dev_sync(struct usb_fs_privdata *); #endif usb_error_t usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index); diff --git a/freebsd/sys/dev/usb/usb_dynamic.c b/freebsd/sys/dev/usb/usb_dynamic.c index 32ff5e6a..65c9a7d7 100644 --- a/freebsd/sys/dev/usb/usb_dynamic.c +++ b/freebsd/sys/dev/usb/usb_dynamic.c @@ -66,7 +66,7 @@ usb_temp_setup_by_index_t *usb_temp_setup_by_index_p = &usb_temp_setup_by_index_ usb_temp_unsetup_t *usb_temp_unsetup_p = &usb_temp_unsetup_w; usb_test_quirk_t *usb_test_quirk_p = &usb_test_quirk_w; usb_quirk_ioctl_t *usb_quirk_ioctl_p = &usb_quirk_ioctl_w; -devclass_t usb_devclass_ptr = NULL; +devclass_t usb_devclass_ptr; static usb_error_t usb_temp_setup_by_index_w(struct usb_device *udev, uint16_t index) diff --git a/freebsd/sys/dev/usb/usb_freebsd.h b/freebsd/sys/dev/usb/usb_freebsd.h index 4cd1758a..ed2c6bba 100644 --- a/freebsd/sys/dev/usb/usb_freebsd.h +++ b/freebsd/sys/dev/usb/usb_freebsd.h @@ -73,7 +73,7 @@ #define USB_EP0_BUFSIZE 1024 /* bytes */ #define USB_CS_RESET_LIMIT 20 /* failures = 20 * 50 ms = 1sec */ -#define USB_MAX_AUTO_QUIRK 4 /* maximum number of dynamic quirks */ +#define USB_MAX_AUTO_QUIRK 8 /* maximum number of dynamic quirks */ typedef uint32_t usb_timeout_t; /* milliseconds */ typedef uint32_t usb_frlength_t; /* bytes */ diff --git a/freebsd/sys/dev/usb/usb_generic.c b/freebsd/sys/dev/usb/usb_generic.c index e1fc141f..d6172908 100644 --- a/freebsd/sys/dev/usb/usb_generic.c +++ b/freebsd/sys/dev/usb/usb_generic.c @@ -1839,14 +1839,13 @@ ugen_get_port_path(struct usb_fifo *f, struct usb_device_port_path *dpp) if (nlevel > USB_DEVICE_PORT_PATH_MAX) goto error; + /* store total level of ports */ + dpp->udp_port_level = nlevel; + /* store port index array */ next = udev; while (next->parent_hub != NULL) { - nlevel--; - - dpp->udp_port_no[nlevel] = next->port_no; - dpp->udp_port_level = nlevel; - + dpp->udp_port_no[--nlevel] = next->port_no; next = next->parent_hub; } return (0); /* success */ diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c index 9b3bd076..0c62ee08 100644 --- a/freebsd/sys/dev/usb/usb_hub.c +++ b/freebsd/sys/dev/usb/usb_hub.c @@ -603,7 +603,6 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) DPRINTF("reattaching port %d\n", portno); - err = 0; timeout = 0; udev = sc->sc_udev; child = usb_bus_port_get_device(udev->bus, @@ -1595,6 +1594,7 @@ uhub_child_location_string(device_t parent, device_t child, struct uhub_softc *sc; struct usb_hub *hub; struct hub_result res; + char *ugen_name; if (!device_is_attached(parent)) { if (buflen) @@ -1614,10 +1614,16 @@ uhub_child_location_string(device_t parent, device_t child, } goto done; } - snprintf(buf, buflen, "bus=%u hubaddr=%u port=%u devaddr=%u interface=%u", +#if USB_HAVE_UGEN + ugen_name = res.udev->ugen_name; +#else + ugen_name = "?"; +#endif + snprintf(buf, buflen, "bus=%u hubaddr=%u port=%u devaddr=%u interface=%u" + " ugen=%s", (res.udev->parent_hub != NULL) ? res.udev->parent_hub->device_index : 0, res.portno, device_get_unit(res.udev->bus->bdev), - res.udev->device_index, res.iface_index); + res.udev->device_index, res.iface_index, ugen_name); done: mtx_unlock(&Giant); @@ -1659,7 +1665,7 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, "release=0x%04x " "mode=%s " "intclass=0x%02x intsubclass=0x%02x " - "intprotocol=0x%02x " "%s%s", + "intprotocol=0x%02x" "%s%s", UGETW(res.udev->ddesc.idVendor), UGETW(res.udev->ddesc.idProduct), res.udev->ddesc.bDeviceClass, diff --git a/freebsd/sys/dev/usb/usb_msctest.c b/freebsd/sys/dev/usb/usb_msctest.c index 4d28346c..19accddf 100644 --- a/freebsd/sys/dev/usb/usb_msctest.c +++ b/freebsd/sys/dev/usb/usb_msctest.c @@ -100,6 +100,9 @@ static uint8_t scsi_cmotech_eject[] = { 0xff, 0x52, 0x44, 0x45, 0x56, 0x43, static uint8_t scsi_huawei_eject[] = { 0x11, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t scsi_huawei_eject2[] = { 0x11, 0x06, 0x20, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; static uint8_t scsi_tct_eject[] = { 0x06, 0xf5, 0x04, 0x02, 0x52, 0x70 }; static uint8_t scsi_sync_cache[] = { 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -107,6 +110,8 @@ static uint8_t scsi_request_sense[] = { 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static uint8_t scsi_read_capacity[] = { 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t scsi_prevent_removal[] = { 0x1e, 0, 0, 0, 1, 0 }; +static uint8_t scsi_allow_removal[] = { 0x1e, 0, 0, 0, 0, 0 }; #define BULK_SIZE 64 /* dummy */ #define ERR_CSW_FAILED -1 @@ -479,6 +484,7 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun, sc->data_rem = data_len; sc->data_timeout = (data_timeout + USB_MS_HZ); sc->actlen = 0; + sc->error = 0; sc->cmd_len = cmd_len; memset(&sc->cbw->CBWCDB, 0, sizeof(sc->cbw->CBWCDB)); memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len); @@ -689,10 +695,28 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) USB_MS_HZ); if (err != 0) { + if (err != ERR_CSW_FAILED) + goto error; + DPRINTF("Test unit ready failed\n"); + } + + err = bbb_command_start(sc, DIR_OUT, 0, NULL, 0, + &scsi_prevent_removal, sizeof(scsi_prevent_removal), + USB_MS_HZ); + + if (err == 0) { + err = bbb_command_start(sc, DIR_OUT, 0, NULL, 0, + &scsi_allow_removal, sizeof(scsi_allow_removal), + USB_MS_HZ); + } + if (err != 0) { if (err != ERR_CSW_FAILED) goto error; + DPRINTF("Device doesn't handle prevent and allow removal\n"); + usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW); } + timeout = 1; retry_sync_cache: @@ -708,7 +732,6 @@ retry_sync_cache: DPRINTF("Device doesn't handle synchronize cache\n"); usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); - } else { /* @@ -782,6 +805,7 @@ error: DPRINTF("Device did not respond, enabling all quirks\n"); usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); + usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW); usbd_add_dynamic_quirk(udev, UQ_MSC_NO_TEST_UNIT_READY); /* Need to re-enumerate the device */ @@ -800,7 +824,6 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method) if (sc == NULL) return (USB_ERR_INVAL); - err = 0; switch (method) { case MSC_EJECT_STOPUNIT: err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, @@ -831,6 +854,11 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method) &scsi_huawei_eject, sizeof(scsi_huawei_eject), USB_MS_HZ); break; + case MSC_EJECT_HUAWEI2: + err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, + &scsi_huawei_eject2, sizeof(scsi_huawei_eject2), + USB_MS_HZ); + break; case MSC_EJECT_TCT: /* * TCTMobile needs DIR_IN flag. To get it, we @@ -841,9 +869,11 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method) sizeof(scsi_tct_eject), USB_MS_HZ); break; default: - printf("usb_msc_eject: unknown eject method (%d)\n", method); - break; + DPRINTF("Unknown eject method (%d)\n", method); + bbb_detach(sc); + return (USB_ERR_INVAL); } + DPRINTF("Eject CD command status: %s\n", usbd_errstr(err)); bbb_detach(sc); diff --git a/freebsd/sys/dev/usb/usb_msctest.h b/freebsd/sys/dev/usb/usb_msctest.h index e4a717fe..4f64f842 100644 --- a/freebsd/sys/dev/usb/usb_msctest.h +++ b/freebsd/sys/dev/usb/usb_msctest.h @@ -33,6 +33,7 @@ enum { MSC_EJECT_ZTESTOR, MSC_EJECT_CMOTECH, MSC_EJECT_HUAWEI, + MSC_EJECT_HUAWEI2, MSC_EJECT_TCT, }; diff --git a/freebsd/sys/dev/usb/usb_process.c b/freebsd/sys/dev/usb/usb_process.c index d36df36e..a5426e1e 100644 --- a/freebsd/sys/dev/usb/usb_process.c +++ b/freebsd/sys/dev/usb/usb_process.c @@ -26,8 +26,6 @@ * SUCH DAMAGE. */ -#define USB_DEBUG_VAR usb_proc_debug - #include #include #include @@ -51,6 +49,8 @@ #include #include #include + +#define USB_DEBUG_VAR usb_proc_debug #include #include diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c index e9137bd2..6f9d7b12 100644 --- a/freebsd/sys/dev/usb/usb_request.c +++ b/freebsd/sys/dev/usb/usb_request.c @@ -806,8 +806,6 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port) /* check for errors */ if (err) goto done; -#ifdef USB_DEBUG -#endif n = 0; while (1) { /* wait for the device to recover from reset */ diff --git a/freebsd/sys/dev/usb/usb_transfer.c b/freebsd/sys/dev/usb/usb_transfer.c index 205a72f7..ab5558e1 100644 --- a/freebsd/sys/dev/usb/usb_transfer.c +++ b/freebsd/sys/dev/usb/usb_transfer.c @@ -945,7 +945,8 @@ usbd_transfer_setup(struct usb_device *udev, #if USB_HAVE_BUSDMA usb_dma_tag_setup(&info->dma_parent_tag, parm->dma_tag_p, udev->bus->dma_parent_tag[0].tag, - xfer_mtx, &usb_bdma_done_event, 32, parm->dma_tag_max); + xfer_mtx, &usb_bdma_done_event, udev->bus->dma_bits, + parm->dma_tag_max); #endif info->bus = udev->bus; @@ -1373,6 +1374,29 @@ usbd_control_transfer_init(struct usb_xfer *xfer) (req.bmRequestType & UT_READ) ? UE_DIR_IN : UE_DIR_OUT; } +/*------------------------------------------------------------------------* + * usbd_control_transfer_did_data + * + * This function returns non-zero if a control endpoint has + * transferred the first DATA packet after the SETUP packet. + * Else it returns zero. + *------------------------------------------------------------------------*/ +static uint8_t +usbd_control_transfer_did_data(struct usb_xfer *xfer) +{ + struct usb_device_request req; + + /* SETUP packet is not yet sent */ + if (xfer->flags_int.control_hdr != 0) + return (0); + + /* copy out the USB request header */ + usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req)); + + /* compare remainder to the initial value */ + return (xfer->flags_int.control_rem != UGETW(req.wLength)); +} + /*------------------------------------------------------------------------* * usbd_setup_ctrl_transfer * @@ -1478,6 +1502,11 @@ usbd_setup_ctrl_transfer(struct usb_xfer *xfer) len = (xfer->sumlen - sizeof(struct usb_device_request)); } + /* update did data flag */ + + xfer->flags_int.control_did_data = + usbd_control_transfer_did_data(xfer); + /* check if there is a length mismatch */ if (len > xfer->flags_int.control_rem) { diff --git a/freebsd/sys/fs/devfs/devfs_int.h b/freebsd/sys/fs/devfs/devfs_int.h index 429a7e3f..1f4f3e69 100644 --- a/freebsd/sys/fs/devfs/devfs_int.h +++ b/freebsd/sys/fs/devfs/devfs_int.h @@ -56,6 +56,7 @@ struct cdev_priv { u_int cdp_flags; #define CDP_ACTIVE (1 << 0) #define CDP_SCHED_DTR (1 << 1) +#define CDP_UNREF_DTR (1 << 2) #ifndef __rtems__ u_int cdp_inuse; diff --git a/freebsd/sys/kern/kern_mib.c b/freebsd/sys/kern/kern_mib.c index c3605582..d1494fbf 100644 --- a/freebsd/sys/kern/kern_mib.c +++ b/freebsd/sys/kern/kern_mib.c @@ -103,7 +103,7 @@ SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD|CTLFLAG_MPSAFE| CTLFLAG_CAPRD, osrelease, 0, "Operating system release"); SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, BSD, "Operating system revision"); + SYSCTL_NULL_INT_PTR, BSD, "Operating system revision"); SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD|CTLFLAG_MPSAFE, version, 0, "Kernel version"); @@ -131,24 +131,24 @@ SYSCTL_INT(_kern, OID_AUTO, maxusers, CTLFLAG_RDTUN, &maxusers, 0, "Hint for kernel tuning"); SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, ARG_MAX, "Maximum bytes of argument to execve(2)"); + SYSCTL_NULL_INT_PTR, ARG_MAX, "Maximum bytes of argument to execve(2)"); SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, _POSIX_VERSION, "Version of POSIX attempting to comply to"); + SYSCTL_NULL_INT_PTR, _POSIX_VERSION, "Version of POSIX attempting to comply to"); SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RDTUN|CTLFLAG_CAPRD, &ngroups_max, 0, "Maximum number of supplemental groups a user can belong to"); SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, 1, "Whether job control is available"); + SYSCTL_NULL_INT_PTR, 1, "Whether job control is available"); #ifdef _POSIX_SAVED_IDS SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, 1, "Whether saved set-group/user ID is available"); + SYSCTL_NULL_INT_PTR, 1, "Whether saved set-group/user ID is available"); #else SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, 0, "Whether saved set-group/user ID is available"); + SYSCTL_NULL_INT_PTR, 0, "Whether saved set-group/user ID is available"); #endif char kernelname[MAXPATHLEN] = "/kernel"; /* XXX bloat */ @@ -160,10 +160,10 @@ SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD|CTLFLAG_CAPRD, &mp_ncpus, 0, "Number of active CPUs"); SYSCTL_INT(_hw, HW_BYTEORDER, byteorder, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, BYTE_ORDER, "System byte order"); + SYSCTL_NULL_INT_PTR, BYTE_ORDER, "System byte order"); SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, CTLFLAG_RD|CTLFLAG_CAPRD, - 0, PAGE_SIZE, "System memory page size"); + SYSCTL_NULL_INT_PTR, PAGE_SIZE, "System memory page size"); static int sysctl_kern_arnd(SYSCTL_HANDLER_ARGS) @@ -490,50 +490,51 @@ FEATURE(compat_freebsd7, "Compatible with FreeBSD 7"); SYSCTL_STRING(_user, USER_CS_PATH, cs_path, CTLFLAG_RD, "", 0, "PATH that finds all the standard utilities"); SYSCTL_INT(_user, USER_BC_BASE_MAX, bc_base_max, CTLFLAG_RD, - 0, 0, "Max ibase/obase values in bc(1)"); + SYSCTL_NULL_INT_PTR, 0, "Max ibase/obase values in bc(1)"); SYSCTL_INT(_user, USER_BC_DIM_MAX, bc_dim_max, CTLFLAG_RD, - 0, 0, "Max array size in bc(1)"); + SYSCTL_NULL_INT_PTR, 0, "Max array size in bc(1)"); SYSCTL_INT(_user, USER_BC_SCALE_MAX, bc_scale_max, CTLFLAG_RD, - 0, 0, "Max scale value in bc(1)"); + SYSCTL_NULL_INT_PTR, 0, "Max scale value in bc(1)"); SYSCTL_INT(_user, USER_BC_STRING_MAX, bc_string_max, CTLFLAG_RD, - 0, 0, "Max string length in bc(1)"); + SYSCTL_NULL_INT_PTR, 0, "Max string length in bc(1)"); SYSCTL_INT(_user, USER_COLL_WEIGHTS_MAX, coll_weights_max, CTLFLAG_RD, - 0, 0, "Maximum number of weights assigned to an LC_COLLATE locale entry"); -SYSCTL_INT(_user, USER_EXPR_NEST_MAX, expr_nest_max, CTLFLAG_RD, 0, 0, ""); + SYSCTL_NULL_INT_PTR, 0, "Maximum number of weights assigned to an LC_COLLATE locale entry"); +SYSCTL_INT(_user, USER_EXPR_NEST_MAX, expr_nest_max, CTLFLAG_RD, + SYSCTL_NULL_INT_PTR, 0, ""); SYSCTL_INT(_user, USER_LINE_MAX, line_max, CTLFLAG_RD, - 0, 0, "Max length (bytes) of a text-processing utility's input line"); + SYSCTL_NULL_INT_PTR, 0, "Max length (bytes) of a text-processing utility's input line"); SYSCTL_INT(_user, USER_RE_DUP_MAX, re_dup_max, CTLFLAG_RD, - 0, 0, "Maximum number of repeats of a regexp permitted"); + SYSCTL_NULL_INT_PTR, 0, "Maximum number of repeats of a regexp permitted"); SYSCTL_INT(_user, USER_POSIX2_VERSION, posix2_version, CTLFLAG_RD, - 0, 0, + SYSCTL_NULL_INT_PTR, 0, "The version of POSIX 1003.2 with which the system attempts to comply"); SYSCTL_INT(_user, USER_POSIX2_C_BIND, posix2_c_bind, CTLFLAG_RD, - 0, 0, "Whether C development supports the C bindings option"); + SYSCTL_NULL_INT_PTR, 0, "Whether C development supports the C bindings option"); SYSCTL_INT(_user, USER_POSIX2_C_DEV, posix2_c_dev, CTLFLAG_RD, - 0, 0, "Whether system supports the C development utilities option"); + SYSCTL_NULL_INT_PTR, 0, "Whether system supports the C development utilities option"); SYSCTL_INT(_user, USER_POSIX2_CHAR_TERM, posix2_char_term, CTLFLAG_RD, - 0, 0, ""); + SYSCTL_NULL_INT_PTR, 0, ""); SYSCTL_INT(_user, USER_POSIX2_FORT_DEV, posix2_fort_dev, CTLFLAG_RD, - 0, 0, "Whether system supports FORTRAN development utilities"); + SYSCTL_NULL_INT_PTR, 0, "Whether system supports FORTRAN development utilities"); SYSCTL_INT(_user, USER_POSIX2_FORT_RUN, posix2_fort_run, CTLFLAG_RD, - 0, 0, "Whether system supports FORTRAN runtime utilities"); + SYSCTL_NULL_INT_PTR, 0, "Whether system supports FORTRAN runtime utilities"); SYSCTL_INT(_user, USER_POSIX2_LOCALEDEF, posix2_localedef, CTLFLAG_RD, - 0, 0, "Whether system supports creation of locales"); + SYSCTL_NULL_INT_PTR, 0, "Whether system supports creation of locales"); SYSCTL_INT(_user, USER_POSIX2_SW_DEV, posix2_sw_dev, CTLFLAG_RD, - 0, 0, "Whether system supports software development utilities"); + SYSCTL_NULL_INT_PTR, 0, "Whether system supports software development utilities"); SYSCTL_INT(_user, USER_POSIX2_UPE, posix2_upe, CTLFLAG_RD, - 0, 0, "Whether system supports the user portability utilities"); + SYSCTL_NULL_INT_PTR, 0, "Whether system supports the user portability utilities"); SYSCTL_INT(_user, USER_STREAM_MAX, stream_max, CTLFLAG_RD, - 0, 0, "Min Maximum number of streams a process may have open at one time"); + SYSCTL_NULL_INT_PTR, 0, "Min Maximum number of streams a process may have open at one time"); SYSCTL_INT(_user, USER_TZNAME_MAX, tzname_max, CTLFLAG_RD, - 0, 0, "Min Maximum number of types supported for timezone names"); + SYSCTL_NULL_INT_PTR, 0, "Min Maximum number of types supported for timezone names"); #include SYSCTL_INT(_debug_sizeof, OID_AUTO, vnode, CTLFLAG_RD, - 0, sizeof(struct vnode), "sizeof(struct vnode)"); + SYSCTL_NULL_INT_PTR, sizeof(struct vnode), "sizeof(struct vnode)"); SYSCTL_INT(_debug_sizeof, OID_AUTO, proc, CTLFLAG_RD, - 0, sizeof(struct proc), "sizeof(struct proc)"); + SYSCTL_NULL_INT_PTR, sizeof(struct proc), "sizeof(struct proc)"); static int sysctl_kern_pid_max(SYSCTL_HANDLER_ARGS) @@ -566,13 +567,13 @@ SYSCTL_PROC(_kern, OID_AUTO, pid_max, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_TUN | #include #include SYSCTL_INT(_debug_sizeof, OID_AUTO, bio, CTLFLAG_RD, - 0, sizeof(struct bio), "sizeof(struct bio)"); + SYSCTL_NULL_INT_PTR, sizeof(struct bio), "sizeof(struct bio)"); SYSCTL_INT(_debug_sizeof, OID_AUTO, buf, CTLFLAG_RD, - 0, sizeof(struct buf), "sizeof(struct buf)"); + SYSCTL_NULL_INT_PTR, sizeof(struct buf), "sizeof(struct buf)"); #include SYSCTL_INT(_debug_sizeof, OID_AUTO, kinfo_proc, CTLFLAG_RD, - 0, sizeof(struct kinfo_proc), "sizeof(struct kinfo_proc)"); + SYSCTL_NULL_INT_PTR, sizeof(struct kinfo_proc), "sizeof(struct kinfo_proc)"); /* XXX compatibility, remove for 6.0 */ #include diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c index 21083a9a..f85ffc5c 100644 --- a/freebsd/sys/kern/kern_synch.c +++ b/freebsd/sys/kern/kern_synch.c @@ -107,8 +107,7 @@ static fixpt_t cexp[3] = { }; /* kernel uses `FSCALE', userland (SHOULD) use kern.fscale */ -static int fscale __unused = FSCALE; -SYSCTL_INT(_kern, OID_AUTO, fscale, CTLFLAG_RD, 0, FSCALE, ""); +SYSCTL_INT(_kern, OID_AUTO, fscale, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, FSCALE, ""); static void loadav(void *arg); diff --git a/freebsd/sys/kern/kern_time.c b/freebsd/sys/kern/kern_time.c index dbb10d01..2050d03b 100644 --- a/freebsd/sys/kern/kern_time.c +++ b/freebsd/sys/kern/kern_time.c @@ -204,13 +204,10 @@ kern_clock_getcpuclockid2(struct thread *td, id_t id, int which, switch (which) { case CPUCLOCK_WHICH_PID: if (id != 0) { - p = pfind(id); - if (p == NULL) - return (ESRCH); - error = p_cansee(td, p); - PROC_UNLOCK(p); + error = pget(id, PGET_CANSEE | PGET_NOTID, &p); if (error != 0) return (error); + PROC_UNLOCK(p); pid = id; } else { pid = td->td_proc->p_pid; @@ -1356,14 +1353,21 @@ struct timer_getoverrun_args { #endif int sys_ktimer_getoverrun(struct thread *td, struct ktimer_getoverrun_args *uap) +{ + + return (kern_ktimer_getoverrun(td, uap->timerid)); +} + +int +kern_ktimer_getoverrun(struct thread *td, int timer_id) { struct proc *p = td->td_proc; struct itimer *it; int error ; PROC_LOCK(p); - if (uap->timerid < 3 || - (it = itimer_find(p, uap->timerid)) == NULL) { + if (timer_id < 3 || + (it = itimer_find(p, timer_id)) == NULL) { PROC_UNLOCK(p); error = EINVAL; } else { diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c index 951a63c6..1d07718d 100644 --- a/freebsd/sys/kern/subr_bus.c +++ b/freebsd/sys/kern/subr_bus.c @@ -1858,6 +1858,8 @@ device_add_child_ordered(device_t dev, u_int order, const char *name, int unit) PDEBUG(("%s at %s with order %u as unit %d", name, DEVICENAME(dev), order, unit)); + KASSERT(name != NULL || unit == -1, + ("child device with wildcard name and specific unit number")); child = make_device(dev, name, unit); if (child == NULL) @@ -3290,7 +3292,10 @@ resource_list_alloc(struct resource_list *rl, device_t bus, device_t child, rle->flags |= RLE_ALLOCATED; return (rle->res); } - panic("resource_list_alloc: resource entry is busy"); + device_printf(bus, + "resource entry %#x type %d for child %s is busy\n", *rid, + type, device_get_nameunit(child)); + return (NULL); } if (isdefault) { diff --git a/freebsd/sys/kern/subr_hints.c b/freebsd/sys/kern/subr_hints.c index 960ceb8a..b91be201 100644 --- a/freebsd/sys/kern/subr_hints.c +++ b/freebsd/sys/kern/subr_hints.c @@ -141,7 +141,7 @@ res_find(int *line, int *startln, if (strncmp(cp, "hint.", 5) != 0) hit = 0; else - n = sscanf(cp, "hint.%32[^.].%d.%32[^=]=%128s", + n = sscanf(cp, "hint.%32[^.].%d.%32[^=]=%127s", r_name, &r_unit, r_resname, r_value); if (hit && n != 4) { printf("CONFIG: invalid hint '%s'\n", cp); diff --git a/freebsd/sys/kern/subr_rman.c b/freebsd/sys/kern/subr_rman.c index c158b36e..69f8d359 100644 --- a/freebsd/sys/kern/subr_rman.c +++ b/freebsd/sys/kern/subr_rman.c @@ -96,12 +96,12 @@ struct resource_i { u_long r_end; /* index of the last entry (inclusive) */ u_int r_flags; void *r_virtual; /* virtual address of this resource */ - struct device *r_dev; /* device which has allocated this resource */ - struct rman *r_rm; /* resource manager from whence this came */ + struct device *r_dev; /* device which has allocated this resource */ + struct rman *r_rm; /* resource manager from whence this came */ int r_rid; /* optional rid for this resource. */ }; -static int rman_debug = 0; +static int rman_debug = 0; TUNABLE_INT("debug.rman_debug", &rman_debug); SYSCTL_INT(_debug, OID_AUTO, rman_debug, CTLFLAG_RW, &rman_debug, 0, "rman debug"); @@ -110,12 +110,9 @@ SYSCTL_INT(_debug, OID_AUTO, rman_debug, CTLFLAG_RW, static MALLOC_DEFINE(M_RMAN, "rman", "Resource manager"); -struct rman_head rman_head; -static struct mtx rman_mtx; /* mutex to protect rman_head */ -static int int_rman_activate_resource(struct rman *rm, struct resource_i *r, - struct resource_i **whohas); -static int int_rman_deactivate_resource(struct resource_i *r); -static int int_rman_release_resource(struct rman *rm, struct resource_i *r); +struct rman_head rman_head; +static struct mtx rman_mtx; /* mutex to protect rman_head */ +static int int_rman_release_resource(struct rman *rm, struct resource_i *r); static __inline struct resource_i * int_alloc_resource(int malloc_flag) @@ -314,12 +311,12 @@ rman_last_free_region(struct rman *rm, u_long *start, u_long *end) int rman_adjust_resource(struct resource *rr, u_long start, u_long end) { - struct resource_i *r, *s, *t, *new; - struct rman *rm; + struct resource_i *r, *s, *t, *new; + struct rman *rm; /* Not supported for shared resources. */ r = rr->__r_i; - if (r->r_flags & (RF_TIMESHARE | RF_SHAREABLE)) + if (r->r_flags & RF_SHAREABLE) return (EINVAL); /* @@ -432,14 +429,16 @@ rman_adjust_resource(struct resource *rr, u_long start, u_long end) return (0); } +#define SHARE_TYPE(f) (f & (RF_SHAREABLE | RF_PREFETCHABLE)) + struct resource * rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, - u_long count, u_long bound, u_int flags, - struct device *dev) + u_long count, u_long bound, u_int flags, + struct device *dev) { - u_int want_activate; - struct resource_i *r, *s, *rv; - u_long rstart, rend, amask, bmask; + u_int new_rflags; + struct resource_i *r, *s, *rv; + u_long rstart, rend, amask, bmask; rv = NULL; @@ -447,8 +446,9 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, "length %#lx, flags %u, device %s\n", rm->rm_descr, start, end, count, flags, dev == NULL ? "" : device_get_nameunit(dev))); - want_activate = (flags & RF_ACTIVE); - flags &= ~RF_ACTIVE; + KASSERT((flags & RF_FIRSTSHARE) == 0, + ("invalid flags %#x", flags)); + new_rflags = (flags & ~RF_FIRSTSHARE) | RF_ALLOCATED; mtx_lock(rm->rm_mtx); @@ -463,10 +463,8 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, } amask = (1ul << RF_ALIGNMENT(flags)) - 1; - if (start > ULONG_MAX - amask) { - DPRINTF(("start+amask would wrap around\n")); - goto out; - } + KASSERT(start <= ULONG_MAX - amask, + ("start (%#lx) + amask (%#lx) would wrap around", start, amask)); /* If bound is 0, bmask will also be 0 */ bmask = ~(bound - 1); @@ -519,7 +517,7 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, if ((s->r_end - s->r_start + 1) == count) { DPRINTF(("candidate region is entire chunk\n")); rv = s; - rv->r_flags |= RF_ALLOCATED | flags; + rv->r_flags = new_rflags; rv->r_dev = dev; goto out; } @@ -539,7 +537,7 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, goto out; rv->r_start = rstart; rv->r_end = rstart + count - 1; - rv->r_flags = flags | RF_ALLOCATED; + rv->r_flags = new_rflags; rv->r_dev = dev; rv->r_rm = rm; @@ -596,11 +594,11 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, * additional work, but this does not seem warranted.) */ DPRINTF(("no unshared regions found\n")); - if ((flags & (RF_SHAREABLE | RF_TIMESHARE)) == 0) + if ((flags & RF_SHAREABLE) == 0) goto out; for (s = r; s && s->r_end <= end; s = TAILQ_NEXT(s, r_link)) { - if ((s->r_flags & flags) == flags && + if (SHARE_TYPE(s->r_flags) == SHARE_TYPE(flags) && s->r_start >= start && (s->r_end - s->r_start + 1) == count && (s->r_start & amask) == 0 && @@ -610,8 +608,7 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, goto out; rv->r_start = s->r_start; rv->r_end = s->r_end; - rv->r_flags = s->r_flags & - (RF_ALLOCATED | RF_SHAREABLE | RF_TIMESHARE); + rv->r_flags = new_rflags; rv->r_dev = dev; rv->r_rm = rm; if (s->r_sharehead == NULL) { @@ -632,26 +629,11 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, goto out; } } - /* * We couldn't find anything. */ -out: - /* - * If the user specified RF_ACTIVE in the initial flags, - * which is reflected in `want_activate', we attempt to atomically - * activate the resource. If this fails, we release the resource - * and indicate overall failure. (This behavior probably doesn't - * make sense for RF_TIMESHARE-type resources.) - */ - if (rv && want_activate) { - struct resource_i *whohas; - if (int_rman_activate_resource(rm, rv, &whohas)) { - int_rman_release_resource(rm, rv); - rv = NULL; - } - } +out: mtx_unlock(rm->rm_mtx); return (rv == NULL ? NULL : &rv->r_r); } @@ -665,102 +647,28 @@ rman_reserve_resource(struct rman *rm, u_long start, u_long end, u_long count, dev)); } -static int -int_rman_activate_resource(struct rman *rm, struct resource_i *r, - struct resource_i **whohas) -{ - struct resource_i *s; - int ok; - - /* - * If we are not timesharing, then there is nothing much to do. - * If we already have the resource, then there is nothing at all to do. - * If we are not on a sharing list with anybody else, then there is - * little to do. - */ - if ((r->r_flags & RF_TIMESHARE) == 0 - || (r->r_flags & RF_ACTIVE) != 0 - || r->r_sharehead == NULL) { - r->r_flags |= RF_ACTIVE; - return 0; - } - - ok = 1; - for (s = LIST_FIRST(r->r_sharehead); s && ok; - s = LIST_NEXT(s, r_sharelink)) { - if ((s->r_flags & RF_ACTIVE) != 0) { - ok = 0; - *whohas = s; - } - } - if (ok) { - r->r_flags |= RF_ACTIVE; - return 0; - } - return EBUSY; -} - int rman_activate_resource(struct resource *re) { - int rv; - struct resource_i *r, *whohas; + struct resource_i *r; struct rman *rm; r = re->__r_i; rm = r->r_rm; mtx_lock(rm->rm_mtx); - rv = int_rman_activate_resource(rm, r, &whohas); + r->r_flags |= RF_ACTIVE; mtx_unlock(rm->rm_mtx); - return rv; -} - -int -rman_await_resource(struct resource *re, int pri, int timo) -{ - int rv; - struct resource_i *r, *whohas; - struct rman *rm; - - r = re->__r_i; - rm = r->r_rm; - mtx_lock(rm->rm_mtx); - for (;;) { - rv = int_rman_activate_resource(rm, r, &whohas); - if (rv != EBUSY) - return (rv); /* returns with mutex held */ - - if (r->r_sharehead == NULL) - panic("rman_await_resource"); - whohas->r_flags |= RF_WANTED; - rv = msleep(r->r_sharehead, rm->rm_mtx, pri, "rmwait", timo); - if (rv) { - mtx_unlock(rm->rm_mtx); - return (rv); - } - } -} - -static int -int_rman_deactivate_resource(struct resource_i *r) -{ - - r->r_flags &= ~RF_ACTIVE; - if (r->r_flags & RF_WANTED) { - r->r_flags &= ~RF_WANTED; - wakeup(r->r_sharehead); - } return 0; } int rman_deactivate_resource(struct resource *r) { - struct rman *rm; + struct rman *rm; rm = r->__r_i->r_rm; mtx_lock(rm->rm_mtx); - int_rman_deactivate_resource(r->__r_i); + r->__r_i->r_flags &= ~RF_ACTIVE; mtx_unlock(rm->rm_mtx); return 0; } @@ -768,10 +676,10 @@ rman_deactivate_resource(struct resource *r) static int int_rman_release_resource(struct rman *rm, struct resource_i *r) { - struct resource_i *s, *t; + struct resource_i *s, *t; if (r->r_flags & RF_ACTIVE) - int_rman_deactivate_resource(r); + r->r_flags &= ~RF_ACTIVE; /* * Check for a sharing list first. If there is one, then we don't @@ -862,9 +770,9 @@ out: int rman_release_resource(struct resource *re) { - int rv; - struct resource_i *r; - struct rman *rm; + int rv; + struct resource_i *r; + struct rman *rm; r = re->__r_i; rm = r->r_rm; @@ -877,7 +785,7 @@ rman_release_resource(struct resource *re) uint32_t rman_make_alignment_flags(uint32_t size) { - int i; + int i; /* * Find the hightest bit set, and add one if more than one bit @@ -895,96 +803,112 @@ rman_make_alignment_flags(uint32_t size) void rman_set_start(struct resource *r, u_long start) { + r->__r_i->r_start = start; } u_long rman_get_start(struct resource *r) { + return (r->__r_i->r_start); } void rman_set_end(struct resource *r, u_long end) { + r->__r_i->r_end = end; } u_long rman_get_end(struct resource *r) { + return (r->__r_i->r_end); } u_long rman_get_size(struct resource *r) { + return (r->__r_i->r_end - r->__r_i->r_start + 1); } u_int rman_get_flags(struct resource *r) { + return (r->__r_i->r_flags); } void rman_set_virtual(struct resource *r, void *v) { + r->__r_i->r_virtual = v; } void * rman_get_virtual(struct resource *r) { + return (r->__r_i->r_virtual); } void rman_set_bustag(struct resource *r, bus_space_tag_t t) { + r->r_bustag = t; } bus_space_tag_t rman_get_bustag(struct resource *r) { + return (r->r_bustag); } void rman_set_bushandle(struct resource *r, bus_space_handle_t h) { + r->r_bushandle = h; } bus_space_handle_t rman_get_bushandle(struct resource *r) { + return (r->r_bushandle); } void rman_set_rid(struct resource *r, int rid) { + r->__r_i->r_rid = rid; } int rman_get_rid(struct resource *r) { + return (r->__r_i->r_rid); } void rman_set_device(struct resource *r, struct device *dev) { + r->__r_i->r_dev = dev; } struct device * rman_get_device(struct resource *r) { + return (r->__r_i->r_dev); } diff --git a/freebsd/sys/kern/subr_uio.c b/freebsd/sys/kern/subr_uio.c index 74f01ffa..d38b337e 100644 --- a/freebsd/sys/kern/subr_uio.c +++ b/freebsd/sys/kern/subr_uio.c @@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$"); #endif #ifndef __rtems__ -SYSCTL_INT(_kern, KERN_IOV_MAX, iov_max, CTLFLAG_RD, NULL, UIO_MAXIOV, +SYSCTL_INT(_kern, KERN_IOV_MAX, iov_max, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, UIO_MAXIOV, "Maximum number of elements in an I/O vector; sysconf(_SC_IOV_MAX)"); #endif /* __rtems__ */ diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c index eb1ed37d..0ed027d5 100644 --- a/freebsd/sys/kern/sys_generic.c +++ b/freebsd/sys/kern/sys_generic.c @@ -79,6 +79,20 @@ __FBSDID("$FreeBSD$"); #include #endif /* __rtems__ */ +/* + * The following macro defines how many bytes will be allocated from + * the stack instead of memory allocated when passing the IOCTL data + * structures from userspace and to the kernel. Some IOCTLs having + * small data structures are used very frequently and this small + * buffer on the stack gives a significant speedup improvement for + * those requests. The value of this define should be greater or equal + * to 64 bytes and should also be power of two. The data structure is + * currently hard-aligned to a 8-byte boundary on the stack. This + * should currently be sufficient for all supported platforms. + */ +#define SYS_IOCTL_SMALL_SIZE 128 /* bytes */ +#define SYS_IOCTL_SMALL_ALIGN 8 /* bytes */ + #ifndef __rtems__ int iosize_max_clamp = 1; SYSCTL_INT(_debug, OID_AUTO, iosize_max_clamp, CTLFLAG_RW, @@ -652,6 +666,7 @@ struct ioctl_args { int sys_ioctl(struct thread *td, struct ioctl_args *uap) { + u_char smalldata[SYS_IOCTL_SMALL_SIZE] __aligned(SYS_IOCTL_SMALL_ALIGN); u_long com; int arg, error; u_int size; @@ -686,17 +701,18 @@ sys_ioctl(struct thread *td, struct ioctl_args *uap) arg = (intptr_t)uap->data; data = (void *)&arg; size = 0; - } else - data = malloc((u_long)size, M_IOCTLOPS, M_WAITOK); + } else { + if (size > SYS_IOCTL_SMALL_SIZE) + data = malloc((u_long)size, M_IOCTLOPS, M_WAITOK); + else + data = smalldata; + } } else data = (void *)&uap->data; if (com & IOC_IN) { error = copyin(uap->data, data, (u_int)size); - if (error) { - if (size > 0) - free(data, M_IOCTLOPS); - return (error); - } + if (error != 0) + goto out; } else if (com & IOC_OUT) { /* * Zero the buffer so the user always @@ -710,7 +726,8 @@ sys_ioctl(struct thread *td, struct ioctl_args *uap) if (error == 0 && (com & IOC_OUT)) error = copyout(data, uap->data, (u_int)size); - if (size > 0) +out: + if (size > SYS_IOCTL_SMALL_SIZE) free(data, M_IOCTLOPS); return (error); } diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c index 03b18b92..bcbd0d9a 100644 --- a/freebsd/sys/kern/uipc_sockbuf.c +++ b/freebsd/sys/kern/uipc_sockbuf.c @@ -994,6 +994,37 @@ sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff) return (ret); } +/* + * Return the first mbuf and the mbuf data offset for the provided + * send offset without changing the "sb_sndptroff" field. + */ +struct mbuf * +sbsndmbuf(struct sockbuf *sb, u_int off, u_int *moff) +{ + struct mbuf *m; + + KASSERT(sb->sb_mb != NULL, ("%s: sb_mb is NULL", __func__)); + + /* + * If the "off" is below the stored offset, which happens on + * retransmits, just use "sb_mb": + */ + if (sb->sb_sndptr == NULL || sb->sb_sndptroff > off) { + m = sb->sb_mb; + } else { + m = sb->sb_sndptr; + off -= sb->sb_sndptroff; + } + while (off > 0 && m != NULL) { + if (off < m->m_len) + break; + off -= m->m_len; + m = m->m_next; + } + *moff = off; + return (m); +} + /* * Drop a record off the front of a sockbuf and move the next record to the * front. diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c index 2dc76a9f..a37518f2 100644 --- a/freebsd/sys/kern/uipc_socket.c +++ b/freebsd/sys/kern/uipc_socket.c @@ -2085,7 +2085,7 @@ restart: /* Socket buffer got some data that we shall deliver now. */ if (sb->sb_cc > 0 && !(flags & MSG_WAITALL) && - ((sb->sb_flags & SS_NBIO) || + ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)) || sb->sb_cc >= sb->sb_lowat || sb->sb_cc >= uio->uio_resid || @@ -2337,7 +2337,8 @@ soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio, * Process one or more MT_CONTROL mbufs present before any data mbufs * in the first mbuf chain on the socket buffer. We call into the * protocol to perform externalization (or freeing if controlp == - * NULL). + * NULL). In some cases there can be only MT_CONTROL mbufs without + * MT_DATA mbufs. */ if (m->m_type == MT_CONTROL) { struct mbuf *cm = NULL, *cmn; @@ -2367,8 +2368,8 @@ soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio, cm = cmn; } } - KASSERT(m->m_type == MT_DATA, ("soreceive_dgram: !data")); - + KASSERT(m == NULL || m->m_type == MT_DATA, + ("soreceive_dgram: !data")); while (m != NULL && uio->uio_resid > 0) { len = uio->uio_resid; if (len > m->m_len) @@ -2385,9 +2386,10 @@ soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio, m->m_len -= len; } } - if (m != NULL) + if (m != NULL) { flags |= MSG_TRUNC; - m_freem(m); + m_freem(m); + } if (flagsp != NULL) *flagsp |= flags; return (0); diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c index b7cc060d..d2ee61ce 100644 --- a/freebsd/sys/kern/uipc_usrreq.c +++ b/freebsd/sys/kern/uipc_usrreq.c @@ -986,7 +986,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, from = &sun_noname; so2 = unp2->unp_socket; SOCKBUF_LOCK(&so2->so_rcv); - if (sbappendaddr_nospacecheck_locked(&so2->so_rcv, from, m, + if (sbappendaddr_locked(&so2->so_rcv, from, m, control)) { sorwakeup_locked(so2); m = NULL; diff --git a/freebsd/sys/net/bpf.c b/freebsd/sys/net/bpf.c index 41756658..7a4eaf9f 100644 --- a/freebsd/sys/net/bpf.c +++ b/freebsd/sys/net/bpf.c @@ -697,6 +697,67 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp) EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); } +/* + * Check if we need to upgrade our descriptor @d from write-only mode. + */ +static int +bpf_check_upgrade(u_long cmd, struct bpf_d *d, struct bpf_insn *fcode, int flen) +{ + int is_snap, need_upgrade; + + /* + * Check if we've already upgraded or new filter is empty. + */ + if (d->bd_writer == 0 || fcode == NULL) + return (0); + + need_upgrade = 0; + + /* + * Check if cmd looks like snaplen setting from + * pcap_bpf.c:pcap_open_live(). + * Note we're not checking .k value here: + * while pcap_open_live() definitely sets to to non-zero value, + * we'd prefer to treat k=0 (deny ALL) case the same way: e.g. + * do not consider upgrading immediately + */ + if (cmd == BIOCSETF && flen == 1 && fcode[0].code == (BPF_RET | BPF_K)) + is_snap = 1; + else + is_snap = 0; + + if (is_snap == 0) { + /* + * We're setting first filter and it doesn't look like + * setting snaplen. We're probably using bpf directly. + * Upgrade immediately. + */ + need_upgrade = 1; + } else { + /* + * Do not require upgrade by first BIOCSETF + * (used to set snaplen) by pcap_open_live(). + */ + + if (--d->bd_writer == 0) { + /* + * First snaplen filter has already + * been set. This is probably catch-all + * filter + */ + need_upgrade = 1; + } + } + + CTR5(KTR_NET, + "%s: filter function set by pid %d, " + "bd_writer counter %d, snap %d upgrade %d", + __func__, d->bd_pid, d->bd_writer, + is_snap, need_upgrade); + + return (need_upgrade); +} + /* * Add d to the list of active bp filters. * Reuqires bpf_attachd() to be called before @@ -1899,17 +1960,7 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd) if (cmd == BIOCSETF) reset_d(d); - if (fcode != NULL) { - /* - * Do not require upgrade by first BIOCSETF - * (used to set snaplen) by pcap_open_live(). - */ - if (d->bd_writer != 0 && --d->bd_writer == 0) - need_upgrade = 1; - CTR4(KTR_NET, "%s: filter function set by pid %d, " - "bd_writer counter %d, need_upgrade %d", - __func__, d->bd_pid, d->bd_writer, need_upgrade); - } + need_upgrade = bpf_check_upgrade(cmd, d, fcode, flen); } BPFD_UNLOCK(d); if (d->bd_bif != NULL) @@ -1922,7 +1973,7 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd) #endif /* Move d to active readers list. */ - if (need_upgrade) + if (need_upgrade != 0) bpf_upgraded(d); BPF_UNLOCK(); @@ -3036,7 +3087,8 @@ bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd) static int bpf_stats_sysctl(SYSCTL_HANDLER_ARGS) { - struct xbpf_d *xbdbuf, *xbd, zerostats; + static const struct xbpf_d zerostats; + struct xbpf_d *xbdbuf, *xbd, tempstats; int index, error; struct bpf_if *bp; struct bpf_d *bd; @@ -3056,11 +3108,13 @@ bpf_stats_sysctl(SYSCTL_HANDLER_ARGS) * as we aren't allowing the user to set the counters currently. */ if (req->newptr != NULL) { - if (req->newlen != sizeof(zerostats)) + if (req->newlen != sizeof(tempstats)) return (EINVAL); - bzero(&zerostats, sizeof(zerostats)); - xbd = req->newptr; - if (bcmp(xbd, &zerostats, sizeof(*xbd)) != 0) + memset(&tempstats, 0, sizeof(tempstats)); + error = SYSCTL_IN(req, &tempstats, sizeof(tempstats)); + if (error) + return (error); + if (bcmp(&tempstats, &zerostats, sizeof(tempstats)) != 0) return (EINVAL); bpf_zero_counters(); return (0); diff --git a/freebsd/sys/net/ieee8023ad_lacp.c b/freebsd/sys/net/ieee8023ad_lacp.c index 20288926..5172ad54 100644 --- a/freebsd/sys/net/ieee8023ad_lacp.c +++ b/freebsd/sys/net/ieee8023ad_lacp.c @@ -586,10 +586,20 @@ lacp_req(struct lagg_softc *sc, caddr_t data) { struct lacp_opreq *req = (struct lacp_opreq *)data; struct lacp_softc *lsc = LACP_SOFTC(sc); - struct lacp_aggregator *la = lsc->lsc_active_aggregator; + struct lacp_aggregator *la; - LACP_LOCK(lsc); bzero(req, sizeof(struct lacp_opreq)); + + /* + * If the LACP softc is NULL, return with the opreq structure full of + * zeros. It is normal for the softc to be NULL while the lagg is + * being destroyed. + */ + if (NULL == lsc) + return; + + la = lsc->lsc_active_aggregator; + LACP_LOCK(lsc); if (la != NULL) { req->actor_prio = ntohs(la->la_actor.lip_systemid.lsi_prio); memcpy(&req->actor_mac, &la->la_actor.lip_systemid.lsi_mac, diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c index 0bd72e44..f227ed9f 100644 --- a/freebsd/sys/net/if.c +++ b/freebsd/sys/net/if.c @@ -160,6 +160,7 @@ static int ifconf(u_long, caddr_t); static void if_freemulti(struct ifmultiaddr *); static void if_init(void *); static void if_grow(void); +static void if_input_default(struct ifnet *, struct mbuf *); static void if_route(struct ifnet *, int flag, int fam); static int if_setflag(struct ifnet *, int, int, int *, int); static int if_transmit(struct ifnet *ifp, struct mbuf *m); @@ -601,6 +602,57 @@ if_attach(struct ifnet *ifp) if_attach_internal(ifp, 0); } +/* + * Compute the least common TSO limit. + */ +void +if_hw_tsomax_common(struct ifnet *ifp, struct ifnet_hw_tsomax *pmax) +{ + /* + * 1) If there is no limit currently, take the limit from + * the network adapter. + * + * 2) If the network adapter has a limit below the current + * limit, apply it. + */ + if (pmax->tsomaxbytes == 0 || (ifp->if_hw_tsomax != 0 && + ifp->if_hw_tsomax < pmax->tsomaxbytes)) { + pmax->tsomaxbytes = ifp->if_hw_tsomax; + } + if (pmax->tsomaxsegcount == 0 || (ifp->if_hw_tsomaxsegcount != 0 && + ifp->if_hw_tsomaxsegcount < pmax->tsomaxsegcount)) { + pmax->tsomaxsegcount = ifp->if_hw_tsomaxsegcount; + } + if (pmax->tsomaxsegsize == 0 || (ifp->if_hw_tsomaxsegsize != 0 && + ifp->if_hw_tsomaxsegsize < pmax->tsomaxsegsize)) { + pmax->tsomaxsegsize = ifp->if_hw_tsomaxsegsize; + } +} + +/* + * Update TSO limit of a network adapter. + * + * Returns zero if no change. Else non-zero. + */ +int +if_hw_tsomax_update(struct ifnet *ifp, struct ifnet_hw_tsomax *pmax) +{ + int retval = 0; + if (ifp->if_hw_tsomax != pmax->tsomaxbytes) { + ifp->if_hw_tsomax = pmax->tsomaxbytes; + retval++; + } + if (ifp->if_hw_tsomaxsegsize != pmax->tsomaxsegsize) { + ifp->if_hw_tsomaxsegsize = pmax->tsomaxsegsize; + retval++; + } + if (ifp->if_hw_tsomaxsegcount != pmax->tsomaxsegcount) { + ifp->if_hw_tsomaxsegcount = pmax->tsomaxsegcount; + retval++; + } + return (retval); +} + static void if_attach_internal(struct ifnet *ifp, int vmove) { @@ -632,7 +684,9 @@ if_attach_internal(struct ifnet *ifp, int vmove) ifp->if_transmit = if_transmit; ifp->if_qflush = if_qflush; } - + if (ifp->if_input == NULL) + ifp->if_input = if_input_default; + if (!vmove) { #ifdef MAC mac_ifnet_create(ifp); @@ -675,13 +729,29 @@ if_attach_internal(struct ifnet *ifp, int vmove) ifp->if_broadcastaddr = NULL; #if defined(INET) || defined(INET6) - /* Initialize to max value. */ - if (ifp->if_hw_tsomax == 0) - ifp->if_hw_tsomax = min(IP_MAXPACKET, 32 * MCLBYTES - + /* Use defaults for TSO, if nothing is set */ + if (ifp->if_hw_tsomax == 0 && + ifp->if_hw_tsomaxsegcount == 0 && + ifp->if_hw_tsomaxsegsize == 0) { + /* + * The TSO defaults needs to be such that an + * NFS mbuf list of 35 mbufs totalling just + * below 64K works and that a chain of mbufs + * can be defragged into at most 32 segments: + */ + ifp->if_hw_tsomax = min(IP_MAXPACKET, (32 * MCLBYTES) - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN)); - KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET && - ifp->if_hw_tsomax >= IP_MAXPACKET / 8, - ("%s: tsomax outside of range", __func__)); + ifp->if_hw_tsomaxsegcount = 35; + ifp->if_hw_tsomaxsegsize = 2048; /* 2K */ + + /* XXX some drivers set IFCAP_TSO after ethernet attach */ + if (ifp->if_capabilities & IFCAP_TSO) { + if_printf(ifp, "Using defaults for TSO: %u/%u/%u\n", + ifp->if_hw_tsomax, + ifp->if_hw_tsomaxsegcount, + ifp->if_hw_tsomaxsegsize); + } + } #endif } #ifdef VIMAGE @@ -1481,7 +1551,7 @@ ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia) info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC; info.rti_info[RTAX_DST] = ia; info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; - error = rtrequest1_fib(RTM_ADD, &info, &rt, 0); + error = rtrequest1_fib(RTM_ADD, &info, &rt, ifa->ifa_ifp->if_fib); if (error == 0 && rt != NULL) { RT_LOCK(rt); @@ -1513,7 +1583,7 @@ ifa_del_loopback_route(struct ifaddr *ifa, struct sockaddr *ia) info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC; info.rti_info[RTAX_DST] = ia; info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; - error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0); + error = rtrequest1_fib(RTM_DELETE, &info, NULL, ifa->ifa_ifp->if_fib); if (error != 0) log(LOG_INFO, "ifa_del_loopback_route: deletion failed\n"); @@ -1630,7 +1700,7 @@ done: */ /*ARGSUSED*/ struct ifaddr * -ifa_ifwithdstaddr(struct sockaddr *addr) +ifa_ifwithdstaddr_fib(struct sockaddr *addr, int fibnum) { struct ifnet *ifp; struct ifaddr *ifa; @@ -1639,6 +1709,8 @@ ifa_ifwithdstaddr(struct sockaddr *addr) TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if ((ifp->if_flags & IFF_POINTOPOINT) == 0) continue; + if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum)) + continue; IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != addr->sa_family) @@ -1658,12 +1730,19 @@ done: return (ifa); } +struct ifaddr * +ifa_ifwithdstaddr(struct sockaddr *addr) +{ + + return (ifa_ifwithdstaddr_fib(addr, RT_ALL_FIBS)); +} + /* * Find an interface on a specific network. If many, choice * is most specific found. */ struct ifaddr * -ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp) +ifa_ifwithnet_fib(struct sockaddr *addr, int ignore_ptp, int fibnum) { struct ifnet *ifp; struct ifaddr *ifa; @@ -1683,12 +1762,14 @@ ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp) /* * Scan though each interface, looking for ones that have addresses - * in this address family. Maintain a reference on ifa_maybe once - * we find one, as we release the IF_ADDR_RLOCK() that kept it stable - * when we move onto the next interface. + * in this address family and the requested fib. Maintain a reference + * on ifa_maybe once we find one, as we release the IF_ADDR_RLOCK() that + * kept it stable when we move onto the next interface. */ IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { + if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum)) + continue; IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { char *cp, *cp2, *cp3; @@ -1770,6 +1851,13 @@ done: return (ifa); } +struct ifaddr * +ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp) +{ + + return (ifa_ifwithnet_fib(addr, ignore_ptp, RT_ALL_FIBS)); +} + /* * Find an interface address specific to an interface best matching * a given address. @@ -3398,6 +3486,13 @@ if_transmit(struct ifnet *ifp, struct mbuf *m) return (error); } +static void +if_input_default(struct ifnet *ifp __unused, struct mbuf *m) +{ + + m_freem(m); +} + int if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust) { diff --git a/freebsd/sys/net/if_lagg.c b/freebsd/sys/net/if_lagg.c index b0be3643..46f3f46c 100644 --- a/freebsd/sys/net/if_lagg.c +++ b/freebsd/sys/net/if_lagg.c @@ -288,10 +288,10 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params) oid = SYSCTL_ADD_NODE(&sc->ctx, &SYSCTL_NODE_CHILDREN(_net_link, lagg), OID_AUTO, num, CTLFLAG_RD, NULL, ""); SYSCTL_ADD_INT(&sc->ctx, SYSCTL_CHILDREN(oid), OID_AUTO, - "use_flowid", CTLTYPE_INT|CTLFLAG_RW, &sc->use_flowid, sc->use_flowid, + "use_flowid", CTLFLAG_RW, &sc->use_flowid, sc->use_flowid, "Use flow id for load sharing"); SYSCTL_ADD_INT(&sc->ctx, SYSCTL_CHILDREN(oid), OID_AUTO, - "count", CTLTYPE_INT|CTLFLAG_RD, &sc->sc_count, sc->sc_count, + "count", CTLFLAG_RD, &sc->sc_count, sc->sc_count, "Total number of ports"); /* Hash all layers by default */ sc->sc_flags = LAGG_F_HASHL2|LAGG_F_HASHL3|LAGG_F_HASHL4; @@ -408,23 +408,18 @@ lagg_capabilities(struct lagg_softc *sc) struct lagg_port *lp; int cap = ~0, ena = ~0; u_long hwa = ~0UL; -#if defined(INET) || defined(INET6) - u_int hw_tsomax = IP_MAXPACKET; /* Initialize to the maximum value. */ -#else - u_int hw_tsomax = ~0; /* if_hw_tsomax is only for INET/INET6, but.. */ -#endif + struct ifnet_hw_tsomax hw_tsomax; LAGG_WLOCK_ASSERT(sc); + memset(&hw_tsomax, 0, sizeof(hw_tsomax)); + /* Get capabilities from the lagg ports */ SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { cap &= lp->lp_ifp->if_capabilities; ena &= lp->lp_ifp->if_capenable; hwa &= lp->lp_ifp->if_hwassist; - /* Set to the minimum value of the lagg ports. */ - if (lp->lp_ifp->if_hw_tsomax < hw_tsomax && - lp->lp_ifp->if_hw_tsomax > 0) - hw_tsomax = lp->lp_ifp->if_hw_tsomax; + if_hw_tsomax_common(lp->lp_ifp, &hw_tsomax); } cap = (cap == ~0 ? 0 : cap); ena = (ena == ~0 ? 0 : ena); @@ -433,11 +428,10 @@ lagg_capabilities(struct lagg_softc *sc) if (sc->sc_ifp->if_capabilities != cap || sc->sc_ifp->if_capenable != ena || sc->sc_ifp->if_hwassist != hwa || - sc->sc_ifp->if_hw_tsomax != hw_tsomax) { + if_hw_tsomax_update(sc->sc_ifp, &hw_tsomax) != 0) { sc->sc_ifp->if_capabilities = cap; sc->sc_ifp->if_capenable = ena; sc->sc_ifp->if_hwassist = hwa; - sc->sc_ifp->if_hw_tsomax = hw_tsomax; getmicrotime(&sc->sc_ifp->if_lastchange); if (sc->sc_ifflags & IFF_DEBUG) @@ -525,7 +519,7 @@ static int lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) { struct lagg_softc *sc_ptr; - struct lagg_port *lp; + struct lagg_port *lp, *tlp; int error = 0; LAGG_WLOCK_ASSERT(sc); @@ -632,8 +626,23 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp)); } - /* Insert into the list of ports */ - SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries); + /* + * Insert into the list of ports. + * Keep ports sorted by if_index. It is handy, when configuration + * is predictable and `ifconfig laggN create ...` command + * will lead to the same result each time. + */ + SLIST_FOREACH(tlp, &sc->sc_ports, lp_entries) { + if (tlp->lp_ifp->if_index < ifp->if_index && ( + SLIST_NEXT(tlp, lp_entries) == NULL || + SLIST_NEXT(tlp, lp_entries)->lp_ifp->if_index > + ifp->if_index)) + break; + } + if (tlp != NULL) + SLIST_INSERT_AFTER(tlp, lp, lp_entries); + else + SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries); sc->sc_count++; /* Update lagg capabilities */ diff --git a/freebsd/sys/net/if_stf.c b/freebsd/sys/net/if_stf.c index 985c5651..e88fd34d 100644 --- a/freebsd/sys/net/if_stf.c +++ b/freebsd/sys/net/if_stf.c @@ -517,8 +517,6 @@ stf_output(ifp, m, dst, ro) } M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); - if (m && m->m_len < sizeof(struct ip)) - m = m_pullup(m, sizeof(struct ip)); if (m == NULL) { ifa_free(&ia6->ia_ifa); ifp->if_oerrors++; diff --git a/freebsd/sys/net/if_var.h b/freebsd/sys/net/if_var.h index fb590fa6..ee4db195 100644 --- a/freebsd/sys/net/if_var.h +++ b/freebsd/sys/net/if_var.h @@ -111,6 +111,12 @@ struct ifqueue { struct mtx ifq_mtx; }; +struct ifnet_hw_tsomax { + u_int tsomaxbytes; /* TSO total burst length limit in bytes */ + u_int tsomaxsegcount; /* TSO maximum segment count */ + u_int tsomaxsegsize; /* TSO maximum segment size in bytes */ +}; + /* * Structure defining a network interface. * @@ -205,11 +211,31 @@ struct ifnet { * be used with care where binary compatibility is required. */ char if_cspare[3]; - u_int if_hw_tsomax; /* tso burst length limit, the minmum - * is (IP_MAXPACKET / 8). - * XXXAO: Have to find a better place - * for it eventually. */ - int if_ispare[3]; + + /* + * Network adapter TSO limits: + * =========================== + * + * If the "if_hw_tsomax" field is zero the maximum segment + * length limit does not apply. If the "if_hw_tsomaxsegcount" + * or the "if_hw_tsomaxsegsize" field is zero the TSO segment + * count limit does not apply. If all three fields are zero, + * there is no TSO limit. + * + * NOTE: The TSO limits only apply to the data payload part of + * a TCP/IP packet. That means there is no need to subtract + * space for ethernet-, vlan-, IP- or TCP- headers from the + * TSO limits unless the hardware driver in question requires + * so. + */ + u_int if_hw_tsomax; + int if_ispare[1]; + /* + * TSO fields for segment limits. If a field is zero below, + * there is no limit: + */ + u_int if_hw_tsomaxsegcount; /* TSO maximum segment count */ + u_int if_hw_tsomaxsegsize; /* TSO maximum segment size in bytes */ void *if_pspare[8]; /* 1 netmap, 7 TDB */ }; @@ -940,7 +966,9 @@ struct ifaddr *ifa_ifwithaddr(struct sockaddr *); int ifa_ifwithaddr_check(struct sockaddr *); struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *); struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); +struct ifaddr *ifa_ifwithdstaddr_fib(struct sockaddr *, int); struct ifaddr *ifa_ifwithnet(struct sockaddr *, int); +struct ifaddr *ifa_ifwithnet_fib(struct sockaddr *, int, int); struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); struct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int); @@ -964,6 +992,10 @@ int ether_poll_register(poll_handler_t *h, struct ifnet *ifp); int ether_poll_deregister(struct ifnet *ifp); #endif /* DEVICE_POLLING */ +/* TSO */ +void if_hw_tsomax_common(struct ifnet *, struct ifnet_hw_tsomax *); +int if_hw_tsomax_update(struct ifnet *, struct ifnet_hw_tsomax *); + #endif /* _KERNEL */ #endif /* !_NET_IF_VAR_H_ */ diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c index accfbbb6..7d08e298 100644 --- a/freebsd/sys/net/if_vlan.c +++ b/freebsd/sys/net/if_vlan.c @@ -1477,6 +1477,7 @@ vlan_capabilities(struct ifvlan *ifv) { struct ifnet *p = PARENT(ifv); struct ifnet *ifp = ifv->ifv_ifp; + struct ifnet_hw_tsomax hw_tsomax; TRUNK_LOCK_ASSERT(TRUNK(ifv)); @@ -1503,8 +1504,9 @@ vlan_capabilities(struct ifvlan *ifv) * propagate the hardware-assisted flag. TSO on VLANs * does not necessarily require hardware VLAN tagging. */ - if (p->if_hw_tsomax > 0) - ifp->if_hw_tsomax = p->if_hw_tsomax; + memset(&hw_tsomax, 0, sizeof(hw_tsomax)); + if_hw_tsomax_common(p, &hw_tsomax); + if_hw_tsomax_update(ifp, &hw_tsomax); if (p->if_capabilities & IFCAP_VLAN_HWTSO) ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO; if (p->if_capenable & IFCAP_VLAN_HWTSO) { diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c index b444b740..781d8bb9 100644 --- a/freebsd/sys/net/route.c +++ b/freebsd/sys/net/route.c @@ -585,7 +585,7 @@ rtredirect_fib(struct sockaddr *dst, } /* verify the gateway is directly reachable */ - if ((ifa = ifa_ifwithnet(gateway, 0)) == NULL) { + if ((ifa = ifa_ifwithnet_fib(gateway, 0, fibnum)) == NULL) { error = ENETUNREACH; goto out; } @@ -742,7 +742,7 @@ ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway, */ ifa = NULL; if (flags & RTF_HOST) - ifa = ifa_ifwithdstaddr(dst); + ifa = ifa_ifwithdstaddr_fib(dst, fibnum); if (ifa == NULL) ifa = ifa_ifwithaddr(gateway); } else { @@ -751,10 +751,10 @@ ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway, * or host, the gateway may still be on the * other end of a pt to pt link. */ - ifa = ifa_ifwithdstaddr(gateway); + ifa = ifa_ifwithdstaddr_fib(gateway, fibnum); } if (ifa == NULL) - ifa = ifa_ifwithnet(gateway, 0); + ifa = ifa_ifwithnet_fib(gateway, 0, fibnum); if (ifa == NULL) { struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum); if (rt == NULL) @@ -868,7 +868,7 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum) */ if (info->rti_ifp == NULL && ifpaddr != NULL && ifpaddr->sa_family == AF_LINK && - (ifa = ifa_ifwithnet(ifpaddr, 0)) != NULL) { + (ifa = ifa_ifwithnet_fib(ifpaddr, 0, fibnum)) != NULL) { info->rti_ifp = ifa->ifa_ifp; ifa_free(ifa); } @@ -1560,7 +1560,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) if (fibnum == RT_ALL_FIBS) { if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) { #ifndef __rtems__ - startfib = endfib = curthread->td_proc->p_fibnum; + startfib = endfib = ifa->ifa_ifp->if_fib; #else /* __rtems__ */ startfib = endfib = BSD_DEFAULT_FIB; #endif /* __rtems__ */ @@ -1674,7 +1674,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) info.rti_ifa = NULL; info.rti_flags = RTF_RNH_LOCKED; - error = rtrequest1_fib(RTM_DELETE, &info, &rt, fibnum); + error = rtrequest1_fib(RTM_DELETE, &info, NULL, fibnum); if (error == 0) { info.rti_ifa = ifa; info.rti_flags = flags | RTF_RNH_LOCKED | diff --git a/freebsd/sys/netinet/cc/cc.c b/freebsd/sys/netinet/cc/cc.c index 8aea8dd2..4be9a63b 100644 --- a/freebsd/sys/netinet/cc/cc.c +++ b/freebsd/sys/netinet/cc/cc.c @@ -94,33 +94,33 @@ cc_default_algo(SYSCTL_HANDLER_ARGS) { char default_cc[TCP_CA_NAME_MAX]; struct cc_algo *funcs; - int err, found; - - err = found = 0; - - if (req->newptr == NULL) { - /* Just print the current default. */ - CC_LIST_RLOCK(); - strlcpy(default_cc, CC_DEFAULT()->name, TCP_CA_NAME_MAX); - CC_LIST_RUNLOCK(); - err = sysctl_handle_string(oidp, default_cc, 1, req); - } else { - /* Find algo with specified name and set it to default. */ - CC_LIST_RLOCK(); - STAILQ_FOREACH(funcs, &cc_list, entries) { - if (strncmp((char *)req->newptr, funcs->name, - TCP_CA_NAME_MAX) == 0) { - found = 1; - V_default_cc_ptr = funcs; - } - } - CC_LIST_RUNLOCK(); + int error; - if (!found) - err = ESRCH; - } + /* Get the current default: */ + CC_LIST_RLOCK(); + strlcpy(default_cc, CC_DEFAULT()->name, sizeof(default_cc)); + CC_LIST_RUNLOCK(); - return (err); + error = sysctl_handle_string(oidp, default_cc, sizeof(default_cc), req); + + /* Check for error or no change */ + if (error != 0 || req->newptr == NULL) + goto done; + + error = ESRCH; + + /* Find algo with specified name and set it to default. */ + CC_LIST_RLOCK(); + STAILQ_FOREACH(funcs, &cc_list, entries) { + if (strncmp(default_cc, funcs->name, sizeof(default_cc))) + continue; + V_default_cc_ptr = funcs; + error = 0; + break; + } + CC_LIST_RUNLOCK(); +done: + return (error); } #ifndef __rtems__ @@ -169,7 +169,7 @@ cc_list_available(SYSCTL_HANDLER_ARGS) if (!err) { sbuf_finish(s); - err = sysctl_handle_string(oidp, sbuf_data(s), 1, req); + err = sysctl_handle_string(oidp, sbuf_data(s), 0, req); } sbuf_delete(s); diff --git a/freebsd/sys/netinet/if_ether.c b/freebsd/sys/netinet/if_ether.c index e4f76fee..eec06dd8 100644 --- a/freebsd/sys/netinet/if_ether.c +++ b/freebsd/sys/netinet/if_ether.c @@ -156,10 +156,10 @@ arp_ifscrub(struct ifnet *ifp, uint32_t addr) addr4.sin_len = sizeof(addr4); addr4.sin_family = AF_INET; addr4.sin_addr.s_addr = addr; - IF_AFDATA_RLOCK(ifp); + IF_AFDATA_WLOCK(ifp); lla_lookup(LLTABLE(ifp), (LLE_DELETE | LLE_IFADDR), (struct sockaddr *)&addr4); - IF_AFDATA_RUNLOCK(ifp); + IF_AFDATA_WUNLOCK(ifp); } #endif @@ -328,8 +328,8 @@ retry: if (la == NULL) { if (flags & LLE_CREATE) log(LOG_DEBUG, - "arpresolve: can't allocate llinfo for %s\n", - inet_ntoa(SIN(dst)->sin_addr)); + "arpresolve: can't allocate llinfo for %s on %s\n", + inet_ntoa(SIN(dst)->sin_addr), ifp->if_xname); m_freem(m); return (EINVAL); } diff --git a/freebsd/sys/netinet/igmp.c b/freebsd/sys/netinet/igmp.c index 3056fa3a..78d9685b 100644 --- a/freebsd/sys/netinet/igmp.c +++ b/freebsd/sys/netinet/igmp.c @@ -1535,8 +1535,7 @@ igmp_input(struct mbuf *m, int off) case IGMP_VERSION_3: { struct igmpv3 *igmpv3; uint16_t igmpv3len; - uint16_t srclen; - int nsrc; + uint16_t nsrc; IGMPSTAT_INC(igps_rcv_v3_queries); igmpv3 = (struct igmpv3 *)igmp; @@ -1544,8 +1543,8 @@ igmp_input(struct mbuf *m, int off) * Validate length based on source count. */ nsrc = ntohs(igmpv3->igmp_numsrc); - srclen = sizeof(struct in_addr) * nsrc; - if (nsrc * sizeof(in_addr_t) > srclen) { + if (nsrc * sizeof(in_addr_t) > + UINT16_MAX - iphlen - IGMP_V3_QUERY_MINLEN) { IGMPSTAT_INC(igps_rcv_tooshort); return; } @@ -1554,7 +1553,7 @@ igmp_input(struct mbuf *m, int off) * this scope. */ igmpv3len = iphlen + IGMP_V3_QUERY_MINLEN + - srclen; + sizeof(struct in_addr) * nsrc; if ((m->m_flags & M_EXT || m->m_len < igmpv3len) && (m = m_pullup(m, igmpv3len)) == NULL) { diff --git a/freebsd/sys/netinet/in.c b/freebsd/sys/netinet/in.c index bc7323e3..653580c7 100644 --- a/freebsd/sys/netinet/in.c +++ b/freebsd/sys/netinet/in.c @@ -970,7 +970,7 @@ in_addprefix(struct in_ifaddr *target, int flags) { struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; - int error, fibnum; + int error; if ((flags & RTF_HOST) != 0) { prefix = target->ia_dstaddr.sin_addr; @@ -981,9 +981,8 @@ in_addprefix(struct in_ifaddr *target, int flags) prefix.s_addr &= mask.s_addr; } - fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; - IN_IFADDR_RLOCK(); + /* Look for an existing address with the same prefix, mask, and fib */ TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { p = ia->ia_dstaddr.sin_addr; @@ -999,6 +998,8 @@ in_addprefix(struct in_ifaddr *target, int flags) mask.s_addr != m.s_addr) continue; } + if (target->ia_ifp->if_fib != ia->ia_ifp->if_fib) + continue; /* * If we got a matching prefix route inserted by other @@ -1019,6 +1020,10 @@ in_addprefix(struct in_ifaddr *target, int flags) IN_IFADDR_RUNLOCK(); return (EEXIST); } else { + int fibnum; + + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : + target->ia_ifp->if_fib; rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum); IN_IFADDR_RUNLOCK(); return (0); @@ -1048,11 +1053,9 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) { struct in_ifaddr *ia; struct in_addr prefix, mask, p; - int error = 0, fibnum; + int error = 0; struct sockaddr_in prefix0, mask0; - fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; - /* * Remove the loopback route to the interface address. * The "useloopback" setting is not consulted because if the @@ -1068,10 +1071,12 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) (target->ia_flags & IFA_RTSELF)) { struct route ia_ro; int freeit = 0; + int fibnum; bzero(&ia_ro, sizeof(ia_ro)); *((struct sockaddr_in *)(&ia_ro.ro_dst)) = target->ia_addr; - rtalloc_ign_fib(&ia_ro, 0, 0); + fibnum = target->ia_ifp->if_fib; + rtalloc_ign_fib(&ia_ro, 0, fibnum); if ((ia_ro.ro_rt != NULL) && (ia_ro.ro_rt->rt_ifp != NULL) && (ia_ro.ro_rt->rt_ifp == V_loif)) { RT_LOCK(ia_ro.ro_rt); @@ -1104,6 +1109,10 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) } if ((target->ia_flags & IFA_ROUTE) == 0) { + int fibnum; + + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : + target->ia_ifp->if_fib; rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum); return (0); } @@ -1368,8 +1377,9 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr KASSERT(l3addr->sa_family == AF_INET, ("sin_family %d", l3addr->sa_family)); - /* XXX rtalloc1 should take a const param */ - rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0); + /* XXX rtalloc1_fib should take a const param */ + rt = rtalloc1_fib(__DECONST(struct sockaddr *, l3addr), 0, 0, + ifp->if_fib); if (rt == NULL) return (EINVAL); diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c index 93ebf4d6..a06fed68 100644 --- a/freebsd/sys/netinet/ip_output.c +++ b/freebsd/sys/netinet/ip_output.c @@ -743,10 +743,8 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, * be less than the receiver's page size ? */ int newlen; - struct mbuf *m; - for (m = m0, off = 0; m && (off+m->m_len) <= mtu; m = m->m_next) - off += m->m_len; + off = MIN(mtu, m0->m_pkthdr.len); /* * firstlen (off - hlen) must be aligned on an @@ -789,7 +787,11 @@ smart_frag_failure: IPSTAT_INC(ips_odropped); goto done; } - m->m_flags |= (m0->m_flags & M_MCAST) | M_FRAG; + /* copy multicast and flowid flag, if any */ + m->m_flags |= (m0->m_flags & (M_FLOWID | M_MCAST)) | M_FRAG; + /* make sure the flowid is the same for the fragmented mbufs */ + M_HASHTYPE_SET(m, M_HASHTYPE_GET(m0)); + m->m_pkthdr.flowid = m0->m_pkthdr.flowid; /* * In the first mbuf, leave room for the link header, then * copy the original IP header including options. The payload diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c index baf25af8..9e35c882 100644 --- a/freebsd/sys/netinet/sctp_input.c +++ b/freebsd/sys/netinet/sctp_input.c @@ -3664,6 +3664,9 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb, /* huh ? */ return (0); } + if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) { + return (0); + } if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) { resp = (struct sctp_stream_reset_response_tsn *)respin; asoc->stream_reset_outstanding--; @@ -4052,7 +4055,7 @@ __attribute__((noinline)) sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset, struct sctp_chunkhdr *ch_req) { - int chk_length, param_len, ptype; + uint16_t remaining_length, param_len, ptype; struct sctp_paramhdr pstore; uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE]; uint32_t seq = 0; @@ -4065,7 +4068,7 @@ __attribute__((noinline)) int num_param = 0; /* now it may be a reset or a reset-response */ - chk_length = ntohs(ch_req->chunk_length); + remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr); /* setup for adding the response */ sctp_alloc_a_chunk(stcb, chk); @@ -4101,20 +4104,27 @@ strres_nochunk: ch->chunk_length = htons(chk->send_size); SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size); offset += sizeof(struct sctp_chunkhdr); - while ((size_t)chk_length >= sizeof(struct sctp_stream_reset_tsn_request)) { + while (remaining_length >= sizeof(struct sctp_paramhdr)) { ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *) & pstore); - if (ph == NULL) + if (ph == NULL) { + /* TSNH */ break; + } param_len = ntohs(ph->param_length); - if (param_len < (int)sizeof(struct sctp_stream_reset_tsn_request)) { - /* bad param */ + if ((param_len > remaining_length) || + (param_len < (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)))) { + /* bad parameter length */ break; } - ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, (int)sizeof(cstore)), + ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, sizeof(cstore)), (uint8_t *) & cstore); + if (ph == NULL) { + /* TSNH */ + break; + } ptype = ntohs(ph->param_type); num_param++; - if (param_len > (int)sizeof(cstore)) { + if (param_len > sizeof(cstore)) { trunc = 1; } else { trunc = 0; @@ -4126,6 +4136,9 @@ strres_nochunk: if (ptype == SCTP_STR_RESET_OUT_REQUEST) { struct sctp_stream_reset_out_request *req_out; + if (param_len < sizeof(struct sctp_stream_reset_out_request)) { + break; + } req_out = (struct sctp_stream_reset_out_request *)ph; num_req++; if (stcb->asoc.stream_reset_outstanding) { @@ -4139,12 +4152,18 @@ strres_nochunk: } else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) { struct sctp_stream_reset_add_strm *str_add; + if (param_len < sizeof(struct sctp_stream_reset_add_strm)) { + break; + } str_add = (struct sctp_stream_reset_add_strm *)ph; num_req++; sctp_handle_str_reset_add_strm(stcb, chk, str_add); } else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) { struct sctp_stream_reset_add_strm *str_add; + if (param_len < sizeof(struct sctp_stream_reset_add_strm)) { + break; + } str_add = (struct sctp_stream_reset_add_strm *)ph; num_req++; sctp_handle_str_reset_add_out_strm(stcb, chk, str_add); @@ -4169,6 +4188,9 @@ strres_nochunk: struct sctp_stream_reset_response *resp; uint32_t result; + if (param_len < sizeof(struct sctp_stream_reset_response)) { + break; + } resp = (struct sctp_stream_reset_response *)ph; seq = ntohl(resp->response_seq); result = ntohl(resp->result); @@ -4180,7 +4202,11 @@ strres_nochunk: break; } offset += SCTP_SIZE32(param_len); - chk_length -= SCTP_SIZE32(param_len); + if (remaining_length >= SCTP_SIZE32(param_len)) { + remaining_length -= SCTP_SIZE32(param_len); + } else { + remaining_length = 0; + } } if (num_req == 0) { /* we have no response free the stuff */ diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c index f3cb4b44..cbc25b9c 100644 --- a/freebsd/sys/netinet/sctp_output.c +++ b/freebsd/sys/netinet/sctp_output.c @@ -12059,8 +12059,8 @@ sctp_copy_resume(struct uio *uio, m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0, (M_PKTHDR | (user_marks_eor ? M_EOR : 0))); if (m == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - *error = ENOMEM; + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + *error = ENOBUFS; } else { *sndout = m_length(m, NULL); *new_tail = m_last(m); @@ -12079,8 +12079,8 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp, sp->data = m_uiotombuf(uio, M_WAITOK, sp->length, resv_upfront, 0); if (sp->data == NULL) { - SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); - return (ENOMEM); + SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOBUFS); + return (ENOBUFS); } sp->tail_mbuf = m_last(sp->data); return (0); diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c index ba7a00bf..d0da7a6f 100644 --- a/freebsd/sys/netinet/sctp_sysctl.c +++ b/freebsd/sys/netinet/sctp_sysctl.c @@ -686,14 +686,18 @@ static int sysctl_stat_get(SYSCTL_HANDLER_ARGS) { int cpu, error; - struct sctpstat sb, *sarry, *cpin = NULL; + struct sctpstat sb, sb_temp, *sarry, *cpin = NULL; if ((req->newptr) && (req->newlen == sizeof(struct sctpstat))) { /* * User wants us to clear or at least reset the counters to * the specified values. */ - cpin = (struct sctpstat *)req->newptr; + cpin = &sb_temp; + memset(&sb_temp, 0, sizeof(sb_temp)); + error = SYSCTL_IN(req, &sb_temp, sizeof(sb_temp)); + if (error != 0) + return (error); } else if (req->newptr) { /* Must be a stat structure */ return (EINVAL); diff --git a/freebsd/sys/netinet/sctp_usrreq.c b/freebsd/sys/netinet/sctp_usrreq.c index e2bbced4..b19a7499 100644 --- a/freebsd/sys/netinet/sctp_usrreq.c +++ b/freebsd/sys/netinet/sctp_usrreq.c @@ -1856,8 +1856,9 @@ flags_out: SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize); SCTP_FIND_STCB(inp, stcb, av->assoc_id); if (stcb) { - if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], - &av->stream_value) < 0) { + if ((av->stream_id >= stcb->asoc.streamoutcnt) || + (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], + &av->stream_value) < 0)) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; } else { @@ -3662,8 +3663,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize); SCTP_FIND_STCB(inp, stcb, av->assoc_id); if (stcb) { - if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], - av->stream_value) < 0) { + if ((av->stream_id >= stcb->asoc.streamoutcnt) || + (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], + av->stream_value) < 0)) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; } @@ -3673,10 +3675,12 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_INP_RLOCK(inp); LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { SCTP_TCB_LOCK(stcb); - stcb->asoc.ss_functions.sctp_ss_set_value(stcb, - &stcb->asoc, - &stcb->asoc.strmout[av->stream_id], - av->stream_value); + if (av->stream_id < stcb->asoc.streamoutcnt) { + stcb->asoc.ss_functions.sctp_ss_set_value(stcb, + &stcb->asoc, + &stcb->asoc.strmout[av->stream_id], + av->stream_value); + } SCTP_TCB_UNLOCK(stcb); } SCTP_INP_RUNLOCK(inp); diff --git a/freebsd/sys/netinet/tcp_hostcache.c b/freebsd/sys/netinet/tcp_hostcache.c index ee98af3f..260d161d 100644 --- a/freebsd/sys/netinet/tcp_hostcache.c +++ b/freebsd/sys/netinet/tcp_hostcache.c @@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -594,30 +595,27 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml) static int sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS) { - int bufsize; int linesize = 128; - char *p, *buf; - int len, i, error; + struct sbuf sb; + int i, error; struct hc_metrics *hc_entry; #ifdef INET6 char ip6buf[INET6_ADDRSTRLEN]; #endif - bufsize = linesize * (V_tcp_hostcache.cache_count + 1); + sbuf_new(&sb, NULL, linesize * (V_tcp_hostcache.cache_count + 1), + SBUF_FIXEDLEN); - p = buf = (char *)malloc(bufsize, M_TEMP, M_WAITOK|M_ZERO); - - len = snprintf(p, linesize, - "\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH " + sbuf_printf(&sb, + "\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH " " CWND SENDPIPE RECVPIPE HITS UPD EXP\n"); - p += len; #define msec(u) (((u) + 500) / 1000) for (i = 0; i < V_tcp_hostcache.hashsize; i++) { THC_LOCK(&V_tcp_hostcache.hashbase[i].hch_mtx); TAILQ_FOREACH(hc_entry, &V_tcp_hostcache.hashbase[i].hch_bucket, rmx_q) { - len = snprintf(p, linesize, + sbuf_printf(&sb, "%-15s %5lu %8lu %6lums %6lums %9lu %8lu %8lu %8lu " "%4lu %4lu %4i\n", hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) : @@ -639,13 +637,13 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS) hc_entry->rmx_hits, hc_entry->rmx_updates, hc_entry->rmx_expire); - p += len; } THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx); } #undef msec - error = SYSCTL_OUT(req, buf, p - buf); - free(buf, M_TEMP); + sbuf_finish(&sb); + error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb)); + sbuf_delete(&sb); return(error); } diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c index 20d645f0..f9512eb3 100644 --- a/freebsd/sys/netinet/tcp_input.c +++ b/freebsd/sys/netinet/tcp_input.c @@ -504,10 +504,13 @@ do { \ * the ack that opens up a 0-sized window and * - delayed acks are enabled or * - this is a half-synchronized T/TCP connection. + * - the segment size is not larger than the MSS and LRO wasn't used + * for this segment. */ -#define DELAY_ACK(tp) \ +#define DELAY_ACK(tp, tlen) \ ((!tcp_timer_active(tp, TT_DELACK) && \ (tp->t_flags & TF_RXWIN0SENT) == 0) && \ + (tlen <= tp->t_maxopd) && \ (V_tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN))) /* @@ -1852,7 +1855,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, } /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); - if (DELAY_ACK(tp)) { + if (DELAY_ACK(tp, tlen)) { tp->t_flags |= TF_DELACK; } else { tp->t_flags |= TF_ACKNOW; @@ -1940,7 +1943,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * If there's data, delay ACK; if there's also a FIN * ACKNOW will be turned on later. */ - if (DELAY_ACK(tp) && tlen != 0) + if (DELAY_ACK(tp, tlen) && tlen != 0) tcp_timer_activate(tp, TT_DELACK, tcp_delacktime); else @@ -2183,11 +2186,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, todrop = tp->rcv_nxt - th->th_seq; if (todrop > 0) { - /* - * If this is a duplicate SYN for our current connection, - * advance over it and pretend and it's not a SYN. - */ - if (thflags & TH_SYN && th->th_seq == tp->irs) { + if (thflags & TH_SYN) { thflags &= ~TH_SYN; th->th_seq++; if (th->th_urp > 1) @@ -2907,7 +2906,7 @@ dodata: /* XXX */ if (th->th_seq == tp->rcv_nxt && LIST_EMPTY(&tp->t_segq) && TCPS_HAVEESTABLISHED(tp->t_state)) { - if (DELAY_ACK(tp)) + if (DELAY_ACK(tp, tlen)) tp->t_flags |= TF_DELACK; else tp->t_flags |= TF_ACKNOW; @@ -3631,6 +3630,8 @@ tcp_mss(struct tcpcb *tp, int offer) if (cap.ifcap & CSUM_TSO) { tp->t_flags |= TF_TSO; tp->t_tsomax = cap.tsomax; + tp->t_tsomaxsegcount = cap.tsomaxsegcount; + tp->t_tsomaxsegsize = cap.tsomaxsegsize; } } diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c index 6215c4e2..550af64f 100644 --- a/freebsd/sys/netinet/tcp_output.c +++ b/freebsd/sys/netinet/tcp_output.c @@ -767,28 +767,112 @@ send: flags &= ~TH_FIN; if (tso) { + u_int if_hw_tsomax; + u_int if_hw_tsomaxsegcount; + u_int if_hw_tsomaxsegsize; + struct mbuf *mb; + u_int moff; + int max_len; + + /* extract TSO information */ + if_hw_tsomax = tp->t_tsomax; + if_hw_tsomaxsegcount = tp->t_tsomaxsegcount; + if_hw_tsomaxsegsize = tp->t_tsomaxsegsize; + + /* + * Limit a TSO burst to prevent it from + * overflowing or exceeding the maximum length + * allowed by the network interface: + */ KASSERT(ipoptlen == 0, ("%s: TSO can't do IP options", __func__)); /* - * Limit a burst to t_tsomax minus IP, - * TCP and options length to keep ip->ip_len - * from overflowing or exceeding the maximum - * length allowed by the network interface. + * Check if we should limit by maximum payload + * length: */ - if (len > tp->t_tsomax - hdrlen) { - len = tp->t_tsomax - hdrlen; - sendalot = 1; + if (if_hw_tsomax != 0) { + /* compute maximum TSO length */ + max_len = (if_hw_tsomax - hdrlen); + if (max_len <= 0) { + len = 0; + } else if (len > max_len) { + sendalot = 1; + len = max_len; + } + } + + /* + * Check if we should limit by maximum segment + * size and count: + */ + if (if_hw_tsomaxsegcount != 0 && + if_hw_tsomaxsegsize != 0) { + max_len = 0; + mb = sbsndmbuf(&so->so_snd, off, &moff); + + while (mb != NULL && max_len < len) { + u_int mlen; + u_int frags; + + /* + * Get length of mbuf fragment + * and how many hardware frags, + * rounded up, it would use: + */ + mlen = (mb->m_len - moff); + frags = howmany(mlen, + if_hw_tsomaxsegsize); + + /* Handle special case: Zero Length Mbuf */ + if (frags == 0) + frags = 1; + + /* + * Check if the fragment limit + * will be reached or exceeded: + */ + if (frags >= if_hw_tsomaxsegcount) { + max_len += min(mlen, + if_hw_tsomaxsegcount * + if_hw_tsomaxsegsize); + break; + } + max_len += mlen; + if_hw_tsomaxsegcount -= frags; + moff = 0; + mb = mb->m_next; + } + if (max_len <= 0) { + len = 0; + } else if (len > max_len) { + sendalot = 1; + len = max_len; + } } /* * Prevent the last segment from being - * fractional unless the send sockbuf can - * be emptied. + * fractional unless the send sockbuf can be + * emptied: + */ + max_len = (tp->t_maxopd - optlen); + if ((off + len) < so->so_snd.sb_cc) { + moff = len % max_len; + if (moff != 0) { + len -= moff; + sendalot = 1; + } + } + + /* + * In case there are too many small fragments + * don't use TSO: */ - if (sendalot && off + len < so->so_snd.sb_cc) { - len -= len % (tp->t_maxopd - optlen); + if (len <= max_len) { + len = max_len; sendalot = 1; + tso = 0; } /* diff --git a/freebsd/sys/netinet/tcp_reass.c b/freebsd/sys/netinet/tcp_reass.c index d4f0bcde..2570a5f3 100644 --- a/freebsd/sys/netinet/tcp_reass.c +++ b/freebsd/sys/netinet/tcp_reass.c @@ -94,7 +94,7 @@ SYSCTL_VNET_PROC(_net_inet_tcp_reass, OID_AUTO, cursegments, static VNET_DEFINE(int, tcp_reass_overflows) = 0; #define V_tcp_reass_overflows VNET(tcp_reass_overflows) SYSCTL_VNET_INT(_net_inet_tcp_reass, OID_AUTO, overflows, - CTLTYPE_INT | CTLFLAG_RD, + CTLFLAG_RD, &VNET_NAME(tcp_reass_overflows), 0, "Global number of TCP Segment Reassembly Queue Overflows"); diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c index d577f18f..b175c0c0 100644 --- a/freebsd/sys/netinet/tcp_subr.c +++ b/freebsd/sys/netinet/tcp_subr.c @@ -1750,6 +1750,8 @@ tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap) ifp->if_hwassist & CSUM_TSO) { cap->ifcap |= CSUM_TSO; cap->tsomax = ifp->if_hw_tsomax; + cap->tsomaxsegcount = ifp->if_hw_tsomaxsegcount; + cap->tsomaxsegsize = ifp->if_hw_tsomaxsegsize; } } RTFREE(sro.ro_rt); @@ -1789,6 +1791,8 @@ tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap) ifp->if_hwassist & CSUM_TSO) { cap->ifcap |= CSUM_TSO; cap->tsomax = ifp->if_hw_tsomax; + cap->tsomaxsegcount = ifp->if_hw_tsomaxsegcount; + cap->tsomaxsegsize = ifp->if_hw_tsomaxsegsize; } } RTFREE(sro6.ro_rt); diff --git a/freebsd/sys/netinet/tcp_var.h b/freebsd/sys/netinet/tcp_var.h index 171eafb6..dbd9ed11 100644 --- a/freebsd/sys/netinet/tcp_var.h +++ b/freebsd/sys/netinet/tcp_var.h @@ -212,7 +212,9 @@ struct tcpcb { uint32_t t_ispare[7]; /* 5 UTO, 2 TBD */ void *t_pspare2[4]; /* 4 TBD */ - uint64_t _pad[6]; /* 6 TBD (1-2 CC/RTT?) */ + uint64_t _pad[5]; /* 5 TBD (1-2 CC/RTT?) */ + uint32_t t_tsomaxsegcount; /* TSO maximum segment count */ + uint32_t t_tsomaxsegsize; /* TSO maximum segment size in bytes */ }; /* @@ -333,6 +335,8 @@ struct hc_metrics_lite { /* must stay in sync with hc_metrics */ struct tcp_ifcap { int ifcap; u_int tsomax; + u_int tsomaxsegcount; + u_int tsomaxsegsize; }; #ifndef _NETINET_IN_PCB_H_ diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c index 20b03a21..49b1bd8a 100644 --- a/freebsd/sys/netinet6/icmp6.c +++ b/freebsd/sys/netinet6/icmp6.c @@ -363,8 +363,6 @@ icmp6_error(struct mbuf *m, int type, int code, int param) preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); M_PREPEND(m, preplen, M_DONTWAIT); /* FIB is also copied over. */ - if (m && m->m_len < preplen) - m = m_pullup(m, preplen); if (m == NULL) { nd6log((LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__)); return; diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c index f68f21f2..8dc4d29f 100644 --- a/freebsd/sys/netinet6/in6.c +++ b/freebsd/sys/netinet6/in6.c @@ -286,7 +286,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, return (mrt6_ioctl ? mrt6_ioctl(cmd, data) : EOPNOTSUPP); } - switch(cmd) { + switch (cmd) { case SIOCAADDRCTL_POLICY: case SIOCDADDRCTL_POLICY: if (td != NULL) { @@ -358,14 +358,10 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, if (error) return (error); } - return (scope6_set(ifp, - (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + /* FALLTHROUGH */ case SIOCGSCOPE6: - return (scope6_get(ifp, - (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); case SIOCGSCOPE6DEF: - return (scope6_get_default((struct scope6_id *) - ifr->ifr_ifru.ifru_scope_id)); + return (scope6_ioctl(cmd, data, ifp)); } switch (cmd) { @@ -496,6 +492,13 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, if (error) goto out; } + /* FALLTHROUGH */ + case SIOCGIFSTAT_IN6: + case SIOCGIFSTAT_ICMP6: + if (ifp->if_afdata[AF_INET6] == NULL) { + error = EPFNOSUPPORT; + goto out; + } break; case SIOCGIFADDR_IN6: @@ -571,10 +574,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, break; case SIOCGIFSTAT_IN6: - if (ifp == NULL) { - error = EINVAL; - goto out; - } bzero(&ifr->ifr_ifru.ifru_stat, sizeof(ifr->ifr_ifru.ifru_stat)); ifr->ifr_ifru.ifru_stat = @@ -582,10 +581,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, break; case SIOCGIFSTAT_ICMP6: - if (ifp == NULL) { - error = EINVAL; - goto out; - } bzero(&ifr->ifr_ifru.ifru_icmp6stat, sizeof(ifr->ifr_ifru.ifru_icmp6stat)); ifr->ifr_ifru.ifru_icmp6stat = @@ -801,7 +796,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, } default: - if (ifp == NULL || ifp->if_ioctl == 0) { + if (ifp->if_ioctl == NULL) { error = EOPNOTSUPP; goto out; } diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c index e5457707..d32d57c6 100644 --- a/freebsd/sys/netinet6/in6_mcast.c +++ b/freebsd/sys/netinet6/in6_mcast.c @@ -1077,6 +1077,8 @@ in6m_purge(struct in6_multi *inm) free(ims, M_IP6MSOURCE); inm->in6m_nsrc--; } + /* Free state-change requests that might be queued. */ + _IF_DRAIN(&inm->in6m_scq); } /* diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c index 4b0b3389..8a7581c9 100644 --- a/freebsd/sys/netinet6/in6_pcb.c +++ b/freebsd/sys/netinet6/in6_pcb.c @@ -638,18 +638,12 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst, /* * If the error designates a new path MTU for a destination * and the application (associated with this socket) wanted to - * know the value, notify. Note that we notify for all - * disconnected sockets if the corresponding application - * wanted. This is because some UDP applications keep sending - * sockets disconnected. + * know the value, notify. * XXX: should we avoid to notify the value to TCP sockets? */ - if (cmd == PRC_MSGSIZE && (inp->inp_flags & IN6P_MTU) != 0 && - (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) || - IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &sa6_dst->sin6_addr))) { + if (cmd == PRC_MSGSIZE && cmdarg != NULL) ip6_notify_pmtu(inp, (struct sockaddr_in6 *)dst, - (u_int32_t *)cmdarg); - } + *(u_int32_t *)cmdarg); /* * Detect if we should notify the error. If no source and diff --git a/freebsd/sys/netinet6/in6_src.c b/freebsd/sys/netinet6/in6_src.c index cc2f5ee5..79beb703 100644 --- a/freebsd/sys/netinet6/in6_src.c +++ b/freebsd/sys/netinet6/in6_src.c @@ -444,6 +444,16 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, (ia->ia_ifp->if_flags & IFF_UP)) REPLACE(8); + /* + * Rule 10: prefer address with `prefer_source' flag. + */ + if ((ia_best->ia6_flags & IN6_IFF_PREFER_SOURCE) == 0 && + (ia->ia6_flags & IN6_IFF_PREFER_SOURCE) != 0) + REPLACE(10); + if ((ia_best->ia6_flags & IN6_IFF_PREFER_SOURCE) != 0 && + (ia->ia6_flags & IN6_IFF_PREFER_SOURCE) == 0) + NEXT(10); + /* * Rule 14: Use longest matching prefix. * Note: in the address selection draft, this rule is diff --git a/freebsd/sys/netinet6/in6_var.h b/freebsd/sys/netinet6/in6_var.h index c7ebe523..90530a68 100644 --- a/freebsd/sys/netinet6/in6_var.h +++ b/freebsd/sys/netinet6/in6_var.h @@ -473,6 +473,7 @@ struct in6_rrenumreq { */ #define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */ #define IN6_IFF_TEMPORARY 0x80 /* temporary (anonymous) address. */ +#define IN6_IFF_PREFER_SOURCE 0x0100 /* preferred address for SAS */ #define IN6_IFF_NOPFX 0x8000 /* skip kernel prefix management. * XXX: this should be temporary. */ diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c index 0de64eb7..17420faf 100644 --- a/freebsd/sys/netinet6/ip6_input.c +++ b/freebsd/sys/netinet6/ip6_input.c @@ -1605,24 +1605,28 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp) #undef IS2292 void -ip6_notify_pmtu(struct inpcb *in6p, struct sockaddr_in6 *dst, u_int32_t *mtu) +ip6_notify_pmtu(struct inpcb *inp, struct sockaddr_in6 *dst, u_int32_t mtu) { struct socket *so; struct mbuf *m_mtu; struct ip6_mtuinfo mtuctl; - so = in6p->inp_socket; - - if (mtu == NULL) + KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); + /* + * Notify the error by sending IPV6_PATHMTU ancillary data if + * application wanted to know the MTU value. + * NOTE: we notify disconnected sockets, because some udp + * applications keep sending sockets disconnected. + * NOTE: our implementation doesn't notify connected sockets that has + * foreign address that is different than given destination addresses + * (this is permitted by RFC 3542). + */ + if ((inp->inp_flags & IN6P_MTU) == 0 || ( + !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && + !IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &dst->sin6_addr))) return; -#ifdef DIAGNOSTIC - if (so == NULL) /* I believe this is impossible */ - panic("ip6_notify_pmtu: socket is NULL"); -#endif - - bzero(&mtuctl, sizeof(mtuctl)); /* zero-clear for safety */ - mtuctl.ip6m_mtu = *mtu; + mtuctl.ip6m_mtu = mtu; mtuctl.ip6m_addr = *dst; if (sa6_recoverscope(&mtuctl.ip6m_addr)) return; @@ -1631,14 +1635,13 @@ ip6_notify_pmtu(struct inpcb *in6p, struct sockaddr_in6 *dst, u_int32_t *mtu) IPV6_PATHMTU, IPPROTO_IPV6)) == NULL) return; + so = inp->inp_socket; if (sbappendaddr(&so->so_rcv, (struct sockaddr *)dst, NULL, m_mtu) == 0) { m_freem(m_mtu); /* XXX: should count statistics */ } else sorwakeup(so); - - return; } #ifdef PULLDOWN_TEST diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c index 06f1246a..95231631 100644 --- a/freebsd/sys/netinet6/ip6_output.c +++ b/freebsd/sys/netinet6/ip6_output.c @@ -998,19 +998,12 @@ passout: * Even if the DONTFRAG option is specified, we cannot send the * packet when the data length is larger than the MTU of the * outgoing interface. - * Notify the error by sending IPV6_PATHMTU ancillary data as - * well as returning an error code (the latter is not described - * in the API spec.) + * Notify the error by sending IPV6_PATHMTU ancillary data if + * application wanted to know the MTU value. Also return an + * error code (this is not described in the API spec). */ - u_int32_t mtu32; - struct ip6ctlparam ip6cp; - - mtu32 = (u_int32_t)mtu; - bzero(&ip6cp, sizeof(ip6cp)); - ip6cp.ip6c_cmdarg = (void *)&mtu32; - pfctlinput2(PRC_MSGSIZE, (struct sockaddr *)&ro_pmtu->ro_dst, - (void *)&ip6cp); - + if (inp != NULL) + ip6_notify_pmtu(inp, &dst_sa, (u_int32_t)mtu); error = EMSGSIZE; goto bad; } diff --git a/freebsd/sys/netinet6/ip6_var.h b/freebsd/sys/netinet6/ip6_var.h index 4a094d42..4e8c42bd 100644 --- a/freebsd/sys/netinet6/ip6_var.h +++ b/freebsd/sys/netinet6/ip6_var.h @@ -406,8 +406,7 @@ int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *, struct mbuf **ip6_savecontrol_v4(struct inpcb *, struct mbuf *, struct mbuf **, int *); void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **); -void ip6_notify_pmtu(struct inpcb *, struct sockaddr_in6 *, - u_int32_t *); +void ip6_notify_pmtu(struct inpcb *, struct sockaddr_in6 *, u_int32_t); int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); void ip6_forward(struct mbuf *, int); diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c index 9233bef5..1b855cae 100644 --- a/freebsd/sys/netinet6/nd6.c +++ b/freebsd/sys/netinet6/nd6.c @@ -2283,6 +2283,8 @@ SYSCTL_NODE(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist, CTLFLAG_RD, nd6_sysctl_prlist, ""); SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen, CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, ""); +SYSCTL_VNET_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer, + CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), ""); static int nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS) diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h index 79e41e38..94202e10 100644 --- a/freebsd/sys/netinet6/nd6.h +++ b/freebsd/sys/netinet6/nd6.h @@ -79,7 +79,7 @@ struct nd_ifinfo { #define ND6_IFF_PERFORMNUD 0x1 #define ND6_IFF_ACCEPT_RTADV 0x2 -#define ND6_IFF_PREFER_SOURCE 0x4 /* XXX: not related to ND. */ +#define ND6_IFF_PREFER_SOURCE 0x4 /* Not used in FreeBSD. */ #define ND6_IFF_IFDISABLED 0x8 /* IPv6 operation is disabled due to * DAD failure. (XXX: not ND-specific) */ diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c index 09011b7e..ce26d54f 100644 --- a/freebsd/sys/netinet6/nd6_nbr.c +++ b/freebsd/sys/netinet6/nd6_nbr.c @@ -234,41 +234,28 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) /* (2) check. */ if (ifa == NULL) { - struct rtentry *rt; - struct sockaddr_in6 tsin6; - int need_proxy; -#ifdef RADIX_MPATH struct route_in6 ro; -#endif + int need_proxy; - bzero(&tsin6, sizeof tsin6); - tsin6.sin6_len = sizeof(struct sockaddr_in6); - tsin6.sin6_family = AF_INET6; - tsin6.sin6_addr = taddr6; + bzero(&ro, sizeof(ro)); + ro.ro_dst.sin6_len = sizeof(struct sockaddr_in6); + ro.ro_dst.sin6_family = AF_INET6; + ro.ro_dst.sin6_addr = taddr6; /* Always use the default FIB. */ #ifdef RADIX_MPATH - bzero(&ro, sizeof(ro)); - ro.ro_dst = tsin6; rtalloc_mpath_fib((struct route *)&ro, RTF_ANNOUNCE, RT_DEFAULT_FIB); - rt = ro.ro_rt; #else - rt = in6_rtalloc1((struct sockaddr *)&tsin6, 0, 0, - RT_DEFAULT_FIB); + in6_rtalloc(&ro, RT_DEFAULT_FIB); #endif - need_proxy = (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 && - rt->rt_gateway->sa_family == AF_LINK); - if (rt != NULL) { - /* - * Make a copy while we can be sure that rt_gateway - * is still stable before unlocking to avoid lock - * order problems. proxydl will only be used if - * proxy will be set in the next block. - */ + need_proxy = (ro.ro_rt && + (ro.ro_rt->rt_flags & RTF_ANNOUNCE) != 0 && + ro.ro_rt->rt_gateway->sa_family == AF_LINK); + if (ro.ro_rt != NULL) { if (need_proxy) - proxydl = *SDL(rt->rt_gateway); - RTFREE_LOCKED(rt); + proxydl = *SDL(ro.ro_rt->rt_gateway); + RTFREE(ro.ro_rt); } if (need_proxy) { /* @@ -711,8 +698,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) */ if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) { - ifa_free(ifa); nd6_dad_na_input(ifa); + ifa_free(ifa); goto freeit; } diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c index bd6fa33b..030cac3d 100644 --- a/freebsd/sys/netinet6/nd6_rtr.c +++ b/freebsd/sys/netinet6/nd6_rtr.c @@ -298,8 +298,16 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) } if (nd_ra->nd_ra_retransmit) ndi->retrans = ntohl(nd_ra->nd_ra_retransmit); - if (nd_ra->nd_ra_curhoplimit) - ndi->chlim = nd_ra->nd_ra_curhoplimit; + if (nd_ra->nd_ra_curhoplimit) { + if (ndi->chlim < nd_ra->nd_ra_curhoplimit) + ndi->chlim = nd_ra->nd_ra_curhoplimit; + else if (ndi->chlim != nd_ra->nd_ra_curhoplimit) { + log(LOG_ERR, "RA with a lower CurHopLimit sent from " + "%s on %s (current = %d, received = %d). " + "Ignored.\n", ip6_sprintf(ip6bufs, &ip6->ip6_src), + if_name(ifp), ndi->chlim, nd_ra->nd_ra_curhoplimit); + } + } dr = defrtrlist_update(&dr0); } diff --git a/freebsd/sys/netinet6/scope6.c b/freebsd/sys/netinet6/scope6.c index f891c9ce..2ccd2f7a 100644 --- a/freebsd/sys/netinet6/scope6.c +++ b/freebsd/sys/netinet6/scope6.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -74,6 +75,9 @@ static VNET_DEFINE(struct scope6_id, sid_default); #define SID(ifp) \ (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->scope6_id) +static int scope6_get(struct ifnet *, struct scope6_id *); +static int scope6_set(struct ifnet *, struct scope6_id *); + void scope6_init(void) { @@ -117,6 +121,30 @@ scope6_ifdetach(struct scope6_id *sid) } int +scope6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) +{ + struct in6_ifreq *ifr; + + if (ifp->if_afdata[AF_INET6] == NULL) + return (EPFNOSUPPORT); + + ifr = (struct in6_ifreq *)data; + switch (cmd) { + case SIOCSSCOPE6: + return (scope6_set(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + case SIOCGSCOPE6: + return (scope6_get(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + case SIOCGSCOPE6DEF: + return (scope6_get_default( + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + default: + return (EOPNOTSUPP); + } +} + +static int scope6_set(struct ifnet *ifp, struct scope6_id *idlist) { int i; @@ -179,7 +207,7 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) return (error); } -int +static int scope6_get(struct ifnet *ifp, struct scope6_id *idlist) { struct scope6_id *sid; @@ -198,7 +226,6 @@ scope6_get(struct ifnet *ifp, struct scope6_id *idlist) return (0); } - /* * Get a scope of the address. Node-local, link-local, site-local or global. */ diff --git a/freebsd/sys/netinet6/scope6_var.h b/freebsd/sys/netinet6/scope6_var.h index ae337b86..990325e9 100644 --- a/freebsd/sys/netinet6/scope6_var.h +++ b/freebsd/sys/netinet6/scope6_var.h @@ -45,8 +45,7 @@ struct scope6_id { void scope6_init(void); struct scope6_id *scope6_ifattach(struct ifnet *); void scope6_ifdetach(struct scope6_id *); -int scope6_set(struct ifnet *, struct scope6_id *); -int scope6_get(struct ifnet *, struct scope6_id *); +int scope6_ioctl(u_long cmd, caddr_t data, struct ifnet *); void scope6_setdefault(struct ifnet *); int scope6_get_default(struct scope6_id *); u_int32_t scope6_addr2default(struct in6_addr *); diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h index a0a73522..b4f270f4 100644 --- a/freebsd/sys/sys/conf.h +++ b/freebsd/sys/sys/conf.h @@ -253,6 +253,7 @@ void clone_cleanup(struct clonedevs **); int clone_create(struct clonedevs **, struct cdevsw *, int *unit, struct cdev **dev, int extra); int count_dev(struct cdev *_dev); +void delist_dev(struct cdev *_dev); void destroy_dev(struct cdev *_dev); int destroy_dev_sched(struct cdev *dev); int destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg); diff --git a/freebsd/sys/sys/mman.h b/freebsd/sys/sys/mman.h index c79ad86d..c96fedc2 100644 --- a/freebsd/sys/sys/mman.h +++ b/freebsd/sys/sys/mman.h @@ -211,6 +211,7 @@ struct shmfd { struct timespec shm_mtime; struct timespec shm_ctime; struct timespec shm_birthtime; + ino_t shm_ino; struct label *shm_label; /* MAC label */ const char *shm_path; diff --git a/freebsd/sys/sys/rman.h b/freebsd/sys/sys/rman.h index b34ef37d..547ff843 100644 --- a/freebsd/sys/sys/rman.h +++ b/freebsd/sys/sys/rman.h @@ -42,8 +42,8 @@ #define RF_ALLOCATED 0x0001 /* resource has been reserved */ #define RF_ACTIVE 0x0002 /* resource allocation has been activated */ #define RF_SHAREABLE 0x0004 /* resource permits contemporaneous sharing */ -#define RF_TIMESHARE 0x0008 /* resource permits time-division sharing */ -#define RF_WANTED 0x0010 /* somebody is waiting for this resource */ +#define RF_SPARE1 0x0008 +#define RF_SPARE2 0x0010 #define RF_FIRSTSHARE 0x0020 /* first in sharing list */ #define RF_PREFETCHABLE 0x0040 /* resource is prefetchable */ #define RF_OPTIONAL 0x0080 /* for bus_alloc_resources() */ diff --git a/freebsd/sys/sys/sleepqueue.h b/freebsd/sys/sys/sleepqueue.h index ddec1478..4c4ea651 100644 --- a/freebsd/sys/sys/sleepqueue.h +++ b/freebsd/sys/sys/sleepqueue.h @@ -46,13 +46,6 @@ * call sleepq_set_timeout() after sleepq_add() to setup a timeout. It * should then use one of the sleepq_timedwait() functions to block. * - * If the thread wants the sleep to be interruptible by signals, it can - * call sleepq_catch_signals() after sleepq_add(). It should then use - * one of the sleepq_wait_sig() functions to block. After the thread has - * been resumed, it should call sleepq_calc_signal_retval() to determine - * if it should return EINTR or ERESTART passing in the value returned from - * the earlier call to sleepq_catch_signals(). - * * A thread is normally resumed from a sleep queue by either the * sleepq_signal() or sleepq_broadcast() functions. Sleepq_signal() wakes * the thread with the highest priority that is sleeping on the specified diff --git a/freebsd/sys/sys/sockbuf.h b/freebsd/sys/sys/sockbuf.h index 84fd1aa1..76197aea 100644 --- a/freebsd/sys/sys/sockbuf.h +++ b/freebsd/sys/sys/sockbuf.h @@ -155,6 +155,8 @@ int sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so, struct thread *td); struct mbuf * sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff); +struct mbuf * + sbsndmbuf(struct sockbuf *sb, u_int off, u_int *moff); void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb); int sbwait(struct sockbuf *sb); int sblock(struct sockbuf *sb, int flags); diff --git a/freebsd/sys/sys/socket.h b/freebsd/sys/sys/socket.h index fee7f1fd..ff592cc0 100644 --- a/freebsd/sys/sys/socket.h +++ b/freebsd/sys/sys/socket.h @@ -222,7 +222,9 @@ struct accept_filter_arg { #define AF_ARP 35 #define AF_BLUETOOTH 36 /* Bluetooth sockets */ #define AF_IEEE80211 37 /* IEEE 802.11 protocol */ -#define AF_MAX 38 +#define AF_INET_SDP 40 /* OFED Socket Direct Protocol ipv4 */ +#define AF_INET6_SDP 42 /* OFED Socket Direct Protocol ipv6 */ +#define AF_MAX 42 /* * When allocating a new AF_ constant, please only allocate * even numbered constants for FreeBSD until 134 as odd numbered AF_ @@ -344,6 +346,8 @@ struct sockproto { #define PF_SCLUSTER AF_SCLUSTER #define PF_ARP AF_ARP #define PF_BLUETOOTH AF_BLUETOOTH +#define PF_INET_SDP AF_INET_SDP +#define PF_INET6_SDP AF_INET6_SDP #define PF_MAX AF_MAX diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h index 1fca343c..cfbbc7f3 100644 --- a/freebsd/sys/sys/sysctl.h +++ b/freebsd/sys/sys/sysctl.h @@ -121,7 +121,14 @@ struct ctlname { #ifdef _KERNEL #include -#define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, \ +#ifdef KLD_MODULE +/* XXX allow overspecification of type in external kernel modules */ +#define SYSCTL_CT_ASSERT_MASK CTLTYPE +#else +#define SYSCTL_CT_ASSERT_MASK 0 +#endif + +#define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, \ intptr_t arg2, struct sysctl_req *req /* definitions for sysctl_req 'lock' member */ @@ -237,53 +244,6 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); _bsd_sysctl_##parent##_##name##_children #endif /* __rtems__ */ -/* - * These macros provide type safety for sysctls. SYSCTL_ALLOWED_TYPES() - * defines a transparent union of the allowed types. SYSCTL_ASSERT_TYPE() - * and SYSCTL_ADD_ASSERT_TYPE() use the transparent union to assert that - * the pointer matches the allowed types. - * - * The allow_0 member allows a literal 0 to be passed for ptr. - */ -#define SYSCTL_ALLOWED_TYPES(type, decls) \ - union sysctl_##type { \ - long allow_0; \ - decls \ - } __attribute__((__transparent_union__)); \ - \ - static inline void * \ - __sysctl_assert_##type(union sysctl_##type ptr) \ - { \ - return (ptr.a); \ - } \ - struct __hack - -SYSCTL_ALLOWED_TYPES(INT, int *a; ); -SYSCTL_ALLOWED_TYPES(UINT, unsigned int *a; ); -SYSCTL_ALLOWED_TYPES(LONG, long *a; ); -SYSCTL_ALLOWED_TYPES(ULONG, unsigned long *a; ); -SYSCTL_ALLOWED_TYPES(INT64, int64_t *a; long long *b; ); -SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a; unsigned long long *b; ); - -#ifdef notyet -#define SYSCTL_ADD_ASSERT_TYPE(type, ptr) \ - __sysctl_assert_ ## type (ptr) -#define SYSCTL_ASSERT_TYPE(type, ptr, parent, name) \ - _SYSCTL_ASSERT_TYPE(type, ptr, __LINE__, parent##_##name) -#else -#define SYSCTL_ADD_ASSERT_TYPE(type, ptr) ptr -#define SYSCTL_ASSERT_TYPE(type, ptr, parent, name) -#endif -#define _SYSCTL_ASSERT_TYPE(t, p, l, id) \ - __SYSCTL_ASSERT_TYPE(t, p, l, id) -#define __SYSCTL_ASSERT_TYPE(type, ptr, line, id) \ - static inline void \ - sysctl_assert_##line##_##id(void) \ - { \ - (void)__sysctl_assert_##type(ptr); \ - } \ - struct __hack - #ifndef NO_SYSCTL_DESCR #define __DESCR(d) d #else @@ -308,130 +268,242 @@ SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a; unsigned long long *b; ); #define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \ sysctl_add_oid(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, __DESCR(descr)) +/* This constructs a root node from which other nodes can hang. */ +#define SYSCTL_ROOT_NODE(nbr, name, access, handler, descr) \ + SYSCTL_NODE(, nbr, name, access, handler, descr) + /* This constructs a node from which other oids can hang. */ #define SYSCTL_NODE(parent, nbr, name, access, handler, descr) \ struct sysctl_oid_list SYSCTL_NODE_CHILDREN(parent, name); \ SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|(access), \ - (void*)&SYSCTL_NODE_CHILDREN(parent, name), 0, handler, "N", descr) + (void*)&SYSCTL_NODE_CHILDREN(parent, name), 0, handler, "N", descr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_NODE) -#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), \ - NULL, 0, handler, "N", __DESCR(descr)) - -/* Oid for a string. len can be 0 to indicate '\0' termination. */ -#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), \ - arg, len, sysctl_handle_string, "A", descr) +#define SYSCTL_ADD_ROOT_NODE(ctx, nbr, name, access, handler, descr) \ + SYSCTL_ADD_NODE(ctx, SYSCTL_STATIC_CHILDREN(), nbr, name, access, handler, descr) -#define SYSCTL_ADD_STRING(ctx, parent, nbr, name, access, arg, len, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \ - arg, len, sysctl_handle_string, "A", __DESCR(descr)) +#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \ +({ \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_NODE); \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), \ + NULL, 0, handler, "N", __DESCR(descr)); \ +}) -/* Oid for an int. If ptr is NULL, val is returned. */ -#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_ASSERT_TYPE(INT, ptr, parent, name); \ - SYSCTL_OID(parent, nbr, name, \ - CTLTYPE_INT | CTLFLAG_MPSAFE | (access), \ - ptr, val, sysctl_handle_int, "I", descr) +/* Oid for a string. len can be 0 to indicate '\0' termination. */ +#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), \ + arg, len, sysctl_handle_string, "A", descr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_STRING) + +#define SYSCTL_ADD_STRING(ctx, parent, nbr, name, access, arg, len, descr) \ +({ \ + char *__arg = (arg); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_STRING); \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \ + __arg, len, sysctl_handle_string, "A", __DESCR(descr)); \ +}) + +/* Oid for an int. If ptr is SYSCTL_NULL_INT_PTR, val is returned. */ +#define SYSCTL_NULL_INT_PTR ((int *)NULL) +#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_INT | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_int, "I", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT) && \ + sizeof(int) == sizeof(*(ptr))) #define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + int *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_INT); \ sysctl_add_oid(ctx, parent, nbr, name, \ CTLTYPE_INT | CTLFLAG_MPSAFE | (access), \ - SYSCTL_ADD_ASSERT_TYPE(INT, ptr), val, \ - sysctl_handle_int, "I", __DESCR(descr)) + __ptr, val, sysctl_handle_int, "I", __DESCR(descr)); \ +}) /* Oid for an unsigned int. If ptr is NULL, val is returned. */ -#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_ASSERT_TYPE(UINT, ptr, parent, name); \ - SYSCTL_OID(parent, nbr, name, \ - CTLTYPE_UINT | CTLFLAG_MPSAFE | (access), \ - ptr, val, sysctl_handle_int, "IU", descr) +#define SYSCTL_NULL_UINT_PTR ((unsigned *)NULL) +#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_UINT | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_int, "IU", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_UINT) && \ + sizeof(unsigned) == sizeof(*(ptr))) #define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + unsigned *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_UINT); \ sysctl_add_oid(ctx, parent, nbr, name, \ CTLTYPE_UINT | CTLFLAG_MPSAFE | (access), \ - SYSCTL_ADD_ASSERT_TYPE(UINT, ptr), val, \ - sysctl_handle_int, "IU", __DESCR(descr)) + __ptr, val, sysctl_handle_int, "IU", __DESCR(descr)); \ +}) /* Oid for a long. The pointer must be non NULL. */ -#define SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_ASSERT_TYPE(LONG, ptr, parent, name); \ - SYSCTL_OID(parent, nbr, name, \ - CTLTYPE_LONG | CTLFLAG_MPSAFE | (access), \ - ptr, val, sysctl_handle_long, "L", descr) +#define SYSCTL_NULL_LONG_PTR ((long *)NULL) +#define SYSCTL_LONG(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_LONG | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_long, "L", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_LONG) && \ + sizeof(long) == sizeof(*(ptr))) #define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \ +({ \ + long *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_LONG); \ sysctl_add_oid(ctx, parent, nbr, name, \ CTLTYPE_LONG | CTLFLAG_MPSAFE | (access), \ - SYSCTL_ADD_ASSERT_TYPE(LONG, ptr), 0, \ - sysctl_handle_long, "L", __DESCR(descr)) + __ptr, 0, sysctl_handle_long, "L", __DESCR(descr)); \ +}) /* Oid for an unsigned long. The pointer must be non NULL. */ +#define SYSCTL_NULL_ULONG_PTR ((unsigned long *)NULL) #define SYSCTL_ULONG(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_ASSERT_TYPE(ULONG, ptr, parent, name); \ SYSCTL_OID(parent, nbr, name, \ CTLTYPE_ULONG | CTLFLAG_MPSAFE | (access), \ - ptr, val, sysctl_handle_long, "LU", descr) + ptr, val, sysctl_handle_long, "LU", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_ULONG) && \ + sizeof(unsigned long) == sizeof(*(ptr))) #define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \ +({ \ + unsigned long *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_ULONG); \ sysctl_add_oid(ctx, parent, nbr, name, \ CTLTYPE_ULONG | CTLFLAG_MPSAFE | (access), \ - SYSCTL_ADD_ASSERT_TYPE(ULONG, ptr), 0, \ - sysctl_handle_long, "LU", __DESCR(descr)) + __ptr, 0, sysctl_handle_long, "LU", __DESCR(descr)); \ +}) /* Oid for a quad. The pointer must be non NULL. */ -#define SYSCTL_QUAD(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_ASSERT_TYPE(INT64, ptr, parent, name); \ - SYSCTL_OID(parent, nbr, name, \ - CTLTYPE_S64 | CTLFLAG_MPSAFE | (access), \ - ptr, val, sysctl_handle_64, "Q", descr) +#define SYSCTL_NULL_QUAD_PTR ((int64_t *)NULL) +#define SYSCTL_QUAD(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_S64 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_64, "Q", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S64) && \ + sizeof(int64_t) == sizeof(*(ptr))) #define SYSCTL_ADD_QUAD(ctx, parent, nbr, name, access, ptr, descr) \ +({ \ + int64_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_S64); \ sysctl_add_oid(ctx, parent, nbr, name, \ CTLTYPE_S64 | CTLFLAG_MPSAFE | (access), \ - SYSCTL_ADD_ASSERT_TYPE(INT64, ptr), 0, \ - sysctl_handle_64, "Q", __DESCR(descr)) + __ptr, 0, sysctl_handle_64, "Q", __DESCR(descr)); \ +}) +#define SYSCTL_NULL_UQUAD_PTR ((uint64_t *)NULL) #define SYSCTL_UQUAD(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_ASSERT_TYPE(UINT64, ptr, parent, name); \ SYSCTL_OID(parent, nbr, name, \ CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ - ptr, val, sysctl_handle_64, "QU", descr) + ptr, val, sysctl_handle_64, "QU", descr); \ + CTASSERT((((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64) && \ + sizeof(uint64_t) == sizeof(*(ptr))) #define SYSCTL_ADD_UQUAD(ctx, parent, nbr, name, access, ptr, descr) \ +({ \ + uint64_t *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U64); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ + __ptr, 0, sysctl_handle_64, "QU", __DESCR(descr)); \ +}) + +/* Oid for a 64-bit unsigned counter(9). The pointer must be non NULL. */ +#define SYSCTL_COUNTER_U64(parent, nbr, name, access, ptr, descr) \ + SYSCTL_ASSERT_TYPE(UINT64, ptr, parent, name); \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ + ptr, 0, sysctl_handle_counter_u64, "QU", descr) + +#define SYSCTL_ADD_COUNTER_U64(ctx, parent, nbr, name, access, ptr, descr)\ sysctl_add_oid(ctx, parent, nbr, name, \ CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ SYSCTL_ADD_ASSERT_TYPE(UINT64, ptr), 0, \ - sysctl_handle_64, "QU", __DESCR(descr)) + sysctl_handle_counter_u64, "QU", __DESCR(descr)) + +/* Oid for a CPU dependant variable */ +#define SYSCTL_ADD_UAUTO(ctx, parent, nbr, name, access, ptr, descr) \ +({ \ + struct sysctl_oid *__ret; \ + CTASSERT((sizeof(uint64_t) == sizeof(*(ptr)) || \ + sizeof(unsigned) == sizeof(*(ptr))) && \ + ((access) & CTLTYPE) == 0); \ + if (sizeof(uint64_t) == sizeof(*(ptr))) { \ + __ret = sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_U64 | CTLFLAG_MPSAFE | (access), \ + (ptr), 0, sysctl_handle_64, "QU", \ + __DESCR(descr)); \ + } else { \ + __ret = sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_UINT | CTLFLAG_MPSAFE | (access), \ + (ptr), 0, sysctl_handle_int, "IU", \ + __DESCR(descr)); \ + } \ + __ret; \ +}) /* Oid for an opaque object. Specified by a pointer and a length. */ -#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, len, sysctl_handle_opaque, fmt, descr) - -#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr)\ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, len, sysctl_handle_opaque, fmt, __DESCR(descr)) +#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \ + ptr, len, sysctl_handle_opaque, fmt, descr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE) + +#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr) \ +({ \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE); \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ + ptr, len, sysctl_handle_opaque, fmt, __DESCR(descr)); \ +}) /* Oid for a struct. Specified by a pointer and a type. */ -#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, sizeof(struct type), sysctl_handle_opaque, \ - "S," #type, descr) +#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), \ + ptr, sizeof(struct type), sysctl_handle_opaque, \ + "S," #type, descr); \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE) #define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ - ptr, sizeof(struct type), sysctl_handle_opaque, "S," #type, __DESCR(descr)) +({ \ + CTASSERT(((access) & CTLTYPE) == 0 || \ + ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_OPAQUE); \ + sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \ + (ptr), sizeof(struct type), \ + sysctl_handle_opaque, "S," #type, __DESCR(descr)); \ +}) /* Oid for a procedure. Specified by a pointer and an arg. */ #define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \ - CTASSERT(((access) & CTLTYPE) != 0); \ - SYSCTL_OID(parent, nbr, name, (access), \ - ptr, arg, handler, fmt, descr) + SYSCTL_OID(parent, nbr, name, (access), \ + ptr, arg, handler, fmt, descr); \ + CTASSERT(((access) & CTLTYPE) != 0) #define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \ - sysctl_add_oid(ctx, parent, nbr, name, (access), \ - ptr, arg, handler, fmt, __DESCR(descr)) +({ \ + CTASSERT(((access) & CTLTYPE) != 0); \ + sysctl_add_oid(ctx, parent, nbr, name, (access), \ + (ptr), (arg), (handler), (fmt), __DESCR(descr)); \ +}) /* * A macro to generate a read-only sysctl to indicate the presense of optional @@ -439,7 +511,7 @@ SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a; unsigned long long *b; ); */ #define FEATURE(name, desc) \ SYSCTL_INT(_kern_features, OID_AUTO, name, CTLFLAG_RD | CTLFLAG_CAPRD, \ - 0, 1, desc) + SYSCTL_NULL_INT_PTR, 1, desc) #endif /* _KERNEL */ diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index ed58a487..5af3b62c 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/9/sys/kern/syscalls.master 260208 2014-01-02 21:57:03Z jhb + * created from FreeBSD: stable/9/sys/kern/syscalls.master 276957 2015-01-11 07:10:43Z dchagin */ #ifndef _SYS_SYSPROTO_H_ @@ -934,7 +934,7 @@ struct munlockall_args { register_t dummy; }; struct __getcwd_args { - char buf_l_[PADL_(u_char *)]; u_char * buf; char buf_r_[PADR_(u_char *)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; char buflen_l_[PADL_(u_int)]; u_int buflen; char buflen_r_[PADR_(u_int)]; }; struct sched_setparam_args { diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h index f0a3fc63..c761555e 100644 --- a/freebsd/sys/sys/systm.h +++ b/freebsd/sys/sys/systm.h @@ -47,11 +47,12 @@ #ifndef __rtems__ extern int cold; /* nonzero if we are doing a cold boot */ +extern int rebooting; /* kern_reboot() has been called. */ #else /* __rtems__ */ -/* In RTEMS there is no cold boot */ +/* In RTEMS there is no cold boot and reboot */ #define cold 0 +#define rebooting 0 #endif /* __rtems__ */ -extern int rebooting; /* kern_reboot() has been called. */ #ifndef __rtems__ extern const char *panicstr; /* panic message */ #else /* __rtems__ */ @@ -110,10 +111,8 @@ enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN }; } while (0) #endif -#ifndef CTASSERT /* Allow lint to override */ -#define CTASSERT(x) _CTASSERT(x, __LINE__) -#define _CTASSERT(x, y) __CTASSERT(x, y) -#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] +#ifndef CTASSERT /* Allow lint to override */ +#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") #endif /* @@ -372,8 +371,9 @@ void cpu_startprofclock(void); void cpu_stopprofclock(void); void cpu_idleclock(void); void cpu_activeclock(void); -extern int cpu_can_deep_sleep; -extern int cpu_disable_deep_sleep; +extern int cpu_deepest_sleep; +extern int cpu_disable_c2_sleep; +extern int cpu_disable_c3_sleep; #ifndef __rtems__ int cr_cansee(struct ucred *u1, struct ucred *u2); diff --git a/freebsd/sys/sys/timetc.h b/freebsd/sys/sys/timetc.h index 4f75c3de..7e00ffc8 100644 --- a/freebsd/sys/sys/timetc.h +++ b/freebsd/sys/sys/timetc.h @@ -58,7 +58,7 @@ struct timecounter { * means "only use at explicit request". */ u_int tc_flags; -#define TC_FLAGS_C3STOP 1 /* Timer dies in C3. */ +#define TC_FLAGS_C2STOP 1 /* Timer dies in C2+. */ void *tc_priv; /* Pointer to the timecounter's private parts. */ diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c index 1f79d287..1d429ef8 100644 --- a/freebsd/sys/vm/uma_core.c +++ b/freebsd/sys/vm/uma_core.c @@ -791,9 +791,7 @@ zone_drain_wait(uma_zone_t zone, int waitok) while (zone->uz_flags & UMA_ZFLAG_DRAINING) { if (waitok == M_NOWAIT) goto out; - mtx_unlock(&uma_mtx); msleep(zone, zone->uz_lock, PVM, "zonedrain", 1); - mtx_lock(&uma_mtx); } zone->uz_flags |= UMA_ZFLAG_DRAINING; bucket_cache_drain(zone); diff --git a/freebsd/usr.bin/netstat/inet6.c b/freebsd/usr.bin/netstat/inet6.c index 2d3d2db8..07086318 100644 --- a/freebsd/usr.bin/netstat/inet6.c +++ b/freebsd/usr.bin/netstat/inet6.c @@ -348,7 +348,7 @@ static char *srcrule_str[] = { "public/temporary address", "alive interface", "preferred interface", - "rule #10", + "preferred source", "rule #11", "rule #12", "rule #13", @@ -542,13 +542,13 @@ ip6_ifstats(char *ifname) } strcpy(ifr.ifr_name, ifname); - printf("ip6 on %s:\n", ifr.ifr_name); - if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { - perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); + if (errno != EPFNOSUPPORT) + perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); goto end; } + printf("ip6 on %s:\n", ifr.ifr_name); p(ifs6_in_receive, "\t%ju total input datagram%s\n"); p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n"); p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n"); @@ -947,13 +947,13 @@ icmp6_ifstats(char *ifname) } strcpy(ifr.ifr_name, ifname); - printf("icmp6 on %s:\n", ifr.ifr_name); - if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { - perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); + if (errno != EPFNOSUPPORT) + perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); goto end; } + printf("icmp6 on %s:\n", ifr.ifr_name); p(ifs6_in_msg, "\t%ju total input message%s\n"); p(ifs6_in_error, "\t%ju total input error message%s\n"); p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n"); diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs.h b/rtemsbsd/include/rtems/bsd/local/usbdevs.h index 3543d85a..7472c005 100644 --- a/rtemsbsd/include/rtems/bsd/local/usbdevs.h +++ b/rtemsbsd/include/rtems/bsd/local/usbdevs.h @@ -702,6 +702,7 @@ #define USB_VENDOR_ELV 0x18ef /* ELV */ #define USB_VENDOR_LINKSYS3 0x1915 /* Linksys */ #define USB_VENDOR_QUALCOMMINC 0x19d2 /* Qualcomm, Incorporated */ +#define USB_VENDOR_QUALCOMM3 0x19f5 /* Qualcomm, Inc. */ #define USB_VENDOR_BAYER 0x1a79 /* Bayer */ #define USB_VENDOR_WCH2 0x1a86 /* QinHeng Electronics */ #define USB_VENDOR_STELERA 0x1a8d /* Stelera Wireless */ @@ -720,6 +721,7 @@ #define USB_VENDOR_MPMAN 0x1cae /* MpMan */ #define USB_VENDOR_DRESDENELEKTRONIK 0x1cf1 /* dresden elektronik */ #define USB_VENDOR_NEOTEL 0x1d09 /* Neotel */ +#define USB_VENDOR_DREAMLINK 0x1d34 /* Dream Link */ #define USB_VENDOR_PEGATRON 0x1d4d /* Pegatron */ #define USB_VENDOR_QISDA 0x1da5 /* Qisda */ #define USB_VENDOR_METAGEEK2 0x1dd5 /* MetaGeek */ @@ -1180,6 +1182,7 @@ /* ASUS products */ #define USB_PRODUCT_ASUS2_USBN11 0x0b05 /* USB-N11 */ +#define USB_PRODUCT_ASUS_RT2570 0x1706 /* RT2500USB Wireless Adapter */ #define USB_PRODUCT_ASUS_WL167G 0x1707 /* WL-167g Wireless Adapter */ #define USB_PRODUCT_ASUS_WL159G 0x170c /* WL-159g */ #define USB_PRODUCT_ASUS_A9T_WIFI 0x171b /* A9T wireless */ @@ -1193,16 +1196,17 @@ #define USB_PRODUCT_ASUS_RT2870_4 0x1760 /* RT2870 */ #define USB_PRODUCT_ASUS_RT2870_5 0x1761 /* RT2870 */ #define USB_PRODUCT_ASUS_USBN13 0x1784 /* USB-N13 */ -#define USB_PRODUCT_ASUS_RT3070_1 0x1790 /* RT3070 */ #define USB_PRODUCT_ASUS_USBN10 0x1786 /* USB-N10 */ +#define USB_PRODUCT_ASUS_RT3070_1 0x1790 /* RT3070 */ +#define USB_PRODUCT_ASUS_RTL8192SU 0x1791 /* RTL8192SU */ +#define USB_PRODUCT_ASUS_USB_N53 0x179d /* ASUS Black Diamond Dual Band USB-N53 */ #define USB_PRODUCT_ASUS_RTL8192CU 0x17ab /* RTL8192CU */ #define USB_PRODUCT_ASUS_USBN66 0x17ad /* USB-N66 */ -#define USB_PRODUCT_ASUS_RTL8192SU 0x1791 /* RTL8192SU */ +#define USB_PRODUCT_ASUS_USBN10NANO 0x17ba /* USB-N10 Nano */ +#define USB_PRODUCT_ASUS_USBAC51 0x17d1 /* USB-AC51 */ #define USB_PRODUCT_ASUS_A730W 0x4202 /* ASUS MyPal A730W */ #define USB_PRODUCT_ASUS_P535 0x420f /* ASUS P535 PDA */ #define USB_PRODUCT_ASUS_GMSC 0x422f /* ASUS Generic Mass Storage */ -#define USB_PRODUCT_ASUS_RT2570 0x1706 /* RT2500USB Wireless Adapter */ -#define USB_PRODUCT_ASUS_USB_N53 0x179d /* ASUS Black Diamond Dual Band USB-N53 */ /* ATen products */ #define USB_PRODUCT_ATEN_UC1284 0x2001 /* Parallel printer */ @@ -1385,6 +1389,7 @@ #define USB_PRODUCT_CHICONY_KB8933 0x0001 /* KB-8933 keyboard */ #define USB_PRODUCT_CHICONY_KU0325 0x0116 /* KU-0325 keyboard */ #define USB_PRODUCT_CHICONY_CNF7129 0xb071 /* Notebook Web Camera */ +#define USB_PRODUCT_CHICONY_HDUVCCAM 0xb40a /* HD UVC WebCam */ #define USB_PRODUCT_CHICONY_RTL8188CUS_1 0xaff7 /* RTL8188CUS */ #define USB_PRODUCT_CHICONY_RTL8188CUS_2 0xaff8 /* RTL8188CUS */ #define USB_PRODUCT_CHICONY_RTL8188CUS_3 0xaff9 /* RTL8188CUS */ @@ -1490,6 +1495,7 @@ /* Corsair products */ #define USB_PRODUCT_CORSAIR_K60 0x0a60 /* Corsair Vengeance K60 keyboard */ +#define USB_PRODUCT_CORSAIR_K70 0x1b09 /* Corsair Vengeance K70 keyboard */ /* Creative products */ #define USB_PRODUCT_CREATIVE_NOMAD_II 0x1002 /* Nomad II MP3 player */ @@ -1597,6 +1603,7 @@ #define USB_PRODUCT_DLINK_DUBE100C1 0x1a02 /* DUB-E100 rev C1 */ #define USB_PRODUCT_DLINK_DSB650TX4 0x200c /* 10/100 Ethernet */ #define USB_PRODUCT_DLINK_DWL120E 0x3200 /* DWL-120 rev E */ +#define USB_PRODUCT_DLINK_DWA125D1 0x330f /* DWA-125 rev D1 */ #define USB_PRODUCT_DLINK_DWL122 0x3700 /* DWL-122 */ #define USB_PRODUCT_DLINK_DWLG120 0x3701 /* DWL-G120 */ #define USB_PRODUCT_DLINK_DWL120F 0x3702 /* DWL-120 rev F */ @@ -1626,6 +1633,8 @@ #define USB_PRODUCT_DLINK_DUBH7 0xf103 /* DUB-H7 USB 2.0 7-Port Hub */ #define USB_PRODUCT_DLINK_DWR510_CD 0xa805 /* DWR-510 CD-ROM Mode */ #define USB_PRODUCT_DLINK_DWR510 0x7e12 /* DWR-510 */ +#define USB_PRODUCT_DLINK_DWM157 0x7d02 /* DWM-157 */ +#define USB_PRODUCT_DLINK_DWM157_CD 0xa707 /* DWM-157 CD-ROM Mode */ #define USB_PRODUCT_DLINK_RTL8188CU 0x3308 /* RTL8188CU */ #define USB_PRODUCT_DLINK_RTL8192CU_1 0x3307 /* RTL8192CU */ #define USB_PRODUCT_DLINK_RTL8192CU_2 0x3309 /* RTL8192CU */ @@ -1659,9 +1668,13 @@ /* DrayTek products */ #define USB_PRODUCT_DRAYTEK_VIGOR550 0x0550 /* Vigor550 */ +/* Dream Link products */ +#define USB_PRODUCT_DREAMLINK_DL100B 0x0004 /* USB Webmail Notifier */ + /* dresden elektronik products */ #define USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD 0x0001 /* SensorTerminalBoard */ #define USB_PRODUCT_DRESDENELEKTRONIK_WIRELESSHANDHELDTERMINAL 0x0004 /* Wireless Handheld Terminal */ +#define USB_PRODUCT_DRESDENELEKTRONIK_DE_RFNODE 0x001c /* deRFnode */ #define USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST 0x0022 /* Levelshifter Stick Low Cost */ /* Dynastream Innovations */ @@ -1850,7 +1863,8 @@ #define USB_PRODUCT_FTDI_232EX 0x6015 /* FTDI compatible adapter */ #define USB_PRODUCT_FTDI_SERIAL_2232D 0x9e90 /* FT2232D Dual port Serial */ #define USB_PRODUCT_FTDI_SERIAL_4232H 0x6011 /* FT4232H Quad port Serial */ -#define USB_PRODUCT_FTDI_BEAGLEBONE 0xa6d0 /* BeagleBone */ +#define USB_PRODUCT_FTDI_XDS100V2 0xa6d0 /* TI XDS100V1/V2 and early Beaglebones */ +#define USB_PRODUCT_FTDI_XDS100V3 0xa6d1 /* TI XDS100V3 */ #define USB_PRODUCT_FTDI_KTLINK 0xbbe2 /* KT-LINK Embedded Hackers Multitool */ #define USB_PRODUCT_FTDI_TURTELIZER2 0xbdc8 /* egnite Turtelizer 2 JTAG/RS232 Adapter */ /* Gude Analog- und Digitalsysteme products also uses FTDI's id: */ @@ -2226,6 +2240,8 @@ #define USB_PRODUCT_HP_CDW8200 0x0207 /* CD-Writer Plus 8200e */ #define USB_PRODUCT_HP_MMKEYB 0x020c /* Multimedia keyboard */ #define USB_PRODUCT_HP_1220C 0x0212 /* DeskJet 1220C */ +#define USB_PRODUCT_HP_UN2420_QDL 0x241d /* UN2420 QDL Firmware Loader */ +#define USB_PRODUCT_HP_UN2420 0x251d /* UN2420 WWAN/GPS Module */ #define USB_PRODUCT_HP_810C 0x0304 /* DeskJet 810C/812C */ #define USB_PRODUCT_HP_4300C 0x0305 /* Scanjet 4300C */ #define USB_PRODUCT_HP_CDW4E 0x0307 /* CD-Writer+ CD-4e */ @@ -2341,15 +2357,21 @@ #define USB_PRODUCT_HUAWEI_K3765 0x1465 /* 3G modem */ #define USB_PRODUCT_HUAWEI_E1820 0x14ac /* E1820 HSPA+ USB Slider */ #define USB_PRODUCT_HUAWEI_K3770 0x14c9 /* 3G modem */ +#define USB_PRODUCT_HUAWEI_K3772 0x14cf /* K3772 */ #define USB_PRODUCT_HUAWEI_K3770_INIT 0x14d1 /* K3770 Initial */ #define USB_PRODUCT_HUAWEI_E3131_INIT 0x14fe /* 3G modem initial */ #define USB_PRODUCT_HUAWEI_E392 0x1505 /* LTE modem */ #define USB_PRODUCT_HUAWEI_E3131 0x1506 /* 3G modem */ #define USB_PRODUCT_HUAWEI_K3765_INIT 0x1520 /* K3765 Initial */ #define USB_PRODUCT_HUAWEI_K4505_INIT 0x1521 /* K4505 Initial */ +#define USB_PRODUCT_HUAWEI_K3772_INIT 0x1526 /* K3772 Initial */ +#define USB_PRODUCT_HUAWEI_E3272_INIT 0x155b /* LTE modem initial */ +#define USB_PRODUCT_HUAWEI_R215_INIT 0x1582 /* LTE modem initial */ +#define USB_PRODUCT_HUAWEI_R215 0x1588 /* LTE modem */ #define USB_PRODUCT_HUAWEI_ETS2055 0x1803 /* CDMA modem */ #define USB_PRODUCT_HUAWEI_E173 0x1c05 /* 3G modem */ #define USB_PRODUCT_HUAWEI_E173_INIT 0x1c0b /* 3G modem initial */ +#define USB_PRODUCT_HUAWEI_E3272 0x1c1e /* LTE modem */ /* HUAWEI 3com products */ #define USB_PRODUCT_HUAWEI3COM_WUB320G 0x0009 /* Aolynk WUB320g */ @@ -2396,6 +2418,8 @@ #define USB_PRODUCT_INTEL_TESTBOARD 0x9890 /* 82930 test board */ #define USB_PRODUCT_INTEL2_IRMH 0x0020 /* Integrated Rate Matching Hub */ #define USB_PRODUCT_INTEL2_IRMH2 0x0024 /* Integrated Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_IRMH3 0x8000 /* Integrated Rate Matching Hub */ +#define USB_PRODUCT_INTEL2_IRMH4 0x8008 /* Integrated Rate Matching Hub */ /* Interbiometric products */ #define USB_PRODUCT_INTERBIOMETRICS_IOBOARD 0x1002 /* FTDI compatible adapter */ @@ -2590,6 +2614,7 @@ /* Lexar products */ #define USB_PRODUCT_LEXAR_JUMPSHOT 0x0001 /* jumpSHOT CompactFlash Reader */ #define USB_PRODUCT_LEXAR_CF_READER 0xb002 /* USB CF Reader */ +#define USB_PRODUCT_LEXAR_JUMPDRIVE 0xa833 /* USB Jumpdrive Flash Drive */ /* Lexmark products */ #define USB_PRODUCT_LEXMARK_S2450 0x0009 /* Optra S 2450 */ @@ -3236,6 +3261,7 @@ #define USB_PRODUCT_NOVATEL_EU870D 0x2420 /* Expedite EU870D */ #define USB_PRODUCT_NOVATEL_U727 0x4100 /* Merlin U727 CDMA */ #define USB_PRODUCT_NOVATEL_MC950D 0x4400 /* Novatel MC950D HSUPA */ +#define USB_PRODUCT_NOVATEL_MC990D 0x7001 /* Novatel MC990D */ #define USB_PRODUCT_NOVATEL_ZEROCD 0x5010 /* Novatel ZeroCD */ #define USB_PRODUCT_NOVATEL_MIFI2200V 0x5020 /* Novatel MiFi 2200 CDMA Virgin Mobile */ #define USB_PRODUCT_NOVATEL_ZEROCD2 0x5030 /* Novatel ZeroCD */ @@ -3244,6 +3270,7 @@ #define USB_PRODUCT_NOVATEL_U760 0x6000 /* Novatel U760 */ #define USB_PRODUCT_NOVATEL_MC760 0x6002 /* Novatel MC760 */ #define USB_PRODUCT_NOVATEL_MC547 0x7042 /* Novatel MC547 */ +#define USB_PRODUCT_NOVATEL_MC679 0x7031 /* Novatel MC679 */ #define USB_PRODUCT_NOVATEL2_FLEXPACKGPS 0x0100 /* NovAtel FlexPack GPS receiver */ /* Merlin products */ @@ -3555,8 +3582,11 @@ #define USB_PRODUCT_QUALCOMM2_AC8700 0x6000 /* AC8700 */ #define USB_PRODUCT_QUALCOMM2_VW110L 0x1000 /* Vertex Wireless 110L modem */ #define USB_PRODUCT_QUALCOMM2_SIM5218 0x9000 /* SIM5218 */ +#define USB_PRODUCT_QUALCOMM2_WM620 0x9002 /* Neoway WM620 */ #define USB_PRODUCT_QUALCOMM2_GOBI2000_QDL 0x9204 /* Qualcomm Gobi 2000 QDL */ #define USB_PRODUCT_QUALCOMM2_GOBI2000 0x9205 /* Qualcomm Gobi 2000 modem */ +#define USB_PRODUCT_QUALCOMM2_VT80N 0x6500 /* Venus VT80N */ +#define USB_PRODUCT_QUALCOMM3_VFAST2 0x9909 /* Venus Fast2 modem */ #define USB_PRODUCT_QUALCOMMINC_CDMA_MSM 0x0001 /* CDMA Technologies MSM modem */ #define USB_PRODUCT_QUALCOMMINC_E0002 0x0002 /* 3G modem */ #define USB_PRODUCT_QUALCOMMINC_E0003 0x0003 /* 3G modem */ @@ -3624,10 +3654,16 @@ #define USB_PRODUCT_QUALCOMMINC_E0082 0x0082 /* 3G modem */ #define USB_PRODUCT_QUALCOMMINC_E0086 0x0086 /* 3G modem */ #define USB_PRODUCT_QUALCOMMINC_SURFSTICK 0x0117 /* 1&1 Surf Stick */ -#define USB_PRODUCT_QUALCOMMINC_K3772_Z 0x1179 /* 3G modem */ +#define USB_PRODUCT_QUALCOMMINC_K3772_Z_INIT 0x1179 /* K3772-Z Initial */ +#define USB_PRODUCT_QUALCOMMINC_K3772_Z 0x1181 /* K3772-Z */ +#define USB_PRODUCT_QUALCOMMINC_ZTE_MF730M 0x1420 /* 3G modem */ +#define USB_PRODUCT_QUALCOMMINC_MF195E_INIT 0x1514 /* MF195E initial */ +#define USB_PRODUCT_QUALCOMMINC_MF195E 0x1516 /* MF195E */ #define USB_PRODUCT_QUALCOMMINC_ZTE_STOR 0x2000 /* USB ZTE Storage */ #define USB_PRODUCT_QUALCOMMINC_E2002 0x2002 /* 3G modem */ #define USB_PRODUCT_QUALCOMMINC_E2003 0x2003 /* 3G modem */ +#define USB_PRODUCT_QUALCOMMINC_AC682 0xffdd /* CDMA 1xEVDO USB modem */ +#define USB_PRODUCT_QUALCOMMINC_AC682_INIT 0xffde /* CDMA 1xEVDO USB modem (initial) */ #define USB_PRODUCT_QUALCOMMINC_AC8710 0xfff1 /* 3G modem */ #define USB_PRODUCT_QUALCOMMINC_AC2726 0xfff5 /* 3G modem */ #define USB_PRODUCT_QUALCOMMINC_AC8700 0xfffe /* CDMA 1xEVDO USB modem */ @@ -3684,6 +3720,7 @@ /* Green House and CompUSA OEM this part */ #define USB_PRODUCT_REALTEK_DUMMY 0x0000 /* Dummy product */ #define USB_PRODUCT_REALTEK_USB20CRW 0x0158 /* USB20CRW Card Reader */ +#define USB_PRODUCT_REALTEK_RTL8188ETV 0x0179 /* RTL8188ETV */ #define USB_PRODUCT_REALTEK_RTL8188CTV 0x018a /* RTL8188CTV */ #define USB_PRODUCT_REALTEK_USBKR100 0x8150 /* USBKR100 USB Ethernet */ #define USB_PRODUCT_REALTEK_RTL8188CE_0 0x8170 /* RTL8188CE */ @@ -3707,6 +3744,7 @@ #define USB_PRODUCT_REALTEK_RTL8192CU 0x8178 /* RTL8192CU */ #define USB_PRODUCT_REALTEK_RTL8192CE 0x817c /* RTL8192CE */ #define USB_PRODUCT_REALTEK_RTL8188RU_1 0x817d /* RTL8188RU */ +#define USB_PRODUCT_REALTEK_RTL8188RU_3 0x817f /* RTL8188RU */ #define USB_PRODUCT_REALTEK_RTL8712 0x8712 /* RTL8712 */ #define USB_PRODUCT_REALTEK_RTL8713 0x8712 /* RTL8713 */ #define USB_PRODUCT_REALTEK_RTL8188RU_2 0x317f /* RTL8188RU */ @@ -4125,6 +4163,23 @@ #define USB_PRODUCT_SMC2_2020HUB 0x2020 /* USB Hub */ #define USB_PRODUCT_SMC2_2514HUB 0x2514 /* USB Hub */ #define USB_PRODUCT_SMC3_2662WUSB 0xa002 /* 2662W-AR Wireless */ +#define USB_PRODUCT_SMC2_LAN9500_ETH 0x9500 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9505_ETH 0x9505 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9530_ETH 0x9530 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9730_ETH 0x9730 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9500_SAL10 0x9900 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9505_SAL10 0x9901 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9500A_SAL10 0x9902 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9505A_SAL10 0x9903 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9514_SAL10 0x9904 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9500A_HAL 0x9905 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9505A_HAL 0x9906 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9500_ETH_2 0x9907 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9500A_ETH_2 0x9908 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9514_ETH_2 0x9909 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9500A_ETH 0x9e00 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN9505A_ETH 0x9e01 /* USB/Ethernet */ +#define USB_PRODUCT_SMC2_LAN89530_ETH 0x9e08 /* USB/Ethernet */ #define USB_PRODUCT_SMC2_LAN9514_ETH 0xec00 /* USB/Ethernet */ /* SOHOware products */ @@ -4446,8 +4501,28 @@ #define USB_PRODUCT_WESTERN_EXTHDD 0x0400 /* External HDD */ #define USB_PRODUCT_WESTERN_HUB 0x0500 /* USB HUB */ #define USB_PRODUCT_WESTERN_MYBOOK 0x0901 /* MyBook External HDD */ -#define USB_PRODUCT_WESTERN_MYPASSWORD 0x0704 /* MyPassword External HDD */ -#define USB_PRODUCT_WESTERN_MYPASSPORT 0x0748 /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_00 0x0704 /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_11 0x0741 /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_01 0x0746 /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_02 0x0748 /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_03 0x074A /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_04 0x074C /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_05 0x074E /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_06 0x07A6 /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_07 0x07A8 /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_08 0x07AA /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_09 0x07AC /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT_10 0x07AE /* MyPassport External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_00 0x070A /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_01 0x071A /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_02 0x0730 /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_03 0x0732 /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_04 0x0740 /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_05 0x0742 /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_06 0x0750 /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_07 0x0752 /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_08 0x07A0 /* MyPassport Essential External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORTES_09 0x07A2 /* MyPassport Essential External HDD */ /* WeTelecom products */ #define USB_PRODUCT_WETELECOM_WM_D200 0x6801 /* WM-D200 */ @@ -4546,5 +4621,6 @@ #define USB_PRODUCT_ZYXEL_G202 0x3410 /* G-202 */ #define USB_PRODUCT_ZYXEL_RT2870_1 0x3416 /* RT2870 */ #define USB_PRODUCT_ZYXEL_RT2870_2 0x341a /* RT2870 */ +#define USB_PRODUCT_ZYXEL_RT3070 0x341e /* NWD2105 */ #define USB_PRODUCT_ZYXEL_RTL8192CU 0x341f /* RTL8192CU */ #define USB_PRODUCT_ZYXEL_NWD2705 0x3421 /* NWD2705 */ diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h index c31eb4ba..71eee376 100644 --- a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h +++ b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h @@ -1617,6 +1617,12 @@ const struct usb_knowndev usb_knowndevs[] = { "ASUS", "USB-N11", }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2570, + 0, + "ASUSTeK Computer", + "RT2500USB Wireless Adapter", + }, { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G, 0, @@ -1695,6 +1701,12 @@ const struct usb_knowndev usb_knowndevs[] = { "ASUSTeK Computer", "USB-N13", }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10, + 0, + "ASUSTeK Computer", + "USB-N10", + }, { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT3070_1, 0, @@ -1702,10 +1714,16 @@ const struct usb_knowndev usb_knowndevs[] = { "RT3070", }, { - USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10, + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192SU, 0, "ASUSTeK Computer", - "USB-N10", + "RTL8192SU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USB_N53, + 0, + "ASUSTeK Computer", + "ASUS Black Diamond Dual Band USB-N53", }, { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU, @@ -1720,10 +1738,16 @@ const struct usb_knowndev usb_knowndevs[] = { "USB-N66", }, { - USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192SU, + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10NANO, 0, "ASUSTeK Computer", - "RTL8192SU", + "USB-N10 Nano", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBAC51, + 0, + "ASUSTeK Computer", + "USB-AC51", }, { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A730W, @@ -1743,18 +1767,6 @@ const struct usb_knowndev usb_knowndevs[] = { "ASUSTeK Computer", "ASUS Generic Mass Storage", }, - { - USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2570, - 0, - "ASUSTeK Computer", - "RT2500USB Wireless Adapter", - }, - { - USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USB_N53, - 0, - "ASUSTeK Computer", - "ASUS Black Diamond Dual Band USB-N53", - }, { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC1284, 0, @@ -2547,6 +2559,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Chicony Electronics", "Notebook Web Camera", }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_HDUVCCAM, + 0, + "Chicony Electronics", + "HD UVC WebCam", + }, { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_1, 0, @@ -3039,6 +3057,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Corsair", "Corsair Vengeance K60 keyboard", }, + { + USB_VENDOR_CORSAIR, USB_PRODUCT_CORSAIR_K70, + 0, + "Corsair", + "Corsair Vengeance K70 keyboard", + }, { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD_II, 0, @@ -3441,6 +3465,12 @@ const struct usb_knowndev usb_knowndevs[] = { "D-Link", "DWL-120 rev E", }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA125D1, + 0, + "D-Link", + "DWA-125 rev D1", + }, { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL122, 0, @@ -3615,6 +3645,18 @@ const struct usb_knowndev usb_knowndevs[] = { "D-Link", "DWR-510", }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWM157, + 0, + "D-Link", + "DWM-157", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWM157_CD, + 0, + "D-Link", + "DWM-157 CD-ROM Mode", + }, { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8188CU, 0, @@ -3783,6 +3825,12 @@ const struct usb_knowndev usb_knowndevs[] = { "DrayTek", "Vigor550", }, + { + USB_VENDOR_DREAMLINK, USB_PRODUCT_DREAMLINK_DL100B, + 0, + "Dream Link", + "USB Webmail Notifier", + }, { USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD, 0, @@ -3795,6 +3843,12 @@ const struct usb_knowndev usb_knowndevs[] = { "dresden elektronik", "Wireless Handheld Terminal", }, + { + USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_DE_RFNODE, + 0, + "dresden elektronik", + "deRFnode", + }, { USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST, 0, @@ -4552,10 +4606,16 @@ const struct usb_knowndev usb_knowndevs[] = { "FT4232H Quad port Serial", }, { - USB_VENDOR_FTDI, USB_PRODUCT_FTDI_BEAGLEBONE, + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XDS100V2, 0, "Future Technology Devices", - "BeagleBone", + "TI XDS100V1/V2 and early Beaglebones", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XDS100V3, + 0, + "Future Technology Devices", + "TI XDS100V3", }, { USB_VENDOR_FTDI, USB_PRODUCT_FTDI_KTLINK, @@ -6453,6 +6513,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Hewlett Packard", "DeskJet 1220C", }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_UN2420_QDL, + 0, + "Hewlett Packard", + "UN2420 QDL Firmware Loader", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_UN2420, + 0, + "Hewlett Packard", + "UN2420 WWAN/GPS Module", + }, { USB_VENDOR_HP, USB_PRODUCT_HP_810C, 0, @@ -7119,6 +7191,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Huawei Technologies", "3G modem", }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3772, + 0, + "Huawei Technologies", + "K3772", + }, { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3770_INIT, 0, @@ -7155,6 +7233,30 @@ const struct usb_knowndev usb_knowndevs[] = { "Huawei Technologies", "K4505 Initial", }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3772_INIT, + 0, + "Huawei Technologies", + "K3772 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E3272_INIT, + 0, + "Huawei Technologies", + "LTE modem initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_R215_INIT, + 0, + "Huawei Technologies", + "LTE modem initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_R215, + 0, + "Huawei Technologies", + "LTE modem", + }, { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_ETS2055, 0, @@ -7173,6 +7275,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Huawei Technologies", "3G modem initial", }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E3272, + 0, + "Huawei Technologies", + "LTE modem", + }, { USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G, 0, @@ -7341,6 +7449,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Intel", "Integrated Rate Matching Hub", }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_IRMH3, + 0, + "Intel", + "Integrated Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_IRMH4, + 0, + "Intel", + "Integrated Rate Matching Hub", + }, { USB_VENDOR_INTERBIOMETRICS, USB_PRODUCT_INTERBIOMETRICS_IOBOARD, 0, @@ -8097,6 +8217,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Lexar Media", "USB CF Reader", }, + { + USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPDRIVE, + 0, + "Lexar Media", + "USB Jumpdrive Flash Drive", + }, { USB_VENDOR_LEXMARK, USB_PRODUCT_LEXMARK_S2450, 0, @@ -11295,6 +11421,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Novatel Wireless", "Novatel MC950D HSUPA", }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC990D, + 0, + "Novatel Wireless", + "Novatel MC990D", + }, { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD, 0, @@ -11343,6 +11475,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Novatel Wireless", "Novatel MC547", }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC679, + 0, + "Novatel Wireless", + "Novatel MC679", + }, { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_FLEXPACKGPS, 0, @@ -12753,6 +12891,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Qualcomm", "SIM5218", }, + { + USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_WM620, + 0, + "Qualcomm", + "Neoway WM620", + }, { USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_GOBI2000_QDL, 0, @@ -12765,6 +12909,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Qualcomm", "Qualcomm Gobi 2000 modem", }, + { + USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_VT80N, + 0, + "Qualcomm", + "Venus VT80N", + }, + { + USB_VENDOR_QUALCOMM3, USB_PRODUCT_QUALCOMM3_VFAST2, + 0, + "Qualcomm, Inc.", + "Venus Fast2 modem", + }, { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM, 0, @@ -13167,12 +13323,36 @@ const struct usb_knowndev usb_knowndevs[] = { "Qualcomm, Incorporated", "1&1 Surf Stick", }, + { + USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_K3772_Z_INIT, + 0, + "Qualcomm, Incorporated", + "K3772-Z Initial", + }, { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_K3772_Z, 0, "Qualcomm, Incorporated", + "K3772-Z", + }, + { + USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_MF730M, + 0, + "Qualcomm, Incorporated", "3G modem", }, + { + USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_MF195E_INIT, + 0, + "Qualcomm, Incorporated", + "MF195E initial", + }, + { + USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_MF195E, + 0, + "Qualcomm, Incorporated", + "MF195E", + }, { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR, 0, @@ -13191,6 +13371,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Qualcomm, Incorporated", "3G modem", }, + { + USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_AC682, + 0, + "Qualcomm, Incorporated", + "CDMA 1xEVDO USB modem", + }, + { + USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_AC682_INIT, + 0, + "Qualcomm, Incorporated", + "CDMA 1xEVDO USB modem (initial)", + }, { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_AC8710, 0, @@ -13425,6 +13617,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Realtek", "USB20CRW Card Reader", }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188ETV, + 0, + "Realtek", + "RTL8188ETV", + }, { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV, 0, @@ -13563,6 +13761,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Realtek", "RTL8188RU", }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_3, + 0, + "Realtek", + "RTL8188RU", + }, { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8712, 0, @@ -15633,6 +15837,108 @@ const struct usb_knowndev usb_knowndevs[] = { "Standard Microsystems", "2662W-AR Wireless", }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9500_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9505_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9530_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9730_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9500_SAL10, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9505_SAL10, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9500A_SAL10, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9505A_SAL10, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9514_SAL10, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9500A_HAL, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9505A_HAL, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9500_ETH_2, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9500A_ETH_2, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9514_ETH_2, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9500A_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9505A_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN89530_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, { USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9514_ETH, 0, @@ -16738,17 +17044,137 @@ const struct usb_knowndev usb_knowndevs[] = { "MyBook External HDD", }, { - USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSWORD, + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_00, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_11, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_01, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_02, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_03, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_04, 0, "Western Digital", - "MyPassword External HDD", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_05, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_06, + 0, + "Western Digital", + "MyPassport External HDD", }, { - USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT, + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_07, 0, "Western Digital", "MyPassport External HDD", }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_08, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_09, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT_10, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_00, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_01, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_02, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_03, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_04, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_05, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_06, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_07, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_08, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORTES_09, + 0, + "Western Digital", + "MyPassport Essential External HDD", + }, { USB_VENDOR_WETELECOM, USB_PRODUCT_WETELECOM_WM_D200, 0, @@ -17109,6 +17535,12 @@ const struct usb_knowndev usb_knowndevs[] = { "ZyXEL Communication", "RT2870", }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT3070, + 0, + "ZyXEL Communication", + "NWD2105", + }, { USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU, 0, @@ -20961,6 +21393,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Qualcomm, Incorporated", NULL, }, + { + USB_VENDOR_QUALCOMM3, 0, + USB_KNOWNDEV_NOPROD, + "Qualcomm, Inc.", + NULL, + }, { USB_VENDOR_BAYER, 0, USB_KNOWNDEV_NOPROD, @@ -21069,6 +21507,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Neotel", NULL, }, + { + USB_VENDOR_DREAMLINK, 0, + USB_KNOWNDEV_NOPROD, + "Dream Link", + NULL, + }, { USB_VENDOR_PEGATRON, 0, USB_KNOWNDEV_NOPROD, -- cgit v1.2.3