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);
48  return FileSystem::IOError;
49  }
50 
51  // Initialize system control subsystem
53  if (sysResult != SunxiSystemControl::Success)
54  {
55  ERROR("failed to initialize System Control: result = " << (int) sysResult);
56  return FileSystem::IOError;
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);
66  return FileSystem::IOError;
67  }
68 
69  // Allocate receive descriptors
75 
77  if (vmResult != API::Success)
78  {
79  ERROR("failed to allocate receive descriptors: result = " << (int) vmResult);
80  return FileSystem::IOError;
81  }
82 
83  // Allocate transmit descriptors
88 
90  if (vmResult != API::Success)
91  {
92  ERROR("failed to allocate transmit descriptors: result = " << (int) vmResult);
93  return FileSystem::IOError;
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
113  const API::Result irqResult = ProcessCtl(SELF, EnableIRQ, InterruptNumber);
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 
224  m_transmitPending.push(pkt);
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 
264  m_transmitPackets.push(pkt);
265 
267  desc->bufsize = pkt->size | (TransmitDescFirst | TransmitDescLast |
269  desc->bufaddr = range.phys;
270  desc->status = FrameDescriptorCtl;
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
338  desc->status = FrameDescriptorCtl;
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 
362  if (m_io.read(MiiCmd) & MiiCmdPhyBusy)
363  {
364  ERROR("PHY is busy");
365  return false;
366  }
367  else
368  {
369  return true;
370  }
371 }
372 
373 u32 Sun8iEmac::miiRead(const u8 phyAddr,
374  const u8 regAddr)
375 {
377  ((regAddr << MiiCmdPhyRegShift) & MiiCmdPhyRegMask) |
379  MiiCmdPhyBusy);
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 
390 void 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 
520  Address descPhys = m_receiveDescRange.phys;
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
542  desc->status = FrameDescriptorCtl;
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);
549  m_receivePackets.insertAt(i, pkt);
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 
571  Address descPhys = m_transmitDescRange.phys;
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  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  {
636  if (!(m_io.read(BasicCtl1) & BasicCtl1Reset))
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 }
Sun8iEmac::m_transmitPending
Queue< NetworkQueue::Packet *, NetworkQueue::MaxPackets > m_transmitPending
List of pointers to packets pending transmission.
Definition: Sun8iEmac.h:435
SunxiSystemControl::Success
@ Success
Definition: SunxiSystemControl.h:76
Sun8iEmac::ReceiveCtl1DmaStart
@ ReceiveCtl1DmaStart
Definition: Sun8iEmac.h:223
Sun8iEmac::MiiCmdPhyRegMask
@ MiiCmdPhyRegMask
Definition: Sun8iEmac.h:139
Sun8iEmac::MiiCmdPhyRegShift
@ MiiCmdPhyRegShift
Definition: Sun8iEmac.h:138
Sun8iEmac::m_receiveDescRange
Memory::Range m_receiveDescRange
Memory range for receive descriptors.
Definition: Sun8iEmac.h:417
Index::insertAt
virtual bool insertAt(const Size position, T *item)
Inserts the given item at the given position.
Definition: Index.h:113
Sun8iEmac::MiiCmdPhyAddrMask
@ MiiCmdPhyAddrMask
Definition: Sun8iEmac.h:137
Memory::Range
Memory range.
Definition: Memory.h:55
Sun8iEmac::TransmitCtl1DmaStart
@ TransmitCtl1DmaStart
Definition: Sun8iEmac.h:204
API::Result
Result
Enumeration of generic kernel API result codes.
Definition: API.h:68
CacheClean
@ CacheClean
Definition: VMCtl.h:46
Sun8iEmac::ReceiveCtl1UnderFrame
@ ReceiveCtl1UnderFrame
Definition: Sun8iEmac.h:226
Sun8iEmac::transmit
virtual FileSystem::Result transmit(NetworkQueue::Packet *pkt)
Add a network packet to the transmit queue.
Definition: Sun8iEmac.cpp:214
SunxiClockControl::ResetEmacTx
@ ResetEmacTx
Definition: SunxiClockControl.h:70
Sun8iEmac::TransmitCtl0
@ TransmitCtl0
< Interrupt Enable
Definition: Sun8iEmac.h:71
WARNING
#define WARNING(msg)
Output a warning message.
Definition: Log.h:68
SunxiClockControl::initialize
Result initialize()
Perform initialization.
Definition: SunxiClockControl.cpp:21
Sun8iEmac::MiiRegIdHigh
@ MiiRegIdHigh
< Status
Definition: Sun8iEmac.h:153
Sun8iEmac::FrameDescriptorCtl
@ FrameDescriptorCtl
Definition: Sun8iEmac.h:246
Sun8iEmac.h
Sun8iEmac::MiiControlAutoEnable
@ MiiControlAutoEnable
Definition: Sun8iEmac.h:166
EnableIRQ
@ EnableIRQ
Definition: ProcessCtl.h:44
dsb
void dsb()
Data Synchronisation Barrier.
Definition: ARMCore.h:198
Sun8iEmac::FrameDescriptor::bufsize
u32 bufsize
Definition: Sun8iEmac.h:236
Sun8iEmac::TransmitStatus
@ TransmitStatus
< MAC Address Low
Definition: Sun8iEmac.h:85
Memory::Writable
@ Writable
Definition: Memory.h:42
NetworkDevice::m_maximumPacketSize
Size m_maximumPacketSize
Maximum size of each packet.
Definition: NetworkDevice.h:138
IO::map
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
NetworkDevice
Network Device abstract class.
Definition: NetworkDevice.h:41
Memory::User
@ User
Definition: Memory.h:44
ARMIO::write
void write(u32 reg, u32 data)
write to memory mapped I/O register
Definition: ARMIO.h:46
Sun8iEmac::MiiAdvSpeed10Full
@ MiiAdvSpeed10Full
Definition: Sun8iEmac.h:187
PAGESIZE
#define PAGESIZE
ARM uses 4K pages.
Definition: ARMConstant.h:97
Sun8iEmac::MiiCmdPhyCsrShift
@ MiiCmdPhyCsrShift
Definition: Sun8iEmac.h:141
NetworkQueue::MaxPackets
static const Size MaxPackets
Maximum number of packets available.
Definition: NetworkQueue.h:45
Sun8iEmac::BasicCtl1
@ BasicCtl1
< Basic Control 0
Definition: Sun8iEmac.h:68
SunxiClockControl::enable
Result enable(const Clock clock)
Enable a clock.
Definition: SunxiClockControl.cpp:37
Sun8iEmac::ReceiveStatus
@ ReceiveStatus
< Transmit Current Buffer
Definition: Sun8iEmac.h:88
Sun8iEmac::FrameDescriptor
Transmit/receive frame descriptor.
Definition: Sun8iEmac.h:233
Sun8iEmac::MemoryAddress
static const Address MemoryAddress
Physical memory address of the device memory mapped registers.
Definition: Sun8iEmac.h:51
Assert.h
Sun8iEmac::TransmitDescList
@ TransmitDescList
< Transmit Flow Control
Definition: Sun8iEmac.h:74
Sun8iEmac::FrameDescriptor::bufaddr
u32 bufaddr
Definition: Sun8iEmac.h:237
Memory::Device
@ Device
Definition: Memory.h:48
NetworkQueue::Packet::data
u8 * data
Definition: NetworkQueue.h:53
Address
unsigned long Address
A memory address.
Definition: Types.h:131
NetworkQueue::release
void release(Packet *packet)
Put unused packet back.
Definition: NetworkQueue.cpp:87
Sun8iEmac::TransmitCtl1
@ TransmitCtl1
< Transmit Control 0
Definition: Sun8iEmac.h:72
NetworkDevice::process
virtual FileSystem::Result process(const NetworkQueue::Packet *packet, const Size offset=0)
Process a received network packet.
Definition: NetworkDevice.cpp:92
FileSystem::IOError
@ IOError
Definition: FileSystem.h:58
NetworkQueue::Packet::size
Size size
Definition: NetworkQueue.h:52
VMCtl
API::Result VMCtl(const ProcessID procID, const MemoryOperation op, Memory::Range *range=ZERO)
Prototype for user applications.
Definition: VMCtl.h:61
CacheInvalidate
@ CacheInvalidate
Definition: VMCtl.h:47
Sun8iEmac::MiiControlReset
@ MiiControlReset
Definition: Sun8iEmac.h:168
SunxiClockControl::Success
@ Success
Definition: SunxiClockControl.h:79
FileSystem::Success
@ Success
Definition: FileSystem.h:54
ProcessCtl
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
Sun8iEmac::m_transmitIndex
Size m_transmitIndex
Current transmit packet index.
Definition: Sun8iEmac.h:441
Sun8iEmac::m_receiveIndex
Size m_receiveIndex
Current receive packet index.
Definition: Sun8iEmac.h:426
Sun8iEmac::ReceiveCtl0
@ ReceiveCtl0
< Transmit Descriptor List Address
Definition: Sun8iEmac.h:75
Memory::Readable
@ Readable
Definition: Memory.h:41
NetworkQueue::get
Packet * get()
Get unused packet.
Definition: NetworkQueue.cpp:72
Log.h
Sun8iEmac::ReceiveCtl1ErrorFrame
@ ReceiveCtl1ErrorFrame
Definition: Sun8iEmac.h:225
Sun8iEmac::Sun8iEmac
Sun8iEmac(const u32 inode, NetworkServer &server)
Constructor.
Definition: Sun8iEmac.cpp:26
Sun8iEmac::FrameDescriptor::next
u32 next
Definition: Sun8iEmac.h:238
SELF
#define SELF
Definition: ProcessID.h:35
Sun8iEmac::BasicCtl1BurstShift
@ BasicCtl1BurstShift
Definition: Sun8iEmac.h:110
Sun8iEmac::MiiData
@ MiiData
< Management Interface Command
Definition: Sun8iEmac.h:82
SunxiClockControl::ClockEphy
@ ClockEphy
Definition: SunxiClockControl.h:62
Sun8iEmac::m_transmitDescRange
Memory::Range m_transmitDescRange
Memory range for transmit descriptors.
Definition: Sun8iEmac.h:429
Sun8iEmac::printRx
void printRx()
Print diagnostic information about the receive queue (RX)
Definition: Sun8iEmac.cpp:143
Sun8iEmac::TransmitDescFirst
@ TransmitDescFirst
Definition: Sun8iEmac.h:248
Sun8iEmac::receive
FileSystem::Result receive()
Receive packets.
Definition: Sun8iEmac.cpp:290
Sun8iEmac::MiiRegControl
@ MiiRegControl
Definition: Sun8iEmac.h:151
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
Sun8iEmac::BasicCtl0Speed100
@ BasicCtl0Speed100
Definition: Sun8iEmac.h:101
Sun8iEmac::FrameDescriptor::status
u32 status
Definition: Sun8iEmac.h:235
Sun8iEmac::printTx
void printTx()
Print diagnostic information about the transmit queue (TX)
Definition: Sun8iEmac.cpp:164
Ethernet::Address
Ethernet network address.
Definition: Ethernet.h:52
Sun8iEmac::m_transmitDesc
Index< FrameDescriptor, NetworkQueue::MaxPackets > m_transmitDesc
List of pointers to transmit descriptors.
Definition: Sun8iEmac.h:432
Sun8iEmac::MiiStatusAutoCompl
@ MiiStatusAutoCompl
Definition: Sun8iEmac.h:179
Sun8iEmac::IntEnable
@ IntEnable
< Interrupt Status
Definition: Sun8iEmac.h:70
Sun8iEmac::miiBusyWait
bool miiBusyWait() const
Wait until the PHY comes out of busy state.
Definition: Sun8iEmac.cpp:348
Memory::Range::phys
Address phys
Physical address.
Definition: Memory.h:58
NetworkServer
Networking server.
Definition: NetworkServer.h:40
Sun8iEmac::interrupt
virtual FileSystem::Result interrupt(const Size vector)
Called when an interrupt has been triggered for this device.
Definition: Sun8iEmac.cpp:175
Sun8iEmac::MiiControlFullDuplex
@ MiiControlFullDuplex
Definition: Sun8iEmac.h:164
Sun8iEmac::MiiRegAdv
@ MiiRegAdv
< Identifier Low
Definition: Sun8iEmac.h:155
Sun8iEmac::resetPhy
FileSystem::Result resetPhy()
Reset the PHY connected to the MAC controller.
Definition: Sun8iEmac.cpp:405
Sun8iEmac::m_ccu
SunxiClockControl m_ccu
Clock Control Unit.
Definition: Sun8iEmac.h:411
Sun8iEmac::TransmitCurDesc
@ TransmitCurDesc
< Transmit DMA Status
Definition: Sun8iEmac.h:86
u16
unsigned short u16
Unsigned 16-bit number.
Definition: Types.h:56
NetworkDevice::m_receive
NetworkQueue m_receive
Definition: NetworkDevice.h:140
Sun8iEmac::ReceiveDescLast
@ ReceiveDescLast
Definition: Sun8iEmac.h:251
Sun8iEmac::BasicCtl0SpeedMask
@ BasicCtl0SpeedMask
Definition: Sun8iEmac.h:100
Sun8iEmac::ReceiveDescList
@ ReceiveDescList
< Receive Control 1
Definition: Sun8iEmac.h:77
Sun8iEmac::ReceiveCurDesc
@ ReceiveCurDesc
< Receive DMA Status
Definition: Sun8iEmac.h:89
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
Sun8iEmac::TransmitCtl1NextFrame
@ TransmitCtl1NextFrame
Definition: Sun8iEmac.h:206
Sun8iEmac::ReceiveDescFrmShift
@ ReceiveDescFrmShift
Definition: Sun8iEmac.h:252
IO::Result
Result
Result codes.
Definition: IO.h:42
Sun8iEmac::MiiCmdPhyBusy
@ MiiCmdPhyBusy
Definition: Sun8iEmac.h:143
Ethernet::Address::addr
u8 addr[6]
Definition: Ethernet.h:54
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
Sun8iEmac::miiRead
u32 miiRead(const u8 phyAddr, const u8 regAddr)
Read a Media-Independent-Interface (MII) register on the PHY.
Definition: Sun8iEmac.cpp:373
SunxiClockControl::ResetEphy
@ ResetEphy
Definition: SunxiClockControl.h:71
Sun8iEmac::TransmitDescChained
@ TransmitDescChained
Definition: Sun8iEmac.h:250
Sun8iEmac::IntStatusTransmit
@ IntStatusTransmit
Definition: Sun8iEmac.h:119
Sun8iEmac::ReceiveCtl1DmaEnable
@ ReceiveCtl1DmaEnable
Definition: Sun8iEmac.h:224
Sun8iEmac::ReceiveCtl1FullFrame
@ ReceiveCtl1FullFrame
Definition: Sun8iEmac.h:227
Sun8iEmac::m_syscon
SunxiSystemControl m_syscon
System Control Unit.
Definition: Sun8iEmac.h:414
Sun8iEmac::MiiRegIdLow
@ MiiRegIdLow
< Identifier High
Definition: Sun8iEmac.h:154
Sun8iEmac::initialize
virtual FileSystem::Result initialize()
Initialize the device.
Definition: Sun8iEmac.cpp:39
ARMIO::read
u32 read(u32 reg) const
read from memory mapped I/O register
Definition: ARMIO.h:62
Sun8iEmac::MaximumResetPoll
static const Size MaximumResetPoll
Maximum number of polling reset iterations.
Definition: Sun8iEmac.h:60
SunxiClockControl::Result
Result
Result codes.
Definition: SunxiClockControl.h:77
Sun8iEmac::AddrLow
@ AddrLow
< MAC Address High
Definition: Sun8iEmac.h:84
Sun8iEmac::configPhy
FileSystem::Result configPhy()
Configure the PHY connected to the MAC controller.
Definition: Sun8iEmac.cpp:477
LookupVirtual
@ LookupVirtual
Definition: VMCtl.h:42
IO::Success
@ Success
Definition: IO.h:44
File::status
virtual FileSystem::Result status(FileSystem::FileStat &st)
Retrieve file statistics.
Definition: File.cpp:62
Sun8iEmac::m_io
Arch::IO m_io
Memory mapped registers.
Definition: Sun8iEmac.h:408
SunxiClockControl::deassert
Result deassert(const Reset reset)
De-assert a reset signal.
Definition: SunxiClockControl.cpp:65
Sun8iEmac::startDMA
virtual FileSystem::Result startDMA()
Start DMA processing.
Definition: Sun8iEmac.cpp:228
Sun8iEmac::PhyMdioAddress
static const u8 PhyMdioAddress
Fixed address of the PHY on the MDIO bus.
Definition: Sun8iEmac.h:54
Sun8iEmac::IntEnableReceive
@ IntEnableReceive
Definition: Sun8iEmac.h:127
Sun8iEmac::BasicCtl1Reset
@ BasicCtl1Reset
Definition: Sun8iEmac.h:109
SunxiSystemControl::setupEmac
Result setupEmac(const uint phyAddr)
Setup EMAC mode.
Definition: SunxiSystemControl.cpp:35
Sun8iEmac::m_transmitPackets
Queue< NetworkQueue::Packet *, NetworkQueue::MaxPackets > m_transmitPackets
List of pointers to packets that the driver has submitted for transmission.
Definition: Sun8iEmac.h:438
Queue::count
virtual Size count() const
Returns the number of items in the Queue.
Definition: Queue.h:153
Sun8iEmac::MiiCmdPhyCsrDiv128
@ MiiCmdPhyCsrDiv128
Definition: Sun8iEmac.h:140
assert
#define assert(exp)
Insert program diagnostics.
Definition: assert.h:60
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
Sun8iEmac::TransmitCtl1DmaEnable
@ TransmitCtl1DmaEnable
Definition: Sun8iEmac.h:205
Sun8iEmac::getAddress
virtual FileSystem::Result getAddress(Ethernet::Address *address)
Read ethernet address.
Definition: Sun8iEmac.cpp:123
FileSystem::Result
Result
Result code for filesystem Actions.
Definition: FileSystem.h:52
u8
unsigned char u8
Unsigned 8-bit number.
Definition: Types.h:59
Sun8iEmac::MiiControlAutoRestart
@ MiiControlAutoRestart
Definition: Sun8iEmac.h:165
Sun8iEmac::TransmitCtl0Enable
@ TransmitCtl0Enable
Definition: Sun8iEmac.h:196
Sun8iEmac::AddrHigh
@ AddrHigh
< Management Interface Data
Definition: Sun8iEmac.h:83
SunxiSystemControl::Result
Result
Result codes.
Definition: SunxiSystemControl.h:74
Sun8iEmac::MiiStatusLink
@ MiiStatusLink
Definition: Sun8iEmac.h:177
Sun8iEmac::MiiCmdPhyAddrShift
@ MiiCmdPhyAddrShift
Definition: Sun8iEmac.h:136
Sun8iEmac::InterruptNumber
static const Size InterruptNumber
Interrupt number for this device on a sun8i family SoC.
Definition: Sun8iEmac.h:46
Sun8iEmac::TransmitDescLast
@ TransmitDescLast
Definition: Sun8iEmac.h:249
SunxiSystemControl::initialize
Result initialize()
Perform initialization.
Definition: SunxiSystemControl.cpp:21
Sun8iEmac::m_receivePackets
Index< NetworkQueue::Packet, NetworkQueue::MaxPackets > m_receivePackets
List of pointers to receive packets.
Definition: Sun8iEmac.h:423
Queue::pop
T & pop()
Remove item from the tail of the Queue.
Definition: Queue.h:76
API::Success
@ Success
Definition: API.h:70
Sun8iEmac::MaximumMiiPoll
static const Size MaximumMiiPoll
Maximum number of polling reads for MII-busy flag.
Definition: Sun8iEmac.h:57
Sun8iEmac::IntStatus
@ IntStatus
< Basic Control 1
Definition: Sun8iEmac.h:69
ARMIO::set
void set(Address addr, u32 data)
Set bits in memory mapped register.
Definition: ARMIO.h:109
Memory::Range::virt
Address virt
Virtual address.
Definition: Memory.h:57
Sun8iEmac::BasicCtl0FullDup
@ BasicCtl0FullDup
Definition: Sun8iEmac.h:99
Sun8iEmac::ReceiveCtl0Enable
@ ReceiveCtl0Enable
Definition: Sun8iEmac.h:215
SunxiClockControl::ClockEmacTx
@ ClockEmacTx
Definition: SunxiClockControl.h:61
Queue::push
bool push(const T &item)
Add item to the head of the Queue.
Definition: Queue.h:55
Sun8iEmac::MiiRegStatus
@ MiiRegStatus
< Control
Definition: Sun8iEmac.h:152
Sun8iEmac::MiiCmdPhyWrite
@ MiiCmdPhyWrite
Definition: Sun8iEmac.h:142
Sun8iEmac::ReceiveCtl1
@ ReceiveCtl1
< Receive Control 0
Definition: Sun8iEmac.h:76
NetworkDevice::m_transmit
NetworkQueue m_transmit
Definition: NetworkDevice.h:142
NetworkQueue::Packet
Represents a network packet.
Definition: NetworkQueue.h:50
Sun8iEmac::resetReceive
FileSystem::Result resetReceive()
Reset receive control functions.
Definition: Sun8iEmac.cpp:515
Memory::Range::size
Size size
Size in number of bytes.
Definition: Memory.h:59
Memory::Range::access
Access access
Page access flags.
Definition: Memory.h:60
NetworkDevice::initialize
virtual FileSystem::Result initialize()
Initialize the device.
Definition: NetworkDevice.cpp:42
ZERO
#define ZERO
Zero value.
Definition: Macros.h:43
Sun8iEmac::reset
FileSystem::Result reset()
Reset the controller.
Definition: Sun8iEmac.cpp:599
MapContiguous
@ MapContiguous
Definition: VMCtl.h:37
Sun8iEmac::TransmitDescRaiseInt
@ TransmitDescRaiseInt
Definition: Sun8iEmac.h:247
Sun8iEmac::m_receiveDesc
Index< FrameDescriptor, NetworkQueue::MaxPackets > m_receiveDesc
List of pointers to receive descriptors.
Definition: Sun8iEmac.h:420
Sun8iEmac::MiiAdvSpeed100Full
@ MiiAdvSpeed100Full
Definition: Sun8iEmac.h:188
Sun8iEmac::BasicCtl0
@ BasicCtl0
Definition: Sun8iEmac.h:67
Sun8iEmac::miiWrite
void miiWrite(const u8 phyAddr, const u8 regAddr, const u32 data)
Write a Media-Independent-Interface (MII) register on the PHY.
Definition: Sun8iEmac.cpp:390
Sun8iEmac::ReceiveDescFrmMask
@ ReceiveDescFrmMask
Definition: Sun8iEmac.h:253
Sun8iEmac::~Sun8iEmac
virtual ~Sun8iEmac()
Destructor.
Definition: Sun8iEmac.cpp:34
Sun8iEmac::resetTransmit
FileSystem::Result resetTransmit()
Reset transmit control functions.
Definition: Sun8iEmac.cpp:566
Sun8iEmac::MiiCmd
@ MiiCmd
< Receive Hash Table 1
Definition: Sun8iEmac.h:81
Sun8iEmac::IntEnableTransmit
@ IntEnableTransmit
Definition: Sun8iEmac.h:128
Sun8iEmac::setAddress
virtual FileSystem::Result setAddress(const Ethernet::Address *address)
Set ethernet address.
Definition: Sun8iEmac.cpp:133
Sun8iEmac::TransmitCtl1FullFrame
@ TransmitCtl1FullFrame
Definition: Sun8iEmac.h:207
Sun8iEmac::MiiControlSpeed100
@ MiiControlSpeed100
Definition: Sun8iEmac.h:167