FreeNOS
Sun8iEmac.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <Assert.h>
19#include <Log.h>
20#include "Sun8iEmac.h"
21
22#pragma clang optimize off
23#pragma GCC push_options
24#pragma GCC optimize ("O0")
25
27 NetworkServer &server)
28 : NetworkDevice(inode, server)
29 , m_receiveIndex(0)
30{
31 DEBUG("");
32}
33
35{
36 DEBUG("");
37}
38
40{
41 DEBUG("");
42
43 // Initialize clock subsystem
44 const SunxiClockControl::Result ccuResult = m_ccu.initialize();
45 if (ccuResult != SunxiClockControl::Success)
46 {
47 ERROR("failed to initialize Clock Control Unit: result = " << (int) ccuResult);
49 }
50
51 // Initialize system control subsystem
53 if (sysResult != SunxiSystemControl::Success)
54 {
55 ERROR("failed to initialize System Control: result = " << (int) sysResult);
57 }
58
59 // Map hardware registers
60 const IO::Result mapResult = m_io.map(MemoryAddress, PAGESIZE,
63 if (mapResult != IO::Success)
64 {
65 ERROR("failed to map hardware registers: result = " << (int) mapResult);
67 }
68
69 // Allocate receive descriptors
75
77 if (vmResult != API::Success)
78 {
79 ERROR("failed to allocate receive descriptors: result = " << (int) vmResult);
81 }
82
83 // Allocate transmit descriptors
88
90 if (vmResult != API::Success)
91 {
92 ERROR("failed to allocate transmit descriptors: result = " << (int) vmResult);
94 }
95
96 // Reset the hardware
97 const FileSystem::Result resetResult = reset();
98 if (resetResult != FileSystem::Success)
99 {
100 ERROR("hardware reset failed: result = " << (int) resetResult);
101 return resetResult;
102 }
103
104 // Initialize network protocols stack
106 if (result != FileSystem::Success)
107 {
108 ERROR("failed to initialize NetworkDevice: result = " << (int) result);
109 return FileSystem::IOError;
110 }
111
112 // Enable interrupts
114 if (irqResult != API::Success)
115 {
116 ERROR("failed to enable interrupt: result = " << (int) irqResult);
117 return FileSystem::IOError;
118 }
119
120 return FileSystem::Success;
121}
122
124{
125 m_io.read(Sun8iEmac::AddrLow, sizeof(u32), address);
126 m_io.read(Sun8iEmac::AddrHigh, sizeof(u16), &address->addr[4]);
127
128 DEBUG("address = " << *address);
129
130 return FileSystem::Success;
131}
132
134{
135 DEBUG("address = " << *address);
136
137 m_io.write(Sun8iEmac::AddrLow, sizeof(u32), address);
138 m_io.write(Sun8iEmac::AddrHigh, sizeof(u16), &address->addr[4]);
139
140 return FileSystem::Success;
141}
142
144{
145 DEBUG("");
146
148
149 DEBUG("receive: current receiveIndex = " << m_receiveIndex << " rx:desc.status = " << (void *)desc->status);
150 DEBUG("receive: current desc: = " << (void *) m_io.read(ReceiveCurDesc));
151 DEBUG("receive: desc base = " << (void *) m_receiveDescRange.phys << " desc size = " << sizeof(FrameDescriptor));
152 DEBUG("receive: DMA status = " << (void *) m_io.read(ReceiveStatus));
153
154 for (Size i = 0; i < m_receiveDesc.count(); i++)
155 {
157
158 DEBUG("m_receiveDesc[" << i << "]: status = " << (void *)d->status <<
159 ", bufsize = " << d->bufsize << ", bufaddr = " << (void *) d->bufaddr <<
160 ", next = " << (void *) d->next)
161 }
162}
163
165{
167
168 DEBUG("transmit: transmitIndex = " << m_transmitIndex << " tx:desc.status = " << (void *)desc->status);
169 DEBUG("transmit: current desc: = " << (void *) m_io.read(TransmitCurDesc));
170 DEBUG("transmit: desc base = " << (void *) m_transmitDescRange.phys <<
171 " desc size = " << sizeof(FrameDescriptor));
172 DEBUG("transmit: DMA status = " << (void *) m_io.read(TransmitStatus));
173}
174
176{
177 // Clear interrupt flags by writing back the values read
178 const u32 status = m_io.read(IntStatus);
180
181 // Re-enable interrupts
182 m_io.write(IntEnable, 0);
184
185 DEBUG("vector = " << vector << " status = " << (void *) status);
186 DEBUG("receivectl1 = " << (void *) m_io.read(ReceiveCtl1) <<
187 " transmitctl1 = " << (void *) m_io.read(TransmitCtl1));
188
190 {
191 printTx();
192
193 // Release all packet buffers
194 while (m_transmitPackets.count() > 0)
195 {
197 DEBUG("releasing tx:pkt = " << (void *) pkt);
198 m_transmit.release(pkt);
199 }
200 }
201
202 // Check if packets are received
203 const FileSystem::Result result = receive();
204 if (result != FileSystem::Success)
205 {
206 ERROR("failed to receive packets");
207 }
208
209 // Re-enable the interrupt line on the interrupt controller
211 return FileSystem::Success;
212}
213
215{
216 DEBUG("size = " << pkt->size);
217
219 {
220 ERROR("transmit queue full");
221 return FileSystem::IOError;
222 }
223
225 return FileSystem::Success;
226}
227
229{
230 DEBUG("");
231
232 // Are we still transmitting?
233 if (m_transmitPackets.count() > 0)
234 {
235 return FileSystem::Success;
236 }
237
238 // Transmitter ready. Prepare the queue with pending packets
239 while (m_transmitPending.count() > 0)
240 {
241 Memory::Range range;
242
244 range.virt = (Address) pkt->data;
245 range.size = PAGESIZE;
246
247 // Retrieve physical address of packet payload memory
248 const API::Result vmResult = VMCtl(SELF, LookupVirtual, &range);
249 if (vmResult != API::Success)
250 {
251 ERROR("failed to lookup packet physical address: result = " << (int) vmResult);
252 return FileSystem::IOError;
253 }
254
255 // Clean cache for packet payload memory
256 const API::Result ccResult = VMCtl(SELF, CacheClean, &range);
257 if (ccResult != API::Success)
258 {
259 ERROR("failed to clean data cache at " << (void *) range.virt <<
260 ": result = " << (int) ccResult);
261 return FileSystem::IOError;
262 }
263
265
269 desc->bufaddr = range.phys;
271 dsb();
272
273 DEBUG("tx:index = " << m_transmitIndex << " tx:desc.status = " << (void *) desc->status <<
274 " tx:size = " << pkt->size << " tx:payload = " << *pkt);
275
277 }
278
279 // Start transmitter DMA engine
280 if (m_transmitPackets.count() > 0)
281 {
282 printTx();
284 }
285
286 // Done
287 return FileSystem::Success;
288}
289
291{
292 DEBUG("");
293
294 printRx();
295
296 while (true)
297 {
299 assert(desc);
300
301 if (desc->status & FrameDescriptorCtl)
302 {
303 break;
304 }
305
307 assert(pkt != ZERO);
308
309 if (!(desc->status & ReceiveDescLast))
310 {
311 ERROR("last flag not set: skipping packet");
312 continue;
313 }
314
315 const Size bytes = (desc->status >> ReceiveDescFrmShift) & ReceiveDescFrmMask;
316 DEBUG("packet: index = " << m_receiveIndex << " bytes = " << bytes);
317
318 // invalidate cache lines here for the payload
319 Memory::Range range;
320 range.virt = (Address) pkt->data;
321 range.size = PAGESIZE;
322 assert(pkt->size <= PAGESIZE);
323
324 const API::Result result = VMCtl(SELF, CacheInvalidate, &range);
325 if (result != API::Success)
326 {
327 ERROR("failed to invalidate cache lines for packet: result = " << (int) result);
328 return FileSystem::IOError;
329 }
330
331 // Process the packet with networking protocols.
332 // Note that we need to remove the Ethernet Frame Check Sequence (FCS)
333 // which is a 4-bytes field padded at the end of each packet.
334 pkt->size = bytes - sizeof(u32);
335 process(pkt);
336
337 // Return descriptor back to the device
339 dsb();
340
341 // Move to the next descriptor
343 }
344
345 return FileSystem::Success;
346}
347
349{
350 DEBUG("");
351
352 for (Size i = 0; i < MaximumMiiPoll; i++)
353 {
354 const u32 value = m_io.read(MiiCmd);
355
356 if (!(value & MiiCmdPhyBusy))
357 {
358 break;
359 }
360 }
361
363 {
364 ERROR("PHY is busy");
365 return false;
366 }
367 else
368 {
369 return true;
370 }
371}
372
374 const u8 regAddr)
375{
377 ((regAddr << MiiCmdPhyRegShift) & MiiCmdPhyRegMask) |
380
381 if (!miiBusyWait())
382 return 0;
383
384 const u32 data = m_io.read(MiiData);
385
386 DEBUG("phyAddr = " << phyAddr << " regAddr = " << regAddr << " data = " << (void *) data);
387 return data;
388}
389
390void Sun8iEmac::miiWrite(const u8 phyAddr,
391 const u8 regAddr,
392 const u32 data)
393{
394 DEBUG("phyAddr = " << phyAddr << " regAddr = " << regAddr << " data = " << (void *) data);
395
396 m_io.write(MiiData, data);
398 ((regAddr << MiiCmdPhyRegShift) & MiiCmdPhyRegMask) |
401
402 miiBusyWait();
403}
404
406{
407 DEBUG("");
408
409 // Enable TX clock
411 if (ccuResult != SunxiClockControl::Success)
412 {
413 ERROR("failed to enable TX clock: result = " << (int) ccuResult);
414 return FileSystem::IOError;
415 }
416
417 // De-assert TX Reset
419 if (ccuResult != SunxiClockControl::Success)
420 {
421 ERROR("failed to de-assert TX clock reset: result = " << (int) ccuResult);
422 return FileSystem::IOError;
423 }
424
425 // Enable Ephy Clock
427 if (ccuResult != SunxiClockControl::Success)
428 {
429 ERROR("failed to enable Ephy clock: result = " << (int) ccuResult);
430 return FileSystem::IOError;
431 }
432
433 // De-assert Ephy Reset
435 if (ccuResult != SunxiClockControl::Success)
436 {
437 ERROR("failed to de-assert Ephy clock reset: result = " << (int) ccuResult);
438 return FileSystem::IOError;
439 }
440
441 // Write system control register to prepare the PHY
443
444 // Read PHY identification
445 const u32 idLow = miiRead(PhyMdioAddress, MiiRegIdLow);
446 const u32 idHigh = miiRead(PhyMdioAddress, MiiRegIdHigh);
447 if (idLow != 0x1400 || idHigh != 0x44)
448 {
449 WARNING("unrecognized PHY identification: high = " << (void *) idHigh <<
450 " low = " << (void *) idLow);
451 }
452 DEBUG("idHigh = " << (void *)idHigh << " idLow " << (void *)idLow);
453
454 // Reset the PHY via MII
456
457 // Check if the reset bit is cleared
458 u32 reg = 0;
459 for (Size i = 0; i < MaximumMiiPoll; i++)
460 {
462 if (!(reg & MiiControlReset))
463 {
464 break;
465 }
466 }
467
468 if (reg & MiiControlReset)
469 {
470 ERROR("failed to reset PHY: reset bit is high: reg = " << (void *) reg);
471 return FileSystem::IOError;
472 }
473
474 return FileSystem::Success;
475}
476
478{
479 DEBUG("");
480
481 // Fill in advertised capabilities
483 val |= MiiAdvSpeed10Full;
484 val |= MiiAdvSpeed100Full;
486
487 // Restart auto-negociation
492
493 // Wait until auto-negociation is complete and link is up
494 for (Size i = 0; i < MaximumMiiPoll; i++)
495 {
497 if ((val & MiiStatusAutoCompl) &&
498 (val & MiiStatusLink))
499 {
500 break;
501 }
502 }
503
504 if (!((val & MiiStatusAutoCompl) &&
505 (val & MiiStatusLink)))
506 {
507 WARNING("timeout waiting for auto negociation/link: status = " << (void *) val);
508 return FileSystem::Success;
509 }
510
511 DEBUG("status = " << (void *) val);
512 return FileSystem::Success;
513}
514
516{
517 DEBUG("");
518
521
522 // Reconstruct receive descriptor list
523 for (Size i = 0; i < NetworkQueue::MaxPackets; i++)
524 {
525 const bool last = (i == NetworkQueue::MaxPackets - 1);
526
528 assert(pkt != ZERO);
529
530 // Find physical address of this packet
531 Memory::Range range;
532 range.virt = (Address) pkt->data;
533 range.size = PAGESIZE;
534 const API::Result result = VMCtl(SELF, LookupVirtual, &range);
535 if (result != API::Success)
536 {
537 ERROR("failed to lookup physical address of packet: result = " << (int) result);
538 return FileSystem::IOError;
539 }
540
541 // Prepare receive descriptor
544 desc->bufaddr = range.phys;
545 desc->next = last ? m_receiveDescRange.phys : descPhys + sizeof(FrameDescriptor);
546
547 // Move to next descriptor
548 m_receiveDesc.insertAt(i, desc);
550 desc++;
551 descPhys += sizeof(FrameDescriptor);
552 }
553
554 dsb();
555
556 // Finalize receive administration
557 m_receiveIndex = 0;
562
563 return FileSystem::Success;
564}
565
567{
568 DEBUG("");
569
572
573 // Reconstruct transmit descriptor list
574 for (Size i = 0; i < NetworkQueue::MaxPackets; i++)
575 {
576 const bool last = (i == NetworkQueue::MaxPackets - 1);
577
578 // Prepare transmit descriptor
579 desc->status = 0;
580 desc->bufsize = 0;
581 desc->bufaddr = 0;
582 desc->next = last ? m_transmitDescRange.phys : descPhys + sizeof(FrameDescriptor);
583
584 // Move to next descriptor
585 m_transmitDesc.insertAt(i, desc);
586 desc++;
587 descPhys += sizeof(FrameDescriptor);
588 }
589
590 // Finalize administration
591 m_transmitIndex = 0;
595
596 return FileSystem::Success;
597}
598
600{
601 DEBUG("");
602
603 // Save the current MAC address (written by the bootloader)
604 ALIGN(sizeof(u32)) Ethernet::Address mac;
605 const FileSystem::Result macRead = getAddress(&mac);
606 if (macRead != FileSystem::Success)
607 {
608 ERROR("failed to read MAC address: result = " << (int) macRead);
609 return macRead;
610 }
611
612 DEBUG("savedMac = " << mac);
613
614 // Reset the PHY and MDIO bus */
615 FileSystem::Result result = resetPhy();
616 if (result != FileSystem::Success)
617 {
618 ERROR("failed to reset PHY: result = " << (int) result);
619 return result;
620 }
621
622 // Configure PHY
623 result = configPhy();
624 if (result != FileSystem::Success)
625 {
626 ERROR("failed to reset PHY: result = " << (int) result);
627 return result;
628 }
629
630 // Initialize hardware
632
633 // Wait for reset to complete
634 for (Size i = 0; i < MaximumResetPoll; i++)
635 {
637 {
638 break;
639 }
640 }
641
642 // Did the hardware reset complete?
644 {
645 ERROR("basic hardware reset failed");
646 return FileSystem::IOError;
647 }
648
649 // Apply saved MAC address
650 const FileSystem::Result macWrite = setAddress(&mac);
651 if (macWrite != FileSystem::Success)
652 {
653 ERROR("failed to write MAC address: result = " << (int) macWrite);
654 return macWrite;
655 }
656
657 // Clear and enable interrupts
658 m_io.write(IntStatus, 0x1FFFFFF);
660
661 // Set DMA burst length
663
664 const FileSystem::Result rxResult = resetReceive();
665 if (rxResult != FileSystem::Success)
666 {
667 ERROR("failed to reset receive control: result = " << (int) rxResult);
668 return rxResult;
669 }
670
671 const FileSystem::Result txResult = resetTransmit();
672 if (txResult != FileSystem::Success)
673 {
674 ERROR("failed to reset transmit control: result = " << (int) txResult);
675 return txResult;
676 }
677
678 // Adjust link bits
679 u32 val = m_io.read(BasicCtl0);
680 val |= BasicCtl0FullDup;
681 val &= ~BasicCtl0SpeedMask;
682 val |= BasicCtl0Speed100;
683 m_io.write(BasicCtl0, val);
684
685 return FileSystem::Success;
686}
#define dsb(type)
Data Memory Barrier.
Result
Enumeration of generic kernel API result codes.
Definition API.h:69
@ Success
Definition API.h:70
void set(Address addr, u32 data)
Set bits in memory mapped register.
Definition ARMIO.h:109
void write(u32 reg, u32 data)
write to memory mapped I/O register
Definition ARMIO.h:46
u32 read(u32 reg) const
read from memory mapped I/O register
Definition ARMIO.h:62
virtual FileSystem::Result status(FileSystem::FileStat &st)
Retrieve file statistics.
Definition File.cpp:62
Result map(Address phys, Size size=4096, Memory::Access access=Memory::Readable|Memory::Writable|Memory::User)
Map I/O address space.
Definition IO.cpp:38
Result
Result codes.
Definition IO.h:43
@ Success
Definition IO.h:44
virtual bool insertAt(const Size position, T *item)
Inserts the given item at the given position.
Definition Index.h:113
Network Device abstract class.
NetworkQueue m_receive
Size m_maximumPacketSize
Maximum size of each packet.
virtual FileSystem::Result process(const NetworkQueue::Packet *packet, const Size offset=0)
Process a received network packet.
virtual FileSystem::Result initialize()
Initialize the device.
NetworkQueue m_transmit
Packet * get()
Get unused packet.
void release(Packet *packet)
Put unused packet back.
static const Size MaxPackets
Maximum number of packets available.
Networking server.
T & pop()
Remove item from the tail of the Queue.
Definition Queue.h:76
virtual Size count() const
Returns the number of items in the Queue.
Definition Queue.h:153
bool push(const T &item)
Add item to the head of the Queue.
Definition Queue.h:55
static const u8 PhyMdioAddress
Fixed address of the PHY on the MDIO bus.
Definition Sun8iEmac.h:54
static const Size MaximumMiiPoll
Maximum number of polling reads for MII-busy flag.
Definition Sun8iEmac.h:57
Index< NetworkQueue::Packet, NetworkQueue::MaxPackets > m_receivePackets
List of pointers to receive packets.
Definition Sun8iEmac.h:423
@ MiiControlSpeed100
Definition Sun8iEmac.h:167
@ MiiControlReset
Definition Sun8iEmac.h:168
@ MiiControlAutoEnable
Definition Sun8iEmac.h:166
@ MiiControlAutoRestart
Definition Sun8iEmac.h:165
@ MiiControlFullDuplex
Definition Sun8iEmac.h:164
Queue< NetworkQueue::Packet *, NetworkQueue::MaxPackets > m_transmitPending
List of pointers to packets pending transmission.
Definition Sun8iEmac.h:435
FileSystem::Result reset()
Reset the controller.
@ ReceiveCtl1ErrorFrame
Definition Sun8iEmac.h:225
@ ReceiveCtl1DmaStart
Definition Sun8iEmac.h:223
@ ReceiveCtl1UnderFrame
Definition Sun8iEmac.h:226
@ ReceiveCtl1DmaEnable
Definition Sun8iEmac.h:224
@ ReceiveCtl1FullFrame
Definition Sun8iEmac.h:227
Index< FrameDescriptor, NetworkQueue::MaxPackets > m_receiveDesc
List of pointers to receive descriptors.
Definition Sun8iEmac.h:420
virtual FileSystem::Result startDMA()
Start DMA processing.
virtual FileSystem::Result interrupt(const Size vector)
Called when an interrupt has been triggered for this device.
virtual FileSystem::Result getAddress(Ethernet::Address *address)
Read ethernet address.
virtual FileSystem::Result setAddress(const Ethernet::Address *address)
Set ethernet address.
u32 miiRead(const u8 phyAddr, const u8 regAddr)
Read a Media-Independent-Interface (MII) register on the PHY.
Sun8iEmac(const u32 inode, NetworkServer &server)
Constructor.
Definition Sun8iEmac.cpp:26
@ MiiData
< Management Interface Command
Definition Sun8iEmac.h:82
@ ReceiveStatus
< Transmit Current Buffer
Definition Sun8iEmac.h:88
@ ReceiveCtl1
< Receive Control 0
Definition Sun8iEmac.h:76
@ BasicCtl1
< Basic Control 0
Definition Sun8iEmac.h:68
@ TransmitCurDesc
< Transmit DMA Status
Definition Sun8iEmac.h:86
@ TransmitCtl1
< Transmit Control 0
Definition Sun8iEmac.h:72
@ IntEnable
< Interrupt Status
Definition Sun8iEmac.h:70
@ AddrHigh
< Management Interface Data
Definition Sun8iEmac.h:83
@ AddrLow
< MAC Address High
Definition Sun8iEmac.h:84
@ IntStatus
< Basic Control 1
Definition Sun8iEmac.h:69
@ ReceiveDescList
< Receive Control 1
Definition Sun8iEmac.h:77
@ TransmitStatus
< MAC Address Low
Definition Sun8iEmac.h:85
@ ReceiveCtl0
< Transmit Descriptor List Address
Definition Sun8iEmac.h:75
@ TransmitCtl0
< Interrupt Enable
Definition Sun8iEmac.h:71
@ ReceiveCurDesc
< Receive DMA Status
Definition Sun8iEmac.h:89
@ TransmitDescList
< Transmit Flow Control
Definition Sun8iEmac.h:74
@ MiiCmd
< Receive Hash Table 1
Definition Sun8iEmac.h:81
@ MiiStatusAutoCompl
Definition Sun8iEmac.h:179
@ MiiStatusLink
Definition Sun8iEmac.h:177
@ MiiCmdPhyBusy
Definition Sun8iEmac.h:143
@ MiiCmdPhyAddrShift
Definition Sun8iEmac.h:136
@ MiiCmdPhyWrite
Definition Sun8iEmac.h:142
@ MiiCmdPhyCsrDiv128
Definition Sun8iEmac.h:140
@ MiiCmdPhyCsrShift
Definition Sun8iEmac.h:141
@ MiiCmdPhyRegMask
Definition Sun8iEmac.h:139
@ MiiCmdPhyAddrMask
Definition Sun8iEmac.h:137
@ MiiCmdPhyRegShift
Definition Sun8iEmac.h:138
Index< FrameDescriptor, NetworkQueue::MaxPackets > m_transmitDesc
List of pointers to transmit descriptors.
Definition Sun8iEmac.h:432
@ TransmitCtl0Enable
Definition Sun8iEmac.h:196
@ MiiAdvSpeed100Full
Definition Sun8iEmac.h:188
@ MiiAdvSpeed10Full
Definition Sun8iEmac.h:187
@ MiiRegControl
Definition Sun8iEmac.h:151
@ MiiRegAdv
< Identifier Low
Definition Sun8iEmac.h:155
@ MiiRegStatus
< Control
Definition Sun8iEmac.h:152
@ MiiRegIdLow
< Identifier High
Definition Sun8iEmac.h:154
@ MiiRegIdHigh
< Status
Definition Sun8iEmac.h:153
FileSystem::Result receive()
Receive packets.
static const Size MaximumResetPoll
Maximum number of polling reset iterations.
Definition Sun8iEmac.h:60
Size m_transmitIndex
Current transmit packet index.
Definition Sun8iEmac.h:441
@ IntStatusTransmit
Definition Sun8iEmac.h:119
bool miiBusyWait() const
Wait until the PHY comes out of busy state.
virtual FileSystem::Result initialize()
Initialize the device.
Definition Sun8iEmac.cpp:39
void printRx()
Print diagnostic information about the receive queue (RX)
@ TransmitCtl1DmaStart
Definition Sun8iEmac.h:204
@ TransmitCtl1DmaEnable
Definition Sun8iEmac.h:205
@ TransmitCtl1FullFrame
Definition Sun8iEmac.h:207
@ TransmitCtl1NextFrame
Definition Sun8iEmac.h:206
Queue< NetworkQueue::Packet *, NetworkQueue::MaxPackets > m_transmitPackets
List of pointers to packets that the driver has submitted for transmission.
Definition Sun8iEmac.h:438
void printTx()
Print diagnostic information about the transmit queue (TX)
Memory::Range m_receiveDescRange
Memory range for receive descriptors.
Definition Sun8iEmac.h:417
void miiWrite(const u8 phyAddr, const u8 regAddr, const u32 data)
Write a Media-Independent-Interface (MII) register on the PHY.
FileSystem::Result configPhy()
Configure the PHY connected to the MAC controller.
SunxiSystemControl m_syscon
System Control Unit.
Definition Sun8iEmac.h:414
FileSystem::Result resetTransmit()
Reset transmit control functions.
FileSystem::Result resetPhy()
Reset the PHY connected to the MAC controller.
Arch::IO m_io
Memory mapped registers.
Definition Sun8iEmac.h:408
@ IntEnableTransmit
Definition Sun8iEmac.h:128
@ IntEnableReceive
Definition Sun8iEmac.h:127
@ BasicCtl1Reset
Definition Sun8iEmac.h:109
@ BasicCtl1BurstShift
Definition Sun8iEmac.h:110
virtual FileSystem::Result transmit(NetworkQueue::Packet *pkt)
Add a network packet to the transmit queue.
static const Address MemoryAddress
Physical memory address of the device memory mapped registers.
Definition Sun8iEmac.h:51
FileSystem::Result resetReceive()
Reset receive control functions.
SunxiClockControl m_ccu
Clock Control Unit.
Definition Sun8iEmac.h:411
@ TransmitDescChained
Definition Sun8iEmac.h:250
@ ReceiveDescFrmMask
Definition Sun8iEmac.h:253
@ ReceiveDescFrmShift
Definition Sun8iEmac.h:252
@ TransmitDescRaiseInt
Definition Sun8iEmac.h:247
@ ReceiveDescLast
Definition Sun8iEmac.h:251
@ TransmitDescFirst
Definition Sun8iEmac.h:248
@ FrameDescriptorCtl
Definition Sun8iEmac.h:246
@ TransmitDescLast
Definition Sun8iEmac.h:249
@ BasicCtl0Speed100
Definition Sun8iEmac.h:101
@ BasicCtl0FullDup
Definition Sun8iEmac.h:99
virtual ~Sun8iEmac()
Destructor.
Definition Sun8iEmac.cpp:34
Size m_receiveIndex
Current receive packet index.
Definition Sun8iEmac.h:426
@ ReceiveCtl0Enable
Definition Sun8iEmac.h:215
static const Size InterruptNumber
Interrupt number for this device on a sun8i family SoC.
Definition Sun8iEmac.h:46
Memory::Range m_transmitDescRange
Memory range for transmit descriptors.
Definition Sun8iEmac.h:429
Result deassert(const Reset reset)
De-assert a reset signal.
Result initialize()
Perform initialization.
Result enable(const Clock clock)
Enable a clock.
Result setupEmac(const uint phyAddr)
Setup EMAC mode.
Result initialize()
Perform initialization.
#define SELF
Definition ProcessID.h:35
API::Result ProcessCtl(const ProcessID proc, const ProcessOperation op, const Address addr=0, const Address output=0)
Prototype for user applications.
Definition ProcessCtl.h:93
API::Result VMCtl(const ProcessID procID, const MemoryOperation op, Memory::Range *range=ZERO)
Prototype for user applications.
Definition VMCtl.h:61
@ CacheClean
Definition VMCtl.h:46
@ CacheInvalidate
Definition VMCtl.h:47
@ LookupVirtual
Definition VMCtl.h:42
@ MapContiguous
Definition VMCtl.h:37
@ EnableIRQ
Definition ProcessCtl.h:44
#define PAGESIZE
ARM uses 4K pages.
Definition ARMConstant.h:97
#define assert(exp)
Insert program diagnostics.
Definition assert.h:60
unsigned int u32
Unsigned 32-bit number.
Definition Types.h:53
unsigned long Address
A memory address.
Definition Types.h:131
#define ERROR(msg)
Output an error message.
Definition Log.h:61
#define WARNING(msg)
Output a warning message.
Definition Log.h:68
unsigned short u16
Unsigned 16-bit number.
Definition Types.h:56
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define ZERO
Zero value.
Definition Macros.h:43
#define ALIGN(n)
Aligns a symbol at the given boundary.
Definition Macros.h:167
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
unsigned char u8
Unsigned 8-bit number.
Definition Types.h:59
Result
Result code for filesystem Actions.
Definition FileSystem.h:53
@ User
Definition Memory.h:44
@ Readable
Definition Memory.h:41
@ Device
Definition Memory.h:48
@ Writable
Definition Memory.h:42
Ethernet network address.
Definition Ethernet.h:53
Memory range.
Definition Memory.h:56
Size size
Size in number of bytes.
Definition Memory.h:59
Address phys
Physical address.
Definition Memory.h:58
Address virt
Virtual address.
Definition Memory.h:57
Access access
Page access flags.
Definition Memory.h:60
Represents a network packet.
Transmit/receive frame descriptor.
Definition Sun8iEmac.h:234