3 @defgroup tx_functions Transmission
8 edge[weight=5;color=red]
10 bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
11 GetPacketQueueIndex->IpVersion4[label="IPV4"]
12 GetPacketQueueIndex->IpVersion6[label="IPV6"]
21 edge[weight=5;color=red]
22 interrupt_service_thread->transmit_packets
23 tx_pkt_hdler->transmit_packets
24 transmit_packets->CheckAndSendPacketFromIndex
25 transmit_packets->UpdateTokenCount
26 CheckAndSendPacketFromIndex->PruneQueue
27 CheckAndSendPacketFromIndex->IsPacketAllowedForFlow
28 CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]
29 SendControlPacket->bcm_cmd53
30 CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]
31 SendPacketFromQueue->SetupNextSend->bcm_cmd53
40 @ingroup ctrl_pkt_functions
41 This function dispatches control packet to the h/w interface
42 @return zero(success) or -ve value(failure)
44 INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket)
46 PLEADER PLeader = (PLEADER)pControlPacket;
48 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
49 if(!pControlPacket || !Adapter)
51 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter");
52 return STATUS_FAILURE;
54 if((atomic_read( &Adapter->CurrNumFreeTxDesc ) <
55 ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
57 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
58 if(Adapter->bcm_jiffies == 0)
60 Adapter->bcm_jiffies = jiffies;
61 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu",
62 Adapter->bcm_jiffies);
64 return STATUS_FAILURE;
67 /* Update the netdevice statistics */
69 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
70 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid);
71 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
72 if(Adapter->device_removed)
74 Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
75 pControlPacket, (PLeader->PLength + LEADER_SIZE));
77 atomic_dec(&Adapter->CurrNumFreeTxDesc);
78 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
79 return STATUS_SUCCESS;
84 This function despatches the IP packets with the given vcid
85 to the target via the host h/w interface.
86 @return zero(success) or -ve value(failure)
88 INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid)
91 BOOLEAN bHeaderSupressionEnabled = FALSE;
92 B_UINT16 uiClassifierRuleID;
93 int QueueIndex = NO_OF_QUEUES + 1;
96 if(Packet->len > MAX_DEVICE_DESC_SIZE)
98 status = STATUS_FAILURE;
102 /* Get the Classifier Rule ID */
103 uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
104 QueueIndex = SearchVcid( Adapter,Vcid);
105 if(QueueIndex < NO_OF_QUEUES)
107 bHeaderSupressionEnabled =
108 Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
109 bHeaderSupressionEnabled =
110 bHeaderSupressionEnabled & Adapter->bPHSEnabled;
112 if(Adapter->device_removed)
114 status = STATUS_FAILURE;
118 status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
119 (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);
121 if(status != STATUS_SUCCESS)
123 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
129 if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
130 Leader.Status = LEADER_STATUS_TCP_ACK;
132 Leader.Status = LEADER_STATUS;
134 if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
136 Leader.PLength = Packet->len;
137 if(skb_headroom(Packet) < LEADER_SIZE)
139 if((status = skb_cow(Packet,LEADER_SIZE)))
141 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n");
145 skb_push(Packet, LEADER_SIZE);
146 memcpy(Packet->data, &Leader, LEADER_SIZE);
150 Leader.PLength = Packet->len - ETH_HLEN;
151 memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
154 status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
155 Packet->data, (Leader.PLength + LEADER_SIZE));
158 ++Adapter->dev->stats.tx_errors;
159 if (netif_msg_tx_err(Adapter))
160 pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
165 Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
166 Adapter->dev->stats.tx_bytes += Leader.PLength;
167 ++Adapter->dev->stats.tx_packets;
168 Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
169 Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
170 Adapter->PackInfo[QueueIndex].uiSentPackets++;
171 Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
173 atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
174 Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
177 atomic_dec(&Adapter->CurrNumFreeTxDesc);
181 dev_kfree_skb(Packet);
185 static int tx_pending(PMINI_ADAPTER Adapter)
187 return (atomic_read(&Adapter->TxPktAvail)
188 && MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc))
189 || Adapter->device_removed || (1 == Adapter->downloadDDR);
193 @ingroup tx_functions
196 int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
201 while(! kthread_should_stop()) {
202 /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
203 if(Adapter->LinkUpStatus)
204 wait_event_timeout(Adapter->tx_packet_wait_queue,
205 tx_pending(Adapter), msecs_to_jiffies(10));
207 wait_event_interruptible(Adapter->tx_packet_wait_queue,
208 tx_pending(Adapter));
210 if (Adapter->device_removed)
213 if(Adapter->downloadDDR == 1)
215 Adapter->downloadDDR +=1;
216 status = download_ddr_settings(Adapter);
218 pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);
222 //Check end point for halt/stall.
223 if(Adapter->bEndPointHalted == TRUE)
225 Bcm_clear_halt_of_endpoints(Adapter);
226 Adapter->bEndPointHalted = FALSE;
227 StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
230 if(Adapter->LinkUpStatus && !Adapter->IdleMode)
232 if(atomic_read(&Adapter->TotalPacketCount))
234 update_per_sf_desc_cnts(Adapter);
238 if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
239 Adapter->LinkStatus == SYNC_UP_REQUEST &&
240 !Adapter->bSyncUpRequestSent)
242 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");
243 LinkMessage(Adapter);
246 if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount))
248 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");
249 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
250 Adapter->bWakeUpDevice = TRUE;
251 wake_up(&Adapter->process_rx_cntrlpkt);
254 transmit_packets(Adapter);
256 atomic_set(&Adapter->TxPktAvail, 0);
259 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
260 Adapter->transmit_packet_thread = NULL;