Exemplo n.º 1
0
void wlan_802_11_to_802_3_packet(
	IN	PRTMP_ADAPTER	pAd,
	IN	RX_BLK			*pRxBlk,
	IN	PUCHAR			pHeader802_3,
	IN  UCHAR			FromWhichBSSID)
{
	struct sk_buff	*pOSPkt;

	ASSERT(pRxBlk->pRxPacket);
	ASSERT(pHeader802_3);

	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);

	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
	pOSPkt->data = pRxBlk->pData;
	pOSPkt->head = pOSPkt->data;
	pOSPkt->len = pRxBlk->DataSize;
	skb_set_tail_pointer(pOSPkt, pOSPkt->len);

	//
	// copy 802.3 header
	//
	//

	NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
}
Exemplo n.º 2
0
/**
 * SIPC header_create() family functions
 *
 * Create SIPC5 header
 *
 * sipc5_hdr_create_skb()
 *	Create common SIPC5 header
 *
 * sipc5_hdr_create_legacy_rfs()
 *	Create SIPC5 header with IPC4.1 RFS header
 *	Because IMC modem used the 256KB rfs packet and RILD check the full
 *	packet with RFS header len, kernel remove the SIPC5 header and add the
 *	lagacy RFS header.
 *
 * sipc5_hdr_create_multifmt()
 *	TBD
 *
 * sipc5_hdr_create_skb_handover()
 *	Remove the ethernet frame When use `handover' with Network Bridge,
 *	user -> bridge device(rmnet0) -> real rmnet(xxxx_rmnet0) -> here.
 *	bridge device is ethernet device unlike xxxx_rmnet(net device).
 *	We remove the an ethernet header of skb before using skb->len,
 *	because bridge device added an ethernet header to skb.
 *
 * RETURN
 *	Returns the socket buffer that added SIPC5 header.
 *
 **/
static struct sk_buff *sipc5_hdr_create(struct io_device *iod,
				struct sipc_hdr *hdr, struct sk_buff *skb)
{
	struct sipc5_link_hdr *sipc5h;
	struct link_device *ld = get_current_link(iod);

	if (skb->len > 0xFFFF - SIPC5_HDR_LEN_MAX) {
		sipc5h = (struct sipc5_link_hdr *)
					skb_push(skb, SIPC5_HDR_LEN_EXT);
		sipc5h->cfg = SIPC5_HDR_CFG_START | SIPC5_HDR_EXT;
		*((u32 *)&sipc5h->len) = (u32)(skb->len);
	} else {
		sipc5h = (struct sipc5_link_hdr *)
					skb_push(skb, SIPC5_HDR_LEN);
		sipc5h->cfg = SIPC5_HDR_CFG_START;
		sipc5h->len = (u16)(skb->len);
	}
	sipc5h->ch = iod->id;

	/* Should check the alignment for dynamic switch link dev*/
	if (ld->aligned) {
		sipc5h->cfg |= SIPC5_HDR_PAD;
		skb_set_tail_pointer(skb, SIPC_ALIGN(skb->len));
		skb->len = SIPC_ALIGN(skb->len);
	}
	skbpriv(skb)->sipch = (void *)sipc5h;
	return skb;
}
Exemplo n.º 3
0
PNDIS_PACKET ClonePacket(
	IN	PRTMP_ADAPTER	pAd,
	IN	PNDIS_PACKET	pPacket,
	IN	PUCHAR			pData,
	IN	ULONG			DataSize)
{
	struct sk_buff	*pRxPkt;
	struct sk_buff	*pClonedPkt;

	ASSERT(pPacket);
	pRxPkt = RTPKT_TO_OSPKT(pPacket);

	// clone the packet
	pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);

	if (pClonedPkt)
	{
    	// set the correct dataptr and data len
    	pClonedPkt->dev = pRxPkt->dev;
    	pClonedPkt->data = pData;
	pClonedPkt->head = pClonedPkt->data;
    	pClonedPkt->len = DataSize;
	skb_set_tail_pointer(pClonedPkt, pClonedPkt->len);
		ASSERT(DataSize < 1530);
	}
	return pClonedPkt;
}
Exemplo n.º 4
0
/* TODO: not verified */
static struct sk_buff *sipc5_hdr_create_multifmt(struct io_device *iod,
				struct sipc_hdr *hdr, struct sk_buff *skb)
{
	struct sipc5_link_hdr *sipc5h;
	struct link_device *ld = get_current_link(iod);

	if (hdr->multifmt) {
		sipc5h = (struct sipc5_link_hdr *)
					skb_push(skb, SIPC5_HDR_LEN_CTRL);
		sipc5h->cfg = SIPC5_HDR_CFG_START | SIPC5_HDR_CONTROL;
		sipc5h->len = skb->len;
		sipc5h->ext.ctl = hdr->multifmt;
		sipc5h->ch = iod->id;

		/* Should check the alignment for dynamic switch link dev*/
		if (ld->aligned) {
			sipc5h->cfg |= SIPC5_HDR_PAD;
			skb_set_tail_pointer(skb, SIPC_ALIGN(skb->len));
			skb->len = SIPC_ALIGN(skb->len);
		}
		skbpriv(skb)->sipch = (void *)sipc5h;
		return skb;
	}
	return sipc5_hdr_create(iod, hdr, skb);
}
Exemplo n.º 5
0
static int
linux_if_rx(struct vr_interface *vif, struct vr_packet *pkt)
{
    int rc;
    struct net_device *dev = (struct net_device *)vif->vif_os;
    struct sk_buff *skb = vp_os_packet(pkt);
    struct vr_ip *ip;
    unsigned short network_off, transport_off, cksum_off = 0;

    skb->data = pkt->vp_head + pkt->vp_data;
    skb->len = pkt_len(pkt);
    skb_set_tail_pointer(skb, pkt_head_len(pkt));

    if (!dev) {
        kfree_skb(skb);
        goto exit_rx;
    }

    (void)__sync_fetch_and_add(&dev->stats.rx_bytes, skb->len);
    (void)__sync_fetch_and_add(&dev->stats.rx_packets, 1);

    /* this is only needed for mirroring */
    if ((pkt->vp_flags & VP_FLAG_FROM_DP) &&
            (pkt->vp_flags & VP_FLAG_CSUM_PARTIAL)) {
    	network_off = pkt_get_network_header_off(pkt);
    	ip = (struct vr_ip *)(pkt_data_at_offset(pkt, network_off));
    	transport_off = network_off + (ip->ip_hl * 4);

        if (ip->ip_proto == VR_IP_PROTO_TCP)
            cksum_off = offsetof(struct vr_tcp, tcp_csum);
        else if (ip->ip_proto == VR_IP_PROTO_UDP)
Exemplo n.º 6
0
static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size)
{
	u32 readsize, ret;
	u8 *readbuf;
	struct recv_priv *recv_priv;
	struct recv_buf	*recvbuf;


	/*  Patch for some SDIO Host 4 bytes issue */
	/*  ex. RK3188 */
	readsize = RND4(size);

	/* 3 1. alloc recvbuf */
	recv_priv = &adapter->recvpriv;
	recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue);
	if (!recvbuf) {
		DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
		return NULL;
	}

	/* 3 2. alloc skb */
	if (!recvbuf->pskb) {
		SIZE_PTR tmpaddr = 0;
		SIZE_PTR alignment = 0;

		recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);

		if (recvbuf->pskb) {
			recvbuf->pskb->dev = adapter->pnetdev;

			tmpaddr = (SIZE_PTR)recvbuf->pskb->data;
			alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
			skb_reserve(recvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
		}

		if (!recvbuf->pskb) {
			DBG_871X("%s: alloc_skb fail! read =%d\n", __func__, readsize);
			return NULL;
		}
	}

	/* 3 3. read data from rxfifo */
	readbuf = recvbuf->pskb->data;
	ret = sdio_read_port(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, readbuf);
	if (ret == _FAIL) {
		RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __func__));
		return NULL;
	}


	/* 3 4. init recvbuf */
	recvbuf->len = size;
	recvbuf->phead = recvbuf->pskb->head;
	recvbuf->pdata = recvbuf->pskb->data;
	skb_set_tail_pointer(recvbuf->pskb, size);
	recvbuf->ptail = skb_tail_pointer(recvbuf->pskb);
	recvbuf->pend = skb_end_pointer(recvbuf->pskb);

	return recvbuf;
}
Exemplo n.º 7
0
static struct sk_buff *
net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
	struct sk_buff		*skb2;
	struct nc_header	*header = NULL;
	struct nc_trailer	*trailer = NULL;
	int			padlen = sizeof (struct nc_trailer);
	int			len = skb->len;

	if (!((len + padlen + sizeof (struct nc_header)) & 0x01))
		padlen++;
	if (!skb_cloned(skb)) {
		int	headroom = skb_headroom(skb);
		int	tailroom = skb_tailroom(skb);

		if (padlen <= tailroom &&
		    sizeof(struct nc_header) <= headroom)
			/* There's enough head and tail room */
			goto encapsulate;

		if ((sizeof (struct nc_header) + padlen) <
				(headroom + tailroom)) {
			/* There's enough total room, so just readjust */
			skb->data = memmove(skb->head
						+ sizeof (struct nc_header),
					    skb->data, skb->len);
			skb_set_tail_pointer(skb, len);
			goto encapsulate;
		}
	}

	/* Create a new skb to use with the correct size */
	skb2 = skb_copy_expand(skb,
				sizeof (struct nc_header),
				padlen,
				flags);
	dev_kfree_skb_any(skb);
	if (!skb2)
		return skb2;
	skb = skb2;

encapsulate:
	/* header first */
	header = (struct nc_header *) skb_push(skb, sizeof *header);
	header->hdr_len = cpu_to_le16(sizeof (*header));
	header->packet_len = cpu_to_le16(len);
	header->packet_id = cpu_to_le16((u16)dev->xid++);

	/* maybe pad; then trailer */
	if (!((skb->len + sizeof *trailer) & 0x01))
		*skb_put(skb, 1) = PAD_BYTE;
	trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer);
	put_unaligned(header->packet_id, &trailer->packet_id);
#if 0
	netdev_dbg(dev->net, "frame >tx h %d p %d id %d\n",
		   header->hdr_len, header->packet_len,
		   header->packet_id);
#endif
	return skb;
}
Exemplo n.º 8
0
void r8712_recv_indicatepkt(struct _adapter *padapter,
			    union recv_frame *precv_frame)
{
	struct recv_priv *precvpriv;
	struct  __queue	*pfree_recv_queue;
	_pkt *skb;
	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;

	precvpriv = &(padapter->recvpriv);
	pfree_recv_queue = &(precvpriv->free_recv_queue);
	skb = precv_frame->u.hdr.pkt;
	if (skb == NULL)
		goto _recv_indicatepkt_drop;
	skb->data = precv_frame->u.hdr.rx_data;
	skb->len = precv_frame->u.hdr.len;
	skb_set_tail_pointer(skb, skb->len);
	if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1))
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	else
		skb->ip_summed = CHECKSUM_NONE;
	skb->dev = padapter->pnetdev;
	skb->protocol = eth_type_trans(skb, padapter->pnetdev);
	netif_rx(skb);
	precv_frame->u.hdr.pkt = NULL; /* pointers to NULL before
					* r8712_free_recvframe() */
	r8712_free_recvframe(precv_frame, pfree_recv_queue);
	return;
_recv_indicatepkt_drop:
	 /*enqueue back to free_recv_queue*/
	 if (precv_frame)
		r8712_free_recvframe(precv_frame, pfree_recv_queue);
	 precvpriv->rx_drop++;
}
Exemplo n.º 9
0
static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size)
{
	u32 readsize, ret;
	u8 *preadbuf;
	struct recv_priv *precvpriv;
	struct recv_buf	*precvbuf;


	readsize = size;

	//3 1. alloc recvbuf
	precvpriv = &padapter->recvpriv;
	precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
	if (precvbuf == NULL) {
		RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: alloc recvbuf FAIL!\n", __FUNCTION__));
		return NULL;
	}

	//3 2. alloc skb
	if (precvbuf->pskb == NULL) {
		SIZE_PTR tmpaddr=0;
		SIZE_PTR alignment=0;

		precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);

		if(precvbuf->pskb)
		{
			precvbuf->pskb->dev = padapter->pnetdev;

			tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
			alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
			skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
		}

		if (precvbuf->pskb == NULL) {
			DBG_871X("%s: alloc_skb fail! read=%d\n", __FUNCTION__, readsize);
			return NULL;
		}
	}

	//3 3. read data from rxfifo
	preadbuf = precvbuf->pskb->data;
//	rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
	ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
	if (ret == _FAIL) {
		RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__));
		return NULL;
	}


	//3 4. init recvbuf
	precvbuf->len = readsize;
	precvbuf->phead = precvbuf->pskb->head;
	precvbuf->pdata = precvbuf->pskb->data;
	skb_set_tail_pointer(precvbuf->pskb, readsize);
	precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
	precvbuf->pend = skb_end_pointer(precvbuf->pskb);

	return precvbuf;
}
Exemplo n.º 10
0
int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
{
	struct recv_priv *precvpriv;
	_queue	*pfree_recv_queue;
	_pkt *skb;
	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;

	DBG_COUNTER(padapter->rx_logs.os_indicate);

	precvpriv = &(padapter->recvpriv);
	pfree_recv_queue = &(precvpriv->free_recv_queue);

	skb = precv_frame->u.hdr.pkt;
	if (skb == NULL)
	{
		RT_TRACE(_module_recv_osdep_c_, _drv_err_, ("rtw_recv_indicatepkt():skb ==NULL something wrong!!!!\n"));
		goto _recv_indicatepkt_drop;
	}

	RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("rtw_recv_indicatepkt():skb != NULL !!!\n"));
	RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head =%p  precv_frame->hdr.rx_data =%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data));
	RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("precv_frame->hdr.rx_tail =%p precv_frame->u.hdr.rx_end =%p precv_frame->hdr.len =%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len));

	skb->data = precv_frame->u.hdr.rx_data;

	skb_set_tail_pointer(skb, precv_frame->u.hdr.len);

	skb->len = precv_frame->u.hdr.len;

	RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("\n skb->head =%p skb->data =%p skb->tail =%p skb->end =%p skb->len =%d\n", skb->head, skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len));

#ifdef CONFIG_AUTO_AP_MODE
	if (0x8899 == pattrib->eth_type)
	{
		rtw_os_ksocket_send(padapter, precv_frame);

		/* goto _recv_indicatepkt_drop; */
	}
#endif /* CONFIG_AUTO_AP_MODE */

	rtw_os_recv_indicate_pkt(padapter, skb, pattrib);

	precv_frame->u.hdr.pkt = NULL; /*  pointers to NULL before rtw_free_recvframe() */

	rtw_free_recvframe(precv_frame, pfree_recv_queue);

	RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("\n rtw_recv_indicatepkt :after rtw_os_recv_indicate_pkt!!!!\n"));

        return _SUCCESS;

_recv_indicatepkt_drop:

	 /* enqueue back to free_recv_queue */
	 if (precv_frame)
		 rtw_free_recvframe(precv_frame, pfree_recv_queue);

	 DBG_COUNTER(padapter->rx_logs.os_indicate_err);
	 return _FAIL;
}
Exemplo n.º 11
0
_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 *pdata)
{
	u16	eth_type;
	u8	*data_ptr;
	_pkt *sub_skb;
	struct rx_pkt_attrib *pattrib;

	pattrib = &prframe->u.hdr.attrib;

#ifdef CONFIG_SKB_COPY
	sub_skb = rtw_skb_alloc(nSubframe_Length + 12);
	if(sub_skb)
	{
		skb_reserve(sub_skb, 12);
		data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
		_rtw_memcpy(data_ptr, (pdata + ETH_HLEN), nSubframe_Length);
	}
	else
#endif // CONFIG_SKB_COPY
	{
		sub_skb = rtw_skb_clone(prframe->u.hdr.pkt);
		if(sub_skb)
		{
			sub_skb->data = pdata + ETH_HLEN;
			sub_skb->len = nSubframe_Length;
			skb_set_tail_pointer(sub_skb, nSubframe_Length);
		}
		else
		{
			DBG_871X("%s(): rtw_skb_clone() Fail!!!\n",__FUNCTION__);
			return NULL;
		}
	}

	eth_type = RTW_GET_BE16(&sub_skb->data[6]);

	if (sub_skb->len >= 8 &&
		((_rtw_memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) &&
		  eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
		 _rtw_memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE) )) {
		/* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
		skb_pull(sub_skb, SNAP_SIZE);
		_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
		_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
	} else {
		u16 len;
		/* Leave Ethernet header part of hdr and full payload */
		len = htons(sub_skb->len);
		_rtw_memcpy(skb_push(sub_skb, 2), &len, 2);
		_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
		_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
	}

	return sub_skb;
}
Exemplo n.º 12
0
static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev,
		struct sk_buff *skb, gfp_t flags)
{
	int pack_len = skb->len;
	int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE;
	int headroom = skb_headroom(skb);
	int tailroom = skb_tailroom(skb);
	int need_tail = 0;
	__le16 *len;

	/*                                                              */
	if ((pack_with_header_len) < dev->maxpacket)
		need_tail = dev->maxpacket - pack_with_header_len + 1;
	/*
                                                                    
                                                                     
                                 
  */
	else if (!(pack_with_header_len % dev->maxpacket))
		need_tail = 1;

	if (!skb_cloned(skb) &&
			(headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) {
		if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) {
			skb->data = memmove(skb->head + INT51X1_HEADER_SIZE,
					skb->data, skb->len);
			skb_set_tail_pointer(skb, skb->len);
		}
	} else {
		struct sk_buff *skb2;

		skb2 = skb_copy_expand(skb,
				INT51X1_HEADER_SIZE,
				need_tail,
				flags);
		dev_kfree_skb_any(skb);
		if (!skb2)
			return NULL;
		skb = skb2;
	}

	pack_len += need_tail;
	pack_len &= 0x07ff;

	len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE);
	*len = cpu_to_le16(pack_len);

	if(need_tail)
		memset(__skb_put(skb, need_tail), 0, need_tail);

	return skb;
}
Exemplo n.º 13
0
static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev,
		struct sk_buff *skb, gfp_t flags)
{
	int pack_len = skb->len;
	int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE;
	int headroom = skb_headroom(skb);
	int tailroom = skb_tailroom(skb);
	int need_tail = 0;
	__le16 *len;

	/* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */
	if ((pack_with_header_len) < dev->maxpacket)
		need_tail = dev->maxpacket - pack_with_header_len + 1;
	/*
	 * usbnet would send a ZLP if packetlength mod urbsize == 0 for us,
	 * but we need to know ourself, because this would add to the length
	 * we send down to the device...
	 */
	else if (!(pack_with_header_len % dev->maxpacket))
		need_tail = 1;

	if (!skb_cloned(skb) &&
			(headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) {
		if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) {
			skb->data = memmove(skb->head + INT51X1_HEADER_SIZE,
					skb->data, skb->len);
			skb_set_tail_pointer(skb, skb->len);
		}
	} else {
		struct sk_buff *skb2;

		skb2 = skb_copy_expand(skb,
				INT51X1_HEADER_SIZE,
				need_tail,
				flags);
		dev_kfree_skb_any(skb);
		if (!skb2)
			return NULL;
		skb = skb2;
	}

	pack_len += need_tail;
	pack_len &= 0x07ff;

	len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE);
	*len = cpu_to_le16(pack_len);

	if(need_tail)
		memset(__skb_put(skb, need_tail), 0, need_tail);

	return skb;
}
Exemplo n.º 14
0
//
// change OS packet DataPtr and DataLen
//
void  update_os_packet_info(
	IN	PRTMP_ADAPTER	pAd,
	IN	RX_BLK			*pRxBlk,
	IN  UCHAR			FromWhichBSSID)
{
	struct sk_buff	*pOSPkt;

	ASSERT(pRxBlk->pRxPacket);
	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);

	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
	pOSPkt->data = pRxBlk->pData;
	pOSPkt->head = pOSPkt->data;
	pOSPkt->len = pRxBlk->DataSize;
	skb_set_tail_pointer(pOSPkt, pOSPkt->len);
}
static struct sk_buff *
rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
	struct rndis_data_hdr	*hdr;
	struct sk_buff		*skb2;
	unsigned		len = skb->len;

	if (likely(!skb_cloned(skb))) {
		int	room = skb_headroom(skb);

		/* enough head room as-is? */
		if (unlikely((sizeof *hdr) <= room))
			goto fill;

		/* enough room, but needs to be readjusted? */
		room += skb_tailroom(skb);
		if (likely((sizeof *hdr) <= room)) {
			skb->data = memmove(skb->head + sizeof *hdr,
					    skb->data, len);
			skb_set_tail_pointer(skb, len);
			goto fill;
		}
	}

	/* create a new skb, with the correct size (and tailpad) */
	skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
	dev_kfree_skb_any(skb);
	if (unlikely(!skb2))
		return skb2;
	skb = skb2;

	/* fill out the RNDIS header.  we won't bother trying to batch
	 * packets; Linux minimizes wasted bandwidth through tx queues.
	 */
fill:
	hdr = (void *) __skb_push(skb, sizeof *hdr);
	memset(hdr, 0, sizeof *hdr);
	hdr->msg_type = RNDIS_MSG_PACKET;
	hdr->msg_len = cpu_to_le32(skb->len);
	hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
	hdr->data_len = cpu_to_le32(len);

	/* FIXME make the last packet always be short ... */
	return skb;
}
Exemplo n.º 16
0
int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame)
{
	int ret = _FAIL;
	struct recv_priv *precvpriv;
	_queue	*pfree_recv_queue;
	_pkt *skb;
	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
	struct rx_pkt_attrib *pattrib;

	if (NULL == precv_frame)
		goto _recv_drop;

	pattrib = &precv_frame->u.hdr.attrib;
	precvpriv = &(padapter->recvpriv);
	pfree_recv_queue = &(precvpriv->free_recv_queue);

	skb = precv_frame->u.hdr.pkt;
	if (skb == NULL) {
		DBG_871X("%s :skb==NULL something wrong!!!!\n", __func__);
		goto _recv_drop;
	}

	skb->data = precv_frame->u.hdr.rx_data;
	skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
	skb->len = precv_frame->u.hdr.len;
	skb->ip_summed = CHECKSUM_NONE;
	skb->pkt_type = PACKET_OTHERHOST;
	skb->protocol = htons(0x0019); /* ETH_P_80211_RAW */

	rtw_netif_rx(padapter->pnetdev, skb);

	/* pointers to NULL before rtw_free_recvframe() */
	precv_frame->u.hdr.pkt = NULL;

	ret = _SUCCESS;

_recv_drop:

	/* enqueue back to free_recv_queue */
	if (precv_frame)
		rtw_free_recvframe(precv_frame, pfree_recv_queue);

	return ret;

}
Exemplo n.º 17
0
struct sk_buff *
rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
	struct rndis_data_hdr	*hdr;
	struct sk_buff		*skb2;
	unsigned		len = skb->len;

	if (likely(!skb_cloned(skb))) {
		int	room = skb_headroom(skb);

		
		if (unlikely((sizeof *hdr) <= room))
			goto fill;

		
		room += skb_tailroom(skb);
		if (likely((sizeof *hdr) <= room)) {
			skb->data = memmove(skb->head + sizeof *hdr,
					    skb->data, len);
			skb_set_tail_pointer(skb, len);
			goto fill;
		}
	}

	
	skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
	dev_kfree_skb_any(skb);
	if (unlikely(!skb2))
		return skb2;
	skb = skb2;

	
fill:
	hdr = (void *) __skb_push(skb, sizeof *hdr);
	memset(hdr, 0, sizeof *hdr);
	hdr->msg_type = RNDIS_MSG_PACKET;
	hdr->msg_len = cpu_to_le32(skb->len);
	hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
	hdr->data_len = cpu_to_le32(len);

	
	return skb;
}
Exemplo n.º 18
0
static struct sk_buff *
genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
	int 	padlen;
	int	length = skb->len;
	int	headroom = skb_headroom(skb);
	int	tailroom = skb_tailroom(skb);
	__le32	*packet_count;
	__le32	*packet_len;

	// FIXME:  magic numbers, bleech
	padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;

	if ((!skb_cloned(skb))
			&& ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
		if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
			skb->data = memmove(skb->head + (4 + 4*1),
					     skb->data, skb->len);
			skb_set_tail_pointer(skb, skb->len);
		}
	} else {
		struct sk_buff	*skb2;
		skb2 = skb_copy_expand(skb, (4 + 4*1) , padlen, flags);
		dev_kfree_skb_any(skb);
		skb = skb2;
		if (!skb)
			return NULL;
	}

	// attach the packet count to the header
	packet_count = (__le32 *) skb_push(skb, (4 + 4*1));
	packet_len = packet_count + 1;

	*packet_count = cpu_to_le32(1);
	*packet_len = cpu_to_le32(length);

	// add padding byte
	if ((skb->len % dev->maxpacket) == 0)
		skb_put(skb, 1);

	return skb;
}
Exemplo n.º 19
0
struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
			     struct cfpkt *addpkt,
			     u16 expectlen)
{
	struct sk_buff *dst = pkt_to_skb(dstpkt);
	struct sk_buff *add = pkt_to_skb(addpkt);
	u16 addlen = skb_headlen(add);
	u16 neededtailspace;
	struct sk_buff *tmp;
	u16 dstlen;
	u16 createlen;
	if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) {
		cfpkt_destroy(addpkt);
		return dstpkt;
	}
	if (expectlen > addlen)
		neededtailspace = expectlen;
	else
		neededtailspace = addlen;

	if (dst->tail + neededtailspace > dst->end) {
		/* Create a dumplicate of 'dst' with more tail space */
		struct cfpkt *tmppkt;
		dstlen = skb_headlen(dst);
		createlen = dstlen + neededtailspace;
		tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX);
		if (tmppkt == NULL)
			return NULL;
		tmp = pkt_to_skb(tmppkt);
		skb_set_tail_pointer(tmp, dstlen);
		tmp->len = dstlen;
		memcpy(tmp->data, dst->data, dstlen);
		cfpkt_destroy(dstpkt);
		dst = tmp;
	}
	memcpy(skb_tail_pointer(dst), add->data, skb_headlen(add));
	cfpkt_destroy(addpkt);
	dst->tail += addlen;
	dst->len += addlen;
	return skb_to_pkt(dst);
}
static struct sk_buff *sipc5_hdr_create_ipcloopback(struct io_device *iod,
				struct sipc_hdr *hdr, struct sk_buff *skb)
{
	struct sipc5_link_hdr *sipc5h;
	struct link_device *ld = get_current_link(iod);

	sipc5h = (struct sipc5_link_hdr *)
				skb_push(skb, SIPC5_HDR_LEN);
	sipc5h->cfg = SIPC5_HDR_CFG_START;
	sipc5h->len = (u16)(skb->len);

	mif_info("send ipcloopback data: %d\n", skb->len);
	sipc5h->ch = SIPC5_CH_ID_FMT_0;

	/* Should check the alignment for dynamic switch link dev*/
	if (ld->aligned) {
		sipc5h->cfg |= SIPC5_HDR_PAD;
		skb_set_tail_pointer(skb, SIPC_ALIGN(skb->len));
		skb->len = SIPC_ALIGN(skb->len);
	}
	skbpriv(skb)->sipch = (void *)sipc5h;
	return skb;
}
Exemplo n.º 21
0
struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
{
	struct sk_buff *skb2;
	struct sk_buff *skb = pkt_to_skb(pkt);
	struct cfpkt *tmppkt;
	u8 *split = skb->data + pos;
	u16 len2nd = skb_tail_pointer(skb) - split;

	if (unlikely(is_erronous(pkt)))
		return NULL;

	if (skb->data + pos > skb_tail_pointer(skb)) {
		PKT_ERROR(pkt, "trying to split beyond end of packet\n");
		return NULL;
	}

	/* Create a new packet for the second part of the data */
	tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
				  PKT_PREFIX);
	if (tmppkt == NULL)
		return NULL;
	skb2 = pkt_to_skb(tmppkt);


	if (skb2 == NULL)
		return NULL;

	/* Reduce the length of the original packet */
	skb_set_tail_pointer(skb, pos);
	skb->len = pos;

	memcpy(skb2->data, split, len2nd);
	skb2->tail += len2nd;
	skb2->len += len2nd;
	skb2->priority = skb->priority;
	return skb_to_pkt(skb2);
}
Exemplo n.º 22
0
int rtw_recv_indicatepkt(struct adapter *padapter,
			 struct recv_frame *precv_frame)
{
	struct recv_priv *precvpriv;
	struct __queue *pfree_recv_queue;
	struct sk_buff *skb;
	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;


	precvpriv = &(padapter->recvpriv);
	pfree_recv_queue = &(precvpriv->free_recv_queue);

	skb = precv_frame->pkt;
	if (!skb) {
		RT_TRACE(_module_recv_osdep_c_, _drv_err_,
			 ("rtw_recv_indicatepkt():skb == NULL something wrong!!!!\n"));
		goto _recv_indicatepkt_drop;
	}

	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
		 ("rtw_recv_indicatepkt():skb != NULL !!!\n"));
	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
		 ("rtw_recv_indicatepkt():precv_frame->rx_head =%p  precv_frame->hdr.rx_data =%p\n",
		 precv_frame->rx_head, precv_frame->rx_data));
	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
		 ("precv_frame->hdr.rx_tail =%p precv_frame->rx_end =%p precv_frame->hdr.len =%d\n",
		 precv_frame->rx_tail, precv_frame->rx_end,
		 precv_frame->len));

	skb->data = precv_frame->rx_data;

	skb_set_tail_pointer(skb, precv_frame->len);

	skb->len = precv_frame->len;

	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
		 ("skb->head =%p skb->data =%p skb->tail =%p skb->end =%p skb->len =%d\n",
		 skb->head, skb->data, skb_tail_pointer(skb),
		 skb_end_pointer(skb), skb->len));

	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
		struct sk_buff *pskb2 = NULL;
		struct sta_info *psta = NULL;
		struct sta_priv *pstapriv = &padapter->stapriv;
		struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
		int bmcast = IS_MCAST(pattrib->dst);

		if (memcmp(pattrib->dst, myid(&padapter->eeprompriv),
			   ETH_ALEN)) {
			if (bmcast) {
				psta = rtw_get_bcmc_stainfo(padapter);
				pskb2 = skb_clone(skb, GFP_ATOMIC);
			} else {
				psta = rtw_get_stainfo(pstapriv, pattrib->dst);
			}

			if (psta) {
				struct net_device *pnetdev;

				pnetdev = (struct net_device *)padapter->pnetdev;
				skb->dev = pnetdev;
				skb_set_queue_mapping(skb, rtw_recv_select_queue(skb));

				rtw_xmit_entry(skb, pnetdev);

				if (bmcast)
					skb = pskb2;
				else
					goto _recv_indicatepkt_end;
			}
		}
	}

	rcu_read_lock();
	rcu_dereference(padapter->pnetdev->rx_handler_data);
	rcu_read_unlock();

	skb->ip_summed = CHECKSUM_NONE;
	skb->dev = padapter->pnetdev;
	skb->protocol = eth_type_trans(skb, padapter->pnetdev);

	netif_rx(skb);

_recv_indicatepkt_end:

	/*  pointers to NULL before rtw_free_recvframe() */
	precv_frame->pkt = NULL;

	rtw_free_recvframe(precv_frame, pfree_recv_queue);

	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
		 ("\n rtw_recv_indicatepkt :after netif_rx!!!!\n"));


	return _SUCCESS;

_recv_indicatepkt_drop:

	 /* enqueue back to free_recv_queue */
	rtw_free_recvframe(precv_frame, pfree_recv_queue);

	 return _FAIL;
}
void rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
{	
       struct recv_priv *precvpriv;
       _queue	*pfree_recv_queue;	     
	_pkt *skb;	
	struct mlme_priv*pmlmepriv = &padapter->mlmepriv;
#ifdef CONFIG_RTL8712_TCP_CSUM_OFFLOAD_RX
	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
#endif

_func_enter_;

	precvpriv = &(padapter->recvpriv);	
	pfree_recv_queue = &(precvpriv->free_recv_queue);	
     
#ifdef CONFIG_DRVEXT_MODULE		
	if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS)
	{		
		rtw_free_recvframe(precv_frame, pfree_recv_queue);
		return;
	}
#endif

	skb = precv_frame->u.hdr.pkt;	       
       if(skb == NULL)
       {        
            RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n"));		   
	     goto _recv_indicatepkt_drop;
	}

	   
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n"));		
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p  precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data));
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len));
		
	skb->data = precv_frame->u.hdr.rx_data;
	
#ifdef NET_SKBUFF_DATA_USES_OFFSET	
	skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
#else
	skb->tail = precv_frame->u.hdr.rx_tail;
#endif

	skb->len = precv_frame->u.hdr.len;
	
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb->tail, skb->end, skb->len));
	
	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)	 	
	{	 	
	 	_pkt *pskb2=NULL;
	 	struct sta_info *psta = NULL;
	 	struct sta_priv *pstapriv = &padapter->stapriv;	
		struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;	
		int bmcast = IS_MCAST(pattrib->dst);

		//DBG_871X("bmcast=%d\n", bmcast);

		if(_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)==_FALSE)		
		{
			psta = rtw_get_stainfo(pstapriv, pattrib->dst);

			//DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst);

			if(bmcast)
			{
				pskb2 = skb_clone(skb, GFP_ATOMIC);	
			}

			if(psta)
			{
				//DBG_871X("directly forwarding to the xmit_entry\n");

				//skb->ip_summed = CHECKSUM_NONE;	
				//skb->protocol = eth_type_trans(skb, pnetdev);

				skb->dev = padapter->pnetdev;	
				rtw_xmit_entry(skb, padapter->pnetdev);			
		
				if(bmcast == _FALSE)				
				        goto _recv_indicatepkt_end;			
			
			}

			if(bmcast)
				skb = pskb2;
			
		}
		else// to APself
		{
			//DBG_871X("to APSelf\n");
		}
		
	}


	
#ifdef CONFIG_RTL8712_TCP_CSUM_OFFLOAD_RX
        if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) {
		skb->ip_summed = CHECKSUM_UNNECESSARY;
		//printk("CHECKSUM_UNNECESSARY \n");
	} else {
		skb->ip_summed = CHECKSUM_NONE;
		//printk("CHECKSUM_NONE(%d, %d) \n", pattrib->tcpchk_valid, pattrib->tcp_chkrpt);
	}
#else /* !CONFIG_RTL8712_TCP_CSUM_OFFLOAD_RX */

	skb->ip_summed = CHECKSUM_NONE;

#endif

	skb->dev = padapter->pnetdev;
	skb->protocol = eth_type_trans(skb, padapter->pnetdev);
	
	netif_rx(skb);

_recv_indicatepkt_end:

	precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe()

	rtw_free_recvframe(precv_frame, pfree_recv_queue);

	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after netif_rx!!!!\n"));

_func_exit_;		

        return;		

_recv_indicatepkt_drop:

	 //enqueue back to free_recv_queue	
	 if(precv_frame)
		 rtw_free_recvframe(precv_frame, pfree_recv_queue);

	 
 	 precvpriv->rx_drop++;	

_func_exit_;

}
Exemplo n.º 24
0
static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
					struct net_device *net)
{
	struct eth_dev		*dev = netdev_priv(net);
	int			length = skb->len;
	int			retval=0;
	struct usb_request	*req = NULL;
	unsigned long		flags;
	struct usb_ep		*in;
	u16			cdc_filter;
    struct rndis_msg    *msg = get_rndis_msg();
    struct pkt_msg      *r_q=NULL,*w_q = NULL;
    int index;
    struct sk_buff *skb_old;

	spin_lock_irqsave(&dev->lock, flags);
	if (dev->port_usb) {
		in = dev->port_usb->in_ep;
		cdc_filter = dev->port_usb->cdc_filter;
	} else {
		in = NULL;
		cdc_filter = 0;
	}
	spin_unlock_irqrestore(&dev->lock, flags);

	if (!in) {
		dev_kfree_skb_any(skb);
		return NETDEV_TX_OK;
	}

	/* apply outgoing CDC or RNDIS filters */
	if (!is_promisc(cdc_filter)) {
		u8		*dest = skb->data;

		if (is_multicast_ether_addr(dest)) {
			u16	type;

			/* ignores USB_CDC_PACKET_TYPE_MULTICAST and host
			 * SET_ETHERNET_MULTICAST_FILTERS requests
			 */
			if (is_broadcast_ether_addr(dest))
				type = USB_CDC_PACKET_TYPE_BROADCAST;
			else
				type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
			if (!(cdc_filter & type)) {
				dev_kfree_skb_any(skb);
				return NETDEV_TX_OK;
			}
		}
		/* ignores USB_CDC_PACKET_TYPE_DIRECTED */
	}
    skb_old=skb;
    eth_alloc_req(net,&req,&w_q,skb);
    if(req == NULL)
        return NETDEV_TX_BUSY;
	/* no buffer copies needed, unless the network stack did it
	 * or the hardware can't use skb buffers.
	 * or there's not enough space for extra headers we need
	 */
	if (dev->wrap) {
		unsigned long	flags;

		spin_lock_irqsave(&dev->lock, flags);

		if (dev->port_usb)
			skb = dev->wrap(dev->port_usb, skb);
		spin_unlock_irqrestore(&dev->lock, flags);
		if (!skb)
			goto drop;

		length = skb->len;
	}
	/*
	 * Align data to 32bit if the dma controller requires it
	 */
	if (gadget_dma32(dev->gadget)) {
		unsigned long align = (unsigned long)skb->data & 3;
		if (WARN_ON(skb_headroom(skb) < align)) {
			dev_kfree_skb_any(skb);
			goto drop;
		} else if (align) {
			u8 *data = skb->data;
			size_t len = skb_headlen(skb);
			skb->data -= align;
			memmove(skb->data, data, len);
			skb_set_tail_pointer(skb, len);
		}
	}

    retval = 0;
    if(w_q==NULL)
		retval = save_to_queue(dev,msg,skb,req,&w_q);
	else if(skb!=skb_old)
		update_sbks_in_queue(w_q,skb,skb_old);

    if(retval == 0){
        spin_lock_irqsave(&msg->buffer_lock, flags);
        if(w_q && w_q->bit_map==FULL_BIT_MAP && (w_q->state != RNDIS_QUEUE_SEND)){
            msg->last_sent = w_q->q_idx;
            w_q->state = RNDIS_QUEUE_SEND;
            spin_unlock_irqrestore(&msg->buffer_lock, flags);
            pkt_msg_send(msg,w_q,net);
            return NETDEV_TX_OK;
        }

        w_q = msg->q + msg->w_idx;
        if(w_q->bit_map==FULL_BIT_MAP && w_q->state != RNDIS_QUEUE_SEND){
            msg->last_sent = w_q->q_idx;
            w_q->state = RNDIS_QUEUE_SEND;
            spin_unlock_irqrestore(&msg->buffer_lock, flags);
            pkt_msg_send(msg,w_q,net);
            return NETDEV_TX_OK;
        }
        if( msg->w_idx == msg->r_idx &&
            w_q->state == RNDIS_QUEUE_GATHER &&
            w_q->skb_idx == w_q->pkt_cnt){
			msg->last_sent = w_q->q_idx;
            w_q->state = RNDIS_QUEUE_SEND;
            spin_unlock_irqrestore(&msg->buffer_lock, flags);
            pkt_msg_send(msg,w_q,net);
            return NETDEV_TX_OK;
        }
        spin_unlock_irqrestore(&msg->buffer_lock, flags);
        return NETDEV_TX_OK;
    }
	if (retval) {
		dev_kfree_skb_any(skb);
drop:
        printk("drop req\n");
		dev->net->stats.tx_dropped++;
		spin_lock_irqsave(&dev->req_lock, flags);
		if (list_empty(&dev->tx_reqs))
			netif_start_queue(net);
		list_add(&req->list, &dev->tx_reqs);
		spin_unlock_irqrestore(&dev->req_lock, flags);
	}
	return NETDEV_TX_OK;
}
Exemplo n.º 25
0
static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
{
	struct sk_buff *skb;
	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
	int len;
	int nframes;
	int x;
	int offset;
	struct usb_cdc_ncm_ndp16 *ndp16;
	struct usb_cdc_ncm_dpe16 *dpe16;
	int ndpoffset;
	int loopcount = 50; /* arbitrary max preventing infinite loop */

	ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in);
	if (ndpoffset < 0)
		goto error;

next_ndp:
	nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset);
	if (nframes < 0)
		goto error;

	ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset);

	if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) {
		pr_debug("invalid DPT16 signature <%u>\n",
			 le32_to_cpu(ndp16->dwSignature));
		goto err_ndp;
	}
	dpe16 = ndp16->dpe16;

	for (x = 0; x < nframes; x++, dpe16++) {
		offset = le16_to_cpu(dpe16->wDatagramIndex);
		len = le16_to_cpu(dpe16->wDatagramLength);

		/*
		 * CDC NCM ch. 3.7
		 * All entries after first NULL entry are to be ignored
		 */
		if ((offset == 0) || (len == 0)) {
			if (!x)
				goto err_ndp; /* empty NTB */
			break;
		}

		/* sanity checking */
		if (((offset + len) > skb_in->len) ||
				(len > ctx->rx_max) || (len < ETH_HLEN)) {
			pr_debug("invalid frame detected (ignored)"
					"offset[%u]=%u, length=%u, skb=%p\n",
					x, offset, len, skb_in);
			if (!x)
				goto err_ndp;
			break;

		} else {
			skb = skb_clone(skb_in, GFP_ATOMIC);
			if (!skb)
				goto error;
			skb->len = len;
			skb->data = ((u8 *)skb_in->data) + offset;
			skb_set_tail_pointer(skb, len);
			usbnet_skb_return(dev, skb);
		}
	}
err_ndp:
	/* are there more NDPs to process? */
	ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex);
	if (ndpoffset && loopcount--)
		goto next_ndp;

	return 1;
error:
	return 0;
}
Exemplo n.º 26
0
int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
{
	struct recv_priv *precvpriv;
	_queue	*pfree_recv_queue;
	_pkt *skb;
	struct mlme_priv*pmlmepriv = &padapter->mlmepriv;
#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
#endif

#ifdef CONFIG_BR_EXT
	void *br_port = NULL;
#endif

_func_enter_;

	precvpriv = &(padapter->recvpriv);
	pfree_recv_queue = &(precvpriv->free_recv_queue);

#ifdef CONFIG_DRVEXT_MODULE
	if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS)
	{
		goto _recv_indicatepkt_drop;
	}
#endif

	skb = precv_frame->u.hdr.pkt;
	if(skb == NULL)
	{
		RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n"));
		goto _recv_indicatepkt_drop;
	}

	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n"));		
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p  precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data));
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len));

	skb->data = precv_frame->u.hdr.rx_data;

	skb_set_tail_pointer(skb, precv_frame->u.hdr.len);

	skb->len = precv_frame->u.hdr.len;

	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb->tail, skb->end, skb->len));

	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
	{
	 	_pkt *pskb2=NULL;
	 	struct sta_info *psta = NULL;
	 	struct sta_priv *pstapriv = &padapter->stapriv;
		struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
		int bmcast = IS_MCAST(pattrib->dst);

		//DBG_871X("bmcast=%d\n", bmcast);

		if(_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)==_FALSE)
		{
			//DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst);

			if(bmcast)
			{
				psta = rtw_get_bcmc_stainfo(padapter);
				pskb2 = rtw_skb_clone(skb);
			} else {
				psta = rtw_get_stainfo(pstapriv, pattrib->dst);
			}

			if(psta)
			{
				struct net_device *pnetdev= (struct net_device*)padapter->pnetdev;			

				//DBG_871X("directly forwarding to the rtw_xmit_entry\n");

				//skb->ip_summed = CHECKSUM_NONE;
				skb->dev = pnetdev;			
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
				skb_set_queue_mapping(skb, rtw_recv_select_queue(skb));
#endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)
			
				_rtw_xmit_entry(skb, pnetdev);
			
				if(bmcast)
					skb = pskb2;
				else
					goto _recv_indicatepkt_end;
			}


		}
		else// to APself
		{
			//DBG_871X("to APSelf\n");
		}
	}
	

#ifdef CONFIG_BR_EXT

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
	br_port = padapter->pnetdev->br_port;
#else   // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
	rcu_read_lock();
	br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
	rcu_read_unlock();
#endif  // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))

	if( br_port	&& (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) )	 	
	{
		int nat25_handle_frame(_adapter *priv, struct sk_buff *skb);
		if (nat25_handle_frame(padapter, skb) == -1) {
			//priv->ext_stats.rx_data_drops++;
			//DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n");
			//return FAIL;
#if 1			
			// bypass this frame to upper layer!!
#else
			goto _recv_indicatepkt_drop;
#endif
		}	
	}

#endif	// CONFIG_BR_EXT


#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
	if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) {
		skb->ip_summed = CHECKSUM_UNNECESSARY;
		//DBG_871X("CHECKSUM_UNNECESSARY \n");
	} else {
		skb->ip_summed = CHECKSUM_NONE;
		//DBG_871X("CHECKSUM_NONE(%d, %d) \n", pattrib->tcpchk_valid, pattrib->tcp_chkrpt);
	}
#else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */

	skb->ip_summed = CHECKSUM_NONE;

#endif

	skb->dev = padapter->pnetdev;
	skb->protocol = eth_type_trans(skb, padapter->pnetdev);

	rtw_netif_rx(padapter->pnetdev, skb);

_recv_indicatepkt_end:

	precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe()

	rtw_free_recvframe(precv_frame, pfree_recv_queue);

	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_netif_rx!!!!\n"));

_func_exit_;

        return _SUCCESS;

_recv_indicatepkt_drop:

	 //enqueue back to free_recv_queue
	 if(precv_frame)
		 rtw_free_recvframe(precv_frame, pfree_recv_queue);

	 return _FAIL;

_func_exit_;

}
Exemplo n.º 27
0
static void c2_rx_interrupt(struct net_device *netdev)
{
	struct c2_port *c2_port = netdev_priv(netdev);
	struct c2_dev *c2dev = c2_port->c2dev;
	struct c2_ring *rx_ring = &c2_port->rx_ring;
	struct c2_element *elem;
	struct c2_rx_desc *rx_desc;
	struct c2_rxp_hdr *rxp_hdr;
	struct sk_buff *skb;
	dma_addr_t mapaddr;
	u32 maplen, buflen;
	unsigned long flags;

	spin_lock_irqsave(&c2dev->lock, flags);

	
	rx_ring->to_clean = rx_ring->start + c2dev->cur_rx;

	for (elem = rx_ring->to_clean; elem->next != rx_ring->to_clean;
	     elem = elem->next) {
		rx_desc = elem->ht_desc;
		mapaddr = elem->mapaddr;
		maplen = elem->maplen;
		skb = elem->skb;
		rxp_hdr = (struct c2_rxp_hdr *) skb->data;

		if (rxp_hdr->flags != RXP_HRXD_DONE)
			break;
		buflen = rxp_hdr->len;

		
		if (rxp_hdr->status != RXP_HRXD_OK ||
		    buflen > (rx_desc->len - sizeof(*rxp_hdr))) {
			c2_rx_error(c2_port, elem);
			continue;
		}

		if (c2_rx_alloc(c2_port, elem)) {
			c2_rx_error(c2_port, elem);
			continue;
		}

		
		pci_unmap_single(c2dev->pcidev, mapaddr, maplen,
				 PCI_DMA_FROMDEVICE);

		prefetch(skb->data);

		skb->data += sizeof(*rxp_hdr);
		skb_set_tail_pointer(skb, buflen);
		skb->len = buflen;
		skb->protocol = eth_type_trans(skb, netdev);

		netif_rx(skb);

		netdev->stats.rx_packets++;
		netdev->stats.rx_bytes += buflen;
	}

	
	rx_ring->to_clean = elem;
	c2dev->cur_rx = elem - rx_ring->start;
	C2_SET_CUR_RX(c2dev, c2dev->cur_rx);

	spin_unlock_irqrestore(&c2dev->lock, flags);
}
Exemplo n.º 28
0
static struct sk_buff *
kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
	struct sk_buff *skb2 = NULL;
	u16 content_len;
	unsigned char *header_start;
	unsigned char ether_type_1, ether_type_2;
	u8 remainder, padlen = 0;

	if (!skb_cloned(skb)) {
		int headroom = skb_headroom(skb);
		int tailroom = skb_tailroom(skb);

		if ((tailroom >= KALMIA_ALIGN_SIZE) && (headroom
			>= KALMIA_HEADER_LENGTH))
			goto done;

		if ((headroom + tailroom) > (KALMIA_HEADER_LENGTH
			+ KALMIA_ALIGN_SIZE)) {
			skb->data = memmove(skb->head + KALMIA_HEADER_LENGTH,
				skb->data, skb->len);
			skb_set_tail_pointer(skb, skb->len);
			goto done;
		}
	}

	skb2 = skb_copy_expand(skb, KALMIA_HEADER_LENGTH,
		KALMIA_ALIGN_SIZE, flags);
	if (!skb2)
		return NULL;

	dev_kfree_skb_any(skb);
	skb = skb2;

done:
	header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
	ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
	ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];

	netdev_dbg(dev->net, "Sending etherType: %02x%02x", ether_type_1,
		ether_type_2);

	/* According to empiric data for data packages */
	header_start[0] = 0x57;
	header_start[1] = 0x44;
	content_len = skb->len - KALMIA_HEADER_LENGTH;

	put_unaligned_le16(content_len, &header_start[2]);
	header_start[4] = ether_type_1;
	header_start[5] = ether_type_2;

	/* Align to 4 bytes by padding with zeros */
	remainder = skb->len % KALMIA_ALIGN_SIZE;
	if (remainder > 0) {
		padlen = KALMIA_ALIGN_SIZE - remainder;
		skb_put_zero(skb, padlen);
	}

	netdev_dbg(dev->net,
		"Sending package with length %i and padding %i. Header: %6phC.",
		content_len, padlen, header_start);

	return skb;
}
Exemplo n.º 29
0
int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
{
	struct recv_priv *precvpriv;
	_queue	*pfree_recv_queue;
	_pkt *skb;
	struct mlme_priv*pmlmepriv = &padapter->mlmepriv;
	struct rx_pkt_attrib *pattrib;
	
	if(NULL == precv_frame)
		goto _recv_indicatepkt_drop;

	DBG_COUNTER(padapter->rx_logs.os_indicate);
	pattrib = &precv_frame->u.hdr.attrib;
	precvpriv = &(padapter->recvpriv);
	pfree_recv_queue = &(precvpriv->free_recv_queue);

#ifdef CONFIG_DRVEXT_MODULE
	if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS)
	{
		goto _recv_indicatepkt_drop;
	}
#endif

#ifdef CONFIG_WAPI_SUPPORT
	if (rtw_wapi_check_for_drop(padapter,precv_frame))
	{
		WAPI_TRACE(WAPI_ERR, "%s(): Rx Reorder Drop case!!\n", __FUNCTION__);
		goto _recv_indicatepkt_drop;
	}
#endif

	skb = precv_frame->u.hdr.pkt;
	if(skb == NULL)
	{
		RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n"));
		goto _recv_indicatepkt_drop;
	}

	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n"));		
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p  precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data));
	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len));

	skb->data = precv_frame->u.hdr.rx_data;

	skb_set_tail_pointer(skb, precv_frame->u.hdr.len);

	skb->len = precv_frame->u.hdr.len;

	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len));

#ifdef CONFIG_AUTO_AP_MODE	
#if 1 //for testing
#if 1
	if (0x8899 == pattrib->eth_type)
	{
		rtw_os_ksocket_send(padapter, precv_frame);

		//goto _recv_indicatepkt_drop;
	}
#else
	if (0x8899 == pattrib->eth_type)
	{
		rtw_auto_ap_mode_rx(padapter, precv_frame);
		
		goto _recv_indicatepkt_end;
	}
#endif
#endif
#endif //CONFIG_AUTO_AP_MODE

	rtw_os_recv_indicate_pkt(padapter, skb, pattrib);

_recv_indicatepkt_end:

	precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe()

	rtw_free_recvframe(precv_frame, pfree_recv_queue);

	RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_os_recv_indicate_pkt!!!!\n"));


        return _SUCCESS;

_recv_indicatepkt_drop:

	 //enqueue back to free_recv_queue
	 if(precv_frame)
		 rtw_free_recvframe(precv_frame, pfree_recv_queue);

	 DBG_COUNTER(padapter->rx_logs.os_indicate_err);

	 return _FAIL;

}
Exemplo n.º 30
0
static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
					struct net_device *net)
{
	struct eth_dev		*dev = netdev_priv(net);
	int			length = skb->len;
	int			retval;
	struct usb_request	*req = NULL;
	unsigned long		flags;
	struct usb_ep		*in;
	u16			cdc_filter;

	spin_lock_irqsave(&dev->lock, flags);
	if (dev->port_usb) {
		in = dev->port_usb->in_ep;
		cdc_filter = dev->port_usb->cdc_filter;
	} else {
		in = NULL;
		cdc_filter = 0;
	}
	spin_unlock_irqrestore(&dev->lock, flags);

	if (!in) {
		dev_kfree_skb_any(skb);
		return NETDEV_TX_OK;
	}

	/* apply outgoing CDC or RNDIS filters */
	if (!is_promisc(cdc_filter)) {
		u8		*dest = skb->data;

		if (is_multicast_ether_addr(dest)) {
			u16	type;

			/* ignores USB_CDC_PACKET_TYPE_MULTICAST and host
			 * SET_ETHERNET_MULTICAST_FILTERS requests
			 */
			if (is_broadcast_ether_addr(dest))
				type = USB_CDC_PACKET_TYPE_BROADCAST;
			else
				type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
			if (!(cdc_filter & type)) {
				dev_kfree_skb_any(skb);
				return NETDEV_TX_OK;
			}
		}
		/* ignores USB_CDC_PACKET_TYPE_DIRECTED */
	}

	spin_lock_irqsave(&dev->req_lock, flags);
	/*
	 * this freelist can be empty if an interrupt triggered disconnect()
	 * and reconfigured the gadget (shutting down this queue) after the
	 * network stack decided to xmit but before we got the spinlock.
	 */
	if (list_empty(&dev->tx_reqs)) {
		spin_unlock_irqrestore(&dev->req_lock, flags);
		return NETDEV_TX_BUSY;
	}

	req = container_of(dev->tx_reqs.next, struct usb_request, list);
	list_del(&req->list);

	/* temporarily stop TX queue when the freelist empties */
	if (list_empty(&dev->tx_reqs))
		netif_stop_queue(net);
	spin_unlock_irqrestore(&dev->req_lock, flags);

	/* no buffer copies needed, unless the network stack did it
	 * or the hardware can't use skb buffers.
	 * or there's not enough space for extra headers we need
	 */
	if (dev->wrap) {
		unsigned long	flags;

		spin_lock_irqsave(&dev->lock, flags);
		if (dev->port_usb)
			skb = dev->wrap(dev->port_usb, skb);
		spin_unlock_irqrestore(&dev->lock, flags);
		if (!skb)
			goto drop;

		length = skb->len;
	}
	/*
	 * Align data to 32bit if the dma controller requires it
	 */
	if (gadget_dma32(dev->gadget)) {
		unsigned long align = (unsigned long)skb->data & 3;
		if (WARN_ON(skb_headroom(skb) < align)) {
			dev_kfree_skb_any(skb);
			goto drop;
		} else if (align) {
			u8 *data = skb->data;
			size_t len = skb_headlen(skb);
			skb->data -= align;
			memmove(skb->data, data, len);
			skb_set_tail_pointer(skb, len);
		}
	}
	req->buf = skb->data;
	req->context = skb;
	req->complete = tx_complete;

	/* NCM requires no zlp if transfer is dwNtbInMaxSize */
	if (dev->port_usb->is_fixed &&
	    length == dev->port_usb->fixed_in_len &&
	    (length % in->maxpacket) == 0)
		req->zero = 0;
	else
		req->zero = 1;

	/* use zlp framing on tx for strict CDC-Ether conformance,
	 * though any robust network rx path ignores extra padding.
	 * and some hardware doesn't like to write zlps.
	 */
	if (req->zero && !dev->zlp && (length % in->maxpacket) == 0)
		length++;

	req->length = length;

	/* throttle high/super speed IRQ rate back slightly */
	if (gadget_is_dualspeed(dev->gadget))
		req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH ||
				     dev->gadget->speed == USB_SPEED_SUPER)
			? ((atomic_read(&dev->tx_qlen) % qmult) != 0)
			: 0;

	retval = usb_ep_queue(in, req, GFP_ATOMIC);
	switch (retval) {
	default:
		DBG(dev, "tx queue err %d\n", retval);
		break;
	case 0:
		net->trans_start = jiffies;
		atomic_inc(&dev->tx_qlen);
	}

	if (retval) {
		dev_kfree_skb_any(skb);
drop:
		dev->net->stats.tx_dropped++;
		spin_lock_irqsave(&dev->req_lock, flags);
		if (list_empty(&dev->tx_reqs))
			netif_start_queue(net);
		list_add(&req->list, &dev->tx_reqs);
		spin_unlock_irqrestore(&dev->req_lock, flags);
	}
	return NETDEV_TX_OK;
}