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 return STATUS_FAILURE;
61 /* Update the netdevice statistics */
63 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
64 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid);
65 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
66 if(Adapter->device_removed)
68 Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
69 pControlPacket, (PLeader->PLength + LEADER_SIZE));
71 atomic_dec(&Adapter->CurrNumFreeTxDesc);
72 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
73 return STATUS_SUCCESS;
78 This function despatches the IP packets with the given vcid
79 to the target via the host h/w interface.
80 @return zero(success) or -ve value(failure)
82 INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid)
85 BOOLEAN bHeaderSupressionEnabled = FALSE;
86 B_UINT16 uiClassifierRuleID;
87 u16 QueueIndex = skb_get_queue_mapping(Packet);
90 if(Packet->len > MAX_DEVICE_DESC_SIZE)
92 status = STATUS_FAILURE;
96 /* Get the Classifier Rule ID */
97 uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
99 bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
100 & Adapter->bPHSEnabled;
102 if(Adapter->device_removed)
104 status = STATUS_FAILURE;
108 status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
109 (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);
111 if(status != STATUS_SUCCESS)
113 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
119 if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
120 Leader.Status = LEADER_STATUS_TCP_ACK;
122 Leader.Status = LEADER_STATUS;
124 if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
126 Leader.PLength = Packet->len;
127 if(skb_headroom(Packet) < LEADER_SIZE)
129 if((status = skb_cow(Packet,LEADER_SIZE)))
131 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n");
135 skb_push(Packet, LEADER_SIZE);
136 memcpy(Packet->data, &Leader, LEADER_SIZE);
140 Leader.PLength = Packet->len - ETH_HLEN;
141 memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
144 status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
145 Packet->data, (Leader.PLength + LEADER_SIZE));
148 ++Adapter->dev->stats.tx_errors;
149 if (netif_msg_tx_err(Adapter))
150 pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
155 struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, QueueIndex);
156 Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
158 txq->tx_bytes += Leader.PLength;
161 Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
162 Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
163 Adapter->PackInfo[QueueIndex].uiSentPackets++;
164 Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
166 atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
167 Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
170 atomic_dec(&Adapter->CurrNumFreeTxDesc);
174 dev_kfree_skb(Packet);
178 static int tx_pending(PMINI_ADAPTER Adapter)
180 return (atomic_read(&Adapter->TxPktAvail)
181 && MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc))
182 || Adapter->device_removed || (1 == Adapter->downloadDDR);
186 @ingroup tx_functions
189 int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
194 while(! kthread_should_stop()) {
195 /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
196 if(Adapter->LinkUpStatus)
197 wait_event_timeout(Adapter->tx_packet_wait_queue,
198 tx_pending(Adapter), msecs_to_jiffies(10));
200 wait_event_interruptible(Adapter->tx_packet_wait_queue,
201 tx_pending(Adapter));
203 if (Adapter->device_removed)
206 if(Adapter->downloadDDR == 1)
208 Adapter->downloadDDR +=1;
209 status = download_ddr_settings(Adapter);
211 pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);
215 //Check end point for halt/stall.
216 if(Adapter->bEndPointHalted == TRUE)
218 Bcm_clear_halt_of_endpoints(Adapter);
219 Adapter->bEndPointHalted = FALSE;
220 StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
223 if(Adapter->LinkUpStatus && !Adapter->IdleMode)
225 if(atomic_read(&Adapter->TotalPacketCount))
227 update_per_sf_desc_cnts(Adapter);
231 if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
232 Adapter->LinkStatus == SYNC_UP_REQUEST &&
233 !Adapter->bSyncUpRequestSent)
235 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");
236 LinkMessage(Adapter);
239 if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount))
241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");
242 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
243 Adapter->bWakeUpDevice = TRUE;
244 wake_up(&Adapter->process_rx_cntrlpkt);
247 transmit_packets(Adapter);
249 atomic_set(&Adapter->TxPktAvail, 0);
252 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
253 Adapter->transmit_packet_thread = NULL;