From 95775d12219285d6e0116acb6267864582cd01ef Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Jan 2015 10:26:12 +0000 Subject: [PATCH] staging: vt6655: [BUG] Protect MACvSelectPage1 with lock. The device must not flip to page 1 while in interrupt lock causing loss of connection or dead lock. Protect from changes to page by adding lock where user can change the page in CARDvSetRSPINF, vnt_configure and set_channel Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 5 +++++ drivers/staging/vt6655/channel.c | 6 ++++++ drivers/staging/vt6655/device_main.c | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index a0796405c308..47801ca94cd9 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -670,6 +670,9 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, u8 bb_type) { union vnt_phy_field_swap phy; unsigned char byTxRate, byRsvTime; /* For OFDM */ + unsigned long flags; + + spin_lock_irqsave(&pDevice->lock, flags); /* Set to Page1 */ MACvSelectPage1(pDevice->PortOffset); @@ -767,6 +770,8 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, u8 bb_type) VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); /* Set to Page0 */ MACvSelectPage0(pDevice->PortOffset); + + spin_unlock_irqrestore(&pDevice->lock, flags); } void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index c8f739dd346e..983d9cbd3439 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -202,6 +202,10 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) BBvSoftwareReset(pDevice); if (pDevice->byLocalID > REV_ID_VT3253_B1) { + unsigned long flags; + + spin_lock_irqsave(&pDevice->lock, flags); + /* set HW default power register */ MACvSelectPage1(pDevice->PortOffset); RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh); @@ -209,6 +213,8 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh); VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr); MACvSelectPage0(pDevice->PortOffset); + + spin_unlock_irqrestore(&pDevice->lock, flags); } if (pDevice->byBBType == BB_TYPE_11B) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index a3f5cd84259a..f5cc78e8254c 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1565,6 +1565,10 @@ static void vnt_configure(struct ieee80211_hw *hw, if (changed_flags & FIF_ALLMULTI) { if (*total_flags & FIF_ALLMULTI) { + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->mc_list_count > 2) { MACvSelectPage1(priv->PortOffset); @@ -1586,6 +1590,8 @@ static void vnt_configure(struct ieee80211_hw *hw, MACvSelectPage0(priv->PortOffset); } + spin_unlock_irqrestore(&priv->lock, flags); + rx_mode |= RCR_MULTICAST | RCR_BROADCAST; } else { rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);