예제 #1
0
INT SendPacketToFW(struct sk_buff *skb)
{
	if(psAdaptertest)
	{
		skb->dev = psAdaptertest->dev;
		return bcm_transmit(skb, psAdaptertest->dev); 
	}
	else
	{
		printk("Dropping as adapter is not initialized yet\n");
		bcm_kfree_skb(skb);
		return STATUS_FAILURE;
	}
}
예제 #2
0
파일: Arp.c 프로젝트: Adjustxx/Savaged-Zen
VOID
reply_to_arp_request(struct sk_buff *skb)
{
	PMINI_ADAPTER		Adapter;
	struct ArpHeader 	*pArpHdr = NULL;
	struct ethhdr		*pethhdr = NULL;
	UCHAR 				uiIPHdr[4];
	/* Check for valid skb */
	if(skb == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n");
		return;
	}


	Adapter = GET_BCM_ADAPTER(skb->dev);
	/* Print the ARP Request Packet */
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :");
	BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);

	/*
	 * Extract the Ethernet Header and Arp Payload including Header
     */
	pethhdr = (struct ethhdr *)skb->data;
	pArpHdr  = (struct ArpHeader *)(skb->data+ETH_HLEN);

	if(Adapter->bETHCSEnabled)
	{
		if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
		{
			bcm_kfree_skb(skb);
			return;
		}
	}

	// Set the Ethernet Header First.
	memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN);
	if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
	{
		pethhdr->h_source[5]++;
	}

	/* Set the reply to ARP Reply */
	pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY);

	/* Set the HW Address properly */
	memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN);
	memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN);

	// Swapping the IP Adddress
	memcpy(uiIPHdr,pArpHdr->ar_sip,4);
	memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4);
	memcpy(pArpHdr->ar_tip,uiIPHdr,4);

	/* Print the ARP Reply Packet */

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: ");

	/* Send the Packet to upper layer */
	BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);

	skb->protocol = eth_type_trans(skb,skb->dev);
	skb->pkt_type = PACKET_HOST;

//	skb->mac.raw=skb->data+LEADER_SIZE;
	skb_set_mac_header (skb, LEADER_SIZE);
	netif_rx(skb);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n");
	return;
}
예제 #3
0
INT bcm_transmit(struct sk_buff *skb, 		/**< skb */
					struct net_device *dev 	/**< net device pointer */
					)
{
	PMINI_ADAPTER      	Adapter = NULL;
	USHORT				qindex=0;
	struct timeval tv;
	UINT		pkt_type = 0;
	UINT 		calltransmit = 0;   
	INT			status = STATUS_SUCCESS;
	
	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__);

	memset(&tv, 0, sizeof(tv));
	/* Check for valid parameters */
	if(skb == NULL || dev==NULL) 
	{
	    BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n");
		return -EINVAL;
	}

	Adapter = GET_BCM_ADAPTER(dev);
	if(!Adapter)
	{
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n");
  		status = -EINVAL;
		goto exit_path;
	}
	if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus)
	{
		if(!netif_queue_stopped(dev)) {
				netif_carrier_off(dev);
				netif_stop_queue(dev);
		}
		status = STATUS_FAILURE;		
		goto exit_path;
	}
	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len);

	/*Add Ethernet CS check here*/
	if(Adapter->TransferMode == IP_PACKET_ONLY_MODE )
	{
        pkt_type = ntohs(*(PUSHORT)(skb->data + 12));
		/* Get the queue index where the packet is to be queued */	
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index.....");
        
		qindex = GetPacketQueueIndex(Adapter,skb);
			
		if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex)
		{
			if(pkt_type == ETH_ARP_FRAME)
			{
				/*
				Reply directly to ARP request packet 
				ARP Spoofing only if NO ETH CS rule matches for it 
				*/
				BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x",

                (*(PUCHAR)(skb->data + 21)));

                reply_to_arp_request(skb);

                BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n");

			}
			else
			{				
                BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, 
    			"Invalid queue index, dropping pkt\n");
				status = STATUS_FAILURE;
			}
			goto exit_path;
        }

		if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
		{
			atomic_inc(&Adapter->TxDroppedPacketCount);
			status = STATUS_FAILURE;
			goto exit_path;
		}
			
		/* Now Enqueue the packet */
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex);
		spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
		Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
		Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;

		*((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies;
		ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
  	                  Adapter->PackInfo[qindex].LastTxQueue, skb);
		atomic_inc(&Adapter->TotalPacketCount);	
		spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
		do_gettimeofday(&tv);
        
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n",
		(skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec);

#ifdef BCM_SHM_INTERFACE			
		spin_lock(&Adapter->txtransmitlock);
		if(Adapter->txtransmit_running == 0)
		{
			Adapter->txtransmit_running = 1;
			calltransmit = 1;
		}
		else
			calltransmit = 0;

		spin_unlock(&Adapter->txtransmitlock);
#endif
		if(calltransmit == 1)
			transmit_packets(Adapter);
		else
		{		
			if(!atomic_read(&Adapter->TxPktAvail))
			{
				atomic_set(&Adapter->TxPktAvail, 1);
#ifdef BCM_SHM_INTERFACE
				virtual_mail_box_interrupt();
#endif
				wake_up(&Adapter->tx_packet_wait_queue);
			}
		}
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<====");
	}
	else
		status = STATUS_FAILURE;

exit_path:

	if(status != STATUS_SUCCESS)
		bcm_kfree_skb(skb);

	/* It is expected to return the correct status if running in cut-through mode */

	if(Adapter->bNetworkInterfaceRegistered == FALSE)
  		return status;

	/* It is expected to return as Success for Network Stack
	- This will ensure that the packet is owned by the driver which shall free the same*/

	else
		return STATUS_SUCCESS;

}
예제 #4
0
/**
@ingroup tx_functions
This function despatches the IP packets with the given vcid
to the target via the host h/w interface.
@return  zero(success) or -ve value(failure)
*/
INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
					struct sk_buff *Packet, /**<data buffer*/
					USHORT Vcid)			/**<VCID for this packet*/
{
	int		status=0;
#ifdef GDMA_INTERFACE  
	int dontfree = 0;
#endif
	BOOLEAN bHeaderSupressionEnabled = FALSE;
	B_UINT16            uiClassifierRuleID;
	int QueueIndex = NO_OF_QUEUES + 1;
	B_UINT32 time_spent_on_host = 0 ;
	if(!Adapter || !Packet)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet");
		return -EINVAL;
	}
	if(Packet->len > MAX_DEVICE_DESC_SIZE)
	{
		status = STATUS_FAILURE;
		goto errExit;
	}
	
	/* Get the Classifier Rule ID */
	uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
	QueueIndex = SearchVcid( Adapter,Vcid);
	if(QueueIndex < NO_OF_QUEUES)
	{
		bHeaderSupressionEnabled = 
			Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
		bHeaderSupressionEnabled = 
			bHeaderSupressionEnabled & Adapter->bPHSEnabled;
	}
	if(Adapter->device_removed)
		{
		status = STATUS_FAILURE;
		goto errExit;
		}
	
	status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled, 
							(UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);

	if(status != STATUS_SUCCESS)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
		goto errExit;
	}

	Leader.Vcid	= Vcid;
	
    if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
	{
        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n");
		Leader.Status = LEADER_STATUS_TCP_ACK;
	}
	else
	{
		Leader.Status = LEADER_STATUS;
	}
	
	if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
	{
		Leader.PLength = Packet->len;
		if(skb_headroom(Packet) < LEADER_SIZE)
        {
			if((status = skb_cow(Packet,LEADER_SIZE)))
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n");
				goto errExit;
			}
		}
		skb_push(Packet, LEADER_SIZE);
		memcpy(Packet->data, &Leader, LEADER_SIZE);
	}
	
	else	
	{
		Leader.PLength = Packet->len - ETH_HLEN;
		memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid);

#ifndef BCM_SHM_INTERFACE
	status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, 
			Packet->data, (Leader.PLength + LEADER_SIZE));
#else
	status = tx_pkts_to_firmware(Packet,Packet->len,0);
#endif
	if(status)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n");
	}
	else
	{
		Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
		atomic_add(Leader.PLength, &Adapter->GoodTxByteCount);
		atomic_inc(&Adapter->TxTotalPacketCount);
#ifdef GDMA_INTERFACE  
    dontfree = 1;
#endif
	}


	
	time_spent_on_host = jiffies - *((UINT32*) (Packet->cb) + SKB_CB_LATENCY_OFFSET);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_TIME_SPENT_IN_HOST, DBG_LVL_ALL, "TIME SPENT ON HOST :%#X \n",time_spent_on_host);
	atomic_dec(&Adapter->CurrNumFreeTxDesc);

errExit:

	if(STATUS_SUCCESS == status)
	{
		Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
		Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
		Adapter->PackInfo[QueueIndex].uiSentPackets++;
		Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;

		atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
#ifdef BCM_SHM_INTERFACE
		if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0)
		{
			atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0);
		}
#endif
		Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
	}
	

#ifdef GDMA_INTERFACE  
  if(!dontfree){
  	bcm_kfree_skb(Packet);
  }
#else
  	bcm_kfree_skb(Packet);
#endif  
	return status;
}