Chip firmware is able to send periodic null frames to keep the
association with the AP.
The driver arbitrary set this period to 30sec. We prefer to rely on
BSS_CHANGED_KEEP_ALIVE that provide a true value.
Note that if BSS_CHANGED_KEEP_ALIVE is not received, we just disable
keep_alive feature. It is not very disturbing since AP will probably
ping the station before to disconnect it.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-9-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
wfx_do_join() calls wfx_tx_lock_flush() ate beginning of the function.
Therefore, the subsequent call to wfx_tx_flush() is useless.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-8-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Chipset need two steps to associate with an AP:
1. it start receiving beacon from the AP (done with wfx_do_join())
2. it sent the association request (done with wfx_join_finalize())
The join request (see hif_join()) contains basic rates, beacon interval
and bssid to connect, so we trig on these events for the first step.
The second step is obviously associated to the event BSS_CHANGED_ASSOC.
Note that conf_mutex is now easier to manage. It is held by
wfx_bss_info_changed() and inner functions does not need to lock it.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-7-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Current code start AP and then configure the different parameters. Since
all the configuration is sent quickly after AP started, it works.
However, it is not very nice. In add, last firmware releases start to
disallow incorrect settings.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-6-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Currently, wfx_bss_info_changed() check interface status changes and
guess when the pattern match with an AP start and AP stop (through
wfx_update_beaconing()). It is far easier to rely on start_ap and
stop_ap callbacks provided by mac80211.
wfx_bss_info_changed() keeps only the responsibility of updating the
frame templates.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-5-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Currently, wfx_do_unjoin() are called by the mean of work queues.
However, the contexts from where they are called are not atomic. So
there is no reason to not call it synchronously.
This change will simplify the code. Notice two main changes:
- There no more reason to lock tx queue before to run
wfx_do_unjoin(). We can lock the tx queue directly from
wfx_do_unjoin().
- Most of the time, wfx_do_unjoin_work() was called with conf_mutex
held. This patch remove lock of conf_mutex in wfx_do_unjoin_work()
and ensure that conf_mutex is always held whatever the context.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-4-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Pointer to cfg80211_bss is held during all duration of wfx_do_join. But,
it is not necessary, We can release it far earlier.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-3-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
wfx_remove_interface() and wfx_configure_filter() can be run
concurrently. Therefore, this patch protect access to the list of
interfaces from wfx_configure_filter().
Notice that wfx_configure_filter() now lock "conf_lock" and "scan_lock".
Beside that, wfx_hw_scan_work() also access to the same locks. So we
have to lock them in same order to avoid any deadlock.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200410133239.438347-2-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Size of hif_mib_template_frame must be sufficient to contains bytes
declared by frame_length and cannot exceed 700bytes.
Change the API to reflect that.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200406111756.154086-12-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Until now, all functions from hif_tx_mib.h are declared "static inline".
However, they are not time critical. So, it does not make so much sense.
We prefer to place them in a .c file as for other hif functions.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200406111756.154086-9-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The chip expects little endian in all structs it sends/receives. This
patch fixes the hif API to reflect this fact. Sparse should now report
meaningful errors.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200406111756.154086-7-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Several values defined in hif API are only here to define length of some
arrays. In most cases, they do not provide any extra information about
the size of the array (ie. "API_FIRMWARE_LABEL_SIZE" is only used to
define the size of member "firmware_label").
Remove these useless definitions.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200406111756.154086-6-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Until now, hif API was directly imported from firmware sources.
However, it does not make sense to keep ton of unused structures in
the driver. Moreover, the hif API is now stable enough to be keep in
sync by importing delta from firmware.
So, drop unused definitions from the hif API.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200406111756.154086-5-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The definitions TX_RETRY_POLICY_MAX and TX_RETRY_POLICY_INVALID are
imposed by the hardware. Therefore, they should be located in the
hardware interface API.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200406111756.154086-4-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The definitions LINK_ID_NO_ASSOC and MAX_STA_IN_AP_MODE are imposed by
the hardware. Therefore, they should be located in the hardware
interface API.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200406111756.154086-3-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Current code contains a weird hack to avoid switch from 54Mbps CTS to
1Mbps. However, we have not been able to reproduce the problem and
hardware team don't know any defect of this kind. So, it seems this hack
is no more necessary.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-33-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
When driver has Content After DTIM Beacon (CAB) in queue, it wait for an
indication from the firmware. However, when we stop to send beacons,
this indication may never happen.
Solve this issue by simply simulate this indication. Firmware will send
data that probably nobody will heard.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-32-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
wfx_tx_flush() wait there are no more frame in device buffer. However,
this event may never happens since wfx_tx_flush() don't forbid to
enqueue new frames.
Note that wfx_tx_flush() should only ensure that all frames currently in
hardware queues are sent. So the current code is more restrictive that
it should.
Note that wfx_tx_flush() release the lock before to return while
wfx_tx_lock_flush() keep the lock.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-31-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
wfx_flush() exited once all frames are retrieved from the device.
However, it did not ensure they were processed by driver before to
return. Therefore, some frame may be processed after the interface has
disappear.
Change the place we signal that the queue is empty to fix that.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-30-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Until now, wfx_flush() flushed queue for while device instead of only
the queue of the intended vif. It sometime failed with a timeout, but
this error was not reported.
Moreover, if the device was frozen, wfx_flush didn't do anything and it
results a potential warning (and maybe a resource leak) when the frozen
device was unregistered.
We can also notice that wfx_tx_queues_wait_empty_vif() did only exist to
work around the broken feature of wfx_flush().
This patch repair wfx_flush() and therefore drop
wfx_tx_queues_wait_empty_vif().
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-29-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
In a next commit, we would like to mark wfx_skb_dtor as static and stop
to declare it in data_tx.h.
Relocate wfx_skb_dtor() prior its callers to avoid compile error.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-28-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Currently, wfx_pending_remove() (from queue.c) call wfx_skb_dtor()
(from data_tx.c) that forward the tx status to mac80211.
Moreover, there no purpose to retrieve a frame from the pending queue
without dequeuing it. So, the main purpose of wfx_pending_remove() is to
forward the tx status to mac80211.
Let's make the architecture cleaner:
- merge wfx_pending_remove() into wfx_pending_get()
- call wfx_skb_dtor() from data_tx.c
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-27-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The queue used for wfx_tx_queue_put() can be deducted from the content
of the skb. So drop this parameter from call to wfx_tx_queues_put().
In add, this change uniformizes usage of functions wfx_tx_queues_*.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-26-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
There is no reason to keep the intermediate struct wfx_queue_stats.
Relocate its members to struct wfx_dev.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-25-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Since we do not rely in QoS parameters to choose which frame to send, it
is no more necessary to keep a copy of EDCA parameters.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-24-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The current code computes itself the QoS policy to choose which frame
should be sent. However, firmware already do that job. Firmware would
prefer to have packets in every queues and be able to choose itself
which queue to use.
So, this patch sort the queues from the emptiest to the fulliest (thanks
to the pending frames counter introduced a few commits earlier). It send
frame to the least full queue.
However, we continue to be careful with frames that have to be sent
after a dtim ("cab": Content After (DTIM) Beacon).
So, this patch splits AC queues in two skb_queues: one for normal frames
and another for cab frames. It cares to send frames from CAB skb_queue
if appropriate.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-23-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This counter will be useful to know which queue is least full in a
further patch.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-22-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
It is not necessary to return a skb. Just getting the information if
there is traffic to be sent after DTIM is sufficient.
In add, the acronym "cab" (Content After (DTIM) Beacon) is used in
mac80211 to designate this kind of traffic.
So, make wfx_tx_queues_get_after_dtim() return a boolean and rename
accordingly.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-21-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Since concept of "raw_link_id" does not exist anymore, rename
wfx_tx_get_raw_link_id() in wfx_tx_get_link_id().
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-20-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
raw_link_id can be retrieved by wfx_tx_get_raw_link_id(). So, it is not
necessary to keep it in struct wfx_tx_priv.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-19-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
link_id was expected to contain identifier of a station. It was also
used to mark frames that has to sent after dtim. We do not use the
further purpose. For the last purpose, we can directly check the flag
value in tx_info.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-17-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Driver does not use link_map_cache anymore. So we can drop it. In add,
we do not have to keep this counter in sync with skb_queue item, so we
can drop explicit spin_locks.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-16-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Since we do not track power save status of the stations anymore,
link_map_cache is now only used to track "Content After (DTIM) Beacon".
We prefer to rely on flags from tx_info. So we will be able to drop
link_map_cache.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-15-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Following the remove of asleep_mask, the tx_allowed_mask argument passed
to various functions is now always the same. Drop this argument and
simplify the code.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-14-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Currently, the driver tracks power save state of the stations with the
variable sta_asleep_mask. Then, it takes care to not sent data to asleep
stations.
However, this work is already done by mac80211. Normally, there are no
frames for asleep stations in our queues. So, driver do not have to
filter frames in its queues (apart the frames marked "AFTER_DTIM").
Notice that there is a risk of race between state of the station and
data send to the firmware. However, this risk is limited since the
number of frame in queues are small. In add, this race also exists with
the current code. Anyway, the firmware is able to detect the problem and
driver will receive a 'REQUEUE' status (translated in
TX_STAT_TX_FILTERED for mac80211).
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-13-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
It is far simpler to return a pointer instead of an error. Thus, it is
no more necessary to pass a pointer reference as argument.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-12-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The argument "total" is not used anymore since commit a3c529a835
("staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM").
Fixes: a3c529a835 ("staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM")
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-11-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Thanks to skb_queue_empty_lockless(), it is not necessary to acquire the
spin_lock before to check if the queue is empty.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-10-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The last argument of hif_handle_tx_data() was now unused. In add,
hif_handle_tx_data() has nothing to do with HIF layer and should be
renamed. Finally, it not convenient to pass a wfx_vif as parameter. It
is easier to let hif_handle_tx_data() find the interface itself.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-9-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
__wfx_flush() wait for all queues to be empty. In current code,
wait_link_id_empty is wake up each time there is no more data for a
station. We can simplify the processing and avoid some wake-up by
raising this event only when the queue is empty.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-8-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
tx_info->hw_queue contains "vif.hw_queue[skb_get_queue_mapping(skb)]".
For now, it is equivalent of "skb_get_queue_mapping(skb)". However, it
is not the same semantic. In wfx_tx_inner(), we want to get the mac80211
queue index, not the hardware queue index.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200401110405.80282-6-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>