Commit c30b5b8c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull staging driver fixes from Greg KH:
 "Here are three small fixes for staging drivers for 5.17-rc8 or -final,
  which ever comes next.

  They resolve some reported problems:

   - rtl8723bs wifi driver deadlock fix for reported problem that is a
     revert of a previous patch. Also a documentation fix is added so
     that the same problem hopefully can not come back again.

   - gdm724x driver use-after-free fix for a reported problem.

  All of these have been in linux-next for a while with no reported
  problems"

* tag 'staging-5.17-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: rtl8723bs: Improve the comment explaining the locking rules
  staging: rtl8723bs: Fix access-point mode deadlock
  staging: gdm724x: fix use after free in gdm_lte_rx()
parents 55b4083b 342e7c6e
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -76,14 +76,15 @@ static void tx_complete(void *arg)

static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type)
{
	int ret;
	int ret, len;

	len = skb->len + ETH_HLEN;
	ret = netif_rx_ni(skb);
	if (ret == NET_RX_DROP) {
		nic->stats.rx_dropped++;
	} else {
		nic->stats.rx_packets++;
		nic->stats.rx_bytes += skb->len + ETH_HLEN;
		nic->stats.rx_bytes += len;
	}

	return 0;
+5 −2
Original line number Diff line number Diff line
@@ -5907,6 +5907,7 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
	struct sta_info *psta_bmc;
	struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
	struct xmit_frame *pxmitframe = NULL;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
	struct sta_priv  *pstapriv = &padapter->stapriv;

	/* for BC/MC Frames */
@@ -5917,7 +5918,8 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
	if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) {
		msleep(10);/*  10ms, ATIM(HIQ) Windows */

		spin_lock_bh(&psta_bmc->sleep_q.lock);
		/* spin_lock_bh(&psta_bmc->sleep_q.lock); */
		spin_lock_bh(&pxmitpriv->lock);

		xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
		list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
@@ -5940,7 +5942,8 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
			rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
		}

		spin_unlock_bh(&psta_bmc->sleep_q.lock);
		/* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
		spin_unlock_bh(&pxmitpriv->lock);

		/* check hi queue and bmc_sleepq */
		rtw_chk_hi_queue_cmd(padapter);
+7 −3
Original line number Diff line number Diff line
@@ -957,8 +957,10 @@ static signed int validate_recv_ctrl_frame(struct adapter *padapter, union recv_
		if ((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) {
			struct list_head	*xmitframe_plist, *xmitframe_phead;
			struct xmit_frame *pxmitframe = NULL;
			struct xmit_priv *pxmitpriv = &padapter->xmitpriv;

			spin_lock_bh(&psta->sleep_q.lock);
			/* spin_lock_bh(&psta->sleep_q.lock); */
			spin_lock_bh(&pxmitpriv->lock);

			xmitframe_phead = get_list_head(&psta->sleep_q);
			xmitframe_plist = get_next(xmitframe_phead);
@@ -989,10 +991,12 @@ static signed int validate_recv_ctrl_frame(struct adapter *padapter, union recv_
					update_beacon(padapter, WLAN_EID_TIM, NULL, true);
				}

				spin_unlock_bh(&psta->sleep_q.lock);
				/* spin_unlock_bh(&psta->sleep_q.lock); */
				spin_unlock_bh(&pxmitpriv->lock);

			} else {
				spin_unlock_bh(&psta->sleep_q.lock);
				/* spin_unlock_bh(&psta->sleep_q.lock); */
				spin_unlock_bh(&pxmitpriv->lock);

				if (pstapriv->tim_bitmap&BIT(psta->aid)) {
					if (psta->sleepq_len == 0) {
+10 −12
Original line number Diff line number Diff line
@@ -293,48 +293,46 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)

	/* list_del_init(&psta->wakeup_list); */

	spin_lock_bh(&psta->sleep_q.lock);
	spin_lock_bh(&pxmitpriv->lock);

	rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
	psta->sleepq_len = 0;
	spin_unlock_bh(&psta->sleep_q.lock);

	spin_lock_bh(&pxmitpriv->lock);

	/* vo */
	spin_lock_bh(&pstaxmitpriv->vo_q.sta_pending.lock);
	/* spin_lock_bh(&(pxmitpriv->vo_pending.lock)); */
	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
	list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
	phwxmit = pxmitpriv->hwxmits;
	phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt;
	pstaxmitpriv->vo_q.qcnt = 0;
	spin_unlock_bh(&pstaxmitpriv->vo_q.sta_pending.lock);
	/* spin_unlock_bh(&(pxmitpriv->vo_pending.lock)); */

	/* vi */
	spin_lock_bh(&pstaxmitpriv->vi_q.sta_pending.lock);
	/* spin_lock_bh(&(pxmitpriv->vi_pending.lock)); */
	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
	list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
	phwxmit = pxmitpriv->hwxmits+1;
	phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt;
	pstaxmitpriv->vi_q.qcnt = 0;
	spin_unlock_bh(&pstaxmitpriv->vi_q.sta_pending.lock);
	/* spin_unlock_bh(&(pxmitpriv->vi_pending.lock)); */

	/* be */
	spin_lock_bh(&pstaxmitpriv->be_q.sta_pending.lock);
	/* spin_lock_bh(&(pxmitpriv->be_pending.lock)); */
	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
	list_del_init(&(pstaxmitpriv->be_q.tx_pending));
	phwxmit = pxmitpriv->hwxmits+2;
	phwxmit->accnt -= pstaxmitpriv->be_q.qcnt;
	pstaxmitpriv->be_q.qcnt = 0;
	spin_unlock_bh(&pstaxmitpriv->be_q.sta_pending.lock);
	/* spin_unlock_bh(&(pxmitpriv->be_pending.lock)); */

	/* bk */
	spin_lock_bh(&pstaxmitpriv->bk_q.sta_pending.lock);
	/* spin_lock_bh(&(pxmitpriv->bk_pending.lock)); */
	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
	list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
	phwxmit = pxmitpriv->hwxmits+3;
	phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt;
	pstaxmitpriv->bk_q.qcnt = 0;
	spin_unlock_bh(&pstaxmitpriv->bk_q.sta_pending.lock);
	/* spin_unlock_bh(&(pxmitpriv->bk_pending.lock)); */

	spin_unlock_bh(&pxmitpriv->lock);

+9 −7
Original line number Diff line number Diff line
@@ -1734,12 +1734,15 @@ void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pfram
	struct list_head *plist, *phead, *tmp;
	struct	xmit_frame	*pxmitframe;

	spin_lock_bh(&pframequeue->lock);

	phead = get_list_head(pframequeue);
	list_for_each_safe(plist, tmp, phead) {
		pxmitframe = list_entry(plist, struct xmit_frame, list);

		rtw_free_xmitframe(pxmitpriv, pxmitframe);
	}
	spin_unlock_bh(&pframequeue->lock);
}

s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe)
@@ -1794,7 +1797,6 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
	struct sta_info *psta;
	struct tx_servq	*ptxservq;
	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
	struct xmit_priv *xmit_priv = &padapter->xmitpriv;
	struct hw_xmit	*phwxmits =  padapter->xmitpriv.hwxmits;
	signed int res = _SUCCESS;

@@ -1812,14 +1814,12 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)

	ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));

	spin_lock_bh(&xmit_priv->lock);
	if (list_empty(&ptxservq->tx_pending))
		list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));

	list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
	ptxservq->qcnt++;
	phwxmits[ac_index].accnt++;
	spin_unlock_bh(&xmit_priv->lock);

exit:

@@ -2202,10 +2202,11 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
	struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
	struct xmit_frame *pxmitframe = NULL;
	struct sta_priv *pstapriv = &padapter->stapriv;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;

	psta_bmc = rtw_get_bcmc_stainfo(padapter);

	spin_lock_bh(&psta->sleep_q.lock);
	spin_lock_bh(&pxmitpriv->lock);

	xmitframe_phead = get_list_head(&psta->sleep_q);
	list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
@@ -2306,7 +2307,7 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)

_exit:

	spin_unlock_bh(&psta->sleep_q.lock);
	spin_unlock_bh(&pxmitpriv->lock);

	if (update_mask)
		update_beacon(padapter, WLAN_EID_TIM, NULL, true);
@@ -2318,8 +2319,9 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst
	struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
	struct xmit_frame *pxmitframe = NULL;
	struct sta_priv *pstapriv = &padapter->stapriv;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;

	spin_lock_bh(&psta->sleep_q.lock);
	spin_lock_bh(&pxmitpriv->lock);

	xmitframe_phead = get_list_head(&psta->sleep_q);
	list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
@@ -2372,7 +2374,7 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst
		}
	}

	spin_unlock_bh(&psta->sleep_q.lock);
	spin_unlock_bh(&pxmitpriv->lock);
}

void enqueue_pending_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
Loading