123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- /**
- @file Transmit.c
- @defgroup tx_functions Transmission
- @section Queueing
- @dot
- digraph transmit1 {
- node[shape=box]
- edge[weight=5;color=red]
- bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
- GetPacketQueueIndex->IpVersion4[label="IPV4"]
- GetPacketQueueIndex->IpVersion6[label="IPV6"]
- }
- @enddot
- @section De-Queueing
- @dot
- digraph transmit2 {
- node[shape=box]
- edge[weight=5;color=red]
- interrupt_service_thread->transmit_packets
- tx_pkt_hdler->transmit_packets
- transmit_packets->CheckAndSendPacketFromIndex
- transmit_packets->UpdateTokenCount
- CheckAndSendPacketFromIndex->PruneQueue
- CheckAndSendPacketFromIndex->IsPacketAllowedForFlow
- CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]
- SendControlPacket->bcm_cmd53
- CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]
- SendPacketFromQueue->SetupNextSend->bcm_cmd53
- }
- @enddot
- */
- #include "headers.h"
- /**
- @ingroup ctrl_pkt_functions
- This function dispatches control packet to the h/w interface
- @return zero(success) or -ve value(failure)
- */
- INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket)
- {
- PLEADER PLeader = (PLEADER)pControlPacket;
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
- if(!pControlPacket || !Adapter)
- {
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter");
- return STATUS_FAILURE;
- }
- if((atomic_read( &Adapter->CurrNumFreeTxDesc ) <
- ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
- {
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
- return STATUS_FAILURE;
- }
- /* Update the netdevice statistics */
- /* Dump Packet */
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid);
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
- if(Adapter->device_removed)
- return 0;
- if (netif_msg_pktdata(Adapter))
- print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE,
- 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0);
- Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
- pControlPacket, (PLeader->PLength + LEADER_SIZE));
- atomic_dec(&Adapter->CurrNumFreeTxDesc);
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
- return STATUS_SUCCESS;
- }
- /**
- @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, struct sk_buff *Packet, USHORT Vcid)
- {
- int status=0;
- BOOLEAN bHeaderSupressionEnabled = FALSE;
- B_UINT16 uiClassifierRuleID;
- u16 QueueIndex = skb_get_queue_mapping(Packet);
- LEADER Leader={0};
- 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);
- bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
- & 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 ))
- 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);
- }
- status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
- Packet->data, (Leader.PLength + LEADER_SIZE));
- if(status)
- {
- ++Adapter->dev->stats.tx_errors;
- if (netif_msg_tx_err(Adapter))
- pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
- status);
- }
- else
- {
- struct net_device_stats *netstats = &Adapter->dev->stats;
- Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
- netstats->tx_bytes += Leader.PLength;
- ++netstats->tx_packets;
- 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);
- Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
- }
- atomic_dec(&Adapter->CurrNumFreeTxDesc);
- errExit:
- dev_kfree_skb(Packet);
- 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
- */
- int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
- )
- {
- int status = 0;
- 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,
- 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)
- {
- Adapter->downloadDDR +=1;
- status = download_ddr_settings(Adapter);
- if(status)
- pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);
- continue;
- }
- //Check end point for halt/stall.
- if(Adapter->bEndPointHalted == TRUE)
- {
- Bcm_clear_halt_of_endpoints(Adapter);
- Adapter->bEndPointHalted = FALSE;
- StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
- }
- if(Adapter->LinkUpStatus && !Adapter->IdleMode)
- {
- if(atomic_read(&Adapter->TotalPacketCount))
- {
- update_per_sf_desc_cnts(Adapter);
- }
- }
- if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
- Adapter->LinkStatus == SYNC_UP_REQUEST &&
- !Adapter->bSyncUpRequestSent)
- {
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");
- LinkMessage(Adapter);
- }
- if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount))
- {
- BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");
- Adapter->usIdleModePattern = ABORT_IDLE_MODE;
- Adapter->bWakeUpDevice = TRUE;
- wake_up(&Adapter->process_rx_cntrlpkt);
- }
- 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;
- }
|