ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
February 2019
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
23 participants
208 discussions
Start a n
N
ew thread
[reactos] 06/06: [E1000] Finished an implementation of the driver. Added PIDs for whole Intel 8254x family. Note: this driver uses legacy interfaces for either receive and transmit descriptors. CORE-14675
by Victor Perevertkin
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d9c4d28e59de351a59a29…
commit d9c4d28e59de351a59a29a9bf450755627138a7c Author: Victor Perevertkin <victor(a)perevertkin.ru> AuthorDate: Tue Jan 22 00:44:25 2019 +0300 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 19:48:54 2019 +0100 [E1000] Finished an implementation of the driver. Added PIDs for whole Intel 8254x family. Note: this driver uses legacy interfaces for either receive and transmit descriptors. CORE-14675 --- drivers/network/dd/e1000/e1000hw.h | 31 ++++++-- drivers/network/dd/e1000/hardware.c | 132 ++++++++++++++++-------------- drivers/network/dd/e1000/info.c | 11 +-- drivers/network/dd/e1000/interrupt.c | 150 ++++++++++++++++++++++------------- drivers/network/dd/e1000/ndis.c | 23 ++---- drivers/network/dd/e1000/nic.h | 35 ++++---- media/inf/nete1000.inf | 40 +++++++++- 7 files changed, 262 insertions(+), 160 deletions(-) diff --git a/drivers/network/dd/e1000/e1000hw.h b/drivers/network/dd/e1000/e1000hw.h index b2293aa0ba..994be06067 100644 --- a/drivers/network/dd/e1000/e1000hw.h +++ b/drivers/network/dd/e1000/e1000hw.h @@ -1,8 +1,9 @@ /* * PROJECT: ReactOS Intel PRO/1000 Driver * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * PURPOSE: Intel PRO/1000 driver definitions - * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + * PURPOSE: Hardware specific definitions + * COPYRIGHT: 2018 Mark Jansen (mark.jansen(a)reactos.org) + * 2019 Victor Perevertkin (victor.perevertkin(a)reactos.org) */ #pragma once @@ -30,6 +31,8 @@ typedef struct _ETH_HEADER { } ETH_HEADER, *PETH_HEADER; +C_ASSERT(sizeof(ETH_HEADER) == 14); + typedef enum _E1000_RCVBUF_SIZE { @@ -53,6 +56,8 @@ typedef enum _E1000_RCVBUF_SIZE /* 3.2.3 Receive Descriptor Format */ +#define E1000_RDESC_STATUS_PIF (1 << 7) /* Passed in-exact filter */ +#define E1000_RDESC_STATUS_IXSM (1 << 2) /* Ignore Checksum Indication */ #define E1000_RDESC_STATUS_EOP (1 << 1) /* End of Packet */ #define E1000_RDESC_STATUS_DD (1 << 0) /* Descriptor Done */ @@ -71,6 +76,7 @@ typedef struct _E1000_RECEIVE_DESCRIPTOR /* 3.3.3 Legacy Transmit Descriptor Format */ +#define E1000_TDESC_CMD_IDE (1 << 7) /* Interrupt Delay Enable */ #define E1000_TDESC_CMD_RS (1 << 3) /* Report Status */ #define E1000_TDESC_CMD_IFCS (1 << 1) /* Insert FCS */ #define E1000_TDESC_CMD_EOP (1 << 0) /* End Of Packet */ @@ -118,18 +124,23 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); #define E1000_REG_RCTL 0x0100 /* Receive Control Register, R/W */ #define E1000_REG_TCTL 0x0400 /* Transmit Control Register, R/W */ +#define E1000_REG_TIPG 0x0410 /* Transmit IPG Register, R/W */ #define E1000_REG_RDBAL 0x2800 /* Receive Descriptor Base Address Low, R/W */ #define E1000_REG_RDBAH 0x2804 /* Receive Descriptor Base Address High, R/W */ #define E1000_REG_RDLEN 0x2808 /* Receive Descriptor Length, R/W */ #define E1000_REG_RDH 0x2810 /* Receive Descriptor Head, R/W */ #define E1000_REG_RDT 0x2818 /* Receive Descriptor Tail, R/W */ +#define E1000_REG_RDTR 0x2820 /* Receive Delay Timer, R/W */ +#define E1000_REG_RADV 0x282C /* Receive Absolute Delay Timer, R/W */ #define E1000_REG_TDBAL 0x3800 /* Transmit Descriptor Base Address Low, R/W */ #define E1000_REG_TDBAH 0x3804 /* Transmit Descriptor Base Address High, R/W */ #define E1000_REG_TDLEN 0x3808 /* Transmit Descriptor Length, R/W */ #define E1000_REG_TDH 0x3810 /* Transmit Descriptor Head, R/W */ #define E1000_REG_TDT 0x3818 /* Transmit Descriptor Tail, R/W */ +#define E1000_REG_TIDV 0x3820 /* Transmit Interrupt Delay Value, R/W */ +#define E1000_REG_TADV 0x382C /* Transmit Absolute Delay Timer, R/W */ #define E1000_REG_RAL 0x5400 /* Receive Address Low, R/W */ @@ -137,11 +148,16 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); /* E1000_REG_CTRL */ +#define E1000_CTRL_LRST (1 << 3) /* Link Reset */ +#define E1000_CTRL_ASDE (1 << 5) /* Auto-Speed Detection Enable */ +#define E1000_CTRL_SLU (1 << 6) /* Set Link Up */ #define E1000_CTRL_RST (1 << 26) /* Device Reset, Self clearing */ +#define E1000_CTRL_VME (1 << 30) /* VLAN Mode Enable */ /* E1000_REG_STATUS */ -#define E1000_STATUS_LU (1 << 0) /* Link Up Indication */ +#define E1000_STATUS_FD (1 << 0) /* Full Duplex Indication */ +#define E1000_STATUS_LU (1 << 1) /* Link Up Indication */ #define E1000_STATUS_SPEEDSHIFT 6 /* Link speed setting */ #define E1000_STATUS_SPEEDMASK (3 << E1000_STATUS_SPEEDSHIFT) @@ -164,9 +180,12 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); /* E1000_REG_IMS */ #define E1000_IMS_TXDW (1 << 0) /* Transmit Descriptor Written Back */ +#define E1000_IMS_TXQE (1 << 1) /* Transmit Queue Empty */ #define E1000_IMS_LSC (1 << 2) /* Sets mask for Link Status Change */ #define E1000_IMS_RXDMT0 (1 << 4) /* Receive Descriptor Minimum Threshold Reached */ #define E1000_IMS_RXT0 (1 << 7) /* Receiver Timer Interrupt */ +#define E1000_IMS_TXD_LOW (1 << 15) /* Transmit Descriptor Low Threshold hit */ +#define E1000_IMS_SRPD (1 << 16) /* Small Receive Packet Detection */ /* E1000_REG_ITR */ @@ -192,7 +211,10 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); #define E1000_TCTL_EN (1 << 1) /* Transmit Enable */ #define E1000_TCTL_PSP (1 << 3) /* Pad Short Packets */ - +/* E1000_REG_TIPG */ +#define E1000_TIPG_IPGT_DEF (10 << 0) /* IPG Transmit Time */ +#define E1000_TIPG_IPGR1_DEF (10 << 10) /* IPG Receive Time 1 */ +#define E1000_TIPG_IPGR2_DEF (10 << 20) /* IPG Receive Time 2 */ /* E1000_REG_RAH */ @@ -222,4 +244,3 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); #define E1000_PSS_SPEED_AND_DUPLEX (1 << 11) /* Speed and Duplex Resolved */ #define E1000_PSS_SPEEDSHIFT 14 #define E1000_PSS_SPEEDMASK (3 << E1000_PSS_SPEEDSHIFT) - diff --git a/drivers/network/dd/e1000/hardware.c b/drivers/network/dd/e1000/hardware.c index 0b7d8f0d1f..aa5fc26896 100644 --- a/drivers/network/dd/e1000/hardware.c +++ b/drivers/network/dd/e1000/hardware.c @@ -2,7 +2,8 @@ * PROJECT: ReactOS Intel PRO/1000 Driver * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) * PURPOSE: Hardware specific functions - * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + * COPYRIGHT: 2018 Mark Jansen (mark.jansen(a)reactos.org) + * 2019 Victor Perevertkin (victor.perevertkin(a)reactos.org) */ #include "nic.h" @@ -12,7 +13,44 @@ static USHORT SupportedDevices[] = { - 0x100f, // Intel 82545EM (VMWare E1000) + /* 8254x Family adapters. Not all of them are tested */ + 0x1000, // Intel 82542 + 0x1001, // Intel 82543GC Fiber + 0x1004, // Intel 82543GC Copper + 0x1008, // Intel 82544EI Copper + 0x1009, // Intel 82544EI Fiber + 0x100A, // Intel 82540EM + 0x100C, // Intel 82544GC Copper + 0x100D, // Intel 82544GC LOM (LAN on Motherboard) + 0x100E, // Intel 82540EM + 0x100F, // Intel 82545EM Copper + 0x1010, // Intel 82546EB Copper + 0x1011, // Intel 82545EM Fiber + 0x1012, // Intel 82546EB Fiber + 0x1013, // Intel 82541EI + 0x1014, // Intel 82541EI LOM + 0x1015, // Intel 82540EM LOM + 0x1016, // Intel 82540EP LOM + 0x1017, // Intel 82540EP + 0x1018, // Intel 82541EI Mobile + 0x1019, // Intel 82547EI + 0x101A, // Intel 82547EI Mobile + 0x101D, // Intel 82546EB Quad Copper + 0x101E, // Intel 82540EP LP (Low profile) + 0x1026, // Intel 82545GM Copper + 0x1027, // Intel 82545GM Fiber + 0x1028, // Intel 82545GM SerDes + 0x1075, // Intel 82547GI + 0x1076, // Intel 82541GI + 0x1077, // Intel 82541GI Mobile + 0x1078, // Intel 82541ER + 0x1079, // Intel 82546GB Copper + 0x107A, // Intel 82546GB Fiber + 0x107B, // Intel 82546GB SerDes + 0x107C, // Intel 82541PI + 0x108A, // Intel 82546GB PCI-E + 0x1099, // Intel 82546GB Quad Copper + 0x10B5, // Intel 82546GB Quad Copper KSP3 }; @@ -29,7 +67,7 @@ VOID NTAPI E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); } -static VOID E1000ReadUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, OUT PULONG Value) +VOID NTAPI E1000ReadUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, OUT PULONG Value) { NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); } @@ -99,6 +137,8 @@ static ULONG RcvBufRegisterMask(E1000_RCVBUF_SIZE BufSize) return Mask; } +#if 0 +/* This function works, but the driver does not use PHY register access right now */ static BOOLEAN E1000ReadMdic(IN PE1000_ADAPTER Adapter, IN ULONG Address, USHORT *Result) { ULONG ResultAddress; @@ -147,11 +187,12 @@ static BOOLEAN E1000ReadMdic(IN PE1000_ADAPTER Adapter, IN ULONG Address, USHORT *Result = (USHORT) Mdic; return TRUE; } +#endif static BOOLEAN E1000ReadEeprom(IN PE1000_ADAPTER Adapter, IN UCHAR Address, USHORT *Result) { - UINT Value; + ULONG Value; UINT n; E1000WriteUlong(Adapter, E1000_REG_EERD, E1000_EERD_START | ((UINT)Address << E1000_EERD_ADDR_SHIFT)); @@ -524,10 +565,9 @@ NICSoftReset( ULONG Value, ResetAttempts; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - //em_get_hw_control(adapter); - NICDisableInterrupts(Adapter); E1000WriteUlong(Adapter, E1000_REG_RCTL, 0); + E1000WriteUlong(Adapter, E1000_REG_TCTL, 0); E1000ReadUlong(Adapter, E1000_REG_CTRL, &Value); /* Write this using IO port, some devices cannot ack this otherwise */ E1000WriteIoUlong(Adapter, E1000_REG_CTRL, Value | E1000_CTRL_RST); @@ -535,7 +575,8 @@ NICSoftReset( for (ResetAttempts = 0; ResetAttempts < MAX_RESET_ATTEMPTS; ResetAttempts++) { - NdisStallExecution(100); + /* Wait 1us after reset (according to manual) */ + NdisStallExecution(1); E1000ReadUlong(Adapter, E1000_REG_CTRL, &Value); if (!(Value & E1000_CTRL_RST)) @@ -543,11 +584,13 @@ NICSoftReset( NDIS_DbgPrint(MAX_TRACE, ("Device is back (%u)\n", ResetAttempts)); NICDisableInterrupts(Adapter); - /* Clear out interrupts */ + /* Clear out interrupts (the register is cleared upon read) */ E1000ReadUlong(Adapter, E1000_REG_ICR, &Value); - //NdisWriteRegisterUlong(Adapter->IoBase + E1000_REG_WUFC, 0); - //NdisWriteRegisterUlong(Adapter->IoBase + E1000_REG_VET, E1000_VET_VLAN); + E1000ReadUlong(Adapter, E1000_REG_CTRL, &Value); + Value &= ~(E1000_CTRL_LRST|E1000_CTRL_VME); + Value |= (E1000_CTRL_ASDE|E1000_CTRL_SLU); + E1000WriteUlong(Adapter, E1000_REG_CTRL, Value); return NDIS_STATUS_SUCCESS; } @@ -582,10 +625,13 @@ NICEnableTxRx( E1000WriteUlong(Adapter, E1000_REG_TDT, 0); Adapter->CurrentTxDesc = 0; + /* Set up interrupt timers */ + E1000WriteUlong(Adapter, E1000_REG_TADV, 96); // value is in 1.024 of usec + E1000WriteUlong(Adapter, E1000_REG_TIDV, 16); - Value = E1000_TCTL_EN | E1000_TCTL_PSP; - E1000WriteUlong(Adapter, E1000_REG_TCTL, Value); + E1000WriteUlong(Adapter, E1000_REG_TCTL, E1000_TCTL_EN | E1000_TCTL_PSP); + E1000WriteUlong(Adapter, E1000_REG_TIPG, E1000_TIPG_IPGT_DEF | E1000_TIPG_IPGR1_DEF | E1000_TIPG_IPGR2_DEF); NDIS_DbgPrint(MID_TRACE, ("Setting up receive.\n")); @@ -602,10 +648,10 @@ NICEnableTxRx( /* Receive descriptor tail / head */ E1000WriteUlong(Adapter, E1000_REG_RDH, 0); E1000WriteUlong(Adapter, E1000_REG_RDT, NUM_RECEIVE_DESCRIPTORS - 1); - Adapter->CurrentRxDesc = 0; - /* Setup Interrupt Throttling */ - E1000WriteUlong(Adapter, E1000_REG_ITR, DEFAULT_ITR); + /* Set up interrupt timers */ + E1000WriteUlong(Adapter, E1000_REG_RADV, 96); + E1000WriteUlong(Adapter, E1000_REG_RDTR, 16); /* Some defaults */ Value = E1000_RCTL_SECRC | E1000_RCTL_EN; @@ -634,9 +680,9 @@ NICDisableTxRx( Value &= ~E1000_TCTL_EN; E1000WriteUlong(Adapter, E1000_REG_TCTL, Value); - //E1000ReadUlong(Adapter, E1000_REG_RCTL, &Value); - //Value &= ~E1000_RCTL_EN; - //E1000WriteUlong(Adapter, E1000_REG_RCTL, Value); + E1000ReadUlong(Adapter, E1000_REG_RCTL, &Value); + Value &= ~E1000_RCTL_EN; + E1000WriteUlong(Adapter, E1000_REG_RCTL, Value); return NDIS_STATUS_SUCCESS; } @@ -724,7 +770,7 @@ NICApplyInterruptMask( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask); + E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask /*| 0x1F6DC*/); return NDIS_STATUS_SUCCESS; } @@ -747,13 +793,13 @@ NICInterruptRecognized( { ULONG Value; - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - /* Reading the interrupt acknowledges them */ E1000ReadUlong(Adapter, E1000_REG_ICR, &Value); *InterruptRecognized = (Value & Adapter->InterruptMask) != 0; + NDIS_DbgPrint(MAX_TRACE, ("NICInterruptRecognized(0x%x, 0x%x).\n", Value, *InterruptRecognized)); + return (Value & Adapter->InterruptMask); } @@ -762,55 +808,23 @@ NTAPI NICUpdateLinkStatus( IN PE1000_ADAPTER Adapter) { - ULONG SpeedIndex; - USHORT PhyStatus; + ULONG DeviceStatus; + SIZE_T SpeedIndex; static ULONG SpeedValues[] = { 10, 100, 1000, 1000 }; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); -#if 0 - /* This does not work */ - E1000ReadUlong(Adapter, E1000_REG_STATUS, &DeviceStatus); E1000ReadUlong(Adapter, E1000_REG_STATUS, &DeviceStatus); Adapter->MediaState = (DeviceStatus & E1000_STATUS_LU) ? NdisMediaStateConnected : NdisMediaStateDisconnected; SpeedIndex = (DeviceStatus & E1000_STATUS_SPEEDMASK) >> E1000_STATUS_SPEEDSHIFT; Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex]; -#else - /* Link bit can be sticky on some boards, read it twice */ - if (!E1000ReadMdic(Adapter, E1000_PHY_STATUS, &PhyStatus)) - NdisStallExecution(100); - - Adapter->MediaState = NdisMediaStateDisconnected; - Adapter->LinkSpeedMbps = 0; - - if (!E1000ReadMdic(Adapter, E1000_PHY_STATUS, &PhyStatus)) - return; - - if (!(PhyStatus & E1000_PS_LINK_STATUS)) - return; - - Adapter->MediaState = NdisMediaStateConnected; - - if (E1000ReadMdic(Adapter, E1000_PHY_SPECIFIC_STATUS, &PhyStatus)) - { - if (PhyStatus & E1000_PSS_SPEED_AND_DUPLEX) - { - SpeedIndex = (PhyStatus & E1000_PSS_SPEEDMASK) >> E1000_PSS_SPEEDSHIFT; - Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex]; - } - else - { - NDIS_DbgPrint(MIN_TRACE, ("Speed and duplex not yet resolved, retry?.\n")); - } - } -#endif } NDIS_STATUS NTAPI NICTransmitPacket( IN PE1000_ADAPTER Adapter, - IN ULONG PhysicalAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, IN ULONG Length) { volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor; @@ -818,10 +832,10 @@ NICTransmitPacket( NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->CurrentTxDesc; - TransmitDescriptor->Address = PhysicalAddress; + TransmitDescriptor->Address = PhysicalAddress.QuadPart; TransmitDescriptor->Length = Length; TransmitDescriptor->ChecksumOffset = 0; - TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS | E1000_TDESC_CMD_EOP; + TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS | E1000_TDESC_CMD_EOP | E1000_TDESC_CMD_IDE; TransmitDescriptor->Status = 0; TransmitDescriptor->ChecksumStartField = 0; TransmitDescriptor->Special = 0; @@ -830,8 +844,6 @@ NICTransmitPacket( E1000WriteUlong(Adapter, E1000_REG_TDT, Adapter->CurrentTxDesc); - NDIS_DbgPrint(MAX_TRACE, ("CurrentTxDesc:%u, LastTxDesc:%u\n", Adapter->CurrentTxDesc, Adapter->LastTxDesc)); - if (Adapter->CurrentTxDesc == Adapter->LastTxDesc) { NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n")); diff --git a/drivers/network/dd/e1000/info.c b/drivers/network/dd/e1000/info.c index 2c98034fe6..e35e3d1b7e 100644 --- a/drivers/network/dd/e1000/info.c +++ b/drivers/network/dd/e1000/info.c @@ -2,8 +2,8 @@ * PROJECT: ReactOS Intel PRO/1000 Driver * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) * PURPOSE: Miniport information callbacks - * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman(a)reactos.org) - * Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + * COPYRIGHT: 2013 Cameron Gutman (cameron.gutman(a)reactos.org) + * 2018 Mark Jansen (mark.jansen(a)reactos.org) */ #include "nic.h" @@ -66,8 +66,6 @@ MiniportQueryInformation( copySource = &genericUlong; copyLength = sizeof(ULONG); - NdisAcquireSpinLock(&Adapter->Lock); - switch (Oid) { case OID_GEN_SUPPORTED_LIST: @@ -219,7 +217,6 @@ MiniportQueryInformation( *BytesNeeded = 0; } - NdisReleaseSpinLock(&Adapter->Lock); /* XMIT_ERROR and RCV_ERROR are really noisy, so do not log those. */ if (Oid != OID_GEN_XMIT_ERROR && Oid != OID_GEN_RCV_ERROR) { @@ -246,8 +243,6 @@ MiniportSetInformation( status = NDIS_STATUS_SUCCESS; - NdisAcquireSpinLock(&Adapter->Lock); - switch (Oid) { case OID_GEN_CURRENT_PACKET_FILTER: @@ -343,8 +338,6 @@ MiniportSetInformation( *BytesNeeded = 0; } - NdisReleaseSpinLock(&Adapter->Lock); - return status; } diff --git a/drivers/network/dd/e1000/interrupt.c b/drivers/network/dd/e1000/interrupt.c index cd94e455e1..e3f1b83da9 100644 --- a/drivers/network/dd/e1000/interrupt.c +++ b/drivers/network/dd/e1000/interrupt.c @@ -2,8 +2,9 @@ * PROJECT: ReactOS Intel PRO/1000 Driver * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) * PURPOSE: Interrupt handlers - * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman(a)reactos.org) - * Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + * COPYRIGHT: 2013 Cameron Gutman (cameron.gutman(a)reactos.org) + * 2018 Mark Jansen (mark.jansen(a)reactos.org) + * 2019 Victor Pereertkin (victor.perevertkin(a)reactos.org) */ #include "nic.h" @@ -39,102 +40,145 @@ NTAPI MiniportHandleInterrupt( IN NDIS_HANDLE MiniportAdapterContext) { - ULONG Value; + ULONG InterruptPending; PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - Value = InterlockedExchange(&Adapter->InterruptPending, 0); + InterruptPending = InterlockedExchange(&Adapter->InterruptPending, 0); - NdisDprAcquireSpinLock(&Adapter->Lock); - if (Value & E1000_IMS_LSC) + /* Link State Changed */ + if (InterruptPending & E1000_IMS_LSC) { ULONG Status; - NdisDprReleaseSpinLock(&Adapter->Lock); - Value &= ~E1000_IMS_LSC; - NDIS_DbgPrint(MIN_TRACE, ("Link status changed!.\n")); + InterruptPending &= ~E1000_IMS_LSC; + NDIS_DbgPrint(MAX_TRACE, ("Link status changed!.\n")); NICUpdateLinkStatus(Adapter); Status = Adapter->MediaState == NdisMediaStateConnected ? NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT; + NdisMIndicateStatus(Adapter->AdapterHandle, Status, NULL, 0); NdisMIndicateStatusComplete(Adapter->AdapterHandle); - - NdisDprAcquireSpinLock(&Adapter->Lock); - } - - if (Value & E1000_IMS_TXDW) - { - while (Adapter->TxFull || Adapter->LastTxDesc != Adapter->CurrentTxDesc) - { - TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->LastTxDesc; - - if (!(TransmitDescriptor->Status & E1000_TDESC_STATUS_DD)) - { - /* Not processed yet */ - break; - } - - Adapter->LastTxDesc = (Adapter->LastTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS; - Value &= ~E1000_IMS_TXDW; - Adapter->TxFull = FALSE; - NDIS_DbgPrint(MAX_TRACE, ("CurrentTxDesc:%u, LastTxDesc:%u\n", Adapter->CurrentTxDesc, Adapter->LastTxDesc)); - } } - if (Value & (E1000_IMS_RXDMT0 | E1000_IMS_RXT0)) + /* Handling receive interrupts */ + if (InterruptPending & (E1000_IMS_RXDMT0 | E1000_IMS_RXT0)) { volatile PE1000_RECEIVE_DESCRIPTOR ReceiveDescriptor; PETH_HEADER EthHeader; ULONG BufferOffset; + BOOLEAN bGotAny = FALSE; + ULONG RxDescHead, RxDescTail, CurrRxDesc; /* Clear out these interrupts */ - Value &= ~(E1000_IMS_RXDMT0 | E1000_IMS_RXT0); + InterruptPending &= ~(E1000_IMS_RXDMT0 | E1000_IMS_RXT0); - while (TRUE) + E1000ReadUlong(Adapter, E1000_REG_RDH, &RxDescHead); + E1000ReadUlong(Adapter, E1000_REG_RDT, &RxDescTail); + + while (((RxDescTail + 1) % NUM_RECEIVE_DESCRIPTORS) != RxDescHead) { - BufferOffset = Adapter->CurrentRxDesc * Adapter->ReceiveBufferEntrySize; - ReceiveDescriptor = Adapter->ReceiveDescriptors + Adapter->CurrentRxDesc; + CurrRxDesc = (RxDescTail + 1) % NUM_RECEIVE_DESCRIPTORS; + BufferOffset = CurrRxDesc * Adapter->ReceiveBufferEntrySize; + ReceiveDescriptor = Adapter->ReceiveDescriptors + CurrRxDesc; + /* Check if the hardware have released this descriptor (DD - Descriptor Done) */ if (!(ReceiveDescriptor->Status & E1000_RDESC_STATUS_DD)) { - /* Not received yet */ + /* No need to check descriptors after the first unfinished one */ break; } - if (ReceiveDescriptor->Length != 0) + /* Ignoring these flags for now */ + ReceiveDescriptor->Status &= ~(E1000_RDESC_STATUS_IXSM | E1000_RDESC_STATUS_PIF); + + if (ReceiveDescriptor->Status != (E1000_RDESC_STATUS_EOP | E1000_RDESC_STATUS_DD)) { - EthHeader = Adapter->ReceiveBuffer + BufferOffset; + NDIS_DbgPrint(MIN_TRACE, ("Unrecognized ReceiveDescriptor status flag: %u\n", ReceiveDescriptor->Status)); + } + + if (ReceiveDescriptor->Length != 0 && ReceiveDescriptor->Address != 0) + { + EthHeader = (PETH_HEADER)(Adapter->ReceiveBuffer + BufferOffset); NdisMEthIndicateReceive(Adapter->AdapterHandle, NULL, - EthHeader, + (PCHAR)EthHeader, sizeof(ETH_HEADER), - EthHeader + 1, + (PCHAR)(EthHeader + 1), ReceiveDescriptor->Length - sizeof(ETH_HEADER), ReceiveDescriptor->Length - sizeof(ETH_HEADER)); - if (ReceiveDescriptor->Status & E1000_RDESC_STATUS_EOP) - { - NdisMEthIndicateReceiveComplete(Adapter->AdapterHandle); - } - else - { - __debugbreak(); - } + bGotAny = TRUE; + } + else + { + NDIS_DbgPrint(MIN_TRACE, ("Got a NULL descriptor")); } - /* Restore the descriptor Address, incase we received a NULL descriptor */ - ReceiveDescriptor->Address = Adapter->ReceiveBufferPa.QuadPart + BufferOffset; /* Give the descriptor back */ ReceiveDescriptor->Status = 0; - E1000WriteUlong(Adapter, E1000_REG_RDT, Adapter->CurrentRxDesc); - Adapter->CurrentRxDesc = (Adapter->CurrentRxDesc + 1) % NUM_RECEIVE_DESCRIPTORS; + + RxDescTail = CurrRxDesc; + } + + if (bGotAny) + { + /* Write back new tail value */ + E1000WriteUlong(Adapter, E1000_REG_RDT, RxDescTail); + + NDIS_DbgPrint(MAX_TRACE, ("Rx done (RDH: %u, RDT: %u)\n", RxDescHead, RxDescTail)); + + NdisMEthIndicateReceiveComplete(Adapter->AdapterHandle); + } + } + + /* Handling transmit interrupts */ + if (InterruptPending & (E1000_IMS_TXD_LOW | E1000_IMS_TXDW | E1000_IMS_TXQE)) + { + PNDIS_PACKET AckPackets[40] = {0}; + ULONG NumPackets = 0, i; + + /* Clear out these interrupts */ + InterruptPending &= ~(E1000_IMS_TXD_LOW | E1000_IMS_TXDW | E1000_IMS_TXQE); + + while ((Adapter->TxFull || Adapter->LastTxDesc != Adapter->CurrentTxDesc) && NumPackets < ARRAYSIZE(AckPackets)) + { + TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->LastTxDesc; + + if (TransmitDescriptor->Status & E1000_TDESC_STATUS_DD) + { + if (Adapter->TransmitPackets[Adapter->LastTxDesc]) + { + AckPackets[NumPackets++] = Adapter->TransmitPackets[Adapter->LastTxDesc]; + Adapter->TransmitPackets[Adapter->LastTxDesc] = NULL; + TransmitDescriptor->Status = 0; + } + + Adapter->LastTxDesc = (Adapter->LastTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS; + Adapter->TxFull = FALSE; + } + else + { + break; + } + } + + if (NumPackets) + { + NDIS_DbgPrint(MAX_TRACE, ("Tx: (TDH: %u, TDT: %u)\n", Adapter->CurrentTxDesc, Adapter->LastTxDesc)); + NDIS_DbgPrint(MAX_TRACE, ("Tx Done: %u packets to ack\n", NumPackets)); + + for (i = 0; i < NumPackets; ++i) + { + NdisMSendComplete(Adapter->AdapterHandle, AckPackets[i], NDIS_STATUS_SUCCESS); + } } } - ASSERT(Value == 0); + ASSERT(InterruptPending == 0); } diff --git a/drivers/network/dd/e1000/ndis.c b/drivers/network/dd/e1000/ndis.c index 0df4f765f0..f73bf5e89d 100644 --- a/drivers/network/dd/e1000/ndis.c +++ b/drivers/network/dd/e1000/ndis.c @@ -10,7 +10,7 @@ #include <debug.h> -ULONG DebugTraceLevel = DEBUG_ULTRA; +ULONG DebugTraceLevel = MIN_TRACE; NDIS_STATUS NTAPI @@ -33,40 +33,32 @@ MiniportSend( PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; PSCATTER_GATHER_LIST sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo); ULONG TransmitLength; - ULONG TransmitBuffer; + PHYSICAL_ADDRESS TransmitBuffer; NDIS_STATUS Status; ASSERT(sgList != NULL); ASSERT(sgList->NumberOfElements == 1); - ASSERT(sgList->Elements[0].Address.HighPart == 0); ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0); ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE); - NDIS_DbgPrint(MAX_TRACE, ("Sending %d byte packet\n", sgList->Elements[0].Length)); - - NdisAcquireSpinLock(&Adapter->Lock); - if (Adapter->TxFull) { - NdisReleaseSpinLock(&Adapter->Lock); NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n")); return NDIS_STATUS_RESOURCES; } TransmitLength = sgList->Elements[0].Length; - TransmitBuffer = sgList->Elements[0].Address.LowPart; + TransmitBuffer = sgList->Elements[0].Address; + Adapter->TransmitPackets[Adapter->CurrentTxDesc] = Packet; Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength); if (Status != NDIS_STATUS_SUCCESS) { - NdisReleaseSpinLock(&Adapter->Lock); NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n")); return Status; } - NdisReleaseSpinLock(&Adapter->Lock); - - return NDIS_STATUS_SUCCESS; + return NDIS_STATUS_PENDING; } VOID @@ -107,7 +99,6 @@ MiniportInitialize( PNDIS_RESOURCE_LIST ResourceList; UINT ResourceListSize; PCI_COMMON_CONFIG PciConfig; - //ULONG Value; /* Make sure the medium is supported */ for (i = 0; i < MediumArraySize; i++) @@ -137,8 +128,6 @@ MiniportInitialize( RtlZeroMemory(Adapter, sizeof(*Adapter)); Adapter->AdapterHandle = MiniportAdapterHandle; - NdisAllocateSpinLock(&Adapter->Lock); - /* Notify NDIS of some characteristics of our NIC */ NdisMSetAttributesEx(MiniportAdapterHandle, @@ -219,7 +208,7 @@ MiniportInitialize( /* Allocate the DMA resources */ Status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, - FALSE, // 32bit + FALSE, // 64bit is supported but can be buggy MAXIMUM_FRAME_SIZE); if (Status != NDIS_STATUS_SUCCESS) { diff --git a/drivers/network/dd/e1000/nic.h b/drivers/network/dd/e1000/nic.h index be198701ed..c1bd82997f 100644 --- a/drivers/network/dd/e1000/nic.h +++ b/drivers/network/dd/e1000/nic.h @@ -1,9 +1,10 @@ /* * PROJECT: ReactOS Intel PRO/1000 Driver * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * PURPOSE: Intel PRO/1000 driver definitions - * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman(a)reactos.org) - * Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + * PURPOSE: Hardware specific functions + * COPYRIGHT: 2013 Cameron Gutman (cameron.gutman(a)reactos.org) + * 2018 Mark Jansen (mark.jansen(a)reactos.org) + * 2019 Victor Perevertkin (victor.perevertkin(a)reactos.org) */ #ifndef _E1000_PCH_ @@ -15,17 +16,18 @@ #define E1000_TAG '001e' -#define MAXIMUM_FRAME_SIZE 1522 -#define RECEIVE_BUFFER_SIZE 2048 +#define MAXIMUM_FRAME_SIZE 1522 +#define RECEIVE_BUFFER_SIZE 2048 #define DRIVER_VERSION 1 +#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC | E1000_IMS_TXDW | E1000_IMS_TXQE | E1000_IMS_RXDMT0 | E1000_IMS_RXT0 | E1000_IMS_TXD_LOW) -#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC | E1000_IMS_TXDW | E1000_IMS_RXDMT0 | E1000_IMS_RXT0) typedef struct _E1000_ADAPTER { - NDIS_SPIN_LOCK Lock; + // NDIS_SPIN_LOCK AdapterLock; + NDIS_HANDLE AdapterHandle; USHORT VendorID; USHORT DeviceID; @@ -60,14 +62,16 @@ typedef struct _E1000_ADAPTER NDIS_MINIPORT_INTERRUPT Interrupt; BOOLEAN InterruptRegistered; - ULONG InterruptMask; - ULONG InterruptPending; + LONG InterruptMask; + LONG InterruptPending; /* Transmit */ PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptors; NDIS_PHYSICAL_ADDRESS TransmitDescriptorsPa; + PNDIS_PACKET TransmitPackets[NUM_TRANSMIT_DESCRIPTORS]; + ULONG CurrentTxDesc; ULONG LastTxDesc; BOOLEAN TxFull; @@ -77,8 +81,6 @@ typedef struct _E1000_ADAPTER PE1000_RECEIVE_DESCRIPTOR ReceiveDescriptors; NDIS_PHYSICAL_ADDRESS ReceiveDescriptorsPa; - ULONG CurrentRxDesc; - E1000_RCVBUF_SIZE ReceiveBufferType; volatile PUCHAR ReceiveBuffer; NDIS_PHYSICAL_ADDRESS ReceiveBufferPa; @@ -179,7 +181,7 @@ NDIS_STATUS NTAPI NICTransmitPacket( IN PE1000_ADAPTER Adapter, - IN ULONG PhysicalAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, IN ULONG Length); NDIS_STATUS @@ -215,6 +217,13 @@ MiniportHandleInterrupt( IN NDIS_HANDLE MiniportAdapterContext); +VOID +NTAPI +E1000ReadUlong( + IN PE1000_ADAPTER Adapter, + IN ULONG Address, + OUT PULONG Value); + VOID NTAPI E1000WriteUlong( @@ -222,6 +231,4 @@ E1000WriteUlong( IN ULONG Address, IN ULONG Value); - - #endif /* _E1000_PCH_ */ diff --git a/media/inf/nete1000.inf b/media/inf/nete1000.inf index ed47b46926..9b026154dc 100644 --- a/media/inf/nete1000.inf +++ b/media/inf/nete1000.inf @@ -1,4 +1,4 @@ -; NETRTL.INF +; NETE1000.INF ; Installation file for Intel-based NICs @@ -9,7 +9,7 @@ LayoutFile = layout.inf Class = Net ClassGUID = {4D36E972-E325-11CE-BFC1-08002BE10318} Provider = %ReactOS% -DriverVer = 18/05/2018,1.00 +DriverVer = 22/01/2019,1.00 [DestinationDirs] DefaultDestDir = 12 @@ -18,7 +18,43 @@ DefaultDestDir = 12 %IntelMfg% = IntelMfg [IntelMfg] +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1000 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1001 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1004 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1008 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1009 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_100A +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_100C +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_100D +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_100E %IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_100F +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1010 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1011 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1012 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1013 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1014 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1015 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1016 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1017 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1018 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1019 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_101A +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_101D +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_101E +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1026 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1027 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1028 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1075 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1076 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1077 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1078 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1079 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_107A +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_107B +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_107C +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_108A +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_1099 +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_10B5 ;----------------------------- E1000 DRIVER -----------------------------
5 years, 10 months
1
0
0
0
[reactos] 05/06: [NDIS] Improve debug output
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1b2ca2810782464458687…
commit 1b2ca2810782464458687cbd70b2feaee10d6279 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Mon Jul 2 22:29:05 2018 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 19:48:54 2019 +0100 [NDIS] Improve debug output --- drivers/network/ndis/include/miniport.h | 3 ++- drivers/network/ndis/ndis/miniport.c | 23 ++++++++++++----------- drivers/network/ndis/ndis/protocol.c | 8 +++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/network/ndis/include/miniport.h b/drivers/network/ndis/include/miniport.h index 6df63d7440..d538909d78 100644 --- a/drivers/network/ndis/include/miniport.h +++ b/drivers/network/ndis/include/miniport.h @@ -109,7 +109,8 @@ extern KSPIN_LOCK AdapterListLock; #if DBG VOID MiniDisplayPacket( - PNDIS_PACKET Packet); + PNDIS_PACKET Packet, + PCSTR Reason); #endif /* DBG */ VOID diff --git a/drivers/network/ndis/ndis/miniport.c b/drivers/network/ndis/ndis/miniport.c index 38ee5d01b3..645291cab9 100644 --- a/drivers/network/ndis/ndis/miniport.c +++ b/drivers/network/ndis/ndis/miniport.c @@ -59,7 +59,8 @@ KSPIN_LOCK AdapterListLock; VOID MiniDisplayPacket( - PNDIS_PACKET Packet) + PNDIS_PACKET Packet, + PCSTR Reason) { #if DBG ULONG i, Length; @@ -71,15 +72,15 @@ MiniDisplayPacket( 0, 64); - DbgPrint("*** PACKET START ***"); + DbgPrint("*** %s PACKET START (%p) ***\n", Reason, Packet); for (i = 0; i < Length; i++) { - if (i % 12 == 0) + if (i % 16 == 0) DbgPrint("\n%04X ", i); DbgPrint("%02X ", Buffer[i]); } - DbgPrint("*** PACKET STOP ***\n"); + DbgPrint("\n*** %s PACKET STOP ***\n", Reason); } #endif /* DBG */ } @@ -624,8 +625,8 @@ MiniAdapterHasAddress( */ { UINT Length; - PUCHAR Start1; - PUCHAR Start2; + PUCHAR PacketAddress; + PUCHAR AdapterAddress; PNDIS_BUFFER NdisBuffer; UINT BufferLength; @@ -653,7 +654,7 @@ MiniAdapterHasAddress( return FALSE; } - NdisQueryBuffer(NdisBuffer, (PVOID)&Start2, &BufferLength); + NdisQueryBuffer(NdisBuffer, (PVOID)&PacketAddress, &BufferLength); /* FIXME: Should handle fragmented packets */ @@ -675,12 +676,12 @@ MiniAdapterHasAddress( return FALSE; } - Start1 = (PUCHAR)&Adapter->Address; + AdapterAddress = (PUCHAR)&Adapter->Address; NDIS_DbgPrint(MAX_TRACE, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n", - *((char *)Start1), *(((char *)Start1)+1), *(((char *)Start1)+2), *(((char *)Start1)+3), *(((char *)Start1)+4), *(((char *)Start1)+5), - *((char *)Start2), *(((char *)Start2)+1), *(((char *)Start2)+2), *(((char *)Start2)+3), *(((char *)Start2)+4), *(((char *)Start2)+5))); + *(PacketAddress), *(PacketAddress+1), *(PacketAddress+2), *(PacketAddress+3), *(PacketAddress+4), *(PacketAddress+5), + *(AdapterAddress), *(AdapterAddress+1), *(AdapterAddress+2), *(AdapterAddress+3), *(AdapterAddress+4), *(AdapterAddress+5))); - return (RtlCompareMemory((PVOID)Start1, (PVOID)Start2, Length) == Length); + return (RtlCompareMemory(PacketAddress, AdapterAddress, Length) == Length); } diff --git a/drivers/network/ndis/ndis/protocol.c b/drivers/network/ndis/ndis/protocol.c index c32bfd45d3..d584d36f15 100644 --- a/drivers/network/ndis/ndis/protocol.c +++ b/drivers/network/ndis/ndis/protocol.c @@ -262,7 +262,7 @@ ProIndicatePacket( NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); #if DBG - MiniDisplayPacket(Packet); + MiniDisplayPacket(Packet, "INDICATE"); #endif NdisQueryPacket(Packet, NULL, NULL, NULL, &PacketLength); @@ -395,11 +395,17 @@ proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet) KIRQL RaiseOldIrql; NDIS_STATUS NdisStatus; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + if(MiniIsBusy(Adapter, NdisWorkItemSend)) { + NDIS_DbgPrint(MID_TRACE, ("Busy: NdisWorkItemSend.\n")); + MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE); return NDIS_STATUS_PENDING; } + MiniDisplayPacket(Packet, "SEND"); + if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler) { if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE)
5 years, 10 months
1
0
0
0
[reactos] 04/06: [E1000] Initial send implementation.
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3606404b2e38974213334…
commit 3606404b2e38974213334a53da307e89bacf3d03 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Jun 3 22:43:50 2018 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 19:48:54 2019 +0100 [E1000] Initial send implementation. CORE-14675 --- drivers/network/dd/e1000/e1000hw.h | 35 +++++- drivers/network/dd/e1000/hardware.c | 203 +++++++++++++++++++++++++++++------ drivers/network/dd/e1000/interrupt.c | 51 +++++++++ drivers/network/dd/e1000/nic.h | 24 ++++- 4 files changed, 280 insertions(+), 33 deletions(-) diff --git a/drivers/network/dd/e1000/e1000hw.h b/drivers/network/dd/e1000/e1000hw.h index 2ee489342a..b2293aa0ba 100644 --- a/drivers/network/dd/e1000/e1000hw.h +++ b/drivers/network/dd/e1000/e1000hw.h @@ -31,6 +31,22 @@ typedef struct _ETH_HEADER { +typedef enum _E1000_RCVBUF_SIZE +{ + E1000_RCVBUF_2048 = 0, + E1000_RCVBUF_1024 = 1, + E1000_RCVBUF_512 = 2, + E1000_RCVBUF_256 = 3, + + E1000_RCVBUF_INDEXMASK = 3, + E1000_RCVBUF_RESERVED = 4 | 0, + + E1000_RCVBUF_16384 = 4 | 1, + E1000_RCVBUF_8192 = 4 | 2, + E1000_RCVBUF_4096 = 4 | 3, +} E1000_RCVBUF_SIZE; + + #include <pshpack1.h> @@ -95,13 +111,20 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); #define E1000_REG_MDIC 0x0020 /* MDI Control Register, R/W */ #define E1000_REG_VET 0x0038 /* VLAN Ether Type, R/W */ #define E1000_REG_ICR 0x00C0 /* Interrupt Cause Read, R/clr */ +#define E1000_REG_ITR 0x00C4 /* Interrupt Throttling Register, R/W */ #define E1000_REG_IMS 0x00D0 /* Interrupt Mask Set/Read Register, R/W */ #define E1000_REG_IMC 0x00D8 /* Interrupt Mask Clear, W */ -#define E1000_REG_RCTL 0x0100 /* Receive Control Register, R/W */ +#define E1000_REG_RCTL 0x0100 /* Receive Control Register, R/W */ #define E1000_REG_TCTL 0x0400 /* Transmit Control Register, R/W */ +#define E1000_REG_RDBAL 0x2800 /* Receive Descriptor Base Address Low, R/W */ +#define E1000_REG_RDBAH 0x2804 /* Receive Descriptor Base Address High, R/W */ +#define E1000_REG_RDLEN 0x2808 /* Receive Descriptor Length, R/W */ +#define E1000_REG_RDH 0x2810 /* Receive Descriptor Head, R/W */ +#define E1000_REG_RDT 0x2818 /* Receive Descriptor Tail, R/W */ + #define E1000_REG_TDBAL 0x3800 /* Transmit Descriptor Base Address Low, R/W */ #define E1000_REG_TDBAH 0x3804 /* Transmit Descriptor Base Address High, R/W */ #define E1000_REG_TDLEN 0x3808 /* Transmit Descriptor Length, R/W */ @@ -142,6 +165,13 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); /* E1000_REG_IMS */ #define E1000_IMS_TXDW (1 << 0) /* Transmit Descriptor Written Back */ #define E1000_IMS_LSC (1 << 2) /* Sets mask for Link Status Change */ +#define E1000_IMS_RXDMT0 (1 << 4) /* Receive Descriptor Minimum Threshold Reached */ +#define E1000_IMS_RXT0 (1 << 7) /* Receiver Timer Interrupt */ + + +/* E1000_REG_ITR */ +#define MAX_INTS_PER_SEC 2000 +#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256) /* E1000_REG_RCTL */ @@ -150,7 +180,10 @@ C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); #define E1000_RCTL_UPE (1 << 3) /* Unicast Promiscuous Enabled */ #define E1000_RCTL_MPE (1 << 4) /* Multicast Promiscuous Enabled */ #define E1000_RCTL_BAM (1 << 15) /* Broadcast Accept Mode */ +#define E1000_RCTL_BSIZE_SHIFT 16 #define E1000_RCTL_PMCF (1 << 23) /* Pass MAC Control Frames */ +#define E1000_RCTL_BSEX (1 << 25) /* Buffer Size Extension */ +#define E1000_RCTL_SECRC (1 << 26) /* Strip Ethernet CRC from incoming packet */ #define E1000_RCTL_FILTER_BITS (E1000_RCTL_SBP | E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_BAM | E1000_RCTL_PMCF) diff --git a/drivers/network/dd/e1000/hardware.c b/drivers/network/dd/e1000/hardware.c index f510d9991d..0b7d8f0d1f 100644 --- a/drivers/network/dd/e1000/hardware.c +++ b/drivers/network/dd/e1000/hardware.c @@ -24,7 +24,7 @@ static ULONG E1000WriteFlush(IN PE1000_ADAPTER Adapter) return Value; } -static VOID E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value) +VOID NTAPI E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value) { NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); } @@ -41,6 +41,64 @@ static VOID E1000WriteIoUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN UL NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value); } +static ULONG PacketFilterToMask(ULONG PacketFilter) +{ + ULONG FilterMask = 0; + + if (PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) + { + /* Multicast Promiscuous Enabled */ + FilterMask |= E1000_RCTL_MPE; + } + if (PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) + { + /* Unicast Promiscuous Enabled */ + FilterMask |= E1000_RCTL_UPE; + /* Multicast Promiscuous Enabled */ + FilterMask |= E1000_RCTL_MPE; + } + if (PacketFilter & NDIS_PACKET_TYPE_MAC_FRAME) + { + /* Pass MAC Control Frames */ + FilterMask |= E1000_RCTL_PMCF; + } + if (PacketFilter & NDIS_PACKET_TYPE_BROADCAST) + { + /* Broadcast Accept Mode */ + FilterMask |= E1000_RCTL_BAM; + } + + return FilterMask; +} + +static ULONG RcvBufAllocationSize(E1000_RCVBUF_SIZE BufSize) +{ + static ULONG PredefSizes[4] = { + 2048, 1024, 512, 256, + }; + ULONG Size; + + Size = PredefSizes[BufSize & E1000_RCVBUF_INDEXMASK]; + if (BufSize & E1000_RCVBUF_RESERVED) + { + ASSERT(BufSize != 2048); + Size *= 16; + } + return Size; +} + +static ULONG RcvBufRegisterMask(E1000_RCVBUF_SIZE BufSize) +{ + ULONG Mask = 0; + + Mask |= BufSize & E1000_RCVBUF_INDEXMASK; + Mask <<= E1000_RCTL_BSIZE_SHIFT; + if (BufSize & E1000_RCVBUF_RESERVED) + Mask |= E1000_RCTL_BSEX; + + return Mask; +} + static BOOLEAN E1000ReadMdic(IN PE1000_ADAPTER Adapter, IN ULONG Address, USHORT *Result) { ULONG ResultAddress; @@ -242,6 +300,9 @@ NICAllocateIoResources( IN PE1000_ADAPTER Adapter) { NDIS_STATUS Status; + ULONG AllocationSize; + UINT n; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); Status = NdisMRegisterIoPortRange((PVOID*)&Adapter->IoPort, @@ -271,6 +332,47 @@ NICAllocateIoResources( return NDIS_STATUS_RESOURCES; } + for (n = 0; n < NUM_TRANSMIT_DESCRIPTORS; ++n) + { + PE1000_TRANSMIT_DESCRIPTOR Descriptor = Adapter->TransmitDescriptors + n; + Descriptor->Address = 0; + Descriptor->Length = 0; + } + + NdisMAllocateSharedMemory(Adapter->AdapterHandle, + sizeof(E1000_RECEIVE_DESCRIPTOR) * NUM_RECEIVE_DESCRIPTORS, + FALSE, + (PVOID*)&Adapter->ReceiveDescriptors, + &Adapter->ReceiveDescriptorsPa); + if (Adapter->ReceiveDescriptors == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate receive descriptors\n")); + return NDIS_STATUS_RESOURCES; + } + + AllocationSize = RcvBufAllocationSize(Adapter->ReceiveBufferType); + ASSERT(Adapter->ReceiveBufferEntrySize == 0 || Adapter->ReceiveBufferEntrySize == AllocationSize); + Adapter->ReceiveBufferEntrySize = AllocationSize; + + NdisMAllocateSharedMemory(Adapter->AdapterHandle, + Adapter->ReceiveBufferEntrySize * NUM_RECEIVE_DESCRIPTORS, + FALSE, + (PVOID*)&Adapter->ReceiveBuffer, + &Adapter->ReceiveBufferPa); + + if (Adapter->ReceiveBuffer == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate receive buffer\n")); + return NDIS_STATUS_RESOURCES; + } + + for (n = 0; n < NUM_RECEIVE_DESCRIPTORS; ++n) + { + PE1000_RECEIVE_DESCRIPTOR Descriptor = Adapter->ReceiveDescriptors + n; + + RtlZeroMemory(Descriptor, sizeof(*Descriptor)); + Descriptor->Address = Adapter->ReceiveBufferPa.QuadPart + n * Adapter->ReceiveBufferEntrySize; + } return NDIS_STATUS_SUCCESS; } @@ -323,11 +425,45 @@ NICReleaseIoResources( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + if (Adapter->ReceiveDescriptors != NULL) + { + /* Disassociate our shared buffer before freeing it to avoid NIC-induced memory corruption */ + if (Adapter->IoBase) + { + E1000WriteUlong(Adapter, E1000_REG_RDH, 0); + E1000WriteUlong(Adapter, E1000_REG_RDT, 0); + } + + NdisMFreeSharedMemory(Adapter->AdapterHandle, + sizeof(E1000_RECEIVE_DESCRIPTOR) * NUM_RECEIVE_DESCRIPTORS, + FALSE, + Adapter->ReceiveDescriptors, + Adapter->ReceiveDescriptorsPa); + + Adapter->ReceiveDescriptors = NULL; + } + + if (Adapter->ReceiveBuffer != NULL) + { + NdisMFreeSharedMemory(Adapter->AdapterHandle, + Adapter->ReceiveBufferEntrySize * NUM_RECEIVE_DESCRIPTORS, + FALSE, + Adapter->ReceiveBuffer, + Adapter->ReceiveBufferPa); + + Adapter->ReceiveBuffer = NULL; + Adapter->ReceiveBufferEntrySize = 0; + } + + if (Adapter->TransmitDescriptors != NULL) { /* Disassociate our shared buffer before freeing it to avoid NIC-induced memory corruption */ - //E1000WriteUlong(Adapter, E1000_REG_TDH, 0); - //E1000WriteUlong(Adapter, E1000_REG_TDT, 0); + if (Adapter->IoBase) + { + E1000WriteUlong(Adapter, E1000_REG_TDH, 0); + E1000WriteUlong(Adapter, E1000_REG_TDT, 0); + } NdisMFreeSharedMemory(Adapter->AdapterHandle, sizeof(E1000_TRANSMIT_DESCRIPTOR) * NUM_TRANSMIT_DESCRIPTORS, @@ -429,6 +565,10 @@ NICEnableTxRx( ULONG Value; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + NDIS_DbgPrint(MID_TRACE, ("Setting up transmit.\n")); + + /* Make sure the thing is disabled first. */ + E1000WriteUlong(Adapter, E1000_REG_TCTL, 0); /* Transmit descriptor ring buffer */ E1000WriteUlong(Adapter, E1000_REG_TDBAH, Adapter->TransmitDescriptorsPa.HighPart); @@ -447,12 +587,36 @@ NICEnableTxRx( E1000WriteUlong(Adapter, E1000_REG_TCTL, Value); + NDIS_DbgPrint(MID_TRACE, ("Setting up receive.\n")); + + /* Make sure the thing is disabled first. */ + E1000WriteUlong(Adapter, E1000_REG_RCTL, 0); + /* Receive descriptor ring buffer */ + E1000WriteUlong(Adapter, E1000_REG_RDBAH, Adapter->ReceiveDescriptorsPa.HighPart); + E1000WriteUlong(Adapter, E1000_REG_RDBAL, Adapter->ReceiveDescriptorsPa.LowPart); - //E1000ReadUlong(Adapter, E1000_REG_RCTL, &Value); - //Value = E1000_RCTL_BSIZE_2048 | E1000_RCTL_SECRC | E1000_RCTL_EN; - //E1000WriteUlong(Adapter, E1000_REG_RCTL, Value); + /* Receive descriptor buffer size */ + E1000WriteUlong(Adapter, E1000_REG_RDLEN, sizeof(E1000_RECEIVE_DESCRIPTOR) * NUM_RECEIVE_DESCRIPTORS); + /* Receive descriptor tail / head */ + E1000WriteUlong(Adapter, E1000_REG_RDH, 0); + E1000WriteUlong(Adapter, E1000_REG_RDT, NUM_RECEIVE_DESCRIPTORS - 1); + Adapter->CurrentRxDesc = 0; + + /* Setup Interrupt Throttling */ + E1000WriteUlong(Adapter, E1000_REG_ITR, DEFAULT_ITR); + + /* Some defaults */ + Value = E1000_RCTL_SECRC | E1000_RCTL_EN; + + /* Receive buffer size */ + Value |= RcvBufRegisterMask(Adapter->ReceiveBufferType); + + /* Add our current packet filter */ + Value |= PacketFilterToMask(Adapter->PacketFilter); + + E1000WriteUlong(Adapter, E1000_REG_RCTL, Value); return NDIS_STATUS_SUCCESS; } @@ -542,35 +706,12 @@ NTAPI NICApplyPacketFilter( IN PE1000_ADAPTER Adapter) { - ULONG FilterMask = 0; + ULONG FilterMask; E1000ReadUlong(Adapter, E1000_REG_RCTL, &FilterMask); FilterMask &= ~E1000_RCTL_FILTER_BITS; - - if (Adapter->PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) - { - /* Multicast Promiscuous Enabled */ - FilterMask |= E1000_RCTL_MPE; - } - if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) - { - /* Unicast Promiscuous Enabled */ - FilterMask |= E1000_RCTL_UPE; - /* Multicast Promiscuous Enabled */ - FilterMask |= E1000_RCTL_MPE; - } - if (Adapter->PacketFilter & NDIS_PACKET_TYPE_MAC_FRAME) - { - /* Pass MAC Control Frames */ - FilterMask |= E1000_RCTL_PMCF; - } - if (Adapter->PacketFilter & NDIS_PACKET_TYPE_BROADCAST) - { - /* Broadcast Accept Mode */ - FilterMask |= E1000_RCTL_BAM; - } - + FilterMask |= PacketFilterToMask(Adapter->PacketFilter); E1000WriteUlong(Adapter, E1000_REG_RCTL, FilterMask); return NDIS_STATUS_SUCCESS; diff --git a/drivers/network/dd/e1000/interrupt.c b/drivers/network/dd/e1000/interrupt.c index c65196274a..cd94e455e1 100644 --- a/drivers/network/dd/e1000/interrupt.c +++ b/drivers/network/dd/e1000/interrupt.c @@ -52,6 +52,7 @@ MiniportHandleInterrupt( if (Value & E1000_IMS_LSC) { ULONG Status; + NdisDprReleaseSpinLock(&Adapter->Lock); Value &= ~E1000_IMS_LSC; NDIS_DbgPrint(MIN_TRACE, ("Link status changed!.\n")); @@ -84,6 +85,56 @@ MiniportHandleInterrupt( } } + if (Value & (E1000_IMS_RXDMT0 | E1000_IMS_RXT0)) + { + volatile PE1000_RECEIVE_DESCRIPTOR ReceiveDescriptor; + PETH_HEADER EthHeader; + ULONG BufferOffset; + + /* Clear out these interrupts */ + Value &= ~(E1000_IMS_RXDMT0 | E1000_IMS_RXT0); + + while (TRUE) + { + BufferOffset = Adapter->CurrentRxDesc * Adapter->ReceiveBufferEntrySize; + ReceiveDescriptor = Adapter->ReceiveDescriptors + Adapter->CurrentRxDesc; + + if (!(ReceiveDescriptor->Status & E1000_RDESC_STATUS_DD)) + { + /* Not received yet */ + break; + } + + if (ReceiveDescriptor->Length != 0) + { + EthHeader = Adapter->ReceiveBuffer + BufferOffset; + + NdisMEthIndicateReceive(Adapter->AdapterHandle, + NULL, + EthHeader, + sizeof(ETH_HEADER), + EthHeader + 1, + ReceiveDescriptor->Length - sizeof(ETH_HEADER), + ReceiveDescriptor->Length - sizeof(ETH_HEADER)); + + if (ReceiveDescriptor->Status & E1000_RDESC_STATUS_EOP) + { + NdisMEthIndicateReceiveComplete(Adapter->AdapterHandle); + } + else + { + __debugbreak(); + } + } + + /* Restore the descriptor Address, incase we received a NULL descriptor */ + ReceiveDescriptor->Address = Adapter->ReceiveBufferPa.QuadPart + BufferOffset; + /* Give the descriptor back */ + ReceiveDescriptor->Status = 0; + E1000WriteUlong(Adapter, E1000_REG_RDT, Adapter->CurrentRxDesc); + Adapter->CurrentRxDesc = (Adapter->CurrentRxDesc + 1) % NUM_RECEIVE_DESCRIPTORS; + } + } ASSERT(Value == 0); } diff --git a/drivers/network/dd/e1000/nic.h b/drivers/network/dd/e1000/nic.h index 7b42d055e2..be198701ed 100644 --- a/drivers/network/dd/e1000/nic.h +++ b/drivers/network/dd/e1000/nic.h @@ -21,7 +21,7 @@ #define DRIVER_VERSION 1 -#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC | E1000_IMS_TXDW) +#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC | E1000_IMS_TXDW | E1000_IMS_RXDMT0 | E1000_IMS_RXT0) typedef struct _E1000_ADAPTER { @@ -72,6 +72,18 @@ typedef struct _E1000_ADAPTER ULONG LastTxDesc; BOOLEAN TxFull; + + /* Receive */ + PE1000_RECEIVE_DESCRIPTOR ReceiveDescriptors; + NDIS_PHYSICAL_ADDRESS ReceiveDescriptorsPa; + + ULONG CurrentRxDesc; + + E1000_RCVBUF_SIZE ReceiveBufferType; + volatile PUCHAR ReceiveBuffer; + NDIS_PHYSICAL_ADDRESS ReceiveBufferPa; + ULONG ReceiveBufferEntrySize; + } E1000_ADAPTER, *PE1000_ADAPTER; @@ -202,4 +214,14 @@ NTAPI MiniportHandleInterrupt( IN NDIS_HANDLE MiniportAdapterContext); + +VOID +NTAPI +E1000WriteUlong( + IN PE1000_ADAPTER Adapter, + IN ULONG Address, + IN ULONG Value); + + + #endif /* _E1000_PCH_ */
5 years, 10 months
1
0
0
0
[reactos] 03/06: [E1000] Implement basic sending. Implement some interrupt recognition
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ebad64bcfe782e1e11845…
commit ebad64bcfe782e1e11845bbed6eb38aa56294236 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Tue May 29 22:52:43 2018 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 19:48:54 2019 +0100 [E1000] Implement basic sending. Implement some interrupt recognition CORE-14675 --- drivers/network/dd/e1000/e1000hw.h | 75 +++++++++++++++++++++++- drivers/network/dd/e1000/hardware.c | 109 +++++++++++++++++++++++++++++++---- drivers/network/dd/e1000/interrupt.c | 60 +++++++++++++++---- drivers/network/dd/e1000/ndis.c | 38 +++++++++++- drivers/network/dd/e1000/nic.h | 19 +++--- 5 files changed, 269 insertions(+), 32 deletions(-) diff --git a/drivers/network/dd/e1000/e1000hw.h b/drivers/network/dd/e1000/e1000hw.h index 9932974281..2ee489342a 100644 --- a/drivers/network/dd/e1000/e1000hw.h +++ b/drivers/network/dd/e1000/e1000hw.h @@ -32,6 +32,61 @@ typedef struct _ETH_HEADER { +#include <pshpack1.h> + + +/* 3.2.3 Receive Descriptor Format */ + +#define E1000_RDESC_STATUS_EOP (1 << 1) /* End of Packet */ +#define E1000_RDESC_STATUS_DD (1 << 0) /* Descriptor Done */ + +typedef struct _E1000_RECEIVE_DESCRIPTOR +{ + UINT64 Address; + + USHORT Length; + USHORT Checksum; + UCHAR Status; + UCHAR Errors; + USHORT Special; + +} E1000_RECEIVE_DESCRIPTOR, *PE1000_RECEIVE_DESCRIPTOR; + + +/* 3.3.3 Legacy Transmit Descriptor Format */ + +#define E1000_TDESC_CMD_RS (1 << 3) /* Report Status */ +#define E1000_TDESC_CMD_IFCS (1 << 1) /* Insert FCS */ +#define E1000_TDESC_CMD_EOP (1 << 0) /* End Of Packet */ + +#define E1000_TDESC_STATUS_DD (1 << 0) /* Descriptor Done */ + +typedef struct _E1000_TRANSMIT_DESCRIPTOR +{ + UINT64 Address; + + USHORT Length; + UCHAR ChecksumOffset; + UCHAR Command; + UCHAR Status; + UCHAR ChecksumStartField; + USHORT Special; + +} E1000_TRANSMIT_DESCRIPTOR, *PE1000_TRANSMIT_DESCRIPTOR; + +#include <poppack.h> + + +C_ASSERT(sizeof(E1000_RECEIVE_DESCRIPTOR) == 16); +C_ASSERT(sizeof(E1000_TRANSMIT_DESCRIPTOR) == 16); + + +/* Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers + Valid Range: 80-4096 for 82544 and newer */ +#define NUM_TRANSMIT_DESCRIPTORS 128 +#define NUM_RECEIVE_DESCRIPTORS 128 + + /* Registers */ #define E1000_REG_CTRL 0x0000 /* Device Control Register, R/W */ @@ -43,7 +98,16 @@ typedef struct _ETH_HEADER { #define E1000_REG_IMS 0x00D0 /* Interrupt Mask Set/Read Register, R/W */ #define E1000_REG_IMC 0x00D8 /* Interrupt Mask Clear, W */ -#define E1000_REG_RCTL 0x0100 /* Receive Control, R/W */ +#define E1000_REG_RCTL 0x0100 /* Receive Control Register, R/W */ + +#define E1000_REG_TCTL 0x0400 /* Transmit Control Register, R/W */ + +#define E1000_REG_TDBAL 0x3800 /* Transmit Descriptor Base Address Low, R/W */ +#define E1000_REG_TDBAH 0x3804 /* Transmit Descriptor Base Address High, R/W */ +#define E1000_REG_TDLEN 0x3808 /* Transmit Descriptor Length, R/W */ +#define E1000_REG_TDH 0x3810 /* Transmit Descriptor Head, R/W */ +#define E1000_REG_TDT 0x3818 /* Transmit Descriptor Tail, R/W */ + #define E1000_REG_RAL 0x5400 /* Receive Address Low, R/W */ #define E1000_REG_RAH 0x5404 /* Receive Address High, R/W */ @@ -76,6 +140,7 @@ typedef struct _ETH_HEADER { /* E1000_REG_IMS */ +#define E1000_IMS_TXDW (1 << 0) /* Transmit Descriptor Written Back */ #define E1000_IMS_LSC (1 << 2) /* Sets mask for Link Status Change */ @@ -89,6 +154,14 @@ typedef struct _ETH_HEADER { #define E1000_RCTL_FILTER_BITS (E1000_RCTL_SBP | E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_BAM | E1000_RCTL_PMCF) + +/* E1000_REG_TCTL */ +#define E1000_TCTL_EN (1 << 1) /* Transmit Enable */ +#define E1000_TCTL_PSP (1 << 3) /* Pad Short Packets */ + + + + /* E1000_REG_RAH */ #define E1000_RAH_AV (1 << 31) /* Address Valid */ diff --git a/drivers/network/dd/e1000/hardware.c b/drivers/network/dd/e1000/hardware.c index 5308afadd5..f510d9991d 100644 --- a/drivers/network/dd/e1000/hardware.c +++ b/drivers/network/dd/e1000/hardware.c @@ -259,6 +259,19 @@ NICAllocateIoResources( Adapter->IoAddress, Adapter->IoLength); + + NdisMAllocateSharedMemory(Adapter->AdapterHandle, + sizeof(E1000_TRANSMIT_DESCRIPTOR) * NUM_TRANSMIT_DESCRIPTORS, + FALSE, + (PVOID*)&Adapter->TransmitDescriptors, + &Adapter->TransmitDescriptorsPa); + if (Adapter->TransmitDescriptors == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate transmit descriptors\n")); + return NDIS_STATUS_RESOURCES; + } + + return NDIS_STATUS_SUCCESS; } @@ -310,6 +323,23 @@ NICReleaseIoResources( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + if (Adapter->TransmitDescriptors != NULL) + { + /* Disassociate our shared buffer before freeing it to avoid NIC-induced memory corruption */ + //E1000WriteUlong(Adapter, E1000_REG_TDH, 0); + //E1000WriteUlong(Adapter, E1000_REG_TDT, 0); + + NdisMFreeSharedMemory(Adapter->AdapterHandle, + sizeof(E1000_TRANSMIT_DESCRIPTOR) * NUM_TRANSMIT_DESCRIPTORS, + FALSE, + Adapter->TransmitDescriptors, + Adapter->TransmitDescriptorsPa); + + Adapter->TransmitDescriptors = NULL; + } + + + if (Adapter->IoPort) { NdisMDeregisterIoPortRange(Adapter->AdapterHandle, @@ -396,8 +426,34 @@ NTAPI NICEnableTxRx( IN PE1000_ADAPTER Adapter) { + ULONG Value; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + /* Transmit descriptor ring buffer */ + E1000WriteUlong(Adapter, E1000_REG_TDBAH, Adapter->TransmitDescriptorsPa.HighPart); + E1000WriteUlong(Adapter, E1000_REG_TDBAL, Adapter->TransmitDescriptorsPa.LowPart); + + /* Transmit descriptor buffer size */ + E1000WriteUlong(Adapter, E1000_REG_TDLEN, sizeof(E1000_TRANSMIT_DESCRIPTOR) * NUM_TRANSMIT_DESCRIPTORS); + + /* Transmit descriptor tail / head */ + E1000WriteUlong(Adapter, E1000_REG_TDH, 0); + E1000WriteUlong(Adapter, E1000_REG_TDT, 0); + Adapter->CurrentTxDesc = 0; + + + Value = E1000_TCTL_EN | E1000_TCTL_PSP; + E1000WriteUlong(Adapter, E1000_REG_TCTL, Value); + + + + + //E1000ReadUlong(Adapter, E1000_REG_RCTL, &Value); + //Value = E1000_RCTL_BSIZE_2048 | E1000_RCTL_SECRC | E1000_RCTL_EN; + //E1000WriteUlong(Adapter, E1000_REG_RCTL, Value); + + return NDIS_STATUS_SUCCESS; } @@ -406,8 +462,18 @@ NTAPI NICDisableTxRx( IN PE1000_ADAPTER Adapter) { + ULONG Value; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + E1000ReadUlong(Adapter, E1000_REG_TCTL, &Value); + Value &= ~E1000_TCTL_EN; + E1000WriteUlong(Adapter, E1000_REG_TCTL, Value); + + //E1000ReadUlong(Adapter, E1000_REG_RCTL, &Value); + //Value &= ~E1000_RCTL_EN; + //E1000WriteUlong(Adapter, E1000_REG_RCTL, Value); + return NDIS_STATUS_SUCCESS; } @@ -532,23 +598,22 @@ NICDisableInterrupts( return NDIS_STATUS_SUCCESS; } -USHORT +ULONG NTAPI NICInterruptRecognized( IN PE1000_ADAPTER Adapter, OUT PBOOLEAN InterruptRecognized) { + ULONG Value; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return 0; -} + /* Reading the interrupt acknowledges them */ + E1000ReadUlong(Adapter, E1000_REG_ICR, &Value); -VOID -NTAPI -NICAcknowledgeInterrupts( - IN PE1000_ADAPTER Adapter) -{ - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + *InterruptRecognized = (Value & Adapter->InterruptMask) != 0; + + return (Value & Adapter->InterruptMask); } VOID @@ -604,11 +669,33 @@ NDIS_STATUS NTAPI NICTransmitPacket( IN PE1000_ADAPTER Adapter, - IN UCHAR TxDesc, IN ULONG PhysicalAddress, IN ULONG Length) { + volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->CurrentTxDesc; + TransmitDescriptor->Address = PhysicalAddress; + TransmitDescriptor->Length = Length; + TransmitDescriptor->ChecksumOffset = 0; + TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS | E1000_TDESC_CMD_EOP; + TransmitDescriptor->Status = 0; + TransmitDescriptor->ChecksumStartField = 0; + TransmitDescriptor->Special = 0; + + Adapter->CurrentTxDesc = (Adapter->CurrentTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS; + + E1000WriteUlong(Adapter, E1000_REG_TDT, Adapter->CurrentTxDesc); + + NDIS_DbgPrint(MAX_TRACE, ("CurrentTxDesc:%u, LastTxDesc:%u\n", Adapter->CurrentTxDesc, Adapter->LastTxDesc)); + + if (Adapter->CurrentTxDesc == Adapter->LastTxDesc) + { + NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n")); + Adapter->TxFull = TRUE; + } + + return NDIS_STATUS_SUCCESS; } diff --git a/drivers/network/dd/e1000/interrupt.c b/drivers/network/dd/e1000/interrupt.c index 16e46e76ce..c65196274a 100644 --- a/drivers/network/dd/e1000/interrupt.c +++ b/drivers/network/dd/e1000/interrupt.c @@ -17,15 +17,12 @@ MiniportISR( OUT PBOOLEAN QueueMiniportHandleInterrupt, IN NDIS_HANDLE MiniportAdapterContext) { + ULONG Value; PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; - // - // FIXME: We need to synchronize with this ISR for changes to InterruptPending, - // LinkChange, MediaState, and LinkSpeedMbps. We can get away with IRQL - // synchronization on non-SMP machines because we run a DIRQL here. - // + Value = NICInterruptRecognized(Adapter, InterruptRecognized); + InterlockedOr(&Adapter->InterruptPending, Value); - Adapter->InterruptPending |= NICInterruptRecognized(Adapter, InterruptRecognized); if (!(*InterruptRecognized)) { /* This is not ours. */ @@ -33,10 +30,7 @@ MiniportISR( return; } - UNIMPLEMENTED; - - /* Acknowledge the interrupt and mark the events pending service */ - NICAcknowledgeInterrupts(Adapter); + /* Mark the events pending service */ *QueueMiniportHandleInterrupt = TRUE; } @@ -45,5 +39,51 @@ NTAPI MiniportHandleInterrupt( IN NDIS_HANDLE MiniportAdapterContext) { + ULONG Value; + PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; + volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + Value = InterlockedExchange(&Adapter->InterruptPending, 0); + + NdisDprAcquireSpinLock(&Adapter->Lock); + + if (Value & E1000_IMS_LSC) + { + ULONG Status; + NdisDprReleaseSpinLock(&Adapter->Lock); + Value &= ~E1000_IMS_LSC; + NDIS_DbgPrint(MIN_TRACE, ("Link status changed!.\n")); + + NICUpdateLinkStatus(Adapter); + + Status = Adapter->MediaState == NdisMediaStateConnected ? NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT; + NdisMIndicateStatus(Adapter->AdapterHandle, Status, NULL, 0); + NdisMIndicateStatusComplete(Adapter->AdapterHandle); + + NdisDprAcquireSpinLock(&Adapter->Lock); + } + + if (Value & E1000_IMS_TXDW) + { + while (Adapter->TxFull || Adapter->LastTxDesc != Adapter->CurrentTxDesc) + { + TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->LastTxDesc; + + if (!(TransmitDescriptor->Status & E1000_TDESC_STATUS_DD)) + { + /* Not processed yet */ + break; + } + + Adapter->LastTxDesc = (Adapter->LastTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS; + Value &= ~E1000_IMS_TXDW; + Adapter->TxFull = FALSE; + NDIS_DbgPrint(MAX_TRACE, ("CurrentTxDesc:%u, LastTxDesc:%u\n", Adapter->CurrentTxDesc, Adapter->LastTxDesc)); + } + } + + + ASSERT(Value == 0); } diff --git a/drivers/network/dd/e1000/ndis.c b/drivers/network/dd/e1000/ndis.c index 50b5c44e93..0df4f765f0 100644 --- a/drivers/network/dd/e1000/ndis.c +++ b/drivers/network/dd/e1000/ndis.c @@ -30,9 +30,43 @@ MiniportSend( IN PNDIS_PACKET Packet, IN UINT Flags) { - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; + PSCATTER_GATHER_LIST sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo); + ULONG TransmitLength; + ULONG TransmitBuffer; + NDIS_STATUS Status; - return NDIS_STATUS_FAILURE; + ASSERT(sgList != NULL); + ASSERT(sgList->NumberOfElements == 1); + ASSERT(sgList->Elements[0].Address.HighPart == 0); + ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0); + ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE); + + NDIS_DbgPrint(MAX_TRACE, ("Sending %d byte packet\n", sgList->Elements[0].Length)); + + NdisAcquireSpinLock(&Adapter->Lock); + + if (Adapter->TxFull) + { + NdisReleaseSpinLock(&Adapter->Lock); + NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n")); + return NDIS_STATUS_RESOURCES; + } + + TransmitLength = sgList->Elements[0].Length; + TransmitBuffer = sgList->Elements[0].Address.LowPart; + + Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength); + if (Status != NDIS_STATUS_SUCCESS) + { + NdisReleaseSpinLock(&Adapter->Lock); + NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n")); + return Status; + } + + NdisReleaseSpinLock(&Adapter->Lock); + + return NDIS_STATUS_SUCCESS; } VOID diff --git a/drivers/network/dd/e1000/nic.h b/drivers/network/dd/e1000/nic.h index 9586b615f6..7b42d055e2 100644 --- a/drivers/network/dd/e1000/nic.h +++ b/drivers/network/dd/e1000/nic.h @@ -21,7 +21,7 @@ #define DRIVER_VERSION 1 -#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC) +#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC | E1000_IMS_TXDW) typedef struct _E1000_ADAPTER { @@ -63,6 +63,15 @@ typedef struct _E1000_ADAPTER ULONG InterruptMask; ULONG InterruptPending; + + /* Transmit */ + PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptors; + NDIS_PHYSICAL_ADDRESS TransmitDescriptorsPa; + + ULONG CurrentTxDesc; + ULONG LastTxDesc; + BOOLEAN TxFull; + } E1000_ADAPTER, *PE1000_ADAPTER; @@ -143,17 +152,12 @@ NTAPI NICDisableInterrupts( IN PE1000_ADAPTER Adapter); -USHORT +ULONG NTAPI NICInterruptRecognized( IN PE1000_ADAPTER Adapter, OUT PBOOLEAN InterruptRecognized); -VOID -NTAPI -NICAcknowledgeInterrupts( - IN PE1000_ADAPTER Adapter); - VOID NTAPI NICUpdateLinkStatus( @@ -163,7 +167,6 @@ NDIS_STATUS NTAPI NICTransmitPacket( IN PE1000_ADAPTER Adapter, - IN UCHAR TxDesc, IN ULONG PhysicalAddress, IN ULONG Length);
5 years, 10 months
1
0
0
0
[reactos] 02/06: [E1000] Basic initialization of the card Initialize some registers, allocate basic resources
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d9b0601ceb6ec4d583467…
commit d9b0601ceb6ec4d5834678a561167d2e78c3a368 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Mon May 28 00:09:10 2018 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 19:48:54 2019 +0100 [E1000] Basic initialization of the card Initialize some registers, allocate basic resources CORE-14675 --- drivers/network/dd/e1000/CMakeLists.txt | 1 + drivers/network/dd/e1000/debug.c | 167 ++++++++++++ drivers/network/dd/e1000/debug.h | 2 + drivers/network/dd/e1000/e1000hw.h | 100 +++++++ drivers/network/dd/e1000/hardware.c | 463 ++++++++++++++++++++++++++++++-- drivers/network/dd/e1000/info.c | 114 +++++++- drivers/network/dd/e1000/ndis.c | 6 +- drivers/network/dd/e1000/nic.h | 35 ++- 8 files changed, 856 insertions(+), 32 deletions(-) diff --git a/drivers/network/dd/e1000/CMakeLists.txt b/drivers/network/dd/e1000/CMakeLists.txt index eeee376c2e..591f01d796 100644 --- a/drivers/network/dd/e1000/CMakeLists.txt +++ b/drivers/network/dd/e1000/CMakeLists.txt @@ -11,6 +11,7 @@ list(APPEND SOURCE interrupt.c nic.h e1000hw.h + debug.c debug.h) add_library(e1000 SHARED ${SOURCE} e1000.rc) diff --git a/drivers/network/dd/e1000/debug.c b/drivers/network/dd/e1000/debug.c new file mode 100644 index 0000000000..d3008bcc92 --- /dev/null +++ b/drivers/network/dd/e1000/debug.c @@ -0,0 +1,167 @@ +/* + * PROJECT: ReactOS Intel PRO/1000 Driver + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Translate NDIS_OID to readable string + * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include "nic.h" + +#include <debug.h> + +const char* Oid2Str(IN NDIS_OID Oid) +{ +#if DBG + switch (Oid) + { +#define RETURN_X(x) case x: return #x; + /* Required Object IDs (OIDs) */ + RETURN_X(OID_GEN_SUPPORTED_LIST); + RETURN_X(OID_GEN_HARDWARE_STATUS); + RETURN_X(OID_GEN_MEDIA_SUPPORTED); + RETURN_X(OID_GEN_MEDIA_IN_USE); + RETURN_X(OID_GEN_MAXIMUM_LOOKAHEAD); + RETURN_X(OID_GEN_MAXIMUM_FRAME_SIZE); + RETURN_X(OID_GEN_LINK_SPEED); + RETURN_X(OID_GEN_TRANSMIT_BUFFER_SPACE); + RETURN_X(OID_GEN_RECEIVE_BUFFER_SPACE); + RETURN_X(OID_GEN_TRANSMIT_BLOCK_SIZE); + RETURN_X(OID_GEN_RECEIVE_BLOCK_SIZE); + RETURN_X(OID_GEN_VENDOR_ID); + RETURN_X(OID_GEN_VENDOR_DESCRIPTION); + RETURN_X(OID_GEN_CURRENT_PACKET_FILTER); + RETURN_X(OID_GEN_CURRENT_LOOKAHEAD); + RETURN_X(OID_GEN_DRIVER_VERSION); + RETURN_X(OID_GEN_MAXIMUM_TOTAL_SIZE); + RETURN_X(OID_GEN_PROTOCOL_OPTIONS); + RETURN_X(OID_GEN_MAC_OPTIONS); + RETURN_X(OID_GEN_MEDIA_CONNECT_STATUS); + RETURN_X(OID_GEN_MAXIMUM_SEND_PACKETS); + RETURN_X(OID_GEN_VENDOR_DRIVER_VERSION); + RETURN_X(OID_GEN_SUPPORTED_GUIDS); + RETURN_X(OID_GEN_NETWORK_LAYER_ADDRESSES); + RETURN_X(OID_GEN_TRANSPORT_HEADER_OFFSET); + RETURN_X(OID_GEN_MACHINE_NAME); + RETURN_X(OID_GEN_RNDIS_CONFIG_PARAMETER); + RETURN_X(OID_GEN_VLAN_ID); + + /* Optional OIDs */ + RETURN_X(OID_GEN_MEDIA_CAPABILITIES); + RETURN_X(OID_GEN_PHYSICAL_MEDIUM); + + /* Required statistics OIDs */ + RETURN_X(OID_GEN_XMIT_OK); + RETURN_X(OID_GEN_RCV_OK); + RETURN_X(OID_GEN_XMIT_ERROR); + RETURN_X(OID_GEN_RCV_ERROR); + RETURN_X(OID_GEN_RCV_NO_BUFFER); + + /* Optional statistics OIDs */ + RETURN_X(OID_GEN_DIRECTED_BYTES_XMIT); + RETURN_X(OID_GEN_DIRECTED_FRAMES_XMIT); + RETURN_X(OID_GEN_MULTICAST_BYTES_XMIT); + RETURN_X(OID_GEN_MULTICAST_FRAMES_XMIT); + RETURN_X(OID_GEN_BROADCAST_BYTES_XMIT); + RETURN_X(OID_GEN_BROADCAST_FRAMES_XMIT); + RETURN_X(OID_GEN_DIRECTED_BYTES_RCV); + RETURN_X(OID_GEN_DIRECTED_FRAMES_RCV); + RETURN_X(OID_GEN_MULTICAST_BYTES_RCV); + RETURN_X(OID_GEN_MULTICAST_FRAMES_RCV); + RETURN_X(OID_GEN_BROADCAST_BYTES_RCV); + RETURN_X(OID_GEN_BROADCAST_FRAMES_RCV); + RETURN_X(OID_GEN_RCV_CRC_ERROR); + RETURN_X(OID_GEN_TRANSMIT_QUEUE_LENGTH); + RETURN_X(OID_GEN_GET_TIME_CAPS); + RETURN_X(OID_GEN_GET_NETCARD_TIME); + RETURN_X(OID_GEN_NETCARD_LOAD); + RETURN_X(OID_GEN_DEVICE_PROFILE); + RETURN_X(OID_GEN_INIT_TIME_MS); + RETURN_X(OID_GEN_RESET_COUNTS); + RETURN_X(OID_GEN_MEDIA_SENSE_COUNTS); + RETURN_X(OID_GEN_FRIENDLY_NAME); + RETURN_X(OID_GEN_MINIPORT_INFO); + RETURN_X(OID_GEN_RESET_VERIFY_PARAMETERS); + + /* IEEE 802.3 (Ethernet) OIDs */ + //RETURN_X(NDIS_802_3_MAC_OPTION_PRIORITY); /*Duplicate ID */ + + RETURN_X(OID_802_3_PERMANENT_ADDRESS); + RETURN_X(OID_802_3_CURRENT_ADDRESS); + RETURN_X(OID_802_3_MULTICAST_LIST); + RETURN_X(OID_802_3_MAXIMUM_LIST_SIZE); + RETURN_X(OID_802_3_MAC_OPTIONS); + RETURN_X(OID_802_3_RCV_ERROR_ALIGNMENT); + RETURN_X(OID_802_3_XMIT_ONE_COLLISION); + RETURN_X(OID_802_3_XMIT_MORE_COLLISIONS); + RETURN_X(OID_802_3_XMIT_DEFERRED); + RETURN_X(OID_802_3_XMIT_MAX_COLLISIONS); + RETURN_X(OID_802_3_RCV_OVERRUN); + RETURN_X(OID_802_3_XMIT_UNDERRUN); + RETURN_X(OID_802_3_XMIT_HEARTBEAT_FAILURE); + RETURN_X(OID_802_3_XMIT_TIMES_CRS_LOST); + RETURN_X(OID_802_3_XMIT_LATE_COLLISIONS); + + /* IEEE 802.11 (WLAN) OIDs */ + RETURN_X(OID_802_11_BSSID); + RETURN_X(OID_802_11_SSID); + RETURN_X(OID_802_11_NETWORK_TYPES_SUPPORTED); + RETURN_X(OID_802_11_NETWORK_TYPE_IN_USE); + RETURN_X(OID_802_11_TX_POWER_LEVEL); + RETURN_X(OID_802_11_RSSI); + RETURN_X(OID_802_11_RSSI_TRIGGER); + RETURN_X(OID_802_11_INFRASTRUCTURE_MODE); + RETURN_X(OID_802_11_FRAGMENTATION_THRESHOLD); + RETURN_X(OID_802_11_RTS_THRESHOLD); + RETURN_X(OID_802_11_NUMBER_OF_ANTENNAS); + RETURN_X(OID_802_11_RX_ANTENNA_SELECTED); + RETURN_X(OID_802_11_TX_ANTENNA_SELECTED); + RETURN_X(OID_802_11_SUPPORTED_RATES); + RETURN_X(OID_802_11_DESIRED_RATES); + RETURN_X(OID_802_11_CONFIGURATION); + RETURN_X(OID_802_11_STATISTICS); + RETURN_X(OID_802_11_ADD_WEP); + RETURN_X(OID_802_11_REMOVE_WEP); + RETURN_X(OID_802_11_DISASSOCIATE); + RETURN_X(OID_802_11_POWER_MODE); + RETURN_X(OID_802_11_BSSID_LIST); + RETURN_X(OID_802_11_AUTHENTICATION_MODE); + RETURN_X(OID_802_11_PRIVACY_FILTER); + RETURN_X(OID_802_11_BSSID_LIST_SCAN); + RETURN_X(OID_802_11_WEP_STATUS); + RETURN_X(OID_802_11_RELOAD_DEFAULTS); + + /* OID_GEN_MINIPORT_INFO constants */ + RETURN_X(NDIS_MINIPORT_BUS_MASTER); + RETURN_X(NDIS_MINIPORT_WDM_DRIVER); + RETURN_X(NDIS_MINIPORT_SG_LIST); + RETURN_X(NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY); + RETURN_X(NDIS_MINIPORT_INDICATES_PACKETS); + RETURN_X(NDIS_MINIPORT_IGNORE_PACKET_QUEUE); + RETURN_X(NDIS_MINIPORT_IGNORE_REQUEST_QUEUE); + RETURN_X(NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS); + RETURN_X(NDIS_MINIPORT_INTERMEDIATE_DRIVER); + RETURN_X(NDIS_MINIPORT_IS_NDIS_5); + RETURN_X(NDIS_MINIPORT_IS_CO); + RETURN_X(NDIS_MINIPORT_DESERIALIZE); + RETURN_X(NDIS_MINIPORT_REQUIRES_MEDIA_POLLING); + RETURN_X(NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE); + RETURN_X(NDIS_MINIPORT_NETBOOT_CARD); + RETURN_X(NDIS_MINIPORT_PM_SUPPORTED); + RETURN_X(NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE); + RETURN_X(NDIS_MINIPORT_USES_SAFE_BUFFER_APIS); + RETURN_X(NDIS_MINIPORT_HIDDEN); + RETURN_X(NDIS_MINIPORT_SWENUM); + RETURN_X(NDIS_MINIPORT_SURPRISE_REMOVE_OK); + RETURN_X(NDIS_MINIPORT_NO_HALT_ON_SUSPEND); + RETURN_X(NDIS_MINIPORT_HARDWARE_DEVICE); + RETURN_X(NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS); + RETURN_X(NDIS_MINIPORT_64BITS_DMA); + default: + return "<UNKNOWN>"; + } +#else + return "!DBG"; +#endif +} + + diff --git a/drivers/network/dd/e1000/debug.h b/drivers/network/dd/e1000/debug.h index b6ff2cf92e..481f60429c 100644 --- a/drivers/network/dd/e1000/debug.h +++ b/drivers/network/dd/e1000/debug.h @@ -62,3 +62,5 @@ extern ULONG DebugTraceLevel; } while (0) +const char* Oid2Str(IN NDIS_OID Oid); + diff --git a/drivers/network/dd/e1000/e1000hw.h b/drivers/network/dd/e1000/e1000hw.h index 57ac8fc2e8..9932974281 100644 --- a/drivers/network/dd/e1000/e1000hw.h +++ b/drivers/network/dd/e1000/e1000hw.h @@ -9,6 +9,18 @@ #define IEEE_802_ADDR_LENGTH 6 +#define HW_VENDOR_INTEL 0x8086 + +#define MAX_RESET_ATTEMPTS 10 + +#define MAX_PHY_REG_ADDRESS 0x1F +#define MAX_PHY_READ_ATTEMPTS 1800 + +#define MAX_EEPROM_READ_ATTEMPTS 10000 + + +#define MAXIMUM_MULTICAST_ADDRESSES 16 + /* Ethernet frame header */ typedef struct _ETH_HEADER { @@ -17,3 +29,91 @@ typedef struct _ETH_HEADER { USHORT PayloadType; } ETH_HEADER, *PETH_HEADER; + + + + +/* Registers */ +#define E1000_REG_CTRL 0x0000 /* Device Control Register, R/W */ +#define E1000_REG_STATUS 0x0008 /* Device Status Register, R */ +#define E1000_REG_EERD 0x0014 /* EEPROM Read Register, R/W */ +#define E1000_REG_MDIC 0x0020 /* MDI Control Register, R/W */ +#define E1000_REG_VET 0x0038 /* VLAN Ether Type, R/W */ +#define E1000_REG_ICR 0x00C0 /* Interrupt Cause Read, R/clr */ + +#define E1000_REG_IMS 0x00D0 /* Interrupt Mask Set/Read Register, R/W */ +#define E1000_REG_IMC 0x00D8 /* Interrupt Mask Clear, W */ +#define E1000_REG_RCTL 0x0100 /* Receive Control, R/W */ + +#define E1000_REG_RAL 0x5400 /* Receive Address Low, R/W */ +#define E1000_REG_RAH 0x5404 /* Receive Address High, R/W */ + + +/* E1000_REG_CTRL */ +#define E1000_CTRL_RST (1 << 26) /* Device Reset, Self clearing */ + + +/* E1000_REG_STATUS */ +#define E1000_STATUS_LU (1 << 0) /* Link Up Indication */ +#define E1000_STATUS_SPEEDSHIFT 6 /* Link speed setting */ +#define E1000_STATUS_SPEEDMASK (3 << E1000_STATUS_SPEEDSHIFT) + + +/* E1000_REG_EERD */ +#define E1000_EERD_START (1 << 0) /* Start Read*/ +#define E1000_EERD_DONE (1 << 4) /* Read Done */ +#define E1000_EERD_ADDR_SHIFT 8 +#define E1000_EERD_DATA_SHIFT 16 + + +/* E1000_REG_MDIC */ +#define E1000_MDIC_REGADD_SHIFT 16 /* PHY Register Address */ +#define E1000_MDIC_PHYADD_SHIFT 21 /* PHY Address (1=Gigabit, 2=PCIe) */ +#define E1000_MDIC_PHYADD_GIGABIT 1 +#define E1000_MDIC_OP_READ (2 << 26) /* Opcode */ +#define E1000_MDIC_R (1 << 28) /* Ready Bit */ +#define E1000_MDIC_E (1 << 30) /* Error */ + + +/* E1000_REG_IMS */ +#define E1000_IMS_LSC (1 << 2) /* Sets mask for Link Status Change */ + + +/* E1000_REG_RCTL */ +#define E1000_RCTL_EN (1 << 1) /* Receiver Enable */ +#define E1000_RCTL_SBP (1 << 2) /* Store Bad Packets */ +#define E1000_RCTL_UPE (1 << 3) /* Unicast Promiscuous Enabled */ +#define E1000_RCTL_MPE (1 << 4) /* Multicast Promiscuous Enabled */ +#define E1000_RCTL_BAM (1 << 15) /* Broadcast Accept Mode */ +#define E1000_RCTL_PMCF (1 << 23) /* Pass MAC Control Frames */ + +#define E1000_RCTL_FILTER_BITS (E1000_RCTL_SBP | E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_BAM | E1000_RCTL_PMCF) + +/* E1000_REG_RAH */ +#define E1000_RAH_AV (1 << 31) /* Address Valid */ + + + + +/* NVM */ +#define E1000_NVM_REG_CHECKSUM 0x03f +#define NVM_MAGIC_SUM 0xBABA + + + +/* PHY (Read with MDIC) */ + +#define E1000_PHY_STATUS 0x01 +#define E1000_PHY_SPECIFIC_STATUS 0x11 + + +/* E1000_PHY_STATUS */ +#define E1000_PS_LINK_STATUS (1 << 2) + + + +/* E1000_PHY_SPECIFIC_STATUS */ +#define E1000_PSS_SPEED_AND_DUPLEX (1 << 11) /* Speed and Duplex Resolved */ +#define E1000_PSS_SPEEDSHIFT 14 +#define E1000_PSS_SPEEDMASK (3 << E1000_PSS_SPEEDSHIFT) + diff --git a/drivers/network/dd/e1000/hardware.c b/drivers/network/dd/e1000/hardware.c index b238be0997..5308afadd5 100644 --- a/drivers/network/dd/e1000/hardware.c +++ b/drivers/network/dd/e1000/hardware.c @@ -9,13 +9,162 @@ #include <debug.h> + +static USHORT SupportedDevices[] = +{ + 0x100f, // Intel 82545EM (VMWare E1000) +}; + + +static ULONG E1000WriteFlush(IN PE1000_ADAPTER Adapter) +{ + volatile ULONG Value; + + NdisReadRegisterUlong(Adapter->IoBase + E1000_REG_STATUS, &Value); + return Value; +} + +static VOID E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value) +{ + NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); +} + +static VOID E1000ReadUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, OUT PULONG Value) +{ + NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); +} + +static VOID E1000WriteIoUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value) +{ + NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address); + E1000WriteFlush(Adapter); + NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value); +} + +static BOOLEAN E1000ReadMdic(IN PE1000_ADAPTER Adapter, IN ULONG Address, USHORT *Result) +{ + ULONG ResultAddress; + ULONG Mdic; + UINT n; + + if (Address > MAX_PHY_REG_ADDRESS) + { + NDIS_DbgPrint(MIN_TRACE, ("PHY Address %d is invalid\n", Address)); + return 1; + } + + Mdic = (Address << E1000_MDIC_REGADD_SHIFT); + Mdic |= (E1000_MDIC_PHYADD_GIGABIT << E1000_MDIC_PHYADD_SHIFT); + Mdic |= E1000_MDIC_OP_READ; + + E1000WriteUlong(Adapter, E1000_REG_MDIC, Mdic); + + for (n = 0; n < MAX_PHY_READ_ATTEMPTS; n++) + { + NdisStallExecution(50); + E1000ReadUlong(Adapter, E1000_REG_MDIC, &Mdic); + if (Mdic & E1000_MDIC_R) + break; + } + if (!(Mdic & E1000_MDIC_R)) + { + NDIS_DbgPrint(MIN_TRACE, ("MDI Read incomplete\n")); + return FALSE; + } + if (Mdic & E1000_MDIC_E) + { + NDIS_DbgPrint(MIN_TRACE, ("MDI Read error\n")); + return FALSE; + } + + ResultAddress = (Mdic >> E1000_MDIC_REGADD_SHIFT) & MAX_PHY_REG_ADDRESS; + + if (ResultAddress!= Address) + { + /* Add locking? */ + NDIS_DbgPrint(MIN_TRACE, ("MDI Read got wrong address (%d instead of %d)\n", + ResultAddress, Address)); + return FALSE; + } + *Result = (USHORT) Mdic; + return TRUE; +} + + +static BOOLEAN E1000ReadEeprom(IN PE1000_ADAPTER Adapter, IN UCHAR Address, USHORT *Result) +{ + UINT Value; + UINT n; + + E1000WriteUlong(Adapter, E1000_REG_EERD, E1000_EERD_START | ((UINT)Address << E1000_EERD_ADDR_SHIFT)); + + for (n = 0; n < MAX_EEPROM_READ_ATTEMPTS; ++n) + { + NdisStallExecution(5); + + E1000ReadUlong(Adapter, E1000_REG_EERD, &Value); + + if (Value & E1000_EERD_DONE) + break; + } + if (!(Value & E1000_EERD_DONE)) + { + NDIS_DbgPrint(MIN_TRACE, ("EEPROM Read incomplete\n")); + return FALSE; + } + *Result = (USHORT)(Value >> E1000_EERD_DATA_SHIFT); + return TRUE; +} + +BOOLEAN E1000ValidateNvmChecksum(IN PE1000_ADAPTER Adapter) +{ + USHORT Checksum = 0, Data; + UINT n; + + /* 5.6.35 Checksum Word Calculation (Word 3Fh) */ + for (n = 0; n <= E1000_NVM_REG_CHECKSUM; n++) + { + if (!E1000ReadEeprom(Adapter, n, &Data)) + { + return FALSE; + } + Checksum += Data; + } + + if (Checksum != NVM_MAGIC_SUM) + { + NDIS_DbgPrint(MIN_TRACE, ("EEPROM has an invalid checksum of 0x%x\n", (ULONG)Checksum)); + return FALSE; + } + + return TRUE; +} + + BOOLEAN NTAPI NICRecognizeHardware( IN PE1000_ADAPTER Adapter) { + UINT n; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + if (Adapter->VendorID != HW_VENDOR_INTEL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unknown vendor: 0x%x\n", Adapter->VendorID)); + return FALSE; + } + + for (n = 0; n < ARRAYSIZE(SupportedDevices); ++n) + { + if (SupportedDevices[n] == Adapter->DeviceID) + { + return TRUE; + } + } + + NDIS_DbgPrint(MIN_TRACE, ("Unknown device: 0x%x\n", Adapter->DeviceID)); + return FALSE; } @@ -25,19 +174,92 @@ NICInitializeAdapterResources( IN PE1000_ADAPTER Adapter, IN PNDIS_RESOURCE_LIST ResourceList) { + UINT n; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + for (n = 0; n < ResourceList->Count; n++) + { + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor = ResourceList->PartialDescriptors + n; + + switch (ResourceDescriptor->Type) + { + case CmResourceTypePort: + ASSERT(Adapter->IoPortAddress == 0); + ASSERT(ResourceDescriptor->u.Port.Start.HighPart == 0); + + Adapter->IoPortAddress = ResourceDescriptor->u.Port.Start.LowPart; + Adapter->IoPortLength = ResourceDescriptor->u.Port.Length; + + NDIS_DbgPrint(MID_TRACE, ("I/O port range is %p to %p\n", + Adapter->IoPortAddress, + Adapter->IoPortAddress + Adapter->IoPortLength)); + break; + case CmResourceTypeInterrupt: + ASSERT(Adapter->InterruptVector == 0); + ASSERT(Adapter->InterruptLevel == 0); + + Adapter->InterruptVector = ResourceDescriptor->u.Interrupt.Vector; + Adapter->InterruptLevel = ResourceDescriptor->u.Interrupt.Level; + Adapter->InterruptShared = (ResourceDescriptor->ShareDisposition == CmResourceShareShared); + Adapter->InterruptFlags = ResourceDescriptor->Flags; + + NDIS_DbgPrint(MID_TRACE, ("IRQ vector is %d\n", Adapter->InterruptVector)); + break; + case CmResourceTypeMemory: + /* Internal registers and memories (including PHY) */ + if (ResourceDescriptor->u.Memory.Length == (128 * 1024)) + { + ASSERT(Adapter->IoAddress.LowPart == 0); + ASSERT(ResourceDescriptor->u.Port.Start.HighPart == 0); + + + Adapter->IoAddress.QuadPart = ResourceDescriptor->u.Memory.Start.QuadPart; + Adapter->IoLength = ResourceDescriptor->u.Memory.Length; + NDIS_DbgPrint(MID_TRACE, ("Memory range is %I64x to %I64x\n", + Adapter->IoAddress.QuadPart, + Adapter->IoAddress.QuadPart + Adapter->IoLength)); + } + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unrecognized resource type: 0x%x\n", ResourceDescriptor->Type)); + break; + } + } + + if (Adapter->IoAddress.QuadPart == 0 || Adapter->IoPortAddress == 0 || Adapter->InterruptVector == 0) + { + NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n")); + return NDIS_STATUS_RESOURCES; + } + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS NTAPI -NICAllocateResources( +NICAllocateIoResources( IN PE1000_ADAPTER Adapter) { + NDIS_STATUS Status; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + Status = NdisMRegisterIoPortRange((PVOID*)&Adapter->IoPort, + Adapter->AdapterHandle, + Adapter->IoPortAddress, + Adapter->IoPortLength); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to register IO port range (0x%x)\n", Status)); + return NDIS_STATUS_RESOURCES; + } + + Status = NdisMMapIoSpace((PVOID*)&Adapter->IoBase, + Adapter->AdapterHandle, + Adapter->IoAddress, + Adapter->IoLength); + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS @@ -45,9 +267,24 @@ NTAPI NICRegisterInterrupts( IN PE1000_ADAPTER Adapter) { + NDIS_STATUS Status; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + Status = NdisMRegisterInterrupt(&Adapter->Interrupt, + Adapter->AdapterHandle, + Adapter->InterruptVector, + Adapter->InterruptLevel, + TRUE, // We always want ISR calls + Adapter->InterruptShared, + (Adapter->InterruptFlags & CM_RESOURCE_INTERRUPT_LATCHED) ? + NdisInterruptLatched : NdisInterruptLevelSensitive); + + if (Status == NDIS_STATUS_SUCCESS) + { + Adapter->InterruptRegistered = TRUE; + } + + return Status; } NDIS_STATUS @@ -57,7 +294,13 @@ NICUnregisterInterrupts( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + if (Adapter->InterruptRegistered) + { + NdisMDeregisterInterrupt(&Adapter->Interrupt); + Adapter->InterruptRegistered = FALSE; + } + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS @@ -67,7 +310,21 @@ NICReleaseIoResources( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + if (Adapter->IoPort) + { + NdisMDeregisterIoPortRange(Adapter->AdapterHandle, + Adapter->IoPortAddress, + Adapter->IoPortLength, + Adapter->IoPort); + } + + if (Adapter->IoBase) + { + NdisMUnmapIoSpace(Adapter->AdapterHandle, Adapter->IoBase, Adapter->IoLength); + } + + + return NDIS_STATUS_SUCCESS; } @@ -76,18 +333,61 @@ NTAPI NICPowerOn( IN PE1000_ADAPTER Adapter) { + NDIS_STATUS Status; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + Status = NICSoftReset(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + return Status; + } + + if (!E1000ValidateNvmChecksum(Adapter)) + { + return NDIS_STATUS_INVALID_DATA; + } + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS NTAPI NICSoftReset( - IN PE1000_ADAPTER adapter) + IN PE1000_ADAPTER Adapter) { + ULONG Value, ResetAttempts; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + //em_get_hw_control(adapter); + + NICDisableInterrupts(Adapter); + E1000WriteUlong(Adapter, E1000_REG_RCTL, 0); + E1000ReadUlong(Adapter, E1000_REG_CTRL, &Value); + /* Write this using IO port, some devices cannot ack this otherwise */ + E1000WriteIoUlong(Adapter, E1000_REG_CTRL, Value | E1000_CTRL_RST); + + + for (ResetAttempts = 0; ResetAttempts < MAX_RESET_ATTEMPTS; ResetAttempts++) + { + NdisStallExecution(100); + E1000ReadUlong(Adapter, E1000_REG_CTRL, &Value); + + if (!(Value & E1000_CTRL_RST)) + { + NDIS_DbgPrint(MAX_TRACE, ("Device is back (%u)\n", ResetAttempts)); + + NICDisableInterrupts(Adapter); + /* Clear out interrupts */ + E1000ReadUlong(Adapter, E1000_REG_ICR, &Value); + + //NdisWriteRegisterUlong(Adapter->IoBase + E1000_REG_WUFC, 0); + //NdisWriteRegisterUlong(Adapter->IoBase + E1000_REG_VET, E1000_VET_VLAN); + + return NDIS_STATUS_SUCCESS; + } + } + + NDIS_DbgPrint(MIN_TRACE, ("Device did not recover\n")); return NDIS_STATUS_FAILURE; } @@ -98,7 +398,7 @@ NICEnableTxRx( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + return NDIS_STATUS_SUCCESS; } NDIS_STATUS @@ -108,7 +408,7 @@ NICDisableTxRx( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + return NDIS_STATUS_SUCCESS; } NDIS_STATUS @@ -117,9 +417,97 @@ NICGetPermanentMacAddress( IN PE1000_ADAPTER Adapter, OUT PUCHAR MacAddress) { + USHORT AddrWord; + UINT n; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + /* Should we read from RAL/RAH first? */ + for (n = 0; n < (IEEE_802_ADDR_LENGTH / 2); ++n) + { + if (!E1000ReadEeprom(Adapter, (UCHAR)n, &AddrWord)) + return NDIS_STATUS_FAILURE; + Adapter->PermanentMacAddress[n * 2 + 0] = AddrWord & 0xff; + Adapter->PermanentMacAddress[n * 2 + 1] = (AddrWord >> 8) & 0xff; + } + + NDIS_DbgPrint(MIN_TRACE, ("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + Adapter->PermanentMacAddress[0], + Adapter->PermanentMacAddress[1], + Adapter->PermanentMacAddress[2], + Adapter->PermanentMacAddress[3], + Adapter->PermanentMacAddress[4], + Adapter->PermanentMacAddress[5])); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICUpdateMulticastList( + IN PE1000_ADAPTER Adapter) +{ + UINT n; + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + for (n = 0; n < MAXIMUM_MULTICAST_ADDRESSES; ++n) + { + ULONG Ral = *(ULONG *)Adapter->MulticastList[n].MacAddress; + ULONG Rah = *(USHORT *)&Adapter->MulticastList[n].MacAddress[4]; + + if (Rah || Ral) + { + Rah |= E1000_RAH_AV; + + E1000WriteUlong(Adapter, E1000_REG_RAL + (8*n), Ral); + E1000WriteUlong(Adapter, E1000_REG_RAH + (8*n), Rah); + } + else + { + E1000WriteUlong(Adapter, E1000_REG_RAH + (8*n), 0); + E1000WriteUlong(Adapter, E1000_REG_RAL + (8*n), 0); + } + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICApplyPacketFilter( + IN PE1000_ADAPTER Adapter) +{ + ULONG FilterMask = 0; + + E1000ReadUlong(Adapter, E1000_REG_RCTL, &FilterMask); + + FilterMask &= ~E1000_RCTL_FILTER_BITS; + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) + { + /* Multicast Promiscuous Enabled */ + FilterMask |= E1000_RCTL_MPE; + } + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) + { + /* Unicast Promiscuous Enabled */ + FilterMask |= E1000_RCTL_UPE; + /* Multicast Promiscuous Enabled */ + FilterMask |= E1000_RCTL_MPE; + } + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_MAC_FRAME) + { + /* Pass MAC Control Frames */ + FilterMask |= E1000_RCTL_PMCF; + } + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_BROADCAST) + { + /* Broadcast Accept Mode */ + FilterMask |= E1000_RCTL_BAM; + } + + E1000WriteUlong(Adapter, E1000_REG_RCTL, FilterMask); + + return NDIS_STATUS_SUCCESS; } NDIS_STATUS @@ -129,7 +517,8 @@ NICApplyInterruptMask( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask); + return NDIS_STATUS_SUCCESS; } NDIS_STATUS @@ -139,7 +528,8 @@ NICDisableInterrupts( { NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; + E1000WriteUlong(Adapter, E1000_REG_IMC, ~0); + return NDIS_STATUS_SUCCESS; } USHORT @@ -166,17 +556,48 @@ NTAPI NICUpdateLinkStatus( IN PE1000_ADAPTER Adapter) { - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); -} + ULONG SpeedIndex; + USHORT PhyStatus; + static ULONG SpeedValues[] = { 10, 100, 1000, 1000 }; -NDIS_STATUS -NTAPI -NICApplyPacketFilter( - IN PE1000_ADAPTER Adapter) -{ NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - return NDIS_STATUS_FAILURE; +#if 0 + /* This does not work */ + E1000ReadUlong(Adapter, E1000_REG_STATUS, &DeviceStatus); + E1000ReadUlong(Adapter, E1000_REG_STATUS, &DeviceStatus); + Adapter->MediaState = (DeviceStatus & E1000_STATUS_LU) ? NdisMediaStateConnected : NdisMediaStateDisconnected; + SpeedIndex = (DeviceStatus & E1000_STATUS_SPEEDMASK) >> E1000_STATUS_SPEEDSHIFT; + Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex]; +#else + /* Link bit can be sticky on some boards, read it twice */ + if (!E1000ReadMdic(Adapter, E1000_PHY_STATUS, &PhyStatus)) + NdisStallExecution(100); + + Adapter->MediaState = NdisMediaStateDisconnected; + Adapter->LinkSpeedMbps = 0; + + if (!E1000ReadMdic(Adapter, E1000_PHY_STATUS, &PhyStatus)) + return; + + if (!(PhyStatus & E1000_PS_LINK_STATUS)) + return; + + Adapter->MediaState = NdisMediaStateConnected; + + if (E1000ReadMdic(Adapter, E1000_PHY_SPECIFIC_STATUS, &PhyStatus)) + { + if (PhyStatus & E1000_PSS_SPEED_AND_DUPLEX) + { + SpeedIndex = (PhyStatus & E1000_PSS_SPEEDMASK) >> E1000_PSS_SPEEDSHIFT; + Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex]; + } + else + { + NDIS_DbgPrint(MIN_TRACE, ("Speed and duplex not yet resolved, retry?.\n")); + } + } +#endif } NDIS_STATUS diff --git a/drivers/network/dd/e1000/info.c b/drivers/network/dd/e1000/info.c index 84817956e4..2c98034fe6 100644 --- a/drivers/network/dd/e1000/info.c +++ b/drivers/network/dd/e1000/info.c @@ -13,11 +13,13 @@ static ULONG SupportedOidList[] = { OID_GEN_SUPPORTED_LIST, + OID_GEN_CURRENT_PACKET_FILTER, OID_GEN_HARDWARE_STATUS, OID_GEN_MEDIA_SUPPORTED, OID_GEN_MEDIA_IN_USE, OID_GEN_MAXIMUM_LOOKAHEAD, OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_MAXIMUM_SEND_PACKETS, OID_GEN_LINK_SPEED, OID_GEN_TRANSMIT_BUFFER_SPACE, OID_GEN_RECEIVE_BUFFER_SPACE, @@ -27,14 +29,23 @@ static ULONG SupportedOidList[] = OID_GEN_VENDOR_DESCRIPTION, OID_GEN_VENDOR_DRIVER_VERSION, OID_GEN_CURRENT_LOOKAHEAD, + OID_802_3_MULTICAST_LIST, OID_GEN_DRIVER_VERSION, OID_GEN_MAXIMUM_TOTAL_SIZE, OID_GEN_MAC_OPTIONS, OID_GEN_MEDIA_CONNECT_STATUS, OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS, + OID_802_3_MAXIMUM_LIST_SIZE, + /* Statistics */ + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, }; + NDIS_STATUS NTAPI MiniportQueryInformation( @@ -64,6 +75,10 @@ MiniportQueryInformation( copyLength = sizeof(SupportedOidList); break; + case OID_GEN_CURRENT_PACKET_FILTER: + genericUlong = Adapter->PacketFilter; + break; + case OID_GEN_HARDWARE_STATUS: UNIMPLEMENTED_DBGBREAK(); genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME @@ -86,8 +101,12 @@ MiniportQueryInformation( genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); break; + case OID_802_3_MAXIMUM_LIST_SIZE: + genericUlong = MAXIMUM_MULTICAST_ADDRESSES; + break; + case OID_GEN_LINK_SPEED: - genericUlong = Adapter->LinkSpeedMbps * 1000; + genericUlong = Adapter->LinkSpeedMbps * 10000; break; case OID_GEN_TRANSMIT_BUFFER_SPACE: @@ -131,6 +150,10 @@ MiniportQueryInformation( genericUlong = MAXIMUM_FRAME_SIZE; break; + case OID_GEN_MAXIMUM_SEND_PACKETS: + genericUlong = 1; + break; + case OID_GEN_MAC_OPTIONS: genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | @@ -144,7 +167,7 @@ MiniportQueryInformation( case OID_802_3_CURRENT_ADDRESS: - copySource = Adapter->CurrentMacAddress; + copySource = Adapter->MulticastList[0].MacAddress; copyLength = IEEE_802_ADDR_LENGTH; break; @@ -153,8 +176,24 @@ MiniportQueryInformation( copyLength = IEEE_802_ADDR_LENGTH; break; + case OID_GEN_XMIT_OK: + genericUlong = 0; + break; + case OID_GEN_RCV_OK: + genericUlong = 0; + break; + case OID_GEN_XMIT_ERROR: + genericUlong = 0; + break; + case OID_GEN_RCV_ERROR: + genericUlong = 0; + break; + case OID_GEN_RCV_NO_BUFFER: + genericUlong = 0; + break; + default: - NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x\n", Oid)); + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid))); status = NDIS_STATUS_NOT_SUPPORTED; break; } @@ -181,9 +220,12 @@ MiniportQueryInformation( } NdisReleaseSpinLock(&Adapter->Lock); - - NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x: Completed with status 0x%x (%d, %d)\n", - Oid, status, *BytesWritten, *BytesNeeded)); + /* XMIT_ERROR and RCV_ERROR are really noisy, so do not log those. */ + if (Oid != OID_GEN_XMIT_ERROR && Oid != OID_GEN_RCV_ERROR) + { + NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x(%s): Completed with status 0x%x (%d, %d)\n", + Oid, Oid2Str(Oid), status, *BytesWritten, *BytesNeeded)); + } return status; } @@ -208,6 +250,42 @@ MiniportSetInformation( switch (Oid) { + case OID_GEN_CURRENT_PACKET_FILTER: + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG); + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); + + if (genericUlong & + (NDIS_PACKET_TYPE_SOURCE_ROUTING | + NDIS_PACKET_TYPE_SMT | + NDIS_PACKET_TYPE_ALL_LOCAL | + NDIS_PACKET_TYPE_GROUP | + NDIS_PACKET_TYPE_ALL_FUNCTIONAL | + NDIS_PACKET_TYPE_FUNCTIONAL)) + { + *BytesRead = sizeof(ULONG); + *BytesNeeded = sizeof(ULONG); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + Adapter->PacketFilter = genericUlong; + + status = NICApplyPacketFilter(Adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to apply new packet filter (0x%x)\n", status)); + break; + } + + break; + case OID_GEN_CURRENT_LOOKAHEAD: if (InformationBufferLength < sizeof(ULONG)) { @@ -230,8 +308,29 @@ MiniportSetInformation( break; + case OID_802_3_MULTICAST_LIST: + if (InformationBufferLength % IEEE_802_ADDR_LENGTH) + { + *BytesRead = 0; + *BytesNeeded = InformationBufferLength + (InformationBufferLength % IEEE_802_ADDR_LENGTH); + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + if (InformationBufferLength / 6 > MAXIMUM_MULTICAST_ADDRESSES) + { + *BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH; + *BytesRead = 0; + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength); + NICUpdateMulticastList(Adapter); + break; + default: - NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x\n", Oid)); + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid))); status = NDIS_STATUS_NOT_SUPPORTED; *BytesRead = 0; *BytesNeeded = 0; @@ -248,3 +347,4 @@ MiniportSetInformation( return status; } + diff --git a/drivers/network/dd/e1000/ndis.c b/drivers/network/dd/e1000/ndis.c index b02f397bd9..50b5c44e93 100644 --- a/drivers/network/dd/e1000/ndis.c +++ b/drivers/network/dd/e1000/ndis.c @@ -224,7 +224,9 @@ MiniportInitialize( goto Cleanup; } - RtlCopyMemory(Adapter->CurrentMacAddress, Adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH); + RtlCopyMemory(Adapter->MulticastList[0].MacAddress, Adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH); + + NICUpdateMulticastList(Adapter); /* Update link state and speed */ NICUpdateLinkStatus(Adapter); @@ -238,7 +240,7 @@ MiniportInitialize( } /* Enable interrupts on the NIC */ - //Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; + Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; Status = NICApplyInterruptMask(Adapter); if (Status != NDIS_STATUS_SUCCESS) { diff --git a/drivers/network/dd/e1000/nic.h b/drivers/network/dd/e1000/nic.h index ea6922ed17..9586b615f6 100644 --- a/drivers/network/dd/e1000/nic.h +++ b/drivers/network/dd/e1000/nic.h @@ -21,6 +21,8 @@ #define DRIVER_VERSION 1 +#define DEFAULT_INTERRUPT_MASK (E1000_IMS_LSC) + typedef struct _E1000_ADAPTER { NDIS_SPIN_LOCK Lock; @@ -31,10 +33,34 @@ typedef struct _E1000_ADAPTER USHORT SubsystemVendorID; UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH]; - UCHAR CurrentMacAddress[IEEE_802_ADDR_LENGTH]; + struct { + UCHAR MacAddress[IEEE_802_ADDR_LENGTH]; + } MulticastList[MAXIMUM_MULTICAST_ADDRESSES]; ULONG LinkSpeedMbps; ULONG MediaState; + ULONG PacketFilter; + + /* Io Port */ + ULONG IoPortAddress; + ULONG IoPortLength; + volatile PUCHAR IoPort; + + /* NIC Memory */ + NDIS_PHYSICAL_ADDRESS IoAddress; + ULONG IoLength; + volatile PUCHAR IoBase; + + /* Interrupt */ + ULONG InterruptVector; + ULONG InterruptLevel; + BOOLEAN InterruptShared; + ULONG InterruptFlags; + + NDIS_MINIPORT_INTERRUPT Interrupt; + BOOLEAN InterruptRegistered; + + ULONG InterruptMask; ULONG InterruptPending; } E1000_ADAPTER, *PE1000_ADAPTER; @@ -53,7 +79,7 @@ NICInitializeAdapterResources( NDIS_STATUS NTAPI -NICAllocateResources( +NICAllocateIoResources( IN PE1000_ADAPTER Adapter); NDIS_STATUS @@ -97,6 +123,11 @@ NICGetPermanentMacAddress( IN PE1000_ADAPTER Adapter, OUT PUCHAR MacAddress); +NDIS_STATUS +NTAPI +NICUpdateMulticastList( + IN PE1000_ADAPTER Adapter); + NDIS_STATUS NTAPI NICApplyPacketFilter(
5 years, 10 months
1
0
0
0
[reactos] 01/06: [E1000] Create an initial driver skeleton Based on the rtl8139 driver written by Cameron Gutman
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4561998a45b928461eacf…
commit 4561998a45b928461eacf323ec23d15dd19e6f0e Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sat May 19 00:23:45 2018 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 19:48:54 2019 +0100 [E1000] Create an initial driver skeleton Based on the rtl8139 driver written by Cameron Gutman CORE-14675 --- drivers/network/dd/CMakeLists.txt | 1 + drivers/network/dd/e1000/CMakeLists.txt | 20 ++ drivers/network/dd/e1000/debug.h | 64 +++++++ drivers/network/dd/e1000/e1000.rc | 5 + drivers/network/dd/e1000/e1000hw.h | 19 ++ drivers/network/dd/e1000/hardware.c | 193 +++++++++++++++++++ drivers/network/dd/e1000/info.c | 250 +++++++++++++++++++++++++ drivers/network/dd/e1000/interrupt.c | 49 +++++ drivers/network/dd/e1000/ndis.c | 315 ++++++++++++++++++++++++++++++++ drivers/network/dd/e1000/nic.h | 171 +++++++++++++++++ media/inf/CMakeLists.txt | 1 + media/inf/nete1000.inf | 50 +++++ 12 files changed, 1138 insertions(+) diff --git a/drivers/network/dd/CMakeLists.txt b/drivers/network/dd/CMakeLists.txt index ffa9635eca..89b96df489 100644 --- a/drivers/network/dd/CMakeLists.txt +++ b/drivers/network/dd/CMakeLists.txt @@ -1,4 +1,5 @@ +add_subdirectory(e1000) add_subdirectory(ne2000) add_subdirectory(pcnet) add_subdirectory(rtl8139) diff --git a/drivers/network/dd/e1000/CMakeLists.txt b/drivers/network/dd/e1000/CMakeLists.txt new file mode 100644 index 0000000000..eeee376c2e --- /dev/null +++ b/drivers/network/dd/e1000/CMakeLists.txt @@ -0,0 +1,20 @@ + +add_definitions( + -DNDIS50_MINIPORT + -DNDIS_MINIPORT_DRIVER + -DNDIS_LEGACY_MINIPORT) + +list(APPEND SOURCE + ndis.c + hardware.c + info.c + interrupt.c + nic.h + e1000hw.h + debug.h) + +add_library(e1000 SHARED ${SOURCE} e1000.rc) +add_pch(e1000 nic.h SOURCE) +set_module_type(e1000 kernelmodedriver) +add_importlibs(e1000 ndis ntoskrnl hal) +add_cd_file(TARGET e1000 DESTINATION reactos/system32/drivers FOR all) diff --git a/drivers/network/dd/e1000/debug.h b/drivers/network/dd/e1000/debug.h new file mode 100644 index 0000000000..b6ff2cf92e --- /dev/null +++ b/drivers/network/dd/e1000/debug.h @@ -0,0 +1,64 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Intel PRO/1000 Driver + * FILE: include/debug.h + * PURPOSE: Debugging support macros + * DEFINES: DBG - Enable debug output + * NASSERT - Disable assertions + */ + +#pragma once + +#define NORMAL_MASK 0x000000FF +#define SPECIAL_MASK 0xFFFFFF00 +#define MIN_TRACE 0x00000001 +#define MID_TRACE 0x00000002 +#define MAX_TRACE 0x00000003 + +#define DEBUG_MEMORY 0x00000100 +#define DEBUG_ULTRA 0xFFFFFFFF + +#if DBG + +extern ULONG DebugTraceLevel; + + +#define NDIS_DbgPrint(_t_, _x_) \ + if ((_t_ > NORMAL_MASK) \ + ? (DebugTraceLevel & _t_) > NORMAL_MASK \ + : (DebugTraceLevel & NORMAL_MASK) >= _t_) { \ + DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \ + DbgPrint _x_ ; \ + } + + +#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x)) +#define ASSERT_IRQL_EQUAL(x) ASSERT(KeGetCurrentIrql() == (x)) + +#else /* DBG */ + +#define NDIS_DbgPrint(_t_, _x_) + +#define ASSERT_IRQL(x) +#define ASSERT_IRQL_EQUAL(x) +/* #define ASSERT(x) */ /* ndis.h */ + +#endif /* DBG */ + + +#define assert(x) ASSERT(x) +#define assert_irql(x) ASSERT_IRQL(x) + + +#define UNIMPLEMENTED \ + NDIS_DbgPrint(MIN_TRACE, ("UNIMPLEMENTED.\n")); + + +#define UNIMPLEMENTED_DBGBREAK(...) \ + do { \ + NDIS_DbgPrint(MIN_TRACE, ("UNIMPLEMENTED.\n")); \ + DbgPrint("" __VA_ARGS__); \ + DbgBreakPoint(); \ + } while (0) + + diff --git a/drivers/network/dd/e1000/e1000.rc b/drivers/network/dd/e1000/e1000.rc new file mode 100644 index 0000000000..88019a54a0 --- /dev/null +++ b/drivers/network/dd/e1000/e1000.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Intel PRO/1000 Driver" +#define REACTOS_STR_INTERNAL_NAME "e1000" +#define REACTOS_STR_ORIGINAL_FILENAME "e1000.sys" +#include <reactos/version.rc> diff --git a/drivers/network/dd/e1000/e1000hw.h b/drivers/network/dd/e1000/e1000hw.h new file mode 100644 index 0000000000..57ac8fc2e8 --- /dev/null +++ b/drivers/network/dd/e1000/e1000hw.h @@ -0,0 +1,19 @@ +/* + * PROJECT: ReactOS Intel PRO/1000 Driver + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Intel PRO/1000 driver definitions + * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#pragma once + +#define IEEE_802_ADDR_LENGTH 6 + + +/* Ethernet frame header */ +typedef struct _ETH_HEADER { + UCHAR Destination[IEEE_802_ADDR_LENGTH]; + UCHAR Source[IEEE_802_ADDR_LENGTH]; + USHORT PayloadType; +} ETH_HEADER, *PETH_HEADER; + diff --git a/drivers/network/dd/e1000/hardware.c b/drivers/network/dd/e1000/hardware.c new file mode 100644 index 0000000000..b238be0997 --- /dev/null +++ b/drivers/network/dd/e1000/hardware.c @@ -0,0 +1,193 @@ +/* + * PROJECT: ReactOS Intel PRO/1000 Driver + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Hardware specific functions + * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include "nic.h" + +#include <debug.h> + +BOOLEAN +NTAPI +NICRecognizeHardware( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return FALSE; +} + +NDIS_STATUS +NTAPI +NICInitializeAdapterResources( + IN PE1000_ADAPTER Adapter, + IN PNDIS_RESOURCE_LIST ResourceList) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICAllocateResources( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICRegisterInterrupts( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICUnregisterInterrupts( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICReleaseIoResources( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + + +NDIS_STATUS +NTAPI +NICPowerOn( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICSoftReset( + IN PE1000_ADAPTER adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICEnableTxRx( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICDisableTxRx( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress( + IN PE1000_ADAPTER Adapter, + OUT PUCHAR MacAddress) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICApplyInterruptMask( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICDisableInterrupts( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +USHORT +NTAPI +NICInterruptRecognized( + IN PE1000_ADAPTER Adapter, + OUT PBOOLEAN InterruptRecognized) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return 0; +} + +VOID +NTAPI +NICAcknowledgeInterrupts( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); +} + +VOID +NTAPI +NICUpdateLinkStatus( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); +} + +NDIS_STATUS +NTAPI +NICApplyPacketFilter( + IN PE1000_ADAPTER Adapter) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICTransmitPacket( + IN PE1000_ADAPTER Adapter, + IN UCHAR TxDesc, + IN ULONG PhysicalAddress, + IN ULONG Length) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} diff --git a/drivers/network/dd/e1000/info.c b/drivers/network/dd/e1000/info.c new file mode 100644 index 0000000000..84817956e4 --- /dev/null +++ b/drivers/network/dd/e1000/info.c @@ -0,0 +1,250 @@ +/* + * PROJECT: ReactOS Intel PRO/1000 Driver + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Miniport information callbacks + * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman(a)reactos.org) + * Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include "nic.h" + +#include <debug.h> + +static ULONG SupportedOidList[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BUFFER_SPACE, + OID_GEN_RECEIVE_BUFFER_SPACE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_DRIVER_VERSION, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_MAC_OPTIONS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, +}; + +NDIS_STATUS +NTAPI +MiniportQueryInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded) +{ + PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; + ULONG genericUlong; + ULONG copyLength; + PVOID copySource; + NDIS_STATUS status; + + status = NDIS_STATUS_SUCCESS; + copySource = &genericUlong; + copyLength = sizeof(ULONG); + + NdisAcquireSpinLock(&Adapter->Lock); + + switch (Oid) + { + case OID_GEN_SUPPORTED_LIST: + copySource = (PVOID)&SupportedOidList; + copyLength = sizeof(SupportedOidList); + break; + + case OID_GEN_HARDWARE_STATUS: + UNIMPLEMENTED_DBGBREAK(); + genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + { + static const NDIS_MEDIUM medium = NdisMedium802_3; + copySource = (PVOID)&medium; + copyLength = sizeof(medium); + break; + } + + case OID_GEN_RECEIVE_BLOCK_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_CURRENT_LOOKAHEAD: + case OID_GEN_MAXIMUM_LOOKAHEAD: + case OID_GEN_MAXIMUM_FRAME_SIZE: + genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); + break; + + case OID_GEN_LINK_SPEED: + genericUlong = Adapter->LinkSpeedMbps * 1000; + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + genericUlong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_RECEIVE_BUFFER_SPACE: + genericUlong = RECEIVE_BUFFER_SIZE; + break; + + case OID_GEN_VENDOR_ID: + /* The 3 bytes of the MAC address is the vendor ID */ + genericUlong = 0; + genericUlong |= (Adapter->PermanentMacAddress[0] << 16); + genericUlong |= (Adapter->PermanentMacAddress[1] << 8); + genericUlong |= (Adapter->PermanentMacAddress[2] & 0xFF); + break; + + case OID_GEN_VENDOR_DESCRIPTION: + { + static UCHAR vendorDesc[] = "ReactOS Team"; + copySource = vendorDesc; + copyLength = sizeof(vendorDesc); + break; + } + + case OID_GEN_VENDOR_DRIVER_VERSION: + genericUlong = DRIVER_VERSION; + break; + + case OID_GEN_DRIVER_VERSION: + { + static const USHORT driverVersion = + (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; + copySource = (PVOID)&driverVersion; + copyLength = sizeof(driverVersion); + break; + } + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + genericUlong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_MAC_OPTIONS: + genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | + NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | + NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | + NDIS_MAC_OPTION_NO_LOOPBACK; + break; + + case OID_GEN_MEDIA_CONNECT_STATUS: + genericUlong = Adapter->MediaState; + break; + + + case OID_802_3_CURRENT_ADDRESS: + copySource = Adapter->CurrentMacAddress; + copyLength = IEEE_802_ADDR_LENGTH; + break; + + case OID_802_3_PERMANENT_ADDRESS: + copySource = Adapter->PermanentMacAddress; + copyLength = IEEE_802_ADDR_LENGTH; + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x\n", Oid)); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + if (status == NDIS_STATUS_SUCCESS) + { + if (copyLength > InformationBufferLength) + { + *BytesNeeded = copyLength; + *BytesWritten = 0; + status = NDIS_STATUS_INVALID_LENGTH; + } + else + { + NdisMoveMemory(InformationBuffer, copySource, copyLength); + *BytesWritten = copyLength; + *BytesNeeded = copyLength; + } + } + else + { + *BytesWritten = 0; + *BytesNeeded = 0; + } + + NdisReleaseSpinLock(&Adapter->Lock); + + NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x: Completed with status 0x%x (%d, %d)\n", + Oid, status, *BytesWritten, *BytesNeeded)); + + return status; +} + +NDIS_STATUS +NTAPI +MiniportSetInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded) +{ + PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; + ULONG genericUlong; + NDIS_STATUS status; + + status = NDIS_STATUS_SUCCESS; + + NdisAcquireSpinLock(&Adapter->Lock); + + switch (Oid) + { + case OID_GEN_CURRENT_LOOKAHEAD: + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG); + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); + + if (genericUlong > MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER)) + { + status = NDIS_STATUS_INVALID_DATA; + } + else + { + // Ignore this... + } + + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x\n", Oid)); + status = NDIS_STATUS_NOT_SUPPORTED; + *BytesRead = 0; + *BytesNeeded = 0; + break; + } + + if (status == NDIS_STATUS_SUCCESS) + { + *BytesRead = InformationBufferLength; + *BytesNeeded = 0; + } + + NdisReleaseSpinLock(&Adapter->Lock); + + return status; +} diff --git a/drivers/network/dd/e1000/interrupt.c b/drivers/network/dd/e1000/interrupt.c new file mode 100644 index 0000000000..16e46e76ce --- /dev/null +++ b/drivers/network/dd/e1000/interrupt.c @@ -0,0 +1,49 @@ +/* + * PROJECT: ReactOS Intel PRO/1000 Driver + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Interrupt handlers + * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman(a)reactos.org) + * Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include "nic.h" + +#include <debug.h> + +VOID +NTAPI +MiniportISR( + OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext) +{ + PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; + + // + // FIXME: We need to synchronize with this ISR for changes to InterruptPending, + // LinkChange, MediaState, and LinkSpeedMbps. We can get away with IRQL + // synchronization on non-SMP machines because we run a DIRQL here. + // + + Adapter->InterruptPending |= NICInterruptRecognized(Adapter, InterruptRecognized); + if (!(*InterruptRecognized)) + { + /* This is not ours. */ + *QueueMiniportHandleInterrupt = FALSE; + return; + } + + UNIMPLEMENTED; + + /* Acknowledge the interrupt and mark the events pending service */ + NICAcknowledgeInterrupts(Adapter); + *QueueMiniportHandleInterrupt = TRUE; +} + +VOID +NTAPI +MiniportHandleInterrupt( + IN NDIS_HANDLE MiniportAdapterContext) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); +} diff --git a/drivers/network/dd/e1000/ndis.c b/drivers/network/dd/e1000/ndis.c new file mode 100644 index 0000000000..b02f397bd9 --- /dev/null +++ b/drivers/network/dd/e1000/ndis.c @@ -0,0 +1,315 @@ +/* + * PROJECT: ReactOS Intel PRO/1000 Driver + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Driver entrypoint + * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman(a)reactos.org) + * Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include "nic.h" + +#include <debug.h> + +ULONG DebugTraceLevel = DEBUG_ULTRA; + +NDIS_STATUS +NTAPI +MiniportReset( + OUT PBOOLEAN AddressingReset, + IN NDIS_HANDLE MiniportAdapterContext) +{ + *AddressingReset = FALSE; + UNIMPLEMENTED_DBGBREAK(); + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +MiniportSend( + IN NDIS_HANDLE MiniportAdapterContext, + IN PNDIS_PACKET Packet, + IN UINT Flags) +{ + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NDIS_STATUS_FAILURE; +} + +VOID +NTAPI +MiniportHalt( + IN NDIS_HANDLE MiniportAdapterContext) +{ + PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; + + ASSERT(Adapter != NULL); + + /* First disable sending / receiving */ + NICDisableTxRx(Adapter); + + /* Then unregister interrupts */ + NICUnregisterInterrupts(Adapter); + + /* Finally, free other resources (Ports, IO ranges,...) */ + NICReleaseIoResources(Adapter); + + /* Destroy the adapter context */ + NdisFreeMemory(Adapter, sizeof(*Adapter), 0); +} + +NDIS_STATUS +NTAPI +MiniportInitialize( + OUT PNDIS_STATUS OpenErrorStatus, + OUT PUINT SelectedMediumIndex, + IN PNDIS_MEDIUM MediumArray, + IN UINT MediumArraySize, + IN NDIS_HANDLE MiniportAdapterHandle, + IN NDIS_HANDLE WrapperConfigurationContext) +{ + PE1000_ADAPTER Adapter; + NDIS_STATUS Status; + UINT i; + PNDIS_RESOURCE_LIST ResourceList; + UINT ResourceListSize; + PCI_COMMON_CONFIG PciConfig; + //ULONG Value; + + /* Make sure the medium is supported */ + for (i = 0; i < MediumArraySize; i++) + { + if (MediumArray[i] == NdisMedium802_3) + { + *SelectedMediumIndex = i; + break; + } + } + + if (i == MediumArraySize) + { + NDIS_DbgPrint(MIN_TRACE, ("802.3 medium was not found in the medium array\n")); + return NDIS_STATUS_UNSUPPORTED_MEDIA; + } + + /* Allocate our adapter context */ + Status = NdisAllocateMemoryWithTag((PVOID*)&Adapter, + sizeof(*Adapter), + E1000_TAG); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate adapter context (0x%x)\n", Status)); + return NDIS_STATUS_RESOURCES; + } + + RtlZeroMemory(Adapter, sizeof(*Adapter)); + Adapter->AdapterHandle = MiniportAdapterHandle; + NdisAllocateSpinLock(&Adapter->Lock); + + + /* Notify NDIS of some characteristics of our NIC */ + NdisMSetAttributesEx(MiniportAdapterHandle, + Adapter, + 0, + NDIS_ATTRIBUTE_BUS_MASTER, + NdisInterfacePci); + + NdisReadPciSlotInformation(Adapter->AdapterHandle, + 0, + FIELD_OFFSET(PCI_COMMON_CONFIG, VendorID), + &PciConfig, sizeof(PciConfig)); + + Adapter->VendorID = PciConfig.VendorID; + Adapter->DeviceID = PciConfig.DeviceID; + + Adapter->SubsystemID = PciConfig.u.type0.SubSystemID; + Adapter->SubsystemVendorID = PciConfig.u.type0.SubVendorID; + + + if (!NICRecognizeHardware(Adapter)) + { + NDIS_DbgPrint(MIN_TRACE, ("Hardware not recognized\n")); + Status = NDIS_STATUS_UNSUPPORTED_MEDIA; + goto Cleanup; + } + + + /* Get our resources for IRQ and IO base information */ + ResourceList = NULL; + ResourceListSize = 0; + NdisMQueryAdapterResources(&Status, + WrapperConfigurationContext, + ResourceList, + &ResourceListSize); + if (Status != NDIS_STATUS_RESOURCES) + { + NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status)); + Status = NDIS_STATUS_FAILURE; + /* call NdisWriteErrorLogEntry */ + goto Cleanup; + } + + Status = NdisAllocateMemoryWithTag((PVOID*)&ResourceList, + ResourceListSize, + E1000_TAG); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate resource list (0x%x)\n", Status)); + /* call NdisWriteErrorLogEntry */ + goto Cleanup; + } + + NdisMQueryAdapterResources(&Status, + WrapperConfigurationContext, + ResourceList, + &ResourceListSize); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status)); + /* call NdisWriteErrorLogEntry */ + goto Cleanup; + } + + ASSERT(ResourceList->Version == 1); + ASSERT(ResourceList->Revision == 1); + + Status = NICInitializeAdapterResources(Adapter, ResourceList); + + NdisFreeMemory(ResourceList, ResourceListSize, 0); + ResourceList = NULL; + + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n")); + goto Cleanup; + } + + /* Allocate the DMA resources */ + Status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, + FALSE, // 32bit + MAXIMUM_FRAME_SIZE); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to configure DMA\n")); + Status = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + Status = NICAllocateIoResources(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate resources\n")); + Status = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + /* Adapter setup */ + Status = NICPowerOn(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to power on NIC (0x%x)\n", Status)); + goto Cleanup; + } + + Status = NICSoftReset(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to reset the NIC (0x%x)\n", Status)); + goto Cleanup; + } + + Status = NICGetPermanentMacAddress(Adapter, Adapter->PermanentMacAddress); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to get the fixed MAC address (0x%x)\n", Status)); + goto Cleanup; + } + + RtlCopyMemory(Adapter->CurrentMacAddress, Adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH); + + /* Update link state and speed */ + NICUpdateLinkStatus(Adapter); + + /* We're ready to handle interrupts now */ + Status = NICRegisterInterrupts(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to register interrupt (0x%x)\n", Status)); + goto Cleanup; + } + + /* Enable interrupts on the NIC */ + //Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; + Status = NICApplyInterruptMask(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to apply interrupt mask (0x%x)\n", Status)); + goto Cleanup; + } + + /* Turn on TX and RX now */ + Status = NICEnableTxRx(Adapter); + if (Status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to enable TX and RX (0x%x)\n", Status)); + goto Cleanup; + } + + return NDIS_STATUS_SUCCESS; + +Cleanup: + if (ResourceList != NULL) + { + NdisFreeMemory(ResourceList, ResourceListSize, 0); + } + if (Adapter != NULL) + { + MiniportHalt(Adapter); + } + + return Status; +} + +NTSTATUS +NTAPI +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + NDIS_HANDLE WrapperHandle; + NDIS_MINIPORT_CHARACTERISTICS Characteristics = { 0 }; + NDIS_STATUS Status; + + Characteristics.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION; + Characteristics.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION; + Characteristics.CheckForHangHandler = NULL; + Characteristics.DisableInterruptHandler = NULL; + Characteristics.EnableInterruptHandler = NULL; + Characteristics.HaltHandler = MiniportHalt; + Characteristics.HandleInterruptHandler = MiniportHandleInterrupt; + Characteristics.InitializeHandler = MiniportInitialize; + Characteristics.ISRHandler = MiniportISR; + Characteristics.QueryInformationHandler = MiniportQueryInformation; + Characteristics.ReconfigureHandler = NULL; + Characteristics.ResetHandler = MiniportReset; + Characteristics.SendHandler = MiniportSend; + Characteristics.SetInformationHandler = MiniportSetInformation; + Characteristics.TransferDataHandler = NULL; + Characteristics.ReturnPacketHandler = NULL; + Characteristics.SendPacketsHandler = NULL; + Characteristics.AllocateCompleteHandler = NULL; + + NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, NULL); + if (!WrapperHandle) + { + return NDIS_STATUS_FAILURE; + } + + Status = NdisMRegisterMiniport(WrapperHandle, &Characteristics, sizeof(Characteristics)); + if (Status != NDIS_STATUS_SUCCESS) + { + NdisTerminateWrapper(WrapperHandle, 0); + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} diff --git a/drivers/network/dd/e1000/nic.h b/drivers/network/dd/e1000/nic.h new file mode 100644 index 0000000000..ea6922ed17 --- /dev/null +++ b/drivers/network/dd/e1000/nic.h @@ -0,0 +1,171 @@ +/* + * PROJECT: ReactOS Intel PRO/1000 Driver + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Intel PRO/1000 driver definitions + * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman(a)reactos.org) + * Copyright 2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#ifndef _E1000_PCH_ +#define _E1000_PCH_ + +#include <ndis.h> + +#include "e1000hw.h" + +#define E1000_TAG '001e' + +#define MAXIMUM_FRAME_SIZE 1522 +#define RECEIVE_BUFFER_SIZE 2048 + +#define DRIVER_VERSION 1 + + +typedef struct _E1000_ADAPTER +{ + NDIS_SPIN_LOCK Lock; + NDIS_HANDLE AdapterHandle; + USHORT VendorID; + USHORT DeviceID; + USHORT SubsystemID; + USHORT SubsystemVendorID; + + UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH]; + UCHAR CurrentMacAddress[IEEE_802_ADDR_LENGTH]; + + ULONG LinkSpeedMbps; + ULONG MediaState; + ULONG InterruptPending; + +} E1000_ADAPTER, *PE1000_ADAPTER; + + +BOOLEAN +NTAPI +NICRecognizeHardware( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICInitializeAdapterResources( + IN PE1000_ADAPTER Adapter, + IN PNDIS_RESOURCE_LIST ResourceList); + +NDIS_STATUS +NTAPI +NICAllocateResources( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICRegisterInterrupts( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICUnregisterInterrupts( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICReleaseIoResources( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICPowerOn( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICSoftReset( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICEnableTxRx( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICDisableTxRx( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress( + IN PE1000_ADAPTER Adapter, + OUT PUCHAR MacAddress); + +NDIS_STATUS +NTAPI +NICApplyPacketFilter( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICApplyInterruptMask( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICDisableInterrupts( + IN PE1000_ADAPTER Adapter); + +USHORT +NTAPI +NICInterruptRecognized( + IN PE1000_ADAPTER Adapter, + OUT PBOOLEAN InterruptRecognized); + +VOID +NTAPI +NICAcknowledgeInterrupts( + IN PE1000_ADAPTER Adapter); + +VOID +NTAPI +NICUpdateLinkStatus( + IN PE1000_ADAPTER Adapter); + +NDIS_STATUS +NTAPI +NICTransmitPacket( + IN PE1000_ADAPTER Adapter, + IN UCHAR TxDesc, + IN ULONG PhysicalAddress, + IN ULONG Length); + +NDIS_STATUS +NTAPI +MiniportSetInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded); + +NDIS_STATUS +NTAPI +MiniportQueryInformation( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded); + +VOID +NTAPI +MiniportISR( + OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext); + +VOID +NTAPI +MiniportHandleInterrupt( + IN NDIS_HANDLE MiniportAdapterContext); + +#endif /* _E1000_PCH_ */ diff --git a/media/inf/CMakeLists.txt b/media/inf/CMakeLists.txt index d84ffff539..8080d1ec91 100644 --- a/media/inf/CMakeLists.txt +++ b/media/inf/CMakeLists.txt @@ -25,6 +25,7 @@ list(APPEND INF_FILES msmouse.inf NET_NIC.inf netamd.inf + nete1000.inf netisa.inf netrtl.inf netrtpnt.inf diff --git a/media/inf/nete1000.inf b/media/inf/nete1000.inf new file mode 100644 index 0000000000..ed47b46926 --- /dev/null +++ b/media/inf/nete1000.inf @@ -0,0 +1,50 @@ +; NETRTL.INF + +; Installation file for Intel-based NICs + +[Version] +Signature = "$Windows NT$" +;Signature = "$ReactOS$" +LayoutFile = layout.inf +Class = Net +ClassGUID = {4D36E972-E325-11CE-BFC1-08002BE10318} +Provider = %ReactOS% +DriverVer = 18/05/2018,1.00 + +[DestinationDirs] +DefaultDestDir = 12 + +[Manufacturer] +%IntelMfg% = IntelMfg + +[IntelMfg] +%IntelE1000.DeviceDesc% = E1000_Inst.ndi,PCI\VEN_8086&DEV_100F + +;----------------------------- E1000 DRIVER ----------------------------- + +[E1000_Inst.ndi.NT] +Characteristics = 0x4 ; NCF_PHYSICAL +BusType = 5 ; PCIBus +CopyFiles = E1000_CopyFiles.NT + +[E1000_CopyFiles.NT] +e1000.sys + +[E1000_Inst.ndi.NT.Services] +AddService = e1000, 0x00000002, E1000_Service_Inst + +[E1000_Service_Inst] +ServiceType = 1 +StartType = 3 +ErrorControl = 0 +ServiceBinary = %12%\e1000.sys +LoadOrderGroup = NDIS + +;-------------------------------- STRINGS ------------------------------- + +[Strings] +ReactOS = "ReactOS Team" + +IntelMfg = "Intel" + +IntelE1000.DeviceDesc = "Intel PRO/1000 Ethernet Adapter"
5 years, 10 months
1
0
0
0
[reactos] 03/03: [LDR] Add support for .local files CORE-187
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d93e516747e3220ba182f…
commit d93e516747e3220ba182f77824e8b1a8b548edae Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Oct 14 15:45:02 2018 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 18:48:49 2019 +0100 [LDR] Add support for .local files CORE-187 --- dll/ntdll/include/ntdllp.h | 8 ++++++ dll/ntdll/ldr/ldrinit.c | 70 ++++++++++++++++++++++++++++++++++++++++++---- dll/ntdll/rtl/libsupp.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 6 deletions(-) diff --git a/dll/ntdll/include/ntdllp.h b/dll/ntdll/include/ntdllp.h index 11f1e826f3..0f122a642d 100644 --- a/dll/ntdll/include/ntdllp.h +++ b/dll/ntdll/include/ntdllp.h @@ -203,4 +203,12 @@ VOID NTAPI LdrpFinalizeAndDeallocateDataTableEntry(IN PLDR_DATA_TABLE_ENTRY Entry); + +/* path.c */ +BOOLEAN +NTAPI +RtlDoesFileExists_UStr( + IN PUNICODE_STRING FileName +); + /* EOF */ diff --git a/dll/ntdll/ldr/ldrinit.c b/dll/ntdll/ldr/ldrinit.c index d28cb6e8a1..39567578d9 100644 --- a/dll/ntdll/ldr/ldrinit.c +++ b/dll/ntdll/ldr/ldrinit.c @@ -25,6 +25,7 @@ UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machin UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll"); UNICODE_STRING Kernel32String = RTL_CONSTANT_STRING(L"kernel32.dll"); +const UNICODE_STRING LdrpDotLocal = RTL_CONSTANT_STRING(L".Local"); BOOLEAN LdrpInLdrInit; LONG LdrpProcessInitialized; @@ -1626,6 +1627,66 @@ LdrpInitializeProcessCompat(PVOID* pOldShimData) } } +VOID +NTAPI +LdrpInitializeDotLocalSupport(PRTL_USER_PROCESS_PARAMETERS ProcessParameters) +{ + UNICODE_STRING ImagePathName = ProcessParameters->ImagePathName; + WCHAR LocalBuffer[MAX_PATH]; + UNICODE_STRING DotLocal; + NTSTATUS Status; + ULONG RequiredSize; + + RequiredSize = ImagePathName.Length + LdrpDotLocal.Length + sizeof(UNICODE_NULL); + if (RequiredSize <= sizeof(LocalBuffer)) + { + RtlInitEmptyUnicodeString(&DotLocal, LocalBuffer, sizeof(LocalBuffer)); + } + else if (RequiredSize <= UNICODE_STRING_MAX_BYTES) + { + DotLocal.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, RequiredSize); + DotLocal.Length = 0; + DotLocal.MaximumLength = RequiredSize; + if (!DotLocal.Buffer) + DPRINT1("LDR: Failed to allocate memory for .local check\n"); + } + else + { + DotLocal.Buffer = NULL; + DotLocal.Length = 0; + DotLocal.MaximumLength = 0; + DPRINT1("LDR: String too big for .local check\n"); + } + + if (DotLocal.Buffer) + { + Status = RtlAppendUnicodeStringToString(&DotLocal, &ImagePathName); + ASSERT(NT_SUCCESS(Status)); + if (NT_SUCCESS(Status)) + { + Status = RtlAppendUnicodeStringToString(&DotLocal, &LdrpDotLocal); + ASSERT(NT_SUCCESS(Status)); + } + + if (NT_SUCCESS(Status)) + { + if (RtlDoesFileExists_UStr(&DotLocal)) + { + ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH; + } + } + else + { + DPRINT1("LDR: Failed to append: 0x%lx\n", Status); + } + + if (DotLocal.Buffer != LocalBuffer) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, DotLocal.Buffer); + } + } +} + NTSTATUS NTAPI @@ -2135,13 +2196,10 @@ LdrpInitializeProcess(IN PCONTEXT Context, if (FreeCurDir) RtlFreeUnicodeString(&CurrentDirectory); } - /* Check if we should look for a .local file - FIXME: Thomas suggested that this check might actually be reversed, we should check this file - if the flag is NOT set. */ - if (ProcessParameters && (ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH)) + /* Check if we should look for a .local file */ + if (ProcessParameters && !(ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH)) { - /* FIXME */ - DPRINT1("We don't support .local overrides yet\n"); + LdrpInitializeDotLocalSupport(ProcessParameters); } /* Check if the Application Verifier was enabled */ diff --git a/dll/ntdll/rtl/libsupp.c b/dll/ntdll/rtl/libsupp.c index d29ccaf82d..94c6f0e5b0 100644 --- a/dll/ntdll/rtl/libsupp.c +++ b/dll/ntdll/rtl/libsupp.c @@ -792,6 +792,8 @@ RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, WCHAR *p; BOOLEAN GotExtension; WCHAR c; + C_ASSERT(sizeof(UNICODE_NULL) == sizeof(WCHAR)); + /* Check for invalid parameters */ if (!OriginalName) @@ -819,6 +821,72 @@ RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, return STATUS_SXS_KEY_NOT_FOUND; } + if (NtCurrentPeb()->ProcessParameters && + (NtCurrentPeb()->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH)) + { + UNICODE_STRING RealName, LocalName; + WCHAR RealNameBuf[MAX_PATH], LocalNameBuf[MAX_PATH]; + + RtlInitEmptyUnicodeString(&RealName, RealNameBuf, sizeof(RealNameBuf)); + RtlInitEmptyUnicodeString(&LocalName, LocalNameBuf, sizeof(LocalNameBuf)); + + Status = RtlComputePrivatizedDllName_U(OriginalName, &RealName, &LocalName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlComputePrivatizedDllName_U failed for %wZ: 0x%lx\n", OriginalName, Status); + return Status; + } + + if (RtlDoesFileExists_UStr(&LocalName)) + { + Status = get_buffer(&fullname, LocalName.Length + sizeof(UNICODE_NULL), StaticString, DynamicString != NULL); + if (NT_SUCCESS(Status)) + { + RtlCopyMemory(fullname, LocalName.Buffer, LocalName.Length + sizeof(UNICODE_NULL)); + } + else + { + DPRINT1("Error while retrieving buffer for %wZ: 0x%lx\n", OriginalName, Status); + } + } + else if (RtlDoesFileExists_UStr(&RealName)) + { + Status = get_buffer(&fullname, RealName.Length + sizeof(UNICODE_NULL), StaticString, DynamicString != NULL); + if (NT_SUCCESS(Status)) + { + RtlCopyMemory(fullname, RealName.Buffer, RealName.Length + sizeof(UNICODE_NULL)); + } + else + { + DPRINT1("Error while retrieving buffer for %wZ: 0x%lx\n", OriginalName, Status); + } + } + else + { + Status = STATUS_NOT_FOUND; + } + + if (RealName.Buffer != RealNameBuf) + RtlFreeUnicodeString(&RealName); + if (LocalName.Buffer != LocalNameBuf) + RtlFreeUnicodeString(&LocalName); + + if (NT_SUCCESS(Status)) + { + DPRINT("Redirecting %wZ to %S\n", OriginalName, fullname); + if (!StaticString || StaticString->Buffer != fullname) + { + RtlInitUnicodeString(DynamicString, fullname); + *NewName = DynamicString; + } + else + { + *NewName = StaticString; + } + return Status; + } + } + pstrParam = OriginalName; /* Get the file name with an extension */
5 years, 10 months
1
0
0
0
[reactos] 02/03: [NTDLL_APITEST] Add test for RtlComputePrivatizedDllName_U
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=88cd8d681c15fb06bd417…
commit 88cd8d681c15fb06bd417985fe2c873df688a3e9 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sat Feb 2 02:31:48 2019 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 18:48:49 2019 +0100 [NTDLL_APITEST] Add test for RtlComputePrivatizedDllName_U --- modules/rostests/apitests/ntdll/CMakeLists.txt | 1 + .../apitests/ntdll/RtlComputePrivatizedDllName_U.c | 236 +++++++++++++++++++++ modules/rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 239 insertions(+) diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt b/modules/rostests/apitests/ntdll/CMakeLists.txt index e3a2725d6b..8e8f2fc389 100644 --- a/modules/rostests/apitests/ntdll/CMakeLists.txt +++ b/modules/rostests/apitests/ntdll/CMakeLists.txt @@ -38,6 +38,7 @@ list(APPEND SOURCE NtWriteFile.c RtlAllocateHeap.c RtlBitmap.c + RtlComputePrivatizedDllName_U.c RtlCopyMappedMemory.c RtlDeleteAce.c RtlDetermineDosPathNameType.c diff --git a/modules/rostests/apitests/ntdll/RtlComputePrivatizedDllName_U.c b/modules/rostests/apitests/ntdll/RtlComputePrivatizedDllName_U.c new file mode 100644 index 0000000000..ee91ca618e --- /dev/null +++ b/modules/rostests/apitests/ntdll/RtlComputePrivatizedDllName_U.c @@ -0,0 +1,236 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) + * PURPOSE: Test for RtlComputePrivatizedDllName_U + * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include "precomp.h" + + +static WCHAR ProcessDir[MAX_PATH]; +static WCHAR LocalDir[MAX_PATH + 10]; + +static BOOL InitTestData() +{ + static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/"); + UNICODE_STRING StrU; + USHORT PathDivider; + + GetModuleFileNameW(NULL, ProcessDir, RTL_NUMBER_OF(ProcessDir)); + GetModuleFileNameW(NULL, LocalDir, RTL_NUMBER_OF(LocalDir)); + + RtlInitUnicodeString(&StrU, ProcessDir); + + if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, + &StrU, &PathDividerFind, &PathDivider))) + { + skip("Failed to find path divider\n"); + return FALSE; + } + ProcessDir[PathDivider / sizeof(WCHAR) + 1] = UNICODE_NULL; + + RtlInitUnicodeString(&StrU, LocalDir); + StrU.MaximumLength = sizeof(LocalDir); + + if (!NT_SUCCESS(RtlAppendUnicodeToString(&StrU, L".Local\\"))) + { + skip("Failed to append .Local\\\n"); + return FALSE; + } + return TRUE; +} + +static void ok_strings_(PCUNICODE_STRING RealName, PCUNICODE_STRING LocalName, LPCWSTR DllName, int line) +{ + WCHAR ExpectReal[MAX_PATH*2]; + WCHAR ExpectLocal[MAX_PATH*2]; + int RealLen; + int ExpectLen; + + RealLen = swprintf(ExpectReal, L"%s%s", ProcessDir, DllName) * sizeof(WCHAR); + ExpectLen = swprintf(ExpectLocal, L"%s%s", LocalDir, DllName) * sizeof(WCHAR); + + ok_(__FILE__, line)(RealLen == RealName->Length, "Expected Real %u, got %u\n", + (UINT)RealLen, (UINT)RealName->Length); + ok_(__FILE__, line)(ExpectLen == LocalName->Length, "Expected Local %u, got %u\n", + (UINT)ExpectLen, (UINT)LocalName->Length); + + ok_(__FILE__, line)(!wcscmp(RealName->Buffer, ExpectReal), "Expected Real %s, got %s\n", + wine_dbgstr_w(ExpectReal), wine_dbgstr_w(RealName->Buffer)); + ok_(__FILE__, line)(!wcscmp(LocalName->Buffer, ExpectLocal), "Expected Local %s, got %s\n", + wine_dbgstr_w(ExpectLocal), wine_dbgstr_w(LocalName->Buffer)); +} +#define ok_strings(Real, Local, Dll) ok_strings_(Real, Local, Dll, __LINE__) + + +static void cleanup(PUNICODE_STRING String, WCHAR* Buffer, USHORT BufferSize) +{ + if (String->Buffer != Buffer) + { + RtlFreeUnicodeString(String); + RtlInitEmptyUnicodeString(String, Buffer, BufferSize); + } +} + + +static void test_dllnames(void) +{ + WCHAR Buf1[MAX_PATH]; + WCHAR Buf2[MAX_PATH]; + + UNICODE_STRING Str1, Str2; + UNICODE_STRING DllName; + NTSTATUS Status; + + RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1)); + RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"kernel32.dll"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.dll"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + + RtlInitUnicodeString(&DllName, L"kernel32"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.DLL"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"kernel32.dll.dll"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.dll.dll"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"kernel32.dll.exe"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.dll.exe"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"kernel32."); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32."); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L".kernel32"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L".kernel32.DLL"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"..kernel32"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"..kernel32"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L".kernel32."); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L".kernel32."); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + + RtlInitUnicodeString(&DllName, L"test\\kernel32.dll"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.dll"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"test/kernel32.dll"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.dll"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"test.dll/kernel32"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.DLL"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"test.dll\\kernel32"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.DLL"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"//"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L".DLL"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + // Bug :) + RtlInitUnicodeString(&DllName, L"\\"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + if (wcsstr(Str1.Buffer, L"\\\\")) + { + trace("Allowing bug found in windows' implementation\n"); + ok_strings(&Str1, &Str2, L"\\.DLL"); + } + else + { + ok_strings(&Str1, &Str2, L".DLL"); + } + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L""); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L".DLL"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); +} + +static void test_allocations(void) +{ + WCHAR Buf1[10]; + WCHAR Buf2[10]; + + UNICODE_STRING Str1, Str2; + UNICODE_STRING DllName; + NTSTATUS Status; + + RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1)); + RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2)); + + RtlInitUnicodeString(&DllName, L"kernel32.dll"); + Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); + ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); + ok_strings(&Str1, &Str2, L"kernel32.dll"); + ok(Str1.Buffer != Buf1, "Expected a changed buffer\n"); + ok(Str2.Buffer != Buf2, "Expected a changed buffer\n"); + cleanup(&Str1, Buf1, sizeof(Buf1)); + cleanup(&Str2, Buf2, sizeof(Buf2)); +} + + +START_TEST(RtlComputePrivatizedDllName_U) +{ + if (!InitTestData()) + return; + + test_dllnames(); + test_allocations(); +} diff --git a/modules/rostests/apitests/ntdll/testlist.c b/modules/rostests/apitests/ntdll/testlist.c index a828865d8a..bfaf8b476f 100644 --- a/modules/rostests/apitests/ntdll/testlist.c +++ b/modules/rostests/apitests/ntdll/testlist.c @@ -37,6 +37,7 @@ extern void func_NtSystemInformation(void); extern void func_NtWriteFile(void); extern void func_RtlAllocateHeap(void); extern void func_RtlBitmap(void); +extern void func_RtlComputePrivatizedDllName_U(void); extern void func_RtlCopyMappedMemory(void); extern void func_RtlDeleteAce(void); extern void func_RtlDetermineDosPathNameType(void); @@ -102,6 +103,7 @@ const struct test winetest_testlist[] = { "NtWriteFile", func_NtWriteFile }, { "RtlAllocateHeap", func_RtlAllocateHeap }, { "RtlBitmapApi", func_RtlBitmap }, + { "RtlComputePrivatizedDllName_U", func_RtlComputePrivatizedDllName_U }, { "RtlCopyMappedMemory", func_RtlCopyMappedMemory }, { "RtlDeleteAce", func_RtlDeleteAce }, { "RtlDetermineDosPathNameType", func_RtlDetermineDosPathNameType },
5 years, 10 months
1
0
0
0
[reactos] 01/03: [RTL] Implement RtlComputePrivatizedDllName_U
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e1aae1c62075dbddfc2e1…
commit e1aae1c62075dbddfc2e1a5d1f023fa84d8ce724 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sat Feb 2 02:30:40 2019 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Thu Feb 7 18:48:49 2019 +0100 [RTL] Implement RtlComputePrivatizedDllName_U --- sdk/include/ndk/rtlfuncs.h | 4 +- sdk/lib/rtl/path.c | 153 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h index 68d474f31f..8f5cdf07e5 100644 --- a/sdk/include/ndk/rtlfuncs.h +++ b/sdk/include/ndk/rtlfuncs.h @@ -2777,8 +2777,8 @@ NTSTATUS NTAPI RtlComputePrivatizedDllName_U( _In_ PUNICODE_STRING DllName, - _Out_ PUNICODE_STRING RealName, - _Out_ PUNICODE_STRING LocalName + _Inout_ PUNICODE_STRING RealName, + _Inout_ PUNICODE_STRING LocalName ); NTSYSAPI diff --git a/sdk/lib/rtl/path.c b/sdk/lib/rtl/path.c index 4ac9ba78aa..dd183b6801 100644 --- a/sdk/lib/rtl/path.c +++ b/sdk/lib/rtl/path.c @@ -47,6 +47,11 @@ const UNICODE_STRING RtlpDosNULDevice = RTL_CONSTANT_STRING(L"NUL"); const UNICODE_STRING RtlpDoubleSlashPrefix = RTL_CONSTANT_STRING(L"\\\\"); +static const UNICODE_STRING RtlpDefaultExtension = RTL_CONSTANT_STRING(L".DLL"); +static const UNICODE_STRING RtlpDotLocal = RTL_CONSTANT_STRING(L".Local\\"); +static const UNICODE_STRING RtlpPathDividers = RTL_CONSTANT_STRING(L"\\/"); + + PRTLP_CURDIR_REF RtlpCurDirRef; /* PRIVATE FUNCTIONS **********************************************************/ @@ -459,12 +464,150 @@ RtlGetLengthWithoutLastFullDosOrNtPathElement(IN ULONG Flags, NTSTATUS NTAPI -RtlComputePrivatizedDllName_U(IN PUNICODE_STRING DllName, - IN PUNICODE_STRING a2, - IN PUNICODE_STRING a3) +RtlComputePrivatizedDllName_U( + _In_ PUNICODE_STRING DllName, + _Inout_ PUNICODE_STRING RealName, + _Inout_ PUNICODE_STRING LocalName) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + static const UNICODE_STRING ExtensionChar = RTL_CONSTANT_STRING(L"."); + + USHORT Position; + UNICODE_STRING ImagePathName, DllNameOnly, CopyRealName, CopyLocalName; + BOOLEAN HasExtension; + ULONG RequiredSize; + NTSTATUS Status; + C_ASSERT(sizeof(UNICODE_NULL) == sizeof(WCHAR)); + + CopyRealName = *RealName; + CopyLocalName = *LocalName; + + + /* Get the image path */ + ImagePathName = RtlGetCurrentPeb()->ProcessParameters->ImagePathName; + + /* Check if it's not normalized */ + if (!(RtlGetCurrentPeb()->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_NORMALIZED)) + { + /* Normalize it */ + ImagePathName.Buffer = (PWSTR)((ULONG_PTR)ImagePathName.Buffer + (ULONG_PTR)RtlGetCurrentPeb()->ProcessParameters); + } + + + if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, + DllName, &RtlpPathDividers, &Position))) + { + DllNameOnly = *DllName; + } + else + { + /* Just keep the dll name, ignore path components */ + Position += sizeof(WCHAR); + DllNameOnly.Buffer = DllName->Buffer + Position / sizeof(WCHAR); + DllNameOnly.Length = DllName->Length - Position; + DllNameOnly.MaximumLength = DllName->MaximumLength - Position; + } + + if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, + &DllNameOnly, &ExtensionChar, &Position))) + { + Position = 0; + } + + HasExtension = Position > 1; + + /* First we create the c:\path\processname.exe.Local\something.dll path */ + RequiredSize = ImagePathName.Length + RtlpDotLocal.Length + DllNameOnly.Length + + (HasExtension ? 0 : RtlpDefaultExtension.Length) + sizeof(UNICODE_NULL); + + /* This is not going to work out */ + if (RequiredSize > UNICODE_STRING_MAX_BYTES) + return STATUS_NAME_TOO_LONG; + + /* We need something extra */ + if (RequiredSize > CopyLocalName.MaximumLength) + { + CopyLocalName.Buffer = RtlpAllocateStringMemory(RequiredSize, TAG_USTR); + if (CopyLocalName.Buffer == NULL) + return STATUS_NO_MEMORY; + CopyLocalName.MaximumLength = RequiredSize; + } + /* Now build the entire path */ + CopyLocalName.Length = 0; + Status = RtlAppendUnicodeStringToString(&CopyLocalName, &ImagePathName); + ASSERT(NT_SUCCESS(Status)); + if (NT_SUCCESS(Status)) + { + Status = RtlAppendUnicodeStringToString(&CopyLocalName, &RtlpDotLocal); + ASSERT(NT_SUCCESS(Status)); + } + if (NT_SUCCESS(Status)) + { + Status = RtlAppendUnicodeStringToString(&CopyLocalName, &DllNameOnly); + ASSERT(NT_SUCCESS(Status)); + } + /* Do we need to append an extension? */ + if (NT_SUCCESS(Status) && !HasExtension) + { + Status = RtlAppendUnicodeStringToString(&CopyLocalName, &RtlpDefaultExtension); + ASSERT(NT_SUCCESS(Status)); + } + + if (NT_SUCCESS(Status)) + { + /* then we create the c:\path\something.dll path */ + if (NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, + &ImagePathName, &RtlpPathDividers, &Position))) + { + ImagePathName.Length = Position + sizeof(WCHAR); + } + + RequiredSize = ImagePathName.Length + DllNameOnly.Length + + (HasExtension ? 0 : RtlpDefaultExtension.Length) + sizeof(UNICODE_NULL); + + if (RequiredSize >= UNICODE_STRING_MAX_BYTES) + { + Status = STATUS_NAME_TOO_LONG; + } + else + { + if (RequiredSize > CopyRealName.MaximumLength) + { + CopyRealName.Buffer = RtlpAllocateStringMemory(RequiredSize, TAG_USTR); + if (CopyRealName.Buffer == NULL) + Status = STATUS_NO_MEMORY; + CopyRealName.MaximumLength = RequiredSize; + } + CopyRealName.Length = 0; + if (NT_SUCCESS(Status)) + { + Status = RtlAppendUnicodeStringToString(&CopyRealName, &ImagePathName); + ASSERT(NT_SUCCESS(Status)); + } + if (NT_SUCCESS(Status)) + { + Status = RtlAppendUnicodeStringToString(&CopyRealName, &DllNameOnly); + ASSERT(NT_SUCCESS(Status)); + } + if (NT_SUCCESS(Status) && !HasExtension) + { + Status = RtlAppendUnicodeStringToString(&CopyRealName, &RtlpDefaultExtension); + ASSERT(NT_SUCCESS(Status)); + } + } + } + + if (!NT_SUCCESS(Status)) + { + if (CopyRealName.Buffer && CopyRealName.Buffer != RealName->Buffer) + RtlpFreeStringMemory(CopyRealName.Buffer, TAG_USTR); + if (CopyLocalName.Buffer && CopyLocalName.Buffer != LocalName->Buffer) + RtlpFreeStringMemory(CopyLocalName.Buffer, TAG_USTR); + return Status; + } + + *RealName = CopyRealName; + *LocalName = CopyLocalName; + return STATUS_SUCCESS; } ULONG
5 years, 10 months
1
0
0
0
[reactos] 01/01: [NTOS:MM] ExFreePoolWithTag(): Accept tag mismatch, on release build only (#1334)
by Serge Gautherie
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=84e76b1c4c673f73968d0…
commit 84e76b1c4c673f73968d0ce4c86b771c9cf519d4 Author: Serge Gautherie <32623169+SergeGautherie(a)users.noreply.github.com> AuthorDate: Thu Feb 7 16:57:56 2019 +0100 Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org> CommitDate: Thu Feb 7 16:57:56 2019 +0100 [NTOS:MM] ExFreePoolWithTag(): Accept tag mismatch, on release build only (#1334) "Release" builds should not BSoD on 'Freeing pool - invalid tag specified' case, this is compatible with Windows behaviour. Nothing changes otherwise concerning the "Debug" builds, where pool-tag mismatch triggers a BSoD as expected. CORE-15446 --- ntoskrnl/mm/ARM3/expool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ntoskrnl/mm/ARM3/expool.c b/ntoskrnl/mm/ARM3/expool.c index 9625e50f44..416a2fbda7 100644 --- a/ntoskrnl/mm/ARM3/expool.c +++ b/ntoskrnl/mm/ARM3/expool.c @@ -2558,7 +2558,9 @@ ExFreePoolWithTag(IN PVOID P, if (TagToFree && TagToFree != Tag) { DPRINT1("Freeing pool - invalid tag specified: %.4s != %.4s\n", (char*)&TagToFree, (char*)&Tag); +#if DBG KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, Tag, TagToFree); +#endif } // @@ -2640,7 +2642,9 @@ ExFreePoolWithTag(IN PVOID P, if (TagToFree && TagToFree != Tag) { DPRINT1("Freeing pool - invalid tag specified: %.4s != %.4s\n", (char*)&TagToFree, (char*)&Tag); +#if DBG KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, Tag, TagToFree); +#endif } //
5 years, 10 months
1
0
0
0
← Newer
1
...
11
12
13
14
15
16
17
...
21
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Results per page:
10
25
50
100
200