Some places were still using the old allocator. Using the new one does
not change any behavior. This will help to remove the useless data_len
attribute in net_pkt which legacy allocator was still setting.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Removing the TX timeout handling in the GMAC driver (commit 18b07e09e0)
revealed some issues with the way hardware priority queues work.
For cases with both hardware priority queues enabled, with the default
recommended delta bandwidths (0% - 75%), the lower priority queue (0%)
is hardly able to send any packets. This became visible, because without
the timeout mechanism, we quickly ran out of available TX buffers if
there were multiple packets being queued to the queue.
Here is an excerpt from 802.1Q, chapter 34.3.1 which describes how Qav
bandwidth sharing SHOULD work:
The deltaBandwidth(N) for a given N, plus the deltaBandwidth(N) values
for any higher priority queues (larger values of N) defines the total
percentage of the Port’s bandwidth that can be reserved for that queue
and all higher priority queues. For the highest priority queue, this
means that the maximum value of operIdleSlope(N) is deltaBandwidth(N)%
of portTransmitRate. However, if operIdleSlope(N) is actually less
than this maximum value, any lower priority queue that supports the
credit-based shaper algorithm can make use of the reservable bandwidth
that is unused by the higher priority queue. So, for queue N-1, the
maximum value of (operIdleSlope(N) + operIdleSlope(N-1)) is
(deltaBandwidth(N) + deltaBandwidth(N1))% of portTransmitRate.
However in reality, the lower priority queues (N-1) on the SAM GMAC
hardware DO NOT use the bandwidth available from the higher priority
queues (N).
This commits fixes the issue by changing the defaults. These are still
set to the recommended 75% (total), but this percentage is split between
the priority queues manually.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
There is a log message printed for the non-priority queue (Queue 0). Add
the same message for the priority queues too when they are enabled, and
a corresponding message when the queue is not used (set to idle).
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
Throughout the manual, the queues GMAC is equipped with are identified
by a number - Queue 0, Queue 1 and Queue 2.
However in the context of Qav, the queues are identified with a
character (note that there are only two queues as Qav is not used for
the non-priority queue) - Queue A and Queue B.
Queue B and Queue 2 are also called "the highest priority queues".
Based on that, the previous implementation was using the following
mapping:
Queue 1 - Queue A
Queue 2 - Queue B
However when running some specific tests, that is for example forcing
all the traffic to Queue 1, it showed that this queue is actually
affected by the Queue B registers. Similarly, Queue 2 seems to be
affected by the Queue A registers.
Based on that observation, this commit changes the registers used to
work with the following mapping:
Queue 1 - Queue B
Queue 2 - Queue A
Note that this is based solely on observations, there is nothing in the
datasheet that confirms this, and the "highest priority" label suggests
it is otherwise.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This option is meant to be used only for debugging. Use it to force all
traffic to be routed through a specific hardware queue. With this option
enabled it is easier to verify whether the chosen hardware queue
actually works.
This works only if there are four or fewer RX traffic classes enabled as
the SAM GMAC hardware supports screening up to four traffic classes.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
The j iterator is used for priorities, and the i iterator is used for
choosing the actual screening register. Therefore the screening register
availability needs to be checked with i.
This commit also improves the readability by doing two things:
* by moving the screening register index check to a place where the
index is going to be actually used
* by using the ARRAY_SIZE macro instead of a hard-coded number as the
upper limit
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
The ring_buf implementation is basically used as an array of net_buf
pointers in the RX path. The tail and head indexes are taken from the
RX descriptors and not from the ring_buf. That's why for example the
fact that head is never initialized doesn't cause problem. Only len is
used in free_rx_bufs(), but anyway this function is plainly broken as
it always free the first net_buf and doesn't set it back to NULL.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Scale down the TX path of the GMAC driver by waiting for a packet to be
fully sent before returning from the send function. This has a small
performance impact, but has a few advantages:
- It allows the Ethernet code to modify the packet afterward, fixing PTP
support on this board (see PR #12563).
- It returns an error to the IP stack in case of a transmit failure.
- It doesn't require net_buf to be thread safe.
This change can be reverted by changing GMAC_MULTIPLE_TX_PACKETS from 0
to 1.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The GMAC driver tries to ensure that it can always send a complete
Ethernet frame. However in the TX path this is the problem of the IP
stack: if the buffers can't be allocated, they won't be sent. Therefore
just drop the check.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The SAM GMAC Ethernet driver currently keeps a reference to the packet
being sent in addition than keeping of references of the fragments. In
practice this is only needed when PTP is enabled, otherwise the driver
only need to prevent the fragment (or even their content) to be changed.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The SAM GMAC Ethernet driver uses scatter gather DMA to transmit data.
Each fragment of a network packet is mapped from a set of descriptors
that is used by the controller to do the DMA transfer. This means that
the packet is not necessary sent when the send() function returns. For
that reason the driver calls net_pkt_ref() on the packet to prevent it
from being freed. It is then unreferenced with net_pkt_unref() in the
TX ISR when the packet has effectively been sent.
However this doesn't work if the packet is modified in the meantime,
like it will be done in PR #12563 to remove the Ethernet header
contained in the first fragment. To avoid that, call net_pkt_frag_ref()
on each fragment of the packet, and unreferenced them with
net_pkt_frag_unref() in the TX ISR when the packet has effectively been
sent.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Replace the sole use of i2c_burst_read_addr with a more generic API
function to allow the former to be deprecated along with its unreliable
sibling write and update functions.
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
Previous SAM E70 HAL version was patched by commit 4dcfc8706 ("Add
missing interrupt number definitions") to add missing interrupt
definitions for SAM GMAC Priority Queues. This has been fixed in the
latest HAL by using a slightly different name. This patch updates the
driver accordingly.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Now that the descriptor lists are in non-cached memory, the helpers are
just accessing the w0 or w1 members of the structure. Just drop them and
access the members directly.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Atmel SAM Ethernet module is using a scatter-gather technique to
exchange data with the Ethernet driver. To communicate the location
of the data buffers the driver sets-up a so called descriptor list. This
is effectively a place in RAM containing a sequence of 32-bit words
representing buffer location and its status.
Currently the cache coherency is handled using cache clean or
invalidate. Unfortunately this strategy only works correctly when the
corresponding data size is a multiple of the cache line. This is not
the case here and might lead to data loss or corruption.
Instead of using cache operations, this patch moves the descriptor
listed to the recently added non-cached memory region, as recommended by
ATMEL. A data synchronisation barrier is still required for writes, as
the non-cached memory is defined with TEX=1, i.e. it is not strongly
ordered. The descriptor lists alignment can be decreased to 4 bytes, as
required by the SAM Ethernet module.
The RX/TX buffer are left unchanged, still managed by cache operations.
Fixes#9812
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The RX buffer accounting list is not a list shared with Ethernet device,
therefore there is no need to run a cache clean operation on it.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The SAM E70 GMAC ethernet driver reference a packet with net_pkt_ref()
when queueing a packet, and unreference it with net_pkt_unref() in the
ISR when it has been fully sent.
The call to net_pkt_ref() is done just after re-enabling the
interruptions, so there is however a small race condition that might
cause the packet to be unreference before being referenced. This is
only theoretical and has not been seen in practice.
Fix that by moving the call to net_pkt_ref() just before re-enabling
the interruptions.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The SAM E70 Ethernet driver uses scatter gather DMA to transmit data.
Each fragment of a network packet is mapped from a set of descriptors
that is used by the controller to do the DMA transfer. Each descriptor
contain an address and a length/status. The important status bits are
GMAC_TXW1_LASTBUFFER to indicate the last fragment of a packet and
GMAC_TXW1_USED to indicate that a descriptor has been processed by the
controller.
When starting a transmission, the controller start at the descriptor
after the last one that has been processed. If the descriptor is NOT
flagged by GMAC_TXW1_USED, it sends a first packet by sending all the
fragments up to a descriptor flagged with GMAC_TXW1_LASTBUFFER. The
first descriptor of a packet *and only the first descriptor of a packet*
is then modified to flag it with GMAC_TXW1_USED and to provide a status
(mostly related to errors and checksum offloading). It then continues
with the next packet and so on and only stops if the next descriptor
after GMAC_TXW1_LASTBUFFER is flagged with GMAC_TXW1_USED.
Therefore in order for the controller to stop processing descriptors,
the strategy is to flag the next descriptor after the last fragment to
be sent with GMAC_TXW1_USED. When the next packet has to be queued, the
flag can be removed before starting a transmission.
This is what is currently done in the current driver. However there is a
small race condition in the implementation: if packets are queued fast
enough, the controller is still sending the fragment of the previous
packet when the descriptor are written. When writing the first
descriptor, the GMAC_TXW1_USED flag is removed. This is done after
writing the address (with a memory barrier) so that looks safe. However
given that the GMAC_TXW1_USED flag is only added by the controller to
the first descriptor of a packet it means the next descriptor might
have it cleared. In that case the descriptor is processed, and a junk
packet is sent. That also desynchronize eth_tx and tx_complete as one
or more packets than expected are transmitted.
In order to fix that the strategy is slightly changed to initially write
the first descriptor with the GMAC_TXW1_USED flag set. Once all the
descriptors from the packet are written the bit is cleared (after a
memory barrier). Then the transmission can be started safely.
The patch also does a small optimization writing the next descriptor
with only the GMAC_TXW1_USED bit set instead of setting this bit. As
this will be a non-cached area, it's better avoiding a read followed
by a write if not necessary.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The current SAM E70 Ethernet driver sometimes get stuck if the stack
has to send 2 packets in a row, for example an ack for the just received
data + answer data.
The problem is the following one:
1) The first packet goes through eth_tx, one tx_desc_sem semaphore is
taken, and the tx_timeout_work delayed work is submitted.
2) The second packet also goes through eth_tx, another tx_desc_sem
semaphore is taken, and the tx_timeout_work delayed work is not
started because there is already one already submitted.
3) The first packet has been sent, one tx_desc_sem semaphore is given
and the tx_timeout_work delayed work is cancelled.
4) The second packet has been sent but given the delayed work has
already been cancelled, tx_completed is not called: the tx_desc_sem
semaphore is not given back and the network packet is not
unreferenced.
The whole timeout concept probably has to be reworked. In the meantime
it is probably better to just drop the timeout code instead of keeping
the driver broken. We can only get stuck on the TX path if there is a
bug in the driver or a hardware malfunction. It might happen, but with
the less probability then the current hangs. In addition it just hides
the real issues and prevent them to be fixed.
This commit therefore just remove the timeout code in the TX path.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
There is no need to reserve any space for each frag, as the l2 will
allocate a frag for the ethernet header, arp will do the same.
This is one step further to removing the concept of ll reserve.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Update such statistic on all drivers.
Also, remove TX stats in native and stellaris drivers: such update is
done in L2 now.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Now instead of such path:
net_if_send_data -> L2's send -> net_if tx_queue -> net_if_tx -> driver
net_if's send
It will be:
net_if_send_data -> net_if tx_queue -> net_if_tx -> L2's send -> driver
net_if's send
Only Ethernet is adapted, but 15.4 and bt will follow up.
All Ethernet drivers are made compatible with that new scheme also.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Calculate proper initial PTP clock divisors based on the MCK value.
Additionally do not allow adjusting the rate of the clock. This does not
seem to work properly with current gPTP rate adjustment algorithm.
Having proper PTP clock divisors and callbacks that allow getting,
setting and adjusting current time is sufficient for proper gPTP
support.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
Most of this code is unreachable with priority queues disabled because
of queue id validation.
Fixes#9295.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This is a finishing commit in 802.1Qav support for SAM GMAC. It adds a
possibility to get and set all parameters required by the standard.
Note that to be fully compliant it requires a proper system
configuration, but the prioritizing mechanisms will work just fine
without it so it is not enforced in any way.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
If the application is using TC configuration compatible with HW
configuration (equal number of traffic classes and hardware queues)
setup the screening registers and chose queues based on the chosen TC
mapping.
Use the VLAN priority and hard-coded mappings only as a fallback.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
Updating Qav params made it implicitly enable the Qav support itself.
Since we can now control the on/off status with a management request,
this is not a desired behavior.
Make it read the original register value before updating params and then
writing back what it was before.
Additionally we now have to explicitly enable Qav support in init.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
The standard (and therefore the upper layer) is using bits per second,
the registers in SAM GMAC uses bytes per second - do the conversion
before writing the reg.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
There are too many individual requests for Qav related parameters. There
are more Qav parameters that need to be supported (and will be supported
soon - both on the GET and SET side). Handling it the way it was handled
so far would render the eth mgmt API dominated by Qav parameters. That
would make the file hard to read and understand.
Instead of that - use a single GET and SET requests for all Qav
parameters. This works by adding a separate enum with Qav request type
to the ethernet_qav_param struct.
Additionally this approach makes it much easier to document it all since
we now have just a single request and documentation comments in the
ethernet_qav_param struct.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This commit makes the driver enable HW Qav support for all available
priority queues.
Note that the hardware doesn't support setting the deltaBandwidth
parameter directly, but it is possible to do this by calculating it
from the negotiated link speed.
The default settings are set according to 802.1Qav 34.3.1, that says:
The recommended default value of deltaBandwidth(N) for the highest
numbered traffic class supported is 75%, and for any lower
numbered traffic classes, the recommended default value is 0%.
The default/recommended values can be changed using the ethernet
management API (set_config) - which this commit also adds.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
Handle getting the number of priority queues. The total number of queues
for this driver is configured in kconfig so it is as simple as returning
a defined value in this case.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
Use both PTP Peer Event and PTP Event timestamping registers when
necessary.
Also for non-PTP frames just use current time.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This commit adds support for multiple hardware TX and RX queues.
The number of the queues to use can be configured through defconfig.
Packets are sent and received through different hardware queues
depending on their priority.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This commit fixes how the registers values are calculated and makes sure
there is no overflow effect when converting back to int.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This commit makes the driver disallow drastic clock rate changes.
These changes happen mostly in the very beginning, when the timestamp in
hardware is zeroed.
In such cases the set callback is called soon after and fixes the large
offset. Without this limit the clock offset oscillates for a longer
period before it properly syncs as the requested ratio jumps between
very large and very small values.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This commit fixes a memory leak happening when both gPTP and VLAN are
enabled.
It also moves the get_iface function up in the file so it is accessible
earlier without a redundant function declaration.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This adds packet timestamping support to the GMAC driver.
It is based on the eth_native_posix and eth_mcux drivers.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
The pointers to pkt->frags->data are changed after transmitting.
Other layers (e.g. the gPTP drivers) assume that these will remain
unchanged. This patch adds a workaround for that issue and restores the
original pointers.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
This is needed to avoid compilation warnings when using both the
built-in libc and newlib.
The warnings were caused by typedefs incompatibilities.
This was agreed to be the temporary solution at the TSC.
See #8469 for more details.
Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>