Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/**
2@file Transmit.c
3@defgroup tx_functions Transmission
4@section Queueing
5@dot
6digraph transmit1 {
7node[shape=box]
8edge[weight=5;color=red]
9bcm_transmit->reply_to_arp_request[label="ARP"]
10bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
11GetPacketQueueIndex->IpVersion4[label="IPV4"]
12GetPacketQueueIndex->IpVersion6[label="IPV6"]
13}
14
15@enddot
16
17@section De-Queueing
18@dot
19digraph transmit2 {
20node[shape=box]
21edge[weight=5;color=red]
22interrupt_service_thread->transmit_packets
23tx_pkt_hdler->transmit_packets
24transmit_packets->CheckAndSendPacketFromIndex
25transmit_packets->UpdateTokenCount
26CheckAndSendPacketFromIndex->PruneQueue
27CheckAndSendPacketFromIndex->IsPacketAllowedForFlow
28CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]
29SendControlPacket->bcm_cmd53
30CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]
31SendPacketFromQueue->SetupNextSend->bcm_cmd53
32}
33@enddot
34*/
35
36#include "headers.h"
37
38/*******************************************************************
39* Function - bcm_transmit()
40*
41* Description - This is the main transmit function for our virtual
42* interface(veth0). It handles the ARP packets. It
43* clones this packet and then Queue it to a suitable
44* Queue. Then calls the transmit_packet().
45*
46* Parameter - skb - Pointer to the socket buffer structure
47* dev - Pointer to the virtual net device structure
48*
49* Returns - zero (success) or -ve value (failure)
50*
51*********************************************************************/
52
53INT bcm_transmit(struct sk_buff *skb, /**< skb */
54 struct net_device *dev /**< net device pointer */
55 )
56{
57 PMINI_ADAPTER Adapter = NULL;
58 USHORT qindex=0;
59 struct timeval tv;
60 UINT pkt_type = 0;
61 UINT calltransmit = 0;
62
63 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__);
64
65 memset(&tv, 0, sizeof(tv));
66 /* Check for valid parameters */
67 if(skb == NULL || dev==NULL)
68 {
69 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n");
70 return -EINVAL;
71 }
72
73 Adapter = GET_BCM_ADAPTER(dev);
74 if(!Adapter)
75 {
76 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n");
77 return -EINVAL;
78 }
79 if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus)
80 {
81 if(!netif_queue_stopped(dev)) {
82 netif_carrier_off(dev);
83 netif_stop_queue(dev);
84 }
85 return STATUS_FAILURE;
86 }
87 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len);
88
89 /*Add Ethernet CS check here*/
90 if(Adapter->TransferMode == IP_PACKET_ONLY_MODE )
91 {
92 pkt_type = ntohs(*(PUSHORT)(skb->data + 12));
93 /* Get the queue index where the packet is to be queued */
94 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index.....");
95
96 qindex = GetPacketQueueIndex(Adapter,skb);
97
98 if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex)
99 {
100 if(pkt_type == ETH_ARP_FRAME)
101 {
102 /*
103 Reply directly to ARP request packet
104 ARP Spoofing only if NO ETH CS rule matches for it
105 */
106 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x",
107
108 (*(PUCHAR)(skb->data + 21)));
109
110 reply_to_arp_request(skb);
111
112 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n");
113
114 }
115 else
116 {
117 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,
118 "Invalid queue index, dropping pkt\n");
119
120 bcm_kfree_skb(skb);
121 }
122 return STATUS_SUCCESS;
123 }
124
125 if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
126 {
127 atomic_inc(&Adapter->TxDroppedPacketCount);
128 bcm_kfree_skb(skb);
129 return STATUS_SUCCESS;
130 }
131
132 /* Now Enqueue the packet */
133 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex);
134 spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
135 Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
136 Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
137
138 *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies;
139 ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
140 Adapter->PackInfo[qindex].LastTxQueue, skb);
141 atomic_inc(&Adapter->TotalPacketCount);
142 spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
143 do_gettimeofday(&tv);
144
145 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");
146 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n",
147 (skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec);
148
149#ifdef BCM_SHM_INTERFACE
150 spin_lock(&Adapter->txtransmitlock);
151 if(Adapter->txtransmit_running == 0)
152 {
153 Adapter->txtransmit_running = 1;
154 calltransmit = 1;
155 }
156 else
157 calltransmit = 0;
158
159 spin_unlock(&Adapter->txtransmitlock);
160#endif
161 if(calltransmit == 1)
162 transmit_packets(Adapter);
163 else
164 {
165 if(!atomic_read(&Adapter->TxPktAvail))
166 {
167 atomic_set(&Adapter->TxPktAvail, 1);
168#ifdef BCM_SHM_INTERFACE
169 virtual_mail_box_interrupt();
170#endif
171 wake_up(&Adapter->tx_packet_wait_queue);
172 }
173 }
174 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<====");
175 }
176 else
177 bcm_kfree_skb(skb);
178
179 return STATUS_SUCCESS;
180}
181
182
183/**
184@ingroup ctrl_pkt_functions
185This function dispatches control packet to the h/w interface
186@return zero(success) or -ve value(failure)
187*/
188INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
189 char *pControlPacket/**<Control Packet*/
190 )
191{
192 PLEADER PLeader = NULL;
193 struct timeval tv;
194 memset(&tv, 0, sizeof(tv));
195
196
197
198 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "========>");
199
200 PLeader=(PLEADER)pControlPacket;
201 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
202 if(!pControlPacket || !Adapter)
203 {
204 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter");
205 return STATUS_FAILURE;
206 }
207 if((atomic_read( &Adapter->CurrNumFreeTxDesc ) <
208 ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
209 {
210 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
211 if(Adapter->bcm_jiffies == 0)
212 {
213 Adapter->bcm_jiffies = jiffies;
214 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu",
215 Adapter->bcm_jiffies);
216 }
217 return STATUS_FAILURE;
218 }
219
220 /* Update the netdevice statistics */
221 /* Dump Packet */
222 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
223 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid);
224 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
225 if(Adapter->device_removed)
226 return 0;
227#ifndef BCM_SHM_INTERFACE
228 Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
229 pControlPacket, (PLeader->PLength + LEADER_SIZE));
230#else
231 tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1);
232
233 if(PLeader->Status==IDLE_MESSAGE)
234 {
235 if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD &&
236 ((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)
237 {
238 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n");
239 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n");
240 do_gettimeofday(&tv);
241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "IdleMode Msg sent to f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
242 if(Adapter->bDoSuspend != TRUE)
243 {
244 Adapter->IdleMode = TRUE;
245 Adapter->bPreparingForLowPowerMode = FALSE ;
246 }
247 }
248 }
249 if((PLeader->Status == LINK_UP_CONTROL_REQ) &&
250 ((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK &&
251 ((PUCHAR)pControlPacket)[sizeof(LEADER)+1] ==
252 LINK_SHUTDOWN_REQ_FROM_FIRMWARE &&
253 ((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER)
254 {
255 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n");
256 if(Adapter->bDoSuspend != TRUE)
257 {
258 Adapter->bShutStatus = TRUE;
259 Adapter->bPreparingForLowPowerMode = FALSE;
260 Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
261 }
262
263 }
264#endif
265
266 ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++;
267 ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+=
268 PLeader->PLength;
269 atomic_dec(&Adapter->CurrNumFreeTxDesc);
270 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
271 return STATUS_SUCCESS;
272}
273static LEADER Leader={0};
274/**
275@ingroup tx_functions
276This function despatches the IP packets with the given vcid
277to the target via the host h/w interface.
278@return zero(success) or -ve value(failure)
279*/
280INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
281 struct sk_buff *Packet, /**<data buffer*/
282 USHORT Vcid) /**<VCID for this packet*/
283{
284 int status=0;
285#ifdef GDMA_INTERFACE
286 int dontfree = 0;
287#endif
288 BOOLEAN bHeaderSupressionEnabled = FALSE;
289 B_UINT16 uiClassifierRuleID;
290 int QueueIndex = NO_OF_QUEUES + 1;
291
292 if(!Adapter || !Packet)
293 {
294 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet");
295 return -EINVAL;
296 }
297 if(Packet->len > MAX_DEVICE_DESC_SIZE)
298 {
299 status = STATUS_FAILURE;
300 goto errExit;
301 }
302
303 /* Get the Classifier Rule ID */
304 uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
305 QueueIndex = SearchVcid( Adapter,Vcid);
306 if(QueueIndex < NO_OF_QUEUES)
307 {
308 bHeaderSupressionEnabled =
309 Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
310 bHeaderSupressionEnabled =
311 bHeaderSupressionEnabled & Adapter->bPHSEnabled;
312 }
313 if(Adapter->device_removed)
314 {
315 status = STATUS_FAILURE;
316 goto errExit;
317 }
318
319 status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
320 (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);
321
322 if(status != STATUS_SUCCESS)
323 {
324 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
325 goto errExit;
326 }
327
328 Leader.Vcid = Vcid;
329
330 if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
331 {
332 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n");
333 Leader.Status = LEADER_STATUS_TCP_ACK;
334 }
335 else
336 {
337 Leader.Status = LEADER_STATUS;
338 }
339
340 if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
341 {
342 Leader.PLength = Packet->len;
343 if(skb_headroom(Packet) < LEADER_SIZE)
344 {
345 if((status = skb_cow(Packet,LEADER_SIZE)))
346 {
347 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n");
348 goto errExit;
349 }
350 }
351 skb_push(Packet, LEADER_SIZE);
352 memcpy(Packet->data, &Leader, LEADER_SIZE);
353 }
354
355 else
356 {
357 Leader.PLength = Packet->len - ETH_HLEN;
358 memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
359 }
360
361 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len);
362 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid);
363
364#ifndef BCM_SHM_INTERFACE
365 status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
366 Packet->data, (Leader.PLength + LEADER_SIZE));
367#else
368 status = tx_pkts_to_firmware(Packet,Packet->len,0);
369#endif
370 if(status)
371 {
372 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n");
373 }
374 else
375 {
376 Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
377 atomic_add(Leader.PLength, &Adapter->GoodTxByteCount);
378 atomic_inc(&Adapter->TxTotalPacketCount);
379#ifdef GDMA_INTERFACE
380 dontfree = 1;
381#endif
382 }
383
384 atomic_dec(&Adapter->CurrNumFreeTxDesc);
385
386errExit:
387
388 if(STATUS_SUCCESS == status)
389 {
390 Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
391 Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
392 Adapter->PackInfo[QueueIndex].uiSentPackets++;
393 Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
394
395 atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
396#ifdef BCM_SHM_INTERFACE
397 if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0)
398 {
399 atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0);
400 }
401#endif
402 Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
403 }
404
405
406#ifdef GDMA_INTERFACE
407 if(!dontfree){
408 bcm_kfree_skb(Packet);
409 }
410#else
411 bcm_kfree_skb(Packet);
412#endif
413 return status;
414}
415
416/**
417@ingroup tx_functions
418Transmit thread
419*/
420int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
421 )
422{
423#ifndef BCM_SHM_INTERFACE
424 int status = 0;
425#endif
426
427 UINT calltransmit = 1;
428 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);
429
430
431 while(1)
432 {
433 if(Adapter->LinkUpStatus){
434 wait_event_timeout(Adapter->tx_packet_wait_queue,
435 ((atomic_read(&Adapter->TxPktAvail) &&
436 (MINIMUM_PENDING_DESCRIPTORS <
437 atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
438 (Adapter->device_removed == FALSE))) ||
439 (1 == Adapter->downloadDDR) || kthread_should_stop()
440#ifndef BCM_SHM_INTERFACE
441 || (TRUE == Adapter->bEndPointHalted)
442#endif
443 , msecs_to_jiffies(10));
444 }
445 else{
446 wait_event(Adapter->tx_packet_wait_queue,
447 ((atomic_read(&Adapter->TxPktAvail) &&
448 (MINIMUM_PENDING_DESCRIPTORS <
449 atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
450 (Adapter->device_removed == FALSE))) ||
451 (1 == Adapter->downloadDDR) || kthread_should_stop()
452#ifndef BCM_SHM_INTERFACE
453 || (TRUE == Adapter->bEndPointHalted)
454#endif
455 );
456 }
457
458 if(kthread_should_stop() || Adapter->device_removed)
459 {
460 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
461 Adapter->transmit_packet_thread = NULL;
462 return 0;
463 }
464
465#ifndef BCM_SHM_INTERFACE
466
467 if(Adapter->downloadDDR == 1)
468 {
469 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n");
470 Adapter->downloadDDR +=1;
471 status = download_ddr_settings(Adapter);
472 if(status)
473 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n");
474 continue;
475 }
476
477 //Check end point for halt/stall.
478 if(Adapter->bEndPointHalted == TRUE)
479 {
480 Bcm_clear_halt_of_endpoints(Adapter);
481 Adapter->bEndPointHalted = FALSE;
482 StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
483 }
484
485 if(Adapter->LinkUpStatus && !Adapter->IdleMode)
486 {
487 if(atomic_read(&Adapter->TotalPacketCount))
488 {
489 update_per_sf_desc_cnts(Adapter);
490 }
491 }
492#endif
493
494 if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
495 Adapter->LinkStatus == SYNC_UP_REQUEST &&
496 !Adapter->bSyncUpRequestSent)
497 {
498 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");
499 LinkMessage(Adapter);
500 }
501
502 if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount))
503 {
504 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");
505 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
506 Adapter->bWakeUpDevice = TRUE;
507 wake_up(&Adapter->process_rx_cntrlpkt);
508 }
509
510#ifdef BCM_SHM_INTERFACE
511 spin_lock_bh(&Adapter->txtransmitlock);
512 if(Adapter->txtransmit_running == 0)
513 {
514 Adapter->txtransmit_running = 1;
515 calltransmit = 1;
516 }
517 else
518 calltransmit = 0;
519 spin_unlock_bh(&Adapter->txtransmitlock);
520#endif
521
522 if(calltransmit)
523 transmit_packets(Adapter);
524
525 atomic_set(&Adapter->TxPktAvail, 0);
526 }
527 return 0;
528}
529
530#ifdef BCM_SHM_INTERFACE
531extern PMINI_ADAPTER psAdaptertest;
532void virtual_mail_box_interrupt(void)
533{
534
535#ifndef GDMA_INTERFACE
536 PUINT ptr = (PUINT)CPE_VIRTUAL_MAILBOX_REG;
537 UINT intval = (UINT)((*ptr & 0xFF00) >> 8);
538 if (intval != 0)
539 {
540 atomic_set(&psAdaptertest->CurrNumFreeTxDesc, intval);
541 atomic_set (&psAdaptertest->uiMBupdate, TRUE);
542
543 //make it to 0
544 *ptr = *ptr & 0xffff00ff;
545 }
546#endif
547}
548unsigned int total_tx_pkts_pending(void)
549{
550 return atomic_read(&psAdaptertest->TotalPacketCount);
551}
552
553#endif
554
555