21 #include "modules/system/network-stack/NetworkStack.h" 22 #include "modules/system/usb/UsbConstants.h" 23 #include "pedigree/kernel/LockGuard.h" 24 #include "pedigree/kernel/Log.h" 25 #include "pedigree/kernel/machine/Network.h" 26 #include "pedigree/kernel/network/IpAddress.h" 27 #include "pedigree/kernel/network/MacAddress.h" 28 #include "pedigree/kernel/process/Thread.h" 29 #include "pedigree/kernel/processor/Processor.h" 30 #include "pedigree/kernel/processor/ProcessorInformation.h" 31 #include "pedigree/kernel/time/Time.h" 32 #include "pedigree/kernel/utilities/MemoryPool.h" 33 #include "pedigree/kernel/utilities/Vector.h" 34 #include "pedigree/kernel/utilities/utility.h" 38 m_TxLock(false), m_IncomingPackets(false), m_RxPacketQueue(),
39 m_RxPacketQueueLock(), m_TxPacket(0)
50 for (
size_t i = 0; i < m_pInterface->endpointList.count(); i++)
52 Endpoint *pEndpoint = m_pInterface->endpointList[i];
53 if (!m_pInEndpoint && (pEndpoint->nTransferType == Endpoint::Bulk) &&
55 m_pInEndpoint = pEndpoint;
56 if (!m_pOutEndpoint && (pEndpoint->nTransferType == Endpoint::Bulk) &&
58 m_pOutEndpoint = pEndpoint;
59 if (m_pInEndpoint && m_pOutEndpoint)
65 ERROR(
"dm9601: no bulk IN endpoint");
71 ERROR(
"dm9601: no bulk OUT endpoint");
75 uint16_t *pMac =
new uint16_t[3];
76 for (
size_t i = 0; i < 3; ++i)
77 pMac[i] = readEeprom(i);
78 m_StationInfo.mac.setMac(pMac,
false);
81 "DM9601: MAC " << pMac[0] <<
":" << pMac[1] <<
":" << pMac[2] <<
":" 82 << pMac[3] <<
":" << pMac[4] <<
":" << pMac[5]);
85 writeRegister(NetworkControl, 1);
86 Time::delay(100 * Time::Multiplier::Millisecond);
89 writeRegister(NetworkControl, 0);
92 writeRegister(GeneralPurposeCtl, 0x1);
95 writeRegister(GeneralPurpose, 0);
98 writeRegister(NetworkControl, 0);
101 writeRegister(BackPressThreshold, 0x37);
104 writeRegister(FlowControl, 0x38);
107 writeRegister(RxFlowControl, 1 | (1 << 3) | (1 << 5));
110 writeRegister(UsbControl, 0);
114 writeRegister(PhysicalAddress, reinterpret_cast<uintptr_t>(pMac), 6);
118 writeRegister(RxControl, 5 | (1 << 3));
122 uint8_t *p =
new uint8_t;
126 readRegister(NetworkStatus, reinterpret_cast<uintptr_t>(p), 1);
127 Time::delay(100 * Time::Multiplier::Millisecond);
136 recvTrampoline,
this);
141 m_UsbState = HasDriver;
144 int Dm9601::recvTrampoline(
void *p)
147 pDm9601->receiveLoop();
150 int Dm9601::trampoline(
void *p)
153 pDm9601->receiveThread();
156 void Dm9601::receiveThread()
160 m_IncomingPackets.acquire();
162 m_RxPacketQueueLock.acquire();
163 Packet *pPacket = m_RxPacketQueue.popFront();
164 m_RxPacketQueueLock.release();
167 pPacket->len, pPacket->buffer + pPacket->offset,
this, 0);
169 uintptr_t buffer = pPacket->buffer;
176 void Dm9601::receiveLoop()
187 uint8_t *p =
new uint8_t;
188 readRegister(NetworkStatus, reinterpret_cast<uintptr_t>(p), 1);
189 while (*p & (1 << 4))
191 Time::delay(100 * Time::Multiplier::Millisecond);
192 readRegister(NetworkStatus, reinterpret_cast<uintptr_t>(p), 1);
199 padBytes = nBytes % 64;
200 ByteSet(reinterpret_cast<void *>(buffer + nBytes), 0, padBytes);
205 size_t txSize = nBytes + 2;
211 uint16_t *pBuffer =
new uint16_t[(txSize /
sizeof(uint16_t)) + 1];
212 *pBuffer = HOST_TO_LITTLE16(static_cast<uint16_t>(nBytes));
213 MemoryCopy(&pBuffer[1], reinterpret_cast<void *>(buffer), nBytes);
216 syncOut(m_pOutEndpoint, reinterpret_cast<uintptr_t>(pBuffer), txSize);
220 readRegister(TxStatus1 + m_TxPacket, reinterpret_cast<uintptr_t>(p), 1);
222 m_TxPacket = (m_TxPacket + 1) % 2;
226 readRegister(NetworkStatus, reinterpret_cast<uintptr_t>(p), 1);
233 void Dm9601::doReceive()
236 ssize_t ret = syncIn(m_pInEndpoint, buff, MAX_MTU, 0);
240 WARNING(
"dm9601: rx failure due to USB error: " << ret);
245 uint8_t *pBuffer =
reinterpret_cast<uint8_t *
>(buff);
246 uint8_t rxstatus = pBuffer[0];
248 LITTLE_TO_HOST16(*reinterpret_cast<uint16_t *>(buff + 1)) - 4;
252 WARNING(
"dm9601: rx failure: " << rxstatus <<
", length was " << len);
259 pPacket->buffer = buff;
263 m_RxPacketQueueLock.acquire();
264 m_RxPacketQueue.pushBack(pPacket);
265 m_RxPacketQueueLock.release();
267 m_IncomingPackets.release();
273 if (m_StationInfo.dnsServers)
274 delete[] m_StationInfo.dnsServers;
277 m_StationInfo.ipv4 = info.ipv4;
279 "DM9601: Setting ipv4, " << info.ipv4.toString() <<
", " 280 << m_StationInfo.ipv4.toString() <<
"...");
281 m_StationInfo.ipv6 = info.ipv6;
283 m_StationInfo.subnetMask = info.subnetMask;
285 "DM9601: Setting subnet mask, " << info.subnetMask.toString() <<
", " 286 << m_StationInfo.subnetMask.toString()
288 m_StationInfo.gateway = info.
gateway;
290 "DM9601: Setting gateway, " << info.
gateway.toString() <<
", " 291 << m_StationInfo.gateway.toString()
295 m_StationInfo.dnsServers = info.dnsServers;
298 "DM9601: Setting DNS servers [" <<
Dec << m_StationInfo.nDnsServers
299 <<
Hex <<
" servers being set]...");
306 return m_StationInfo;
311 if (!buffer || (nBytes > 0xFF))
313 return controlRequest(
314 UsbRequestType::Vendor | UsbRequestDirection::In, ReadRegister, 0, reg,
320 if (!buffer || (nBytes > 0xFF))
322 return controlRequest(
323 UsbRequestType::Vendor | UsbRequestDirection::Out, WriteRegister, 0,
324 reg, nBytes, buffer);
329 return controlRequest(
330 UsbRequestType::Vendor | UsbRequestDirection::Out, WriteRegister1, data,
336 if (!buffer || (nBytes > 0xFF))
338 return controlRequest(
339 UsbRequestType::Vendor | UsbRequestDirection::In, ReadMemory, 0, offset,
345 if (!buffer || (nBytes > 0xFF))
347 return controlRequest(
348 UsbRequestType::Vendor | UsbRequestDirection::Out, WriteMemory, 0,
349 offset, nBytes, buffer);
354 return controlRequest(
355 UsbRequestType::Vendor | UsbRequestDirection::Out, WriteMemory1, data,
362 uint16_t *ret =
new uint16_t;
363 writeRegister(PhyAddress, offset);
364 writeRegister(PhyControl, 0x4);
365 Time::delay(100 * Time::Multiplier::Millisecond);
366 writeRegister(PhyControl, 0);
367 readRegister(PhyLowByte, reinterpret_cast<uintptr_t>(ret), 2);
369 uint16_t retVal = *ret;
378 uint16_t *input =
new uint16_t;
380 writeRegister(PhyAddress, offset);
381 writeRegister(PhyLowByte, reinterpret_cast<uintptr_t>(input), 2);
382 writeRegister(PhyControl, 0x12);
383 Time::delay(100 * Time::Multiplier::Millisecond);
384 writeRegister(PhyControl, 0);
392 uint16_t *ret =
new uint16_t;
393 writeRegister(PhyAddress, offset | 0x40);
394 writeRegister(PhyControl, 0xc);
395 Time::delay(100 * Time::Multiplier::Millisecond);
396 writeRegister(PhyControl, 0);
397 readRegister(PhyLowByte, reinterpret_cast<uintptr_t>(ret), 2);
399 uint16_t retVal = *ret;
408 uint16_t *input =
new uint16_t;
410 writeRegister(PhyAddress, offset | 0x40);
411 writeRegister(PhyLowByte, reinterpret_cast<uintptr_t>(input), 2);
412 writeRegister(PhyControl, 0xa);
413 Time::delay(100 * Time::Multiplier::Millisecond);
414 writeRegister(PhyControl, 0);
virtual void initialiseDriver()
Implemented by the driver class, initialises driver-specific stuff.
ssize_t readMemory(uint16_t offset, uintptr_t buffer, size_t nBytes)
Reads data from device memory into a buffer.
ssize_t writeRegister(uint8_t reg, uintptr_t buffer, size_t nBytes)
Writes data from a buffer to a register.
IpAddress gateway
Automatically calculated?
static ProcessorInformation & information()
void receive(size_t nBytes, uintptr_t packet, Network *pCard, uint32_t offset)
void writeMii(uint8_t offset, uint16_t data)
Writes a 16-bit value to the external MII.
size_t nDnsServers
Can contain IPv6 addresses.
uint16_t readMii(uint8_t offset)
Reads a 16-bit value from the external MII.
MemoryPool & getMemPool()
ssize_t writeMemory(uint16_t offset, uintptr_t buffer, size_t nBytes)
Writes data from a buffer into device memory.
virtual bool setStationInfo(const StationInfo &info)
virtual const StationInfo & getStationInfo()
void writeEeprom(uint8_t offset, uint16_t data)
Writes a 16-bit value to the device EEPROM.
uint16_t readEeprom(uint8_t offset)
Reads a 16-bit value from the device EEPROM.
static NetworkStack & instance()
void registerDevice(Network *pDevice)
ssize_t readRegister(uint8_t reg, uintptr_t buffer, size_t nBytes)
Reads data from a register into a buffer.
void free(uintptr_t buffer)
Frees an allocated buffer, allowing it to be used elsewhere.
Device * getParent() const
virtual bool send(size_t nBytes, uintptr_t buffer)