21 #include "Ne2kConstants.h" 22 #include "modules/system/network-stack/NetworkStack.h" 23 #include "pedigree/kernel/LockGuard.h" 24 #include "pedigree/kernel/Log.h" 25 #include "pedigree/kernel/machine/Device.h" 26 #include "pedigree/kernel/machine/IrqManager.h" 27 #include "pedigree/kernel/machine/Machine.h" 28 #include "pedigree/kernel/machine/Network.h" 29 #include "pedigree/kernel/network/IpAddress.h" 30 #include "pedigree/kernel/network/MacAddress.h" 31 #include "pedigree/kernel/process/Thread.h" 32 #include "pedigree/kernel/processor/IoBase.h" 33 #include "pedigree/kernel/processor/Processor.h" 34 #include "pedigree/kernel/processor/ProcessorInformation.h" 35 #include "pedigree/kernel/utilities/MemoryPool.h" 36 #include "pedigree/kernel/utilities/Vector.h" 37 #include "pedigree/kernel/utilities/utility.h" 42 :
Network(pDev), m_pBase(0), m_NextPacket(0), m_PacketQueueSize(0),
43 m_PacketQueue(), m_PacketQueueLock()
56 m_pBase->
write8(0x21, NE_CMD);
60 m_pBase->
write8(0x09, NE_DCR);
61 m_pBase->
write8(0x20, NE_RCR);
62 m_pBase->
write8(0x02, NE_TCR);
65 m_pBase->
write8(0xff, NE_ISR);
66 m_pBase->
write8(0x00, NE_IMR);
69 m_pBase->
write8(0x00, NE_RSAR0);
70 m_pBase->
write8(0x00, NE_RSAR1);
72 m_pBase->
write8(32, NE_RBCR0);
73 m_pBase->
write8(0, NE_RBCR1);
75 m_pBase->
write8(0x0a, NE_CMD);
79 for (i = 0; i < 16; i++)
80 prom[i] = m_pBase->
read16(NE_DATA);
83 m_pBase->
write8(0x61, NE_CMD);
84 for (i = 0; i < 6; i++)
86 m_StationInfo.mac.setMac(prom[i] & 0xff, i);
87 m_pBase->
write8(prom[i] & 0xff, NE_PAR + i);
91 "NE2K: MAC is " << m_StationInfo.mac[0] <<
":" << m_StationInfo.mac[1]
92 <<
":" << m_StationInfo.mac[2] <<
":" 93 << m_StationInfo.mac[3] <<
":" << m_StationInfo.mac[4]
94 <<
":" << m_StationInfo.mac[5] <<
".");
98 m_pBase->
write8(0x61, NE_CMD);
99 m_pBase->
write8(PAGE_RX + 1, NE_CURR);
101 m_NextPacket = PAGE_RX + 1;
103 m_pBase->
write8(0x21, NE_CMD);
105 m_pBase->
write8(PAGE_RX, NE_PSTART);
106 m_pBase->
write8(PAGE_RX, NE_BNDRY);
107 m_pBase->
write8(PAGE_STOP, NE_PSTOP);
111 m_pBase->
write8(0x14, NE_RCR);
112 m_pBase->
write8(0x00, NE_TCR);
117 uint8_t tmp = m_pBase->
read8(NE_CMD);
118 m_pBase->
write8(tmp | 0x40, NE_CMD);
119 for (i = 0; i < MAR_SIZE; i++)
120 m_pBase->
write8(0xFF, NE_MAR + i);
121 m_pBase->
write8(tmp, NE_CMD);
127 reinterpret_cast<void *>(
this));
137 m_pBase->
write8(0xff, NE_ISR);
138 m_pBase->
write8(0x3D, NE_IMR);
141 m_pBase->
write8(0x22, NE_CMD);
154 ERROR(
"NE2K: Attempt to send a packet with size > 64 KB");
159 m_pBase->
write8(0, NE_RSAR0);
160 m_pBase->
write8(PAGE_TX, NE_RSAR1);
163 (nBytes > 64) ? nBytes & 0xff : 64,
165 m_pBase->
write8(nBytes >> 8, NE_RBCR1);
167 m_pBase->
write8(0x12, NE_CMD);
169 uint16_t *data =
reinterpret_cast<uint16_t *
>(buffer);
171 for (i = 0; (i + 1) < nBytes; i += 2)
172 m_pBase->
write16(data[i / 2], NE_DATA);
179 m_pBase->
write8(data[i / 2] & 0xff, NE_DATA);
184 m_pBase->
write8(data[i / 2] & 0xff, NE_DATA);
190 for (; i < 64; i += 2)
194 while (!(m_pBase->
read8(NE_ISR) & 0x40))
196 m_pBase->
write8(0x40, NE_ISR);
199 m_pBase->
write8((nBytes > 64) ? nBytes & 0xff : 64, NE_TBCR0);
200 m_pBase->
write8(nBytes >> 8, NE_TBCR1);
202 m_pBase->
write8(PAGE_TX, NE_TPSR);
204 m_pBase->
write8(0x26, NE_CMD);
213 m_pBase->
write8(0x61, NE_CMD);
214 uint8_t current = m_pBase->
read8(NE_CURR);
215 m_pBase->
write8(0x21, NE_CMD);
218 while (m_NextPacket != current)
221 m_pBase->
write8(0, NE_RSAR0);
222 m_pBase->
write8(m_NextPacket, NE_RSAR1);
223 m_pBase->
write8(4, NE_RBCR0);
224 m_pBase->
write8(0, NE_RBCR1);
225 m_pBase->
write8(0x0a, NE_CMD);
228 uint16_t status = m_pBase->
read16(NE_DATA);
229 uint16_t length = m_pBase->
read16(NE_DATA);
233 ERROR(
"NE2K: length of packet is invalid!");
241 uint8_t *tmp =
reinterpret_cast<uint8_t *
>(
243 uint16_t *packBuffer =
reinterpret_cast<uint16_t *
>(tmp);
244 ByteSet(tmp, 0, length);
247 while (!(m_pBase->
read8(NE_ISR) & 0x40))
249 m_pBase->
write8(0x40, NE_ISR);
251 m_pBase->
write8(4, NE_RSAR0);
252 m_pBase->
write8(m_NextPacket, NE_RSAR1);
253 m_pBase->
write8((length) &0xff, NE_RBCR0);
254 m_pBase->
write8((length) >> 8, NE_RBCR1);
255 m_pBase->
write8(0x0a, NE_CMD);
258 int i, words = length / 2, oddbytes = length % 2;
259 for (i = 0; i < words; ++i)
260 packBuffer[i] = m_pBase->
read16(NE_DATA);
263 for (i = 0; i < oddbytes; ++i)
264 tmp[(length - oddbytes) + i] =
265 m_pBase->
read16(NE_DATA) &
270 while (!(m_pBase->
read8(NE_ISR) & 0x40))
272 m_pBase->
write8(0x40, NE_ISR);
275 m_NextPacket = status >> 8;
277 (m_NextPacket == PAGE_RX) ? (PAGE_STOP - 1) : (m_NextPacket - 1),
282 p->ptr =
reinterpret_cast<uintptr_t
>(packBuffer);
285 #ifdef NE2K_NO_THREADS 296 m_PacketQueue.pushBack(p);
304 int Ne2k::trampoline(
void *p)
306 Ne2k *pNe =
reinterpret_cast<Ne2k *
>(p);
307 pNe->receiveThread();
310 void Ne2k::receiveThread()
321 p = m_PacketQueue.popFront();
326 else if (!p->ptr || !p->len)
341 if (m_StationInfo.dnsServers)
342 delete[] m_StationInfo.dnsServers;
345 m_StationInfo.ipv4 = info.ipv4;
347 "NE2K: Setting ipv4, " << info.ipv4.toString() <<
", " 348 << m_StationInfo.ipv4.toString() <<
"...");
350 m_StationInfo.ipv6 = info.ipv6;
351 m_StationInfo.nIpv6Addresses = info.nIpv6Addresses;
352 NOTICE(
"NE2K: Copied " << info.nIpv6Addresses <<
" IPv6 addresses.");
354 m_StationInfo.subnetMask = info.subnetMask;
356 "NE2K: Setting subnet mask, " << info.subnetMask.toString() <<
", " 357 << m_StationInfo.subnetMask.toString()
361 "NE2K: Setting gateway, " << info.
gateway.toString() <<
", " 362 << m_StationInfo.
gateway.toString() <<
"...");
365 m_StationInfo.dnsServers = info.dnsServers;
369 <<
" servers being set]...");
376 return m_StationInfo;
382 uint8_t irqStatus = m_pBase->
read8(NE_ISR);
386 if (irqStatus & 0x05)
388 m_pBase->
write8(0x3D, NE_IMR);
390 m_pBase->
write8(0x3D, NE_IMR);
394 if (irqStatus & 0x0A)
398 WARNING(
"NE2K: Packet transmit failed!");
403 if (irqStatus & 0x10)
405 WARNING(
"NE2K: Receive buffer overflow");
407 if (irqStatus & 0x20)
409 WARNING(
"NE2K: Counter overflow");
413 m_pBase->
write8(irqStatus, NE_ISR);
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
virtual void write8(uint8_t value, size_t offset=0)=0
virtual uint16_t read16(size_t offset=0)=0
IpAddress gateway
Automatically calculated?
static ProcessorInformation & information()
virtual uintptr_t getInterruptNumber()
void receive(size_t nBytes, uintptr_t packet, Network *pCard, uint32_t offset)
size_t nDnsServers
Can contain IPv6 addresses.
virtual const StationInfo & getStationInfo()
virtual void write16(uint16_t value, size_t offset=0)=0
MemoryPool & getMemPool()
virtual void setSpecificType(String str)
virtual bool setStationInfo(const StationInfo &info)
static NetworkStack & instance()
void registerDevice(Network *pDevice)
Vector< Address * > m_Addresses
virtual irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler *handler, bool bEdge=false)=0
virtual uint8_t read8(size_t offset=0)=0
void free(uintptr_t buffer)
Frees an allocated buffer, allowing it to be used elsewhere.
virtual bool irq(irq_id_t number, InterruptState &state)
Device * getParent() const
virtual bool send(size_t nBytes, uintptr_t buffer)