staging: vt6655: vnt_tx_packet Correct TX order of OWNED_BY_NIC
PATCH 1/3 staging: vt6655: vnt_tx_packet Correct TX order of OWNED_BY_NIC
The state of m_td0TD0.f1Owner should change after the buff_addr has been filled otherwise the device grabs the buffer too early.
m_td0TD0.f1Owner is protected by memory barriers on both sides of change.
iTDUsed is best incremented after MACvTransmit.
It appears that f1Owner actually polls to do the memory transfer.
A back port patch will be needed for v3.19
--- drivers/staging/vt6655/device_main.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/staging/vt6655/device_main.c +7 -8
@@ -1201,14 +1201,6 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)if (dma_idx ==TYPE_AC0DMA ) head_td->pTDInfo->byFlags =TD_FLAGS_NETIF_SKB ; - priv->iTDUsed[dma_idx]++; - -/* Take ownership */ -wmb (); - head_td->m_td0TD0.f1Owner =OWNED_BY_NIC ; - -/* get Next */ -wmb (); priv->apCurrTD[dma_idx] = head_td->next;spin_unlock_irqrestore (&priv->lock, flags);
@@ -1229,11 +1221,18 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) head_td->buff_addr =cpu_to_le32 (head_td->pTDInfo->skb_dma); +/* Poll Transmit the adapter */ +wmb (); + head_td->m_td0TD0.f1Owner =OWNED_BY_NIC ; +wmb ();/* second memory barrier */ +if (head_td->pTDInfo->byFlags &TD_FLAGS_NETIF_SKB )MACvTransmitAC0 (priv->PortOffset);else MACvTransmit0 (priv->PortOffset); + priv->iTDUsed[dma_idx]++; +spin_unlock_irqrestore (&priv->lock, flags);return 0 ;
Signature · 1 line
2.1.4
PATCH 2/3 staging: vt6655: CARDbUpdateTSF bss timestamp correct tsf counter value.
The TSF counter is not set correctly.
Use sync_tsf for last beacon value and get tsf local value.
Remove qwLocalTSF variable and call CARDbGetCurrentTSF.
--- drivers/staging/vt6655/card.c | 10 +++++++--- drivers/staging/vt6655/card.h | 2 +- drivers/staging/vt6655/device_main.c | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-)
drivers/staging/vt6655/card.c +7 -3
@@ -362,12 +362,16 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, u8 bb_type)* Return Value: none */ bool CARDbUpdateTSF (struct vnt_private *pDevice,unsigned char byRxRate, -u64 qwBSSTimestamp,u64 qwLocalTSF) +u64 qwBSSTimestamp) { +u64 local_tsf;u64 qwTSFOffset =0 ; -if (qwBSSTimestamp != qwLocalTSF) { - qwTSFOffset =CARDqGetTSFOffset (byRxRate, qwBSSTimestamp, qwLocalTSF); +CARDbGetCurrentTSF (pDevice, &local_tsf); + +if (qwBSSTimestamp != local_tsf) { + qwTSFOffset =CARDqGetTSFOffset (byRxRate, qwBSSTimestamp, + local_tsf);/* adjust TSF, HW's TSF add TSF Offset reg */ VNSvOutPortD (pDevice->PortOffset +MAC_REG_TSFOFST , (u32 )qwTSFOffset);VNSvOutPortD (pDevice->PortOffset +MAC_REG_TSFOFST +4 , (u32)(qwTSFOffset >>32 ));
drivers/staging/vt6655/card.h +1 -1
@@ -83,7 +83,7 @@ bool CARDbRadioPowerOff(struct vnt_private *);bool CARDbRadioPowerOn (struct vnt_private *);bool CARDbSetPhyParameter (struct vnt_private *,u8 );bool CARDbUpdateTSF (struct vnt_private *,unsigned char byRxRate, -u64 qwBSSTimestamp,u64 qwLocalTSF); +u64 qwBSSTimestamp);bool CARDbSetBeaconPeriod (struct vnt_private *,unsigned short wBeaconInterval);#endif /* __CARD_H__ */
drivers/staging/vt6655/device_main.c +1 -1
@@ -1473,7 +1473,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,if (changed &BSS_CHANGED_ASSOC && priv->op_mode !=NL80211_IFTYPE_AP ) {if (conf->assoc) {CARDbUpdateTSF (priv, conf->beacon_rate->hw_value, - conf->sync_device_ts, conf->sync_tsf); + conf->sync_tsf);CARDbSetBeaconPeriod (priv, conf->beacon_int);
Signature · 1 line
2.1.4
PATCH 3/3 staging: vt6655: lock MACvWriteBSSIDAddress.
In reply to Malcolm PriestleyThis function selects page 1 and cause intermittent problems on interrupt handler.
lock call with spin_lock_irqsave.
--- drivers/staging/vt6655/device_main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/staging/vt6655/device_main.c +8 -1
@@ -1412,9 +1412,16 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, priv->current_aid = conf->aid; -if (changed &BSS_CHANGED_BSSID ) +if (changed &BSS_CHANGED_BSSID ) { +unsigned long flags; + +spin_lock_irqsave (&priv->lock, flags); +MACvWriteBSSIDAddress (priv->PortOffset, (u8 *)conf->bssid); +spin_unlock_irqrestore (&priv->lock, flags); + } +if (changed &BSS_CHANGED_BASIC_RATES ) { priv->basic_rates = conf->basic_rates;
Signature · 1 line
2.1.4