Commit graph

43 commits

Author SHA1 Message Date
Liav A 3f63be949a Kernel/Net: Don't allocate memory for adapters' names
Instead, use a FixedStringBuffer to store a string with up to 16 chars.
2023-08-12 11:48:48 -06:00
Kirill Nikolaev 6cdb1f0415 Kernel: Add an initial implementation of virtio-net driver
It can be exercised by setting
    SERENITY_ETHERNET_DEVICE_TYPE=virtio-net-pci.
2023-07-11 00:49:11 -06:00
Liav A 8f21420a1d Kernel: Move all boot-related code to the new Boot subdirectory 2023-06-04 21:32:34 +02:00
Liav A 7c0540a229 Everywhere: Move global Kernel pattern code to Kernel/Library directory
This has KString, KBuffer, DoubleBuffer, KBufferBuilder, IOWindow,
UserOrKernelBuffer and ScopedCritical classes being moved to the
Kernel/Library subdirectory.

Also, move the panic and assertions handling code to that directory.
2023-06-04 21:32:34 +02:00
Liav A 7c1f645e27 Kernel/Net: Iron out the locking mechanism across the subsystem
There is a big mix of LockRefPtrs all over the Networking subsystem, as
well as lots of room for improvements with our locking patterns, which
this commit will not pursue, but will give a good start for such work.

To deal with this situation, we change the following things:
- Creating instances of NetworkAdapter should always yield a non-locking
  NonnullRefPtr. Acquiring an instance from the NetworkingManagement
  should give a simple RefPtr,as giving LockRefPtr does not really
  protect from concurrency problems in such case.
- Since NetworkingManagement works with normal RefPtrs we should
  protect all instances of RefPtr<NetworkAdapter> with SpinlockProtected
  to ensure references are gone unexpectedly.
- Protect the so_error class member with a proper spinlock. This happens
  to be important because the clear_so_error() method lacked any proper
  locking measures. It also helps preventing a possible TOCTOU when we
  might do a more fine-grained locking in the Socket code, so this could
  be definitely a start for this.
- Change unnecessary LockRefPtr<PacketWithTimestamp> in the structure
  of OutgoingPacket to a simple RefPtr<PacketWithTimestamp> as the whole
  list should be MutexProtected.
2023-04-14 19:27:56 +02:00
Liav A bd7d4513bf Kernel/Net: Make the LoopbackAdapter initializer to use ErrorOr pattern
This looks much more nice, and also matches our pattern for other types
of network adapters' initializers.
2023-04-14 19:27:56 +02:00
Liav A 9f011592be Kernel/Net: Convert initializers to return NonnullRefPtr<NetworkAdapter>
There's no need for using NonnullLockRefPtr here.
2023-04-14 19:27:56 +02:00
Andreas Kling 7369d0ab5f Kernel: Stop using NonnullLockRefPtrVector 2023-03-06 23:46:36 +01:00
Liav A 2d1719da73 Kernel/Net: Propagate proper errno codes from determine_network_device
Returning literal strings is not the proper action here, because we
should always assume that error could be propagated back to userland, so
we need to keep a valid errno when returning an Error.
2023-02-10 09:14:20 +00:00
Liav A c876412b1b Kernel: Remove the NE2000 PCI network adapter driver
Nobody tests this network card as the person who added it, Jean-Baptiste
Boric (known as boricj) is not an active contributor in the project now.
After a discussion with him on the Discord server, we agreed it's for
the best to remove the driver, as for two reasons:
- The original author (boricj) agreed to do this, stating that he will
  not be able to test the driver anymore after his Athlon XP machine is
  no longer supported after the removal of the i686 port.
- It was agreed that the NE2000 network card family is far from the
  ideal hardware we would want to support, similarly to the RTL8139 that
  got removed recently for almost the same reason.
2023-01-08 21:51:59 +01:00
Liav A 5c97c6d874 Kernel: Remove the RTL8139 PCI network adapter driver
Nobody tests this network card, and the driver has bugs (see the issue
https://github.com/SerenityOS/serenity/issues/10198 for more details),
so it's almost certain that this happened due to code being rotting when
there's simply no testing of it.

Essentially this has been determined to be dead-code so this is the most
important reason to drop this code. Another good reason to do so is
because the RTL8139 only supports Fast Ethernet connections (10/100
Megabits per second), and is considered obsolete even for bare metal
setups.
2023-01-07 11:37:57 -07:00
Liav A 0cede94c39 Kernel/Net: Introduce a new mechanism to initialize a PCI device
Instead of using a clunky if-statement paradigm, we now have all drivers
being declaring two methods for their adapter class - create and probe.
These methods are linked in each PCINetworkDriverInitializer structure,
in a new s_initializers static list of them.
Then, when we probe for a PCI device, we use each probe method and if
there's a match, then the corresponding create method is called. After
the adapter instance is created, we call the virtual initialize method
on it, because many drivers actually require a sort of post-construction
initialization sequence to ensure the network adapter can properly
function.

As a result of this change, it's much more easy to add more drivers and
the initialization code is more readable and it's easier to understand
when and where things could fail in the whole initialization sequence.
2023-01-07 12:36:57 +01:00
Andreas Kling 30d3f2789e Kernel: Propagate errors during network adapter detection/initialization
When scanning for network adapters, we give each driver a chance to
claim the PCI device and whoever claims it first gets to keep it.
Before this patch, the driver API returned a LockRefPtr<AdapterType>,
which made it impossible to propagate errors that occurred during
detection and/or initialization.

This patch changes the API so that errors can bubble all the way out
the PCI enumeration in NetworkingManagement::initialize() where we
perform all the network adapter auto-detection on boot.

When we eventually start to support hot-plugging network adapter in the
future, it will be even more important to propagate errors instead of
swallowing them.

Importantly, before this patch, some errors were "handled" by panicking
the kernel. This is no longer the case.

7 FIXMEs were killed in the making of this commit. :^)
2022-12-13 11:20:11 +01:00
Liav A 05ba034000 Kernel: Introduce the IOWindow class
This class is intended to replace all IOAddress usages in the Kernel
codebase altogether. The idea is to ensure IO can be done in
arch-specific manner that is determined mostly in compile-time, but to
still be able to use most of the Kernel code in non-x86 builds. Specific
devices that rely on x86-specific IO instructions are already placed in
the Arch/x86 directory and are omitted for non-x86 builds.

The reason this works so well is the fact that x86 IO space acts in a
similar fashion to the traditional memory space being available in most
CPU architectures - the x86 IO space is essentially just an array of
bytes like the physical memory address space, but requires x86 IO
instructions to load and store data. Therefore, many devices allow host
software to interact with the hardware registers in both ways, with a
noticeable trend even in the modern x86 hardware to move away from the
old x86 IO space to exclusively using memory-mapped IO.

Therefore, the IOWindow class encapsulates both methods for x86 builds.
The idea is to allow PCI devices to be used in either way in x86 builds,
so when trying to map an IOWindow on a PCI BAR, the Kernel will try to
find the proper method being declared with the PCI BAR flags.
For old PCI hardware on non-x86 builds this might turn into a problem as
we can't use port mapped IO, so the Kernel will gracefully fail with
ENOTSUP error code if that's the case, as there's really nothing we can
do within such case.

For general IO, the read{8,16,32} and write{8,16,32} methods are
available as a convenient API for other places in the Kernel. There are
simply no direct 64-bit IO API methods yet, as it's not needed right now
and is not considered to be Arch-agnostic too - the x86 IO space doesn't
support generating 64 bit cycle on IO bus and instead requires two 2
32-bit accesses. If for whatever reason it appears to be necessary to do
IO in such manner, it could probably be added with some neat tricks to
do so. It is recommended to use Memory::TypedMapping struct if direct 64
bit IO is actually needed.
2022-09-23 17:22:15 +01:00
Andreas Kling 11eee67b85 Kernel: Make self-contained locking smart pointers their own classes
Until now, our kernel has reimplemented a number of AK classes to
provide automatic internal locking:

- RefPtr
- NonnullRefPtr
- WeakPtr
- Weakable

This patch renames the Kernel classes so that they can coexist with
the original AK classes:

- RefPtr => LockRefPtr
- NonnullRefPtr => NonnullLockRefPtr
- WeakPtr => LockWeakPtr
- Weakable => LockWeakable

The goal here is to eventually get rid of the Lock* classes in favor of
using external locking.
2022-08-20 17:20:43 +02:00
Liav A 3fb289e27d Kernel/PCI: Don't hold spinlocks when doing fast device enumeration
Instead, hold the lock while we copy the contents to a stack-based
Vector then iterate on it without any locking.

Because we rely on heap allocations, we need to propagate errors back
in case of OOM condition, therefore, both PCI::enumerate API function
and PCI::Access::add_host_controller_and_enumerate_attached_devices use
now a ErrorOr<void> return value to propagate errors. OOM Error can only
occur when enumerating the m_device_identifiers vector under a spinlock
and trying to expand the temporary Vector which will be used locklessly
to actually iterate over the PCI::DeviceIdentifiers objects.
2022-03-14 22:39:09 +01:00
Liav A 71de4f7114 Kernel/Net: Don't try to enumerate PCI adapters if PCI is disabled 2022-03-02 18:41:54 +01:00
Idan Horowitz 74ab8ccde0 Kernel: Add NetworkingManagement::try_for_each() for fallible iteration
This API will allow users to short circuit iteration and properly
propagate errors.
2022-02-27 20:37:57 +01:00
Andreas Kling 3becff9eae Kernel: Protect network adapter list with spinlock instead of mutex 2022-02-03 16:11:26 +01:00
Daniel Bertalan 52beeebe70 Kernel: Remove the KString::try_create(String::formatted(...)) pattern
We can now directly create formatted KStrings with KString::formatted.

:^)
2021-12-28 01:55:22 -08:00
Liav A 7e8beadd57 Kernel/Net: Move Realtek network adapters code to a separate directory 2021-12-28 00:56:47 -08:00
Liav A 7991a92388 Kernel/Net: Move NE2000 network adapter code to a separate directory 2021-12-28 00:56:47 -08:00
Liav A 39d40afa93 Kernel/Net: Move Intel network adapters code to a separate directory 2021-12-28 00:56:47 -08:00
Andreas Kling 8b1108e485 Everywhere: Pass AK::StringView by value 2021-11-11 01:27:46 +01:00
Andreas Kling 79fa9765ca Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.

Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
2021-11-08 01:10:53 +01:00
Liav A 64aaf263a2 Kernel/Net: Generate interface name near construction point
This change allows the Kernel to actually construct other interfaces
besides the E1000 type.
This solves a breakage that was introduced recently because of move
semantics.

A couple of points on this patch:
1. In current situation, we can waste time to create a KString and throw
it for nothing. This patch ensures we only create it near construction
point so we know we actually need it.
2. It's very likely to assume that non-x86 machines will expose network
device with a device tree (or with ACPI). The raspberry pi machine is a
good example of that. Therefore, each driver should explicitly ask the
correct interface name generation method, and this patch simplifies this
pattern greatly, especially in a case where the same network device can
appear as a PCI device or as device in another bus type on the same
platform target. For example, the (in)famous ne2000 device can be used
either as a PCI device or as an ISA device, depending on the model.
3. In my opinion, it seems much more readable to construct the name near
calling point of the object constructor than to just pass it with move
semantics.
2021-10-18 12:25:56 -07:00
Brian Gianforcaro 2770433d30 Kernel: Convert network adapter names to Kernel::KString
Another step of incremental progress of removing `AK::String` from the
kernel, to harden against OOM.
2021-10-01 17:22:17 +00:00
Liav A 4974727dbb Kernel: Move x86 IO instructions code into the x86 specific folder 2021-10-01 12:27:20 +02:00
Liav A 9d9d57056e Kernel/PCI: Remove Address from enumeration callback
If we need that address, we can always get it from the DeviceIdentifier.
2021-09-29 11:24:33 +02:00
Liav A 057f5a12c2 Kernel/PCI: Propagate usage of DeviceIdentifier everywhere
This allows us to remove a bunch of PCI API functions, and instead to
leverage the cached data from DeviceIdentifier object in many places.
2021-09-29 11:24:33 +02:00
Liav A da327746a2 Kernel: Rename two PCI components
Rename ID => HardwareID, and PhysicalID => DeviceIdentifier.
This change merely does that to clarify what these objects really are.
2021-09-29 11:24:33 +02:00
Liav A 82bb08a15c Kernel/PCI: Cache more details about PCI devices when enumerating them
There's no good reason to fetch these values each time we need them.
2021-09-29 11:24:33 +02:00
Liav A 25ea7461a0 Kernel/PCI: Simplify the entire subsystem
A couple of things were changed:
1. Semantic changes - PCI segments are now called PCI domains, to better
match what they are really. It's also the name that Linux gave, and it
seems that Wikipedia also uses this name.
We also remove PCI::ChangeableAddress, because it was used in the past
but now it's no longer being used.
2. There are no WindowedMMIOAccess or MMIOAccess classes anymore, as
they made a bunch of unnecessary complexity. Instead, Windowed access is
removed entirely (this was tested, but never was benchmarked), so we are
left with IO access and memory access options. The memory access option
is essentially mapping the PCI bus (from the chosen PCI domain), to
virtual memory as-is. This means that unless needed, at any time, there
is only one PCI bus being mapped, and this is changed if access to
another PCI bus in the same PCI domain is needed. For now, we don't
support mapping of different PCI buses from different PCI domains at the
same time, because basically it's still a non-issue for most machines
out there.
2. OOM-safety is increased, especially when constructing the Access
object. It means that we pre-allocating any needed resources, and we try
to find PCI domains (if requested to initialize memory access) after we
attempt to construct the Access object, so it's possible to fail at this
point "gracefully".
3. All PCI API functions are now separated into a different header file,
which means only "clients" of the PCI subsystem API will need to include
that header file.
4. Functional changes - we only allow now to enumerate the bus after
a hardware scan. This means that the old method "enumerate_hardware"
is removed, so, when initializing an Access object, the initializing
function must call rescan on it to force it to find devices. This makes
it possible to fail rescan, and also to defer it after construction from
both OOM-safety terms and hotplug capabilities.
2021-09-07 13:47:37 +02:00
Andreas Kling c94c15d45c Everywhere: Replace AK::Singleton => Singleton 2021-08-08 00:03:45 +02:00
Andreas Kling a1d7ebf85a Kernel: Rename Kernel/VM/ to Kernel/Memory/
This directory isn't just about virtual memory, it's about all kinds
of memory management.
2021-08-06 14:05:58 +02:00
Andreas Kling 9457d83986 Kernel: Rename Locker => MutexLocker 2021-07-18 01:53:04 +02:00
Brian Gianforcaro 5743561d32 Kernel: Remove unused header includes in Net subtree 2021-07-11 21:37:38 +02:00
Andreas Kling 241bbce264 Kernel: LoopbackAdapter::create() => try_create()
Allow this to fail (although we VERIFY that it succeeds during boot
for now, since we don't want to boot without a loopback adapter.)
2021-07-11 18:00:31 +02:00
Hendiadyoin1 62f9377656 Kernel: Move special sections into Sections.h
This also removes a lot of CPU.h includes infavor for Sections.h
2021-06-24 00:38:23 +02:00
Idan Horowitz a898e01d4d Kernel: Add driver for RTL8168 & RTL8111 NICs
These are pretty common on older LGA1366 & LGA1150 motherboards.

NOTE: Since the registers datasheets for all versions of the chip
besides versions 1 - 3  are still under NDAs i had to collect
several "magical vendor constants" from the *BSD driver and the
linux driver that i was not able to name verbosely, and as such
these are labeled with the comment "vendor magic values".
2021-06-10 21:54:51 +02:00
Liav A c6480a0426 Kernel/Net: Support Intel 82574 adapter
We call it E1000E, because the layout for these cards is somewhat not
the same like E1000 supported cards.

Also, this card supports advanced features that are not supported on
8254x cards.
2021-06-09 22:44:09 +04:30
Liav A 2e2201e8e1 Kernel/CommandLine: Add option to disable physical networking hardware
This is useful for debugging sessions mostly.
2021-06-09 22:44:09 +04:30
Liav A 1c94b5e8eb Kernel: Introduce the NetworkingManagement singleton
Instead of initializing network adapters in init.cpp, let's move that
logic into a separate class to handle this.
Also, it seems like a good idea to shift responsiblity on enumeration
of network adapters after the boot process, so this singleton will take
care of finding the appropriate network adapter when asked to with an
IPv4 address or interface name.

With this change being merged, we simplify the creation logic of
NetworkAdapter derived classes, so we enumerate the PCI bus only once,
searching for driver candidates when doing so, and we let each driver
to test if it is resposible for the specified PCI device.
2021-06-09 22:44:09 +04:30