drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c

Source file repositories/reference/linux-study-clean/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c
Extension
.c
Size
13118 bytes
Lines
479
Domain
Driver Families
Bucket
drivers/staging
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (psta) {
			precvframe->u.hdr.psta = psta;
			rtl8723b_process_phy_info(padapter, precvframe);
		}
	} else if (pkt_info.to_self || pkt_info.is_beacon) {
		u32 adhoc_state = WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE;

		if (check_fwstate(&padapter->mlmepriv, adhoc_state))
			if (psta)
				precvframe->u.hdr.psta = psta;
		rtl8723b_process_phy_info(padapter, precvframe);
	}
}

static void rtl8723bs_c2h_packet_handler(struct adapter *padapter,
					 u8 *pbuf, u16 length)
{
	u8 *tmp = NULL;
	u8 res = false;

	if (length == 0)
		return;

	tmp = kmemdup(pbuf, length, GFP_ATOMIC);
	if (!tmp)
		return;

	res = rtw_c2h_packet_wk_cmd(padapter, tmp, length);

	if (!res)
		kfree(tmp);
}

static inline union recv_frame *try_alloc_recvframe(struct recv_priv *precvpriv,
						    struct recv_buf *precvbuf)
{
	union recv_frame *precvframe;

	precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
	if (!precvframe) {
		rtw_enqueue_recvbuf_to_head(precvbuf,
					    &precvpriv->recv_buf_pending_queue);

		/*  The case of can't allocate recvframe should be temporary, */
		/*  schedule again and hope recvframe is available next time. */
		tasklet_schedule(&precvpriv->recv_tasklet);
	}

	return precvframe;
}

static inline bool rx_crc_err(struct recv_priv *precvpriv,
			      struct hal_com_data *p_hal_data,
			      struct rx_pkt_attrib *pattrib,
			      union recv_frame *precvframe)
{
	/*  fix Hardware RX data error, drop whole recv_buffer */
	if ((!(p_hal_data->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err) {
		rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
		return true;
	}

	return false;
}

static inline bool pkt_exceeds_tail(struct recv_priv *precvpriv,
				    u8 *end, u8 *tail,
				    union recv_frame *precvframe)
{
	if (end > tail) {
		rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
		return true;
	}

	return false;
}

static void rtl8723bs_recv_tasklet(struct tasklet_struct *t)
{
	struct adapter *padapter = from_tasklet(padapter, t,
						recvpriv.recv_tasklet);
	struct hal_com_data *p_hal_data;
	struct recv_priv *precvpriv;
	struct recv_buf *precvbuf;
	union recv_frame *precvframe;
	struct rx_pkt_attrib *pattrib;
	struct __queue *recv_buf_queue;
	u8 *ptr;
	u32 pkt_offset, skb_len, alloc_sz;
	struct sk_buff *pkt_copy = NULL;

Annotation

Implementation Notes