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
)
69 if (netif_msg_pktdata(Adapter
))
70 print_hex_dump(KERN_DEBUG
, PFX
"tx control: ", DUMP_PREFIX_NONE
,
71 16, 1, pControlPacket
, PLeader
->PLength
+ LEADER_SIZE
, 0);
73 Adapter
->interface_transmit(Adapter
->pvInterfaceAdapter
,
74 pControlPacket
, (PLeader
->PLength
+ LEADER_SIZE
));
76 atomic_dec(&Adapter
->CurrNumFreeTxDesc
);
77 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_CONTROL
, DBG_LVL_ALL
, "<=========");
78 return STATUS_SUCCESS
;
83 This function despatches the IP packets with the given vcid
84 to the target via the host h/w interface.
85 @return zero(success) or -ve value(failure)
87 INT
SetupNextSend(PMINI_ADAPTER Adapter
, struct sk_buff
*Packet
, USHORT Vcid
)
90 BOOLEAN bHeaderSupressionEnabled
= FALSE
;
91 B_UINT16 uiClassifierRuleID
;
92 u16 QueueIndex
= skb_get_queue_mapping(Packet
);
95 if(Packet
->len
> MAX_DEVICE_DESC_SIZE
)
97 status
= STATUS_FAILURE
;
101 /* Get the Classifier Rule ID */
102 uiClassifierRuleID
= *((UINT32
*) (Packet
->cb
)+SKB_CB_CLASSIFICATION_OFFSET
);
104 bHeaderSupressionEnabled
= Adapter
->PackInfo
[QueueIndex
].bHeaderSuppressionEnabled
105 & Adapter
->bPHSEnabled
;
107 if(Adapter
->device_removed
)
109 status
= STATUS_FAILURE
;
113 status
= PHSTransmit(Adapter
, &Packet
, Vcid
, uiClassifierRuleID
, bHeaderSupressionEnabled
,
114 (UINT
*)&Packet
->len
, Adapter
->PackInfo
[QueueIndex
].bEthCSSupport
);
116 if(status
!= STATUS_SUCCESS
)
118 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "PHS Transmit failed..\n");
124 if(TCP_ACK
== *((UINT32
*) (Packet
->cb
) + SKB_CB_TCPACK_OFFSET
))
125 Leader
.Status
= LEADER_STATUS_TCP_ACK
;
127 Leader
.Status
= LEADER_STATUS
;
129 if(Adapter
->PackInfo
[QueueIndex
].bEthCSSupport
)
131 Leader
.PLength
= Packet
->len
;
132 if(skb_headroom(Packet
) < LEADER_SIZE
)
134 if((status
= skb_cow(Packet
,LEADER_SIZE
)))
136 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
,"bcm_transmit : Failed To Increase headRoom\n");
140 skb_push(Packet
, LEADER_SIZE
);
141 memcpy(Packet
->data
, &Leader
, LEADER_SIZE
);
145 Leader
.PLength
= Packet
->len
- ETH_HLEN
;
146 memcpy((LEADER
*)skb_pull(Packet
, (ETH_HLEN
- LEADER_SIZE
)), &Leader
, LEADER_SIZE
);
149 status
= Adapter
->interface_transmit(Adapter
->pvInterfaceAdapter
,
150 Packet
->data
, (Leader
.PLength
+ LEADER_SIZE
));
153 ++Adapter
->dev
->stats
.tx_errors
;
154 if (netif_msg_tx_err(Adapter
))
155 pr_info(PFX
"%s: transmit error %d\n", Adapter
->dev
->name
,
160 struct net_device_stats
*netstats
= &Adapter
->dev
->stats
;
161 Adapter
->PackInfo
[QueueIndex
].uiTotalTxBytes
+= Leader
.PLength
;
163 netstats
->tx_bytes
+= Leader
.PLength
;
164 ++netstats
->tx_packets
;
166 Adapter
->PackInfo
[QueueIndex
].uiCurrentTokenCount
-= Leader
.PLength
<< 3;
167 Adapter
->PackInfo
[QueueIndex
].uiSentBytes
+= (Packet
->len
);
168 Adapter
->PackInfo
[QueueIndex
].uiSentPackets
++;
169 Adapter
->PackInfo
[QueueIndex
].NumOfPacketsSent
++;
171 atomic_dec(&Adapter
->PackInfo
[QueueIndex
].uiPerSFTxResourceCount
);
172 Adapter
->PackInfo
[QueueIndex
].uiThisPeriodSentBytes
+= Leader
.PLength
;
175 atomic_dec(&Adapter
->CurrNumFreeTxDesc
);
179 dev_kfree_skb(Packet
);
183 static int tx_pending(PMINI_ADAPTER Adapter
)
185 return (atomic_read(&Adapter
->TxPktAvail
)
186 && MINIMUM_PENDING_DESCRIPTORS
< atomic_read(&Adapter
->CurrNumFreeTxDesc
))
187 || Adapter
->device_removed
|| (1 == Adapter
->downloadDDR
);
191 @ingroup tx_functions
194 int tx_pkt_handler(PMINI_ADAPTER Adapter
/**< pointer to adapter object*/
199 while(! kthread_should_stop()) {
200 /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
201 if(Adapter
->LinkUpStatus
)
202 wait_event_timeout(Adapter
->tx_packet_wait_queue
,
203 tx_pending(Adapter
), msecs_to_jiffies(10));
205 wait_event_interruptible(Adapter
->tx_packet_wait_queue
,
206 tx_pending(Adapter
));
208 if (Adapter
->device_removed
)
211 if(Adapter
->downloadDDR
== 1)
213 Adapter
->downloadDDR
+=1;
214 status
= download_ddr_settings(Adapter
);
216 pr_err(PFX
"DDR DOWNLOAD FAILED! %d\n", status
);
220 //Check end point for halt/stall.
221 if(Adapter
->bEndPointHalted
== TRUE
)
223 Bcm_clear_halt_of_endpoints(Adapter
);
224 Adapter
->bEndPointHalted
= FALSE
;
225 StartInterruptUrb((PS_INTERFACE_ADAPTER
)(Adapter
->pvInterfaceAdapter
));
228 if(Adapter
->LinkUpStatus
&& !Adapter
->IdleMode
)
230 if(atomic_read(&Adapter
->TotalPacketCount
))
232 update_per_sf_desc_cnts(Adapter
);
236 if( atomic_read(&Adapter
->CurrNumFreeTxDesc
) &&
237 Adapter
->LinkStatus
== SYNC_UP_REQUEST
&&
238 !Adapter
->bSyncUpRequestSent
)
240 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "Calling LinkMessage");
241 LinkMessage(Adapter
);
244 if((Adapter
->IdleMode
|| Adapter
->bShutStatus
) && atomic_read(&Adapter
->TotalPacketCount
))
246 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "Device in Low Power mode...waking up");
247 Adapter
->usIdleModePattern
= ABORT_IDLE_MODE
;
248 Adapter
->bWakeUpDevice
= TRUE
;
249 wake_up(&Adapter
->process_rx_cntrlpkt
);
252 transmit_packets(Adapter
);
254 atomic_set(&Adapter
->TxPktAvail
, 0);
257 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "Exiting the tx thread..\n");
258 Adapter
->transmit_packet_thread
= NULL
;