Since packets sent to an RA / TID in AGG are sent from a
separate HW Tx queue, we may get into a race:
the regular queue isn't empty while we already begin to
send packets from the AGG queue. This would result in sending
packets out of order.
In order to cope with this, mac80211 waits until the driver
reports that the legacy queue is drained before it can send
packets to the AGG queue. During that time, mac80211 buffers
packets for the driver. These packets will be sent in order
after the driver reports it is ready.
The way this was implemented in the driver is as follows:
We held a counter that monitors the number of packets for
an RA / TID in the HW queues. When this counter reached 0,
we knew that the HW queues were drained and we reported to
mac80211 that were ready to proceed.
This patch changes the implementation described above. We
now remember what is the wifi sequence number of the first
packet that will be sent in the AGG queue (lets' call it
ssn). When we reclaim the packet before ssn, we know that
the queue is drained, and we are ready to proceed.
This will allow us to move this logic in the upper layer and
eventually remove the tid_data from the shared area.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Move the calib_results list from the upper layer iwl_priv structure
to the lower layer iwl_trans structure.
Signed-off-by: Don Fry <donald.h.fry@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Add more data when inconsistencies occur in the AGG state machine.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Some information was redundation, other was missing.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Add more information when a queue is stuck and actually get
information from the scheduler instead of looking at internal
variables.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Users complain that the traffic gets stalled sometimes. This will
allow easier debugging.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
As Stanislaw pointed out, my patch
iwlagn: fix a race in the unmapping of the TFDs
solved only part of the problem. The race still exists for TFDs of
the host commands. Fix that too.
Reported-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Use the same calling style for all the mac80211 callback functions
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This one can be _very_ noisy.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
While inspecting the code, I saw that iwl_tx_queue_unmap modifies
the read pointer of the Tx queue without taking any locks. This means
that it can race with the reclaim flow. This can possibly lead to
a DMA warning complaining that we unmap the same buffer twice.
This is more a W/A than a fix since it is really weird to take
sta_lock inside iwl_tx_queue_unmap, but it can help until we revamp
the locking model in the transport layer.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Occasionally, the device will send interrupts
while it is resuming, at a point where we are
not set up again to handle them. This causes
the core IRQ handling to completely disable
the IRQ, and then the driver won't work again
until it is reloaded/rebound.
To fix this issue disable the IRQ on suspend,
this will cause us to only get interrupts
again after we've setup everything on resume.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
802.11 says:
"Sequence numbers for QoS (+)Null frames may be
set to any value."
However, if we use the normal counters then peers
will get confused with aggregation since there'll
be holes in the sequence number sequence.
To avoid that, don't assign sequence numbers to
QoS Null frames.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi GUy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
As everybody knows kcalloc checks the multiplication is safe and
that we don't run into overflow.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Since all the queue logic has been moved to the transport layer,
the sequence number is set in the transport layer.
While doing that I forgot that the mac header is copied to the
TB of the TX cmd in the upper layer before the call to the transport
layer. So basically we used the sequence number from mac80211...
This was fine for the first assocation but after the second, mac80211
resets its counters while we don't hence a shift that led to terrible
impact on performance.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
iwl_trans_rx_alloc is only called from iwl_rx_init, so no need
to init the lists twice.
Signed-off-by: Amit Beka <amit.beka@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
During my works on the transport layer I removed code that updated
a local variable (is_agg) that is needed to keep the pending_frames
count up to date. Fix this.
Also, there should be no way to have a packet with TX_CTL_AMPDU set
while the internal aggregation state machine is not in AGG_ON state.
Add a WARN_ON to ensure that.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This simplifies both the transport layer and the upper layer.
Kill the union in the device command, which avoids the funny syntax
we had: cmd->cmd.payload.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
The transport callbacks might as well be undefined
when CONFIG_PM_SLEEP is not set, so ifdef all of
it out and make everything available for PM_SLEEP
only.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
There's no need to have the transport layer have a
callback for iwl_trans_send_cmd_pdu() since it is
just a generic wrapper around iwl_trans_send_cmd().
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Move all the PCI-E specific transport files to
be iwl-trans-pcie*; specifically iwl-trans.c
which is really iwl-trans-pcie.c.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>