Commit 107aff96 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-5.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver fixes from Greg KH:
 "Here are some small staging driver fixes for a number of reported
  issues.

  The majority here are some fixes for the wfx driver, but also in here
  is a comedi driver fix found during some code review, and an axis-fifo
  build dependancy issue to resolve some reported testing problems.

  All of these have been in linux-next with no reported issues"

* tag 'staging-5.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: wfx: fix wrong error message
  staging: wfx: fix hif_set_mfp() with big endian hosts
  staging: wfx: detect race condition in WEP authentication
  staging: wfx: ensure that retry policy always fallbacks to MCS0 / 1Mbps
  staging: wfx: fix rate control handling
  staging: wfx: firmware does not support more than 32 total retries
  staging: wfx: use boolean appropriately
  staging: wfx: fix counter overflow
  staging: wfx: fix case of lack of tx_retry_policies
  staging: wfx: fix the cache of rate policies on interface reset
  staging: axis-fifo: add unspecified HAS_IOMEM dependency
  staging: comedi: gsc_hpdi: check dma_alloc_coherent() return value
parents 1a4ee867 c05c403b
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
config XIL_AXIS_FIFO config XIL_AXIS_FIFO
tristate "Xilinx AXI-Stream FIFO IP core driver" tristate "Xilinx AXI-Stream FIFO IP core driver"
depends on OF depends on OF && HAS_IOMEM
help help
This adds support for the Xilinx AXI-Stream FIFO IP core driver. This adds support for the Xilinx AXI-Stream FIFO IP core driver.
The AXI Streaming FIFO allows memory mapped access to a AXI Streaming The AXI Streaming FIFO allows memory mapped access to a AXI Streaming
......
...@@ -623,6 +623,11 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, ...@@ -623,6 +623,11 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev,
dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE, dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
&devpriv->dio_buffer_phys_addr[i], &devpriv->dio_buffer_phys_addr[i],
GFP_KERNEL); GFP_KERNEL);
if (!devpriv->dio_buffer[i]) {
dev_warn(dev->class_dev,
"failed to allocate DMA buffer\n");
return -ENOMEM;
}
} }
/* allocate dma descriptors */ /* allocate dma descriptors */
devpriv->dma_desc = dma_alloc_coherent(&pcidev->dev, devpriv->dma_desc = dma_alloc_coherent(&pcidev->dev,
...@@ -630,6 +635,11 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, ...@@ -630,6 +635,11 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev,
NUM_DMA_DESCRIPTORS, NUM_DMA_DESCRIPTORS,
&devpriv->dma_desc_phys_addr, &devpriv->dma_desc_phys_addr,
GFP_KERNEL); GFP_KERNEL);
if (!devpriv->dma_desc) {
dev_warn(dev->class_dev,
"failed to allocate DMA descriptors\n");
return -ENOMEM;
}
if (devpriv->dma_desc_phys_addr & 0xf) { if (devpriv->dma_desc_phys_addr & 0xf) {
dev_warn(dev->class_dev, dev_warn(dev->class_dev,
" dma descriptors not quad-word aligned (bug)\n"); " dma descriptors not quad-word aligned (bug)\n");
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "traces.h" #include "traces.h"
#include "hif_tx_mib.h" #include "hif_tx_mib.h"
#define WFX_INVALID_RATE_ID (0xFF) #define WFX_INVALID_RATE_ID 15
#define WFX_LINK_ID_NO_ASSOC 15 #define WFX_LINK_ID_NO_ASSOC 15
#define WFX_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ)) #define WFX_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
...@@ -184,7 +184,7 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif, ...@@ -184,7 +184,7 @@ static int wfx_tx_policy_get(struct wfx_vif *wvif,
*/ */
entry = list_entry(cache->free.prev, struct tx_policy, link); entry = list_entry(cache->free.prev, struct tx_policy, link);
memcpy(entry->rates, wanted.rates, sizeof(entry->rates)); memcpy(entry->rates, wanted.rates, sizeof(entry->rates));
entry->uploaded = 0; entry->uploaded = false;
entry->usage_count = 0; entry->usage_count = 0;
idx = entry - cache->cache; idx = entry - cache->cache;
} }
...@@ -202,6 +202,8 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx) ...@@ -202,6 +202,8 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
int usage, locked; int usage, locked;
struct tx_policy_cache *cache = &wvif->tx_policy_cache; struct tx_policy_cache *cache = &wvif->tx_policy_cache;
if (idx == WFX_INVALID_RATE_ID)
return;
spin_lock_bh(&cache->lock); spin_lock_bh(&cache->lock);
locked = list_empty(&cache->free); locked = list_empty(&cache->free);
usage = wfx_tx_policy_release(cache, &cache->cache[idx]); usage = wfx_tx_policy_release(cache, &cache->cache[idx]);
...@@ -239,7 +241,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif) ...@@ -239,7 +241,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif)
dst->terminate = 1; dst->terminate = 1;
dst->count_init = 1; dst->count_init = 1;
memcpy(&dst->rates, src->rates, sizeof(src->rates)); memcpy(&dst->rates, src->rates, sizeof(src->rates));
src->uploaded = 1; src->uploaded = true;
arg->num_tx_rate_policies++; arg->num_tx_rate_policies++;
} }
} }
...@@ -249,7 +251,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif) ...@@ -249,7 +251,7 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif)
return 0; return 0;
} }
static void wfx_tx_policy_upload_work(struct work_struct *work) void wfx_tx_policy_upload_work(struct work_struct *work)
{ {
struct wfx_vif *wvif = struct wfx_vif *wvif =
container_of(work, struct wfx_vif, tx_policy_upload_work); container_of(work, struct wfx_vif, tx_policy_upload_work);
...@@ -270,7 +272,6 @@ void wfx_tx_policy_init(struct wfx_vif *wvif) ...@@ -270,7 +272,6 @@ void wfx_tx_policy_init(struct wfx_vif *wvif)
spin_lock_init(&cache->lock); spin_lock_init(&cache->lock);
INIT_LIST_HEAD(&cache->used); INIT_LIST_HEAD(&cache->used);
INIT_LIST_HEAD(&cache->free); INIT_LIST_HEAD(&cache->free);
INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i) for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i)
list_add(&cache->cache[i].link, &cache->free); list_add(&cache->cache[i].link, &cache->free);
...@@ -523,9 +524,9 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) ...@@ -523,9 +524,9 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) { for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) {
if (rates[i + 1].idx == rates[i].idx && if (rates[i + 1].idx == rates[i].idx &&
rates[i].idx != -1) { rates[i].idx != -1) {
rates[i].count = rates[i].count += rates[i + 1].count;
max_t(int, rates[i].count, if (rates[i].count > 15)
rates[i + 1].count); rates[i].count = 15;
rates[i + 1].idx = -1; rates[i + 1].idx = -1;
rates[i + 1].count = 0; rates[i + 1].count = 0;
...@@ -537,6 +538,17 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) ...@@ -537,6 +538,17 @@ static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
} }
} }
} while (!finished); } while (!finished);
// Ensure that MCS0 or 1Mbps is present at the end of the retry list
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
if (rates[i].idx == 0)
break;
if (rates[i].idx == -1) {
rates[i].idx = 0;
rates[i].count = 8; // == hw->max_rate_tries
rates[i].flags = rates[i - 1].flags & IEEE80211_TX_RC_MCS;
break;
}
}
// All retries use long GI // All retries use long GI
for (i = 1; i < IEEE80211_TX_MAX_RATES; i++) for (i = 1; i < IEEE80211_TX_MAX_RATES; i++)
rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI;
...@@ -550,7 +562,8 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif, ...@@ -550,7 +562,8 @@ static u8 wfx_tx_get_rate_id(struct wfx_vif *wvif,
rate_id = wfx_tx_policy_get(wvif, rate_id = wfx_tx_policy_get(wvif,
tx_info->driver_rates, &tx_policy_renew); tx_info->driver_rates, &tx_policy_renew);
WARN(rate_id == WFX_INVALID_RATE_ID, "unable to get a valid Tx policy"); if (rate_id == WFX_INVALID_RATE_ID)
dev_warn(wvif->wdev->dev, "unable to get a valid Tx policy");
if (tx_policy_renew) { if (tx_policy_renew) {
/* FIXME: It's not so optimal to stop TX queues every now and /* FIXME: It's not so optimal to stop TX queues every now and
...@@ -735,7 +748,9 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg) ...@@ -735,7 +748,9 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, struct hif_cnf_tx *arg)
rate = &tx_info->status.rates[i]; rate = &tx_info->status.rates[i];
if (rate->idx < 0) if (rate->idx < 0)
break; break;
if (tx_count < rate->count && arg->status && arg->ack_failures) if (tx_count < rate->count &&
arg->status == HIF_STATUS_RETRY_EXCEEDED &&
arg->ack_failures)
dev_dbg(wvif->wdev->dev, "all retries were not consumed: %d != %d\n", dev_dbg(wvif->wdev->dev, "all retries were not consumed: %d != %d\n",
rate->count, tx_count); rate->count, tx_count);
if (tx_count <= rate->count && tx_count && if (tx_count <= rate->count && tx_count &&
......
...@@ -39,9 +39,9 @@ struct wfx_link_entry { ...@@ -39,9 +39,9 @@ struct wfx_link_entry {
struct tx_policy { struct tx_policy {
struct list_head link; struct list_head link;
int usage_count;
u8 rates[12]; u8 rates[12];
u8 usage_count; bool uploaded;
u8 uploaded;
}; };
struct tx_policy_cache { struct tx_policy_cache {
...@@ -61,6 +61,7 @@ struct wfx_tx_priv { ...@@ -61,6 +61,7 @@ struct wfx_tx_priv {
} __packed; } __packed;
void wfx_tx_policy_init(struct wfx_vif *wvif); void wfx_tx_policy_init(struct wfx_vif *wvif);
void wfx_tx_policy_upload_work(struct work_struct *work);
void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct sk_buff *skb); struct sk_buff *skb);
......
...@@ -147,7 +147,6 @@ static inline int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required) ...@@ -147,7 +147,6 @@ static inline int hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required)
} }
if (!required) if (!required)
val.unpmf_allowed = 1; val.unpmf_allowed = 1;
cpu_to_le32s((u32 *) &val);
return hif_write_mib(wvif->wdev, wvif->id, return hif_write_mib(wvif->wdev, wvif->id,
HIF_MIB_ID_PROTECTED_MGMT_POLICY, HIF_MIB_ID_PROTECTED_MGMT_POLICY,
&val, sizeof(val)); &val, sizeof(val));
......
...@@ -289,7 +289,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, ...@@ -289,7 +289,7 @@ struct wfx_dev *wfx_init_common(struct device *dev,
hw->sta_data_size = sizeof(struct wfx_sta_priv); hw->sta_data_size = sizeof(struct wfx_sta_priv);
hw->queues = 4; hw->queues = 4;
hw->max_rates = 8; hw->max_rates = 8;
hw->max_rate_tries = 15; hw->max_rate_tries = 8;
hw->extra_tx_headroom = sizeof(struct hif_sl_msg_hdr) + hw->extra_tx_headroom = sizeof(struct hif_sl_msg_hdr) +
sizeof(struct hif_msg) sizeof(struct hif_msg)
+ sizeof(struct hif_req_tx) + sizeof(struct hif_req_tx)
......
...@@ -422,6 +422,7 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb, ...@@ -422,6 +422,7 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
break; break;
case do_wep: case do_wep:
wfx_tx_lock(wvif->wdev); wfx_tx_lock(wvif->wdev);
WARN_ON(wvif->wep_pending_skb);
wvif->wep_default_key_id = tx_priv->hw_key->keyidx; wvif->wep_default_key_id = tx_priv->hw_key->keyidx;
wvif->wep_pending_skb = skb; wvif->wep_pending_skb = skb;
if (!schedule_work(&wvif->wep_key_work)) if (!schedule_work(&wvif->wep_key_work))
......
...@@ -592,6 +592,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif) ...@@ -592,6 +592,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
wfx_tx_flush(wvif->wdev); wfx_tx_flush(wvif->wdev);
hif_keep_alive_period(wvif, 0); hif_keep_alive_period(wvif, 0);
hif_reset(wvif, false); hif_reset(wvif, false);
wfx_tx_policy_init(wvif);
hif_set_output_power(wvif, wvif->wdev->output_power * 10); hif_set_output_power(wvif, wvif->wdev->output_power * 10);
wvif->dtim_period = 0; wvif->dtim_period = 0;
hif_set_macaddr(wvif, wvif->vif->addr); hif_set_macaddr(wvif, wvif->vif->addr);
...@@ -880,8 +881,10 @@ static int wfx_update_beaconing(struct wfx_vif *wvif) ...@@ -880,8 +881,10 @@ static int wfx_update_beaconing(struct wfx_vif *wvif)
if (wvif->state != WFX_STATE_AP || if (wvif->state != WFX_STATE_AP ||
wvif->beacon_int != conf->beacon_int) { wvif->beacon_int != conf->beacon_int) {
wfx_tx_lock_flush(wvif->wdev); wfx_tx_lock_flush(wvif->wdev);
if (wvif->state != WFX_STATE_PASSIVE) if (wvif->state != WFX_STATE_PASSIVE) {
hif_reset(wvif, false); hif_reset(wvif, false);
wfx_tx_policy_init(wvif);
}
wvif->state = WFX_STATE_PASSIVE; wvif->state = WFX_STATE_PASSIVE;
wfx_start_ap(wvif); wfx_start_ap(wvif);
wfx_tx_unlock(wvif->wdev); wfx_tx_unlock(wvif->wdev);
...@@ -1567,6 +1570,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -1567,6 +1570,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work); INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work);
INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work); INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work);
INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
mutex_unlock(&wdev->conf_mutex); mutex_unlock(&wdev->conf_mutex);
hif_set_macaddr(wvif, vif->addr); hif_set_macaddr(wvif, vif->addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment