Presently the TX buffer stops while filling the buffer.
However, this does not make use of the available buffer
space, it also lags the speed of the TX troughtput.
Only stop the queue when the buffer becomes full. The
Interupt handler will start the queue again when a
buffer is available.
Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6655/device_main.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 326bce3..07ebdea 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -1105,6 +1105,7 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
if (AVAIL_TD(priv, dma_idx) < 1) {
spin_unlock_irqrestore(&priv->lock, flags);
+ ieee80211_stop_queues(priv->hw);
return -ENOMEM;
}
@@ -1156,13 +1157,8 @@ static void vnt_tx_80211(struct ieee80211_hw *hw,
{
struct vnt_private *priv = hw->priv;
- ieee80211_stop_queues(hw);
-
- if (vnt_tx_packet(priv, skb)) {
+ if (vnt_tx_packet(priv, skb))
ieee80211_free_txskb(hw, skb);
-
- ieee80211_wake_queues(hw);
- }
}
static int vnt_start(struct ieee80211_hw *hw)
--
2.5.0
Presently the TX buffer stops while filling the buffer and urb.
However, this does not make use of the available buffer
space, it also lags the speed of the TX troughtput.
Only stop the queue when the buffer becomes full. The
URB complete will start the queue again when a
buffer and URB is available.
Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/main_usb.c | 7 +------
drivers/staging/vt6656/rxtx.c | 5 ++++-
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 3fc6862..01e642d 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -507,13 +507,8 @@ static void vnt_tx_80211(struct ieee80211_hw *hw,
{
struct vnt_private *priv = hw->priv;
- ieee80211_stop_queues(hw);
-
- if (vnt_tx_packet(priv, skb)) {
+ if (vnt_tx_packet(priv, skb))
ieee80211_free_txskb(hw, skb);
-
- ieee80211_wake_queues(hw);
- }
}
static int vnt_start(struct ieee80211_hw *hw)
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index da075f4..efb54f5 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -101,9 +101,12 @@ static struct vnt_usb_send_context
}
}
- if (ii == priv->num_tx_context)
+ if (ii == priv->num_tx_context) {
dev_dbg(&priv->usb->dev, "%s No Free Tx Context\n", __func__);
+ ieee80211_stop_queues(priv->hw);
+ }
+
return NULL;
}
--
2.5.0
The lock in vnt_submit_rx_urb_complete is blocked by TX activity.
The lock comes from a time when RX needed to be synchronized with
other parts of the driver because the WLAN API was in driver.
Since this is now dealt with in mac80211 the lock is unnecessary.
Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/usbpipe.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index a5912dd..c975c3b 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -168,7 +168,6 @@ static void vnt_submit_rx_urb_complete(struct urb *urb)
{
struct vnt_rcb *rcb = urb->context;
struct vnt_private *priv = rcb->priv;
- unsigned long flags;
switch (urb->status) {
case 0:
@@ -184,8 +183,6 @@ static void vnt_submit_rx_urb_complete(struct urb *urb)
}
if (urb->actual_length) {
- spin_lock_irqsave(&priv->lock, flags);
-
if (vnt_rx_data(priv, rcb, urb->actual_length)) {
rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
if (!rcb->skb) {
@@ -193,7 +190,6 @@ static void vnt_submit_rx_urb_complete(struct urb *urb)
"Failed to re-alloc rx skb\n");
rcb->in_use = false;
- spin_unlock_irqrestore(&priv->lock, flags);
return;
}
} else {
@@ -203,8 +199,6 @@ static void vnt_submit_rx_urb_complete(struct urb *urb)
urb->transfer_buffer = skb_put(rcb->skb,
skb_tailroom(rcb->skb));
-
- spin_unlock_irqrestore(&priv->lock, flags);
}
if (usb_submit_urb(urb, GFP_ATOMIC)) {
--
2.5.0
The device should ready to listen to next beacon so on count down of
wake_up_count == 1.
schedule command WLAN_CMD_TBTT_WAKEUP which calls vnt_next_tbtt_wakeup which
wakes the device.
This restores this back to vendors code with a slight difference the
count down is in the interrupt handler.
Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/device.h | 2 ++
drivers/staging/vt6656/int.c | 14 +++++++++++---
drivers/staging/vt6656/power.c | 2 +-
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 635d931..dec36f2 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -389,6 +389,8 @@ struct vnt_private {
u8 bb_pre_ed_rssi;
u8 bb_pre_ed_index;
+ u16 wake_up_count;
+
/* command timer */
struct delayed_work run_command_work;
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
index 2ef70e4..14b8ebc 100644
--- a/drivers/staging/vt6656/int.c
+++ b/drivers/staging/vt6656/int.c
@@ -149,10 +149,18 @@ void vnt_int_process_data(struct vnt_private *priv)
priv->op_mode == NL80211_IFTYPE_AP)
vnt_schedule_command(priv, WLAN_CMD_BECON_SEND);
- if (int_data->isr0 & ISR_TBTT) {
- if (priv->hw->conf.flags & IEEE80211_CONF_PS)
+ if (int_data->isr0 & ISR_TBTT &&
+ priv->hw->conf.flags & IEEE80211_CONF_PS) {
+ if (!priv->wake_up_count)
+ priv->wake_up_count =
+ priv->hw->conf.listen_interval;
+
+ --priv->wake_up_count;
+
+ /* Turn on wake up to listen next beacon */
+ if (priv->wake_up_count == 1)
vnt_schedule_command(priv,
- WLAN_CMD_TBTT_WAKEUP);
+ WLAN_CMD_TBTT_WAKEUP);
}
priv->current_tsf = le64_to_cpu(int_data->tsf);
diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
index 0ffbaed..d5912d2 100644
--- a/drivers/staging/vt6656/power.c
+++ b/drivers/staging/vt6656/power.c
@@ -134,7 +134,7 @@ int vnt_next_tbtt_wakeup(struct vnt_private *priv)
struct ieee80211_conf *conf = &hw->conf;
int wake_up = false;
- if (conf->listen_interval == 1) {
+ if (conf->listen_interval > 1) {
/* Turn on wake up to listen next beacon */
vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
wake_up = true;
--
2.5.0
The device can now operate in low power mode
Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/main_usb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 7246c76..3fc6862 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -1002,6 +1002,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
ieee80211_hw_set(priv->hw, SIGNAL_DBM);
ieee80211_hw_set(priv->hw, RX_INCLUDES_FCS);
ieee80211_hw_set(priv->hw, REPORTS_TX_ACK_STATUS);
+ ieee80211_hw_set(priv->hw, SUPPORTS_PS);
priv->hw->max_signal = 100;
--
2.5.0
The TSF counter is presently unused on driver in infrastructure mode.
It is needed to implement power saving functions and wireless stats that
are passed in interrupt handling.
Ensuring counter is synced with access point beacon.
Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/main_usb.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index af572d7..7246c76 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -757,6 +757,26 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
}
}
+
+ if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) &&
+ priv->op_mode != NL80211_IFTYPE_AP) {
+ if (conf->assoc && conf->beacon_rate) {
+ vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL,
+ TFTCTL_TSFCNTREN);
+
+ vnt_adjust_tsf(priv, conf->beacon_rate->hw_value,
+ conf->sync_tsf, priv->current_tsf);
+
+ vnt_mac_set_beacon_interval(priv, conf->beacon_int);
+
+ vnt_reset_next_tbtt(priv, conf->beacon_int);
+ } else {
+ vnt_clear_current_tsf(priv);
+
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL,
+ TFTCTL_TSFCNTREN);
+ }
+ }
}
static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
--
2.5.0