[rtems-libbsd commit] Update to FreeBSD Stable/9 2015-04-08
Sebastian Huber
sebh at rtems.org
Wed May 20 07:58:41 UTC 2015
Module: rtems-libbsd
Branch: master
Commit: 165dd8ea1256d71d6a4f52c0a66dcc2799ef8f99
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=165dd8ea1256d71d6a4f52c0a66dcc2799ef8f99
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Wed Apr 8 15:37:49 2015 +0200
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 079ba7a..d8d8e0e 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 b0250fd..9d08d32 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 */
@@ -103,6 +106,18 @@ typedef enum __ns_sect {
} 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
* leading _'s on the member names. Use the accessor functions, not the _'s.
@@ -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 1853bc0..a10d035 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 704a949..7f281e5 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 7aa61f6..9e8ad3b 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 9713be3..d303bf3 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 fef631b..ffd0c51 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 304dd66..4b6e359 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 e5041aa..eab1a42 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/inet_cidr_ntop.c b/freebsd/lib/libc/inet/inet_cidr_ntop.c
index fe83a00..2c99909 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 <sys/cdefs.h>
+__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 746ac95..b6513f7 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/inet_net_ntop.c b/freebsd/lib/libc/inet/inet_net_ntop.c
index 78eade0..998e0fc 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/inet_net_pton.c b/freebsd/lib/libc/inet/inet_net_pton.c
index 9179dce..29f9ca0 100644
--- a/freebsd/lib/libc/inet/inet_net_pton.c
+++ b/freebsd/lib/libc/inet/inet_net_pton.c
@@ -1,24 +1,24 @@
#include <machine/rtems-bsd-user-space.h>
/*
- * 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/inet_neta.c b/freebsd/lib/libc/inet/inet_neta.c
index 11cc18d..69c129d 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/inet_ntoa.c b/freebsd/lib/libc/inet/inet_ntoa.c
index 36d85c1..1097fc7 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/inet_ntop.c b/freebsd/lib/libc/inet/inet_ntop.c
index df3deb1..879b250 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/inet_pton.c b/freebsd/lib/libc/inet/inet_pton.c
index 1a89732..b02dd7f 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/inet/nsap_addr.c b/freebsd/lib/libc/inet/nsap_addr.c
index a7aba04..3bbb396 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/isc/ev_streams.c b/freebsd/lib/libc/isc/ev_streams.c
index 2edfc2c..83fd4a1 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/isc/ev_timers.c b/freebsd/lib/libc/isc/ev_timers.c
index 5b1b226..74dda8e 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/isc/eventlib_p.h b/freebsd/lib/libc/isc/eventlib_p.h
index aea5bd6..b27ab54 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 181a975..fa1a32e 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 <sys/cdefs.h>
+__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;
@@ -387,6 +408,21 @@ 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;
int n, len, checked, l;
@@ -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 <base,len> 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 d13abe1..887bdc4 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
/* Import. */
diff --git a/freebsd/lib/libc/nameser/ns_parse.c b/freebsd/lib/libc/nameser/ns_parse.c
index ad1e765..80325e7 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 <sys/cdefs.h>
+__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 e4b7859..8f79796 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 <sys/cdefs.h>
__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 7a404bd..b10b570 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/nameser/ns_ttl.c b/freebsd/lib/libc/nameser/ns_ttl.c
index 795427a..5a5aa16 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
/* Import. */
diff --git a/freebsd/lib/libc/resolv/herror.c b/freebsd/lib/libc/resolv/herror.c
index d87548a..67ddc51 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/resolv/res_comp.c b/freebsd/lib/libc/resolv/res_comp.c
index 27d613e..c31537e 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/resolv/res_data.c b/freebsd/lib/libc/resolv/res_data.c
index 0ce0c14..a5164c4 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 <sys/cdefs.h>
__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 1bc32a0..b8e6889 100644
--- a/freebsd/lib/libc/resolv/res_debug.c
+++ b/freebsd/lib/libc/resolv/res_debug.c
@@ -1,9 +1,26 @@
#include <machine/rtems-bsd-user-space.h>
/*
+ * 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 <sys/cdefs.h>
__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 2c57055..aa6efcf 100644
--- a/freebsd/lib/libc/resolv/res_findzonecut.c
+++ b/freebsd/lib/libc/resolv/res_findzonecut.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
#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 83da254..cf6449f 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -93,6 +93,19 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include <netdb.h>
+#ifndef HAVE_MD5
+# include "../dst/md5.h"
+#else
+# ifdef SOLARIS2
+# include <sys/md5.h>
+# elif _LIBC
+# include <md5.h>
+# 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 8fa9c3b..eb4df45 100644
--- a/freebsd/lib/libc/resolv/res_mkquery.c
+++ b/freebsd/lib/libc/resolv/res_mkquery.c
@@ -1,9 +1,26 @@
#include <machine/rtems-bsd-user-space.h>
/*
+ * 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 <sys/cdefs.h>
__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 880f46a..e486e31 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 <sys/cdefs.h>
__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 15c39a0..5a5acef 100644
--- a/freebsd/lib/libc/resolv/res_query.c
+++ b/freebsd/lib/libc/resolv/res_query.c
@@ -1,9 +1,26 @@
#include <machine/rtems-bsd-user-space.h>
/*
+ * 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
diff --git a/freebsd/lib/libc/resolv/res_send.c b/freebsd/lib/libc/resolv/res_send.c
index 51bca77..6896113 100644
--- a/freebsd/lib/libc/resolv/res_send.c
+++ b/freebsd/lib/libc/resolv/res_send.c
@@ -1,9 +1,26 @@
#include <machine/rtems-bsd-user-space.h>
/*
+ * 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 <sys/cdefs.h>
__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 1e46429..cd3abbd 100644
--- a/freebsd/lib/libc/resolv/res_update.c
+++ b/freebsd/lib/libc/resolv/res_update.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
#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 f74d3e8..0e099ad 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 74800e8..8fc53f6 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 9553890..2067b54 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 499fffa..ba0e43c 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 4cad972..7e268bb 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 cf84d39..326ce99 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 fa0d528..cae01fe 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 0090356..1058c14 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 c0f78a7..5456f3d 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 ea5e88c..62e9fc4 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 157468e..3807e46 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 8b4ce19..9532339 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 e64e8fa..dadd3a8 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 c76f16f..41d5df0 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 b6356b0..0e06471 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;
}
/**
@@ -1175,6 +1223,61 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
}
/**
+ * 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;
@@ -2647,6 +2766,134 @@ out:
}
/**
+ * __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 c6bbe18..6569b98 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 3c0eb4f..71315bd 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 69db1be..a2ffa16 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 0815ea8..72a8b14 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 e8a8c17..faf64a3 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 d7711fe..2a20ca1 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 e843527..b5c75f2 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;
@@ -1081,6 +1201,256 @@ static s32 e1000_set_obff_timer_pch_lpt(struct e1000_hw *hw, u32 itr)
}
/**
+ * 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 bf92898..999e856 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 b9bf8dc..3967a25 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 3e2ccde..2c1bfe3 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 e33ff56..0648ac9 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 8028487..1b5bb70 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 206f00c..d2aea5c 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 9b9333c..ad0c954 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 7253969..b331bdc 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 9f95508..cb92973 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 9911df7..0e5b2e6 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 516d377..5c2e3f7 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 e525795..17fd7cb 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 0ee73ae..2a78074 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 2a3fe54..05d7fbc 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 09da15c..27ae386 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
@@ -2931,6 +2848,129 @@ msi:
/*********************************************************************
*
+ * 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 6f3a3a5..0c44741 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 64a1bcc..7c22200 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 822ebce..47f77d1 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 501f7f1..ab40dab 100644
--- a/freebsd/sys/dev/mii/micphy.c
+++ b/freebsd/sys/dev/mii/micphy.c
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
-#include <sys/errno.h>
+#include <rtems/bsd/sys/errno.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/malloc.h>
diff --git a/freebsd/sys/dev/mii/ukphy.c b/freebsd/sys/dev/mii/ukphy.c
index 960c797..57958ca 100644
--- a/freebsd/sys/dev/mii/ukphy.c
+++ b/freebsd/sys/dev/mii/ukphy.c
@@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
-#include <sys/errno.h>
+#include <rtems/bsd/sys/errno.h>
#include <sys/module.h>
#include <sys/bus.h>
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index 7dcaa0d..426d06a 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 9975137..b574f9a 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 86c75b2..bf637c2 100644
--- a/freebsd/sys/dev/sdhci/sdhci.c
+++ b/freebsd/sys/dev/sdhci/sdhci.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
-#include <sys/resource.h>
+#include <rtems/bsd/sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/mmcbr_if.h>
#ifndef __rtems__
-#include <rtems/bsd/local/sdhci.h>
+#include "sdhci.h"
#else /* __rtems__ */
#include <dev/sdhci/sdhci.h>
#endif /* __rtems__ */
diff --git a/freebsd/sys/dev/usb/controller/ehci.c b/freebsd/sys/dev/usb/controller/ehci.c
index 730fd66..3eb63c6 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 c0fda65..90e09bb 100644
--- a/freebsd/sys/dev/usb/controller/usb_controller.c
+++ b/freebsd/sys/dev/usb/controller/usb_controller.c
@@ -58,6 +58,7 @@
#include <dev/usb/usb_busdma.h>
#include <dev/usb/usb_dynamic.h>
#include <dev/usb/usb_device.h>
+#include <dev/usb/usb_dev.h>
#include <dev/usb/usb_hub.h>
#include <dev/usb/usb_controller.h>
@@ -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 bd1d635..a0b7397 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 2f7ea79..7447ea8 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 32a60a1..bddc2c5 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 702f623..0a7350c 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 6b6e403..ee420bc 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 48e5ee8..287e69f 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 3ff064e..ce107cf 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 e18c32d..8e0144c 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);
}
/*------------------------------------------------------------------------*
@@ -1999,14 +1961,46 @@ usb_make_dev(struct usb_device *udev, const char *devname, int ep,
}
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 361f5c3..309bd05 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 32ff5e6..65c9a7d 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 4cd1758..ed2c6bb 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 e1fc141..d617290 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 9b3bd07..0c62ee0 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 4d28346..19accdd 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 e4a717f..4f64f84 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 d36df36..a5426e1 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 <sys/stdint.h>
#include <sys/stddef.h>
#include <rtems/bsd/sys/param.h>
@@ -51,6 +49,8 @@
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usb_process.h>
+
+#define USB_DEBUG_VAR usb_proc_debug
#include <dev/usb/usb_debug.h>
#include <dev/usb/usb_util.h>
diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c
index e9137bd..6f9d7b1 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 205a72f..ab5558e 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;
@@ -1374,6 +1375,29 @@ usbd_control_transfer_init(struct usb_xfer *xfer)
}
/*------------------------------------------------------------------------*
+ * 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
*
* This function handles initialisation of control transfers. Control
@@ -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 429a7e3..1f4f3e6 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 c360558..d1494fb 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 <sys/vnode.h>
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 <sys/bio.h>
#include <sys/buf.h>
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 <sys/user.h>
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 <sys/imgact.h>
diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c
index 21083a9..f85ffc5 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 dbb10d0..2050d03 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;
@@ -1357,13 +1354,20 @@ struct timer_getoverrun_args {
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 951a63c..1d07718 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 960ceb8..b91be20 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 c158b36..69f8d35 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 ? "<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 74f01ff..d38b337 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 eb1ed37..0ed027d 100644
--- a/freebsd/sys/kern/sys_generic.c
+++ b/freebsd/sys/kern/sys_generic.c
@@ -79,6 +79,20 @@ __FBSDID("$FreeBSD$");
#include <machine/rtems-bsd-syscall-api.h>
#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 03b18b9..bcbd0d9 100644
--- a/freebsd/sys/kern/uipc_sockbuf.c
+++ b/freebsd/sys/kern/uipc_sockbuf.c
@@ -995,6 +995,37 @@ sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff)
}
/*
+ * 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 2dc76a9..a37518f 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 b7cc060..d2ee61c 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 4175665..7a4eaf9 100644
--- a/freebsd/sys/net/bpf.c
+++ b/freebsd/sys/net/bpf.c
@@ -698,6 +698,67 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
}
/*
+ * 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 2028892..5172ad5 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 0bd72e4..f227ed9 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 b0be364..46f3f46 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 985c565..e88fd34 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 fb590fa..ee4db19 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 accfbbb..7d08e29 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 b444b74..781d8bb 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 8aea8dd..4be9a63 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 e4f76fe..eec06dd 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 3056fa3..78d9685 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 bc7323e..653580c 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 93ebf4d..a06fed6 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 baf25af..9e35c88 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 f3cb4b4..cbc25b9 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 ba7a00b..d0da7a6 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 e2bbced..b19a749 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 ee98af3..260d161 100644
--- a/freebsd/sys/netinet/tcp_hostcache.c
+++ b/freebsd/sys/netinet/tcp_hostcache.c
@@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
+#include <sys/sbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
@@ -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 20d645f..f9512eb 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 6215c4e..550af64 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 d4f0bcd..2570a5f 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 d577f18..b175c0c 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 171eafb..dbd9ed1 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 20b03a2..49b1bd8 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 f68f21f..8dc4d29 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 e545770..d32d57c 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 4b0b338..8a7581c 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 cc2f5ee..79beb70 100644
--- a/freebsd/sys/netinet6/in6_src.c
+++ b/freebsd/sys/netinet6/in6_src.c
@@ -445,6 +445,16 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
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
* documented as "Rule 8". However, since it is also
diff --git a/freebsd/sys/netinet6/in6_var.h b/freebsd/sys/netinet6/in6_var.h
index c7ebe52..90530a6 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 0de64eb..17420fa 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 06f1246..9523163 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 4a094d4..4e8c42b 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 9233bef..1b855ca 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 79e41e3..94202e1 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 09011b7..ce26d54 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 bd6fa33..030cac3 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 f891c9c..2ccd2f7 100644
--- a/freebsd/sys/netinet6/scope6.c
+++ b/freebsd/sys/netinet6/scope6.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
+#include <sys/sockio.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <sys/syslog.h>
@@ -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 ae337b8..990325e 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 a0a7352..b4f270f 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 c79ad86..c96fedc 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 b34ef37..547ff84 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 ddec147..4c4ea65 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 84fd1aa..76197ae 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 fee7f1f..ff592cc 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 1fca343..cfbbc7f 100644
--- a/freebsd/sys/sys/sysctl.h
+++ b/freebsd/sys/sys/sysctl.h
@@ -121,7 +121,14 @@ struct ctlname {
#ifdef _KERNEL
#include <sys/linker_set.h>
-#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 ed58a48..5af3b62 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 f0a3fc6..c761555 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 4f75c3d..7e00ffc 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 1f79d28..1d429ef 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 2d3d2db..0708631 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 3543d85..7472c00 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 c31eb4b..71eee37 100644
--- a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
+++ b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
@@ -1618,6 +1618,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"USB-N11",
},
{
+ USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2570,
+ 0,
+ "ASUSTeK Computer",
+ "RT2500USB Wireless Adapter",
+ },
+ {
USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G,
0,
"ASUSTeK Computer",
@@ -1696,16 +1702,28 @@ const struct usb_knowndev usb_knowndevs[] = {
"USB-N13",
},
{
+ USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10,
+ 0,
+ "ASUSTeK Computer",
+ "USB-N10",
+ },
+ {
USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT3070_1,
0,
"ASUSTeK Computer",
"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,
@@ -1744,18 +1768,6 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"ATEN International",
@@ -2548,6 +2560,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Chicony Electronics",
@@ -3040,6 +3058,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Creative Labs",
@@ -3442,6 +3466,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"D-Link",
@@ -3616,6 +3646,18 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"D-Link",
@@ -3784,6 +3826,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Vigor550",
},
{
+ USB_VENDOR_DREAMLINK, USB_PRODUCT_DREAMLINK_DL100B,
+ 0,
+ "Dream Link",
+ "USB Webmail Notifier",
+ },
+ {
USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD,
0,
"dresden elektronik",
@@ -3796,6 +3844,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Wireless Handheld Terminal",
},
{
+ USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_DE_RFNODE,
+ 0,
+ "dresden elektronik",
+ "deRFnode",
+ },
+ {
USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST,
0,
"dresden elektronik",
@@ -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,
@@ -6454,6 +6514,18 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Hewlett Packard",
@@ -7120,6 +7192,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"3G modem",
},
{
+ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3772,
+ 0,
+ "Huawei Technologies",
+ "K3772",
+ },
+ {
USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3770_INIT,
0,
"Huawei Technologies",
@@ -7156,6 +7234,30 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Huawei Technologies",
@@ -7174,6 +7276,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"3G modem initial",
},
{
+ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E3272,
+ 0,
+ "Huawei Technologies",
+ "LTE modem",
+ },
+ {
USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G,
0,
"Huawei-3Com",
@@ -7342,6 +7450,18 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Interbiometrics",
@@ -8098,6 +8218,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Lexmark International",
@@ -11296,6 +11422,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Novatel MC950D HSUPA",
},
{
+ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC990D,
+ 0,
+ "Novatel Wireless",
+ "Novatel MC990D",
+ },
+ {
USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD,
0,
"Novatel Wireless",
@@ -11344,6 +11476,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Novatel MC547",
},
{
+ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC679,
+ 0,
+ "Novatel Wireless",
+ "Novatel MC679",
+ },
+ {
USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_FLEXPACKGPS,
0,
"Novatel Wireless",
@@ -12754,6 +12892,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"SIM5218",
},
{
+ USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_WM620,
+ 0,
+ "Qualcomm",
+ "Neoway WM620",
+ },
+ {
USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_GOBI2000_QDL,
0,
"Qualcomm",
@@ -12766,6 +12910,18 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Qualcomm, Incorporated",
@@ -13168,12 +13324,36 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Qualcomm, Incorporated",
@@ -13192,6 +13372,18 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Qualcomm, Incorporated",
@@ -13426,6 +13618,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"USB20CRW Card Reader",
},
{
+ USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188ETV,
+ 0,
+ "Realtek",
+ "RTL8188ETV",
+ },
+ {
USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV,
0,
"Realtek",
@@ -13564,6 +13762,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"RTL8188RU",
},
{
+ USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_3,
+ 0,
+ "Realtek",
+ "RTL8188RU",
+ },
+ {
USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8712,
0,
"Realtek",
@@ -15634,6 +15838,108 @@ const struct usb_knowndev usb_knowndevs[] = {
"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,
"Standard Microsystems",
@@ -16738,18 +17044,138 @@ 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,
"WeTelecom",
@@ -17110,6 +17536,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"RT2870",
},
{
+ USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT3070,
+ 0,
+ "ZyXEL Communication",
+ "NWD2105",
+ },
+ {
USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU,
0,
"ZyXEL Communication",
@@ -20962,6 +21394,12 @@ const struct usb_knowndev usb_knowndevs[] = {
NULL,
},
{
+ USB_VENDOR_QUALCOMM3, 0,
+ USB_KNOWNDEV_NOPROD,
+ "Qualcomm, Inc.",
+ NULL,
+ },
+ {
USB_VENDOR_BAYER, 0,
USB_KNOWNDEV_NOPROD,
"Bayer",
@@ -21070,6 +21508,12 @@ const struct usb_knowndev usb_knowndevs[] = {
NULL,
},
{
+ USB_VENDOR_DREAMLINK, 0,
+ USB_KNOWNDEV_NOPROD,
+ "Dream Link",
+ NULL,
+ },
+ {
USB_VENDOR_PEGATRON, 0,
USB_KNOWNDEV_NOPROD,
"Pegatron",
More information about the vc
mailing list