[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),
 						  &reg_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, &reg_data);
+		return ret_val;
+	ret_val =
+	    e1000_read_kmrn_reg_80003es2lan(hw,
+					    E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
+					    &reg_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,
 					       &reg_data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 					       &reg_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,
 					       &reg_data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 					       &reg_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);
+					       &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, &reg);
+		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