Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 227903
b: refs/heads/master
c: 71e253b
h: refs/heads/master
i:
  227901: f689d74
  227899: a4dd462
  227895: 647170f
  227887: a163edf
  227871: b8ad06f
  227839: 4ee1a4f
v: v3
  • Loading branch information
Stephen Hemminger committed Nov 1, 2010
1 parent 2a03fa1 commit 61fb165
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 135 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: de85f9858969f50467bf39ee992ef871ae2492d3
refs/heads/master: 71e253b1699fb777be68cb1028a90e21ea6ff8d8
195 changes: 61 additions & 134 deletions trunk/drivers/staging/bcm/Transmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53
* Function - bcm_transmit()
*
* Description - This is the main transmit function for our virtual
* interface(veth0). It handles the ARP packets. It
* interface(eth0). It handles the ARP packets. It
* clones this packet and then Queue it to a suitable
* Queue. Then calls the transmit_packet().
*
Expand All @@ -50,118 +50,59 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53
*
*********************************************************************/

INT bcm_transmit(struct sk_buff *skb, /**< skb */
struct net_device *dev /**< net device pointer */
)
netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
{
PMINI_ADAPTER Adapter = NULL;
USHORT qindex=0;
struct timeval tv;
UINT pkt_type = 0;
UINT calltransmit = 0;

BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__);
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
SHORT qindex;

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");
return -EINVAL;
}
if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus)
{
if(!netif_queue_stopped(dev)) {
netif_carrier_off(dev);
netif_stop_queue(dev);
}
return STATUS_FAILURE;
}
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len);
if (Adapter->device_removed || !Adapter->LinkUpStatus)
goto drop;

/*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.....");
if (Adapter->TransferMode != IP_PACKET_ONLY_MODE )
goto drop;

qindex = GetPacketQueueIndex(Adapter,skb);
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",
if (INVALID_QUEUE_INDEX==qindex) {
if (ntohs(eth_hdr(skb)->h_proto) != ETH_ARP_FRAME)
goto drop;

(*(PUCHAR)(skb->data + 21)));
/*
Reply directly to ARP request packet
ARP Spoofing only if NO ETH CS rule matches for it
*/
reply_to_arp_request(skb);
return NETDEV_TX_OK;
}

reply_to_arp_request(skb);
if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
return NETDEV_TX_BUSY;

BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n");
/* 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++;

}
else
{
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,
"Invalid queue index, dropping pkt\n");
*((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);

dev_kfree_skb(skb);
}
return STATUS_SUCCESS;
}
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");

if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
{
atomic_inc(&Adapter->TxDroppedPacketCount);
dev_kfree_skb(skb);
return STATUS_SUCCESS;
}

/* 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);

if(calltransmit == 1)
transmit_packets(Adapter);
else
{
if(!atomic_read(&Adapter->TxPktAvail))
{
atomic_set(&Adapter->TxPktAvail, 1);
wake_up(&Adapter->tx_packet_wait_queue);
}
}
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<====");
/* FIXME - this is racy and incorrect, replace with work queue */
if (!atomic_read(&Adapter->TxPktAvail)) {
atomic_set(&Adapter->TxPktAvail, 1);
wake_up(&Adapter->tx_packet_wait_queue);
}
else
dev_kfree_skb(skb);
return NETDEV_TX_OK;

return STATUS_SUCCESS;
drop:
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}


Expand Down Expand Up @@ -337,6 +278,13 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
return status;
}

static int tx_pending(PMINI_ADAPTER Adapter)
{
return (atomic_read(&Adapter->TxPktAvail)
&& MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc))
|| Adapter->device_removed || (1 == Adapter->downloadDDR);
}

/**
@ingroup tx_functions
Transmit thread
Expand All @@ -346,40 +294,17 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
{
int status = 0;

UINT calltransmit = 1;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = %p",Adapter);


while(1)
{
if(Adapter->LinkUpStatus){
while(! kthread_should_stop()) {
/* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
if(Adapter->LinkUpStatus)
wait_event_timeout(Adapter->tx_packet_wait_queue,
((atomic_read(&Adapter->TxPktAvail) &&
(MINIMUM_PENDING_DESCRIPTORS <
atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
(Adapter->device_removed == FALSE))) ||
(1 == Adapter->downloadDDR) || kthread_should_stop()
|| (TRUE == Adapter->bEndPointHalted)
, msecs_to_jiffies(10));
}
else{
wait_event(Adapter->tx_packet_wait_queue,
((atomic_read(&Adapter->TxPktAvail) &&
(MINIMUM_PENDING_DESCRIPTORS <
atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
(Adapter->device_removed == FALSE))) ||
(1 == Adapter->downloadDDR) || kthread_should_stop()
|| (TRUE == Adapter->bEndPointHalted)
);
}

if(kthread_should_stop() || Adapter->device_removed)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
Adapter->transmit_packet_thread = NULL;
return 0;
}
tx_pending(Adapter), msecs_to_jiffies(10));
else
wait_event_interruptible(Adapter->tx_packet_wait_queue,
tx_pending(Adapter));

if (Adapter->device_removed)
break;

if(Adapter->downloadDDR == 1)
{
Expand Down Expand Up @@ -424,11 +349,13 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
}


if(calltransmit)
transmit_packets(Adapter);
transmit_packets(Adapter);

atomic_set(&Adapter->TxPktAvail, 0);
}

BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
Adapter->transmit_packet_thread = NULL;
return 0;
}

Expand Down

0 comments on commit 61fb165

Please sign in to comment.