ReactOS  0.4.15-dev-5606-gf34e425
backoff.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS nVidia nForce Ethernet Controller Driver
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Re-seeding random values for the backoff algorithms
5  * COPYRIGHT: Copyright 2021-2022 Dmitry Borisov <di.sean@protonmail.com>
6  */
7 
8 /*
9  * HW access code was taken from the Linux forcedeth driver
10  * Copyright (C) 2003,4,5 Manfred Spraul
11  * Copyright (C) 2004 Andrew de Quincey
12  * Copyright (C) 2004 Carl-Daniel Hailfinger
13  * Copyright (c) 2004,2005,2006,2007,2008,2009 NVIDIA Corporation
14  */
15 
16 /* INCLUDES *******************************************************************/
17 
18 #include "nvnet.h"
19 
20 #define NDEBUG
21 #include "debug.h"
22 
23 /* GLOBALS ********************************************************************/
24 
25 #define BACKOFF_SEEDSET_ROWS 8
26 #define BACKOFF_SEEDSET_LFSRS 15
27 
28 #define REVERSE_SEED(s) ((((s) & 0xF00) >> 8) | ((s) & 0x0F0) | (((s) & 0x00F) << 8))
29 
31 {
32  {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
33  {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974},
34  {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
35  {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974},
36  {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984},
37  {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984},
38  {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84},
39  {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184}
40 };
41 
43 {
44  {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
45  {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
46  {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397},
47  {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
48  {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295},
49  {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
50  {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
51  {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}
52 };
53 
54 /* FUNCTIONS ******************************************************************/
55 
56 CODE_SEG("PAGE")
57 VOID
59  _In_ PNVNET_ADAPTER Adapter)
60 {
62 
63  PAGED_CODE();
64 
65  if ((Sample.LowPart & NVREG_SLOTTIME_MASK) == 0)
66  {
67  Sample.LowPart = 8;
68  }
69 
70  if (Adapter->Features & (DEV_HAS_HIGH_DMA | DEV_HAS_LARGEDESC))
71  {
72  if (Adapter->Features & DEV_HAS_GEAR_MODE)
73  {
75  NvNetBackoffReseedEx(Adapter);
76  }
77  else
78  {
79  NV_WRITE(Adapter, NvRegSlotTime, (Sample.LowPart & NVREG_SLOTTIME_MASK) |
81  }
82  }
83  else
84  {
85  NV_WRITE(Adapter, NvRegSlotTime,
87  }
88 }
89 
90 VOID
92  _In_ PNVNET_ADAPTER Adapter)
93 {
94  ULONG SlotTime;
95  BOOLEAN RestartTransmitter = FALSE;
97 
98  NDIS_DbgPrint(MIN_TRACE, ("()\n"));
99 
100  if ((Sample.LowPart & NVREG_SLOTTIME_MASK) == 0)
101  {
102  Sample.LowPart = 8;
103  }
104 
105  SlotTime = NV_READ(Adapter, NvRegSlotTime) & ~NVREG_SLOTTIME_MASK;
106  SlotTime |= Sample.LowPart & NVREG_SLOTTIME_MASK;
107 
109  {
110  RestartTransmitter = TRUE;
111  NvNetStopTransmitter(Adapter);
112  }
113  NvNetStopReceiver(Adapter);
114 
115  NV_WRITE(Adapter, NvRegSlotTime, SlotTime);
116 
117  if (RestartTransmitter)
118  {
119  NvNetStartTransmitter(Adapter);
120  }
121  NvNetStartReceiver(Adapter);
122 }
123 
124 VOID
126  _In_ PNVNET_ADAPTER Adapter)
127 {
128  LARGE_INTEGER Sample;
129  ULONG Seed[3], ReversedSeed[2], CombinedSeed, SeedSet;
130  ULONG i, Temp;
131 
132  NDIS_DbgPrint(MIN_TRACE, ("()\n"));
133 
135  Seed[0] = Sample.LowPart & 0x0FFF;
136  if (Seed[0] == 0)
137  {
138  Seed[0] = 0x0ABC;
139  }
140 
142  Seed[1] = Sample.LowPart & 0x0FFF;
143  if (Seed[1] == 0)
144  {
145  Seed[1] = 0x0ABC;
146  }
147  ReversedSeed[0] = REVERSE_SEED(Seed[1]);
148 
150  Seed[2] = Sample.LowPart & 0x0FFF;
151  if (Seed[2] == 0)
152  {
153  Seed[2] = 0x0ABC;
154  }
155  ReversedSeed[1] = REVERSE_SEED(Seed[2]);
156 
157  CombinedSeed = ((Seed[0] ^ ReversedSeed[0]) << 12) | (Seed[1] ^ ReversedSeed[1]);
158  if ((CombinedSeed & NVREG_BKOFFCTRL_SEED_MASK) == 0)
159  {
160  CombinedSeed |= 8;
161  }
162  if ((CombinedSeed & (NVREG_BKOFFCTRL_SEED_MASK << NVREG_BKOFFCTRL_GEAR)) == 0)
163  {
164  CombinedSeed |= 8 << NVREG_BKOFFCTRL_GEAR;
165  }
166 
167  /* No need to disable transmitter here */
169  Temp |= CombinedSeed & NVREG_BKOFFCTRL_SEED_MASK;
170  Temp |= CombinedSeed >> NVREG_BKOFFCTRL_GEAR;
171  NV_WRITE(Adapter, NvRegBackOffControl, Temp);
172 
173  /* Setup seeds for all gear LFSRs */
175  SeedSet = Sample.LowPart % BACKOFF_SEEDSET_ROWS;
176  for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; ++i)
177  {
179  Temp |= NvpMainSeedSet[SeedSet][i - 1] & NVREG_BKOFFCTRL_SEED_MASK;
180  Temp |= (NvpGearSeedSet[SeedSet][i - 1] & NVREG_BKOFFCTRL_SEED_MASK)
182  NV_WRITE(Adapter, NvRegBackOffControl, Temp);
183  }
184 }
#define NVREG_SLOTTIME_10_100_FULL
Definition: nic.h:134
#define BACKOFF_SEEDSET_ROWS
Definition: backoff.c:25
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
VOID NvNetBackoffReseed(_In_ PNVNET_ADAPTER Adapter)
Definition: backoff.c:91
VOID NvNetBackoffSetSlotTime(_In_ PNVNET_ADAPTER Adapter)
Definition: backoff.c:58
VOID NvNetStartReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:104
#define TRUE
Definition: types.h:120
#define NVREG_XMITCTL_START
Definition: nic.h:96
VOID NvNetStartTransmitter(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:130
VOID NvNetStopReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:147
static const ULONG NvpGearSeedSet[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS]
Definition: backoff.c:42
#define DEV_HAS_GEAR_MODE
Definition: nic.h:40
VOID NvNetBackoffReseedEx(_In_ PNVNET_ADAPTER Adapter)
Definition: backoff.c:125
#define FALSE
Definition: types.h:117
#define NVREG_BKOFFCTRL_SEED_MASK
Definition: nic.h:172
unsigned char BOOLEAN
#define _In_
Definition: ms_sal.h:308
#define BACKOFF_SEEDSET_LFSRS
Definition: backoff.c:26
FORCEINLINE VOID NV_WRITE(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register, _In_ ULONG Value)
Definition: nvnet.h:646
#define DEV_HAS_HIGH_DMA
Definition: nic.h:22
VOID NvNetStopTransmitter(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:178
#define NVREG_BKOFFCTRL_SELECT
Definition: nic.h:173
static const ULONG NvpMainSeedSet[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS]
Definition: backoff.c:30
#define REVERSE_SEED(s)
Definition: backoff.c:28
ULONG LowPart
Definition: typedefs.h:106
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
#define NVREG_SLOTTIME_LEGBF_ENABLED
Definition: nic.h:133
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
#define NVREG_SLOTTIME_MASK
Definition: nic.h:138
#define NVREG_BKOFFCTRL_GEAR
Definition: nic.h:174
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
#define DEV_HAS_LARGEDESC
Definition: nic.h:20
#define NVREG_SLOTTIME_DEFAULT
Definition: nic.h:137
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
#define NVREG_BKOFFCTRL_DEFAULT
Definition: nic.h:171
FORCEINLINE ULONG NV_READ(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register)
Definition: nvnet.h:656
#define PAGED_CODE()