GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / usb / Beceem_driver / src / Common / Transmit.c
blob3f1b1e1aa46a35a6bbb05e5159e0be0aa11c390c
1 /*
2 * Transmit.c
4 *Copyright (C) 2010 Beceem Communications, Inc.
6 *This program is free software: you can redistribute it and/or modify
7 *it under the terms of the GNU General Public License version 2 as
8 *published by the Free Software Foundation.
10 *This program is distributed in the hope that it will be useful,but
11 *WITHOUT ANY WARRANTY; without even the implied warranty of
12 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *See the GNU General Public License for more details.
15 *You should have received a copy of the GNU General Public License
16 *along with this program. If not, write to the Free Software Foundation, Inc.,
17 *51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 /**
22 @file Transmit.c
23 @defgroup tx_functions Transmission
24 @section Queueing
25 @dot
26 digraph transmit1 {
27 node[shape=box]
28 edge[weight=5;color=red]
29 bcm_transmit->reply_to_arp_request[label="ARP"]
30 bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
31 GetPacketQueueIndex->IpVersion4[label="IPV4"]
32 GetPacketQueueIndex->IpVersion6[label="IPV6"]
35 @enddot
37 @section De-Queueing
38 @dot
39 digraph transmit2 {
40 node[shape=box]
41 edge[weight=5;color=red]
42 interrupt_service_thread->transmit_packets
43 tx_pkt_hdler->transmit_packets
44 transmit_packets->CheckAndSendPacketFromIndex
45 transmit_packets->UpdateTokenCount
46 CheckAndSendPacketFromIndex->PruneQueue
47 CheckAndSendPacketFromIndex->IsPacketAllowedForFlow
48 CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]
49 SendControlPacket->bcm_cmd53
50 CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]
51 SendPacketFromQueue->SetupNextSend->bcm_cmd53
53 @enddot
56 #include <headers.h>
58 /*******************************************************************
59 * Function - bcm_transmit()
61 * Description - This is the main transmit function for our virtual
62 * interface(veth0). It handles the ARP packets. It
63 * clones this packet and then Queue it to a suitable
64 * Queue. Then calls the transmit_packet().
66 * Parameter - skb - Pointer to the socket buffer structure
67 * dev - Pointer to the virtual net device structure
69 * Returns - zero (success) or -ve value (failure)
71 *********************************************************************/
73 INT bcm_transmit(struct sk_buff *skb, /**< skb */
74 struct net_device *dev /**< net device pointer */
77 PMINI_ADAPTER Adapter = NULL;
78 USHORT qindex=0;
79 struct timeval tv;
80 UINT pkt_type = 0;
81 UINT calltransmit = 0;
82 INT status = STATUS_SUCCESS;
84 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__);
86 memset(&tv, 0, sizeof(tv));
87 /* Check for valid parameters */
88 if(skb == NULL || dev==NULL)
90 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n");
91 return -EINVAL;
94 Adapter = GET_BCM_ADAPTER(dev);
95 if(!Adapter)
97 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n");
98 status = -EINVAL;
99 goto exit_path;
101 if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus)
103 if(!netif_queue_stopped(dev)) {
104 netif_carrier_off(dev);
105 netif_stop_queue(dev);
107 status = STATUS_FAILURE;
108 goto exit_path;
110 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len);
112 /*Add Ethernet CS check here*/
113 if(Adapter->TransferMode == IP_PACKET_ONLY_MODE )
115 pkt_type = ntohs(*(PUSHORT)(skb->data + 12));
116 /* Get the queue index where the packet is to be queued */
117 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index.....");
119 qindex = GetPacketQueueIndex(Adapter,skb);
121 if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex)
123 if(pkt_type == ETH_ARP_FRAME)
126 Reply directly to ARP request packet
127 ARP Spoofing only if NO ETH CS rule matches for it
129 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x",
131 (*(PUCHAR)(skb->data + 21)));
133 reply_to_arp_request(skb);
135 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n");
138 else
140 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,
141 "Invalid queue index, dropping pkt\n");
142 status = STATUS_FAILURE;
144 goto exit_path;
147 if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
149 atomic_inc(&Adapter->TxDroppedPacketCount);
150 status = STATUS_FAILURE;
151 goto exit_path;
154 /* Now Enqueue the packet */
155 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex);
156 spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
157 Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
158 Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
160 *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies;
161 ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
162 Adapter->PackInfo[qindex].LastTxQueue, skb);
163 atomic_inc(&Adapter->TotalPacketCount);
164 spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
165 do_gettimeofday(&tv);
167 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");
168 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n",
169 (skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec);
171 #ifdef BCM_SHM_INTERFACE
172 spin_lock(&Adapter->txtransmitlock);
173 if(Adapter->txtransmit_running == 0)
175 Adapter->txtransmit_running = 1;
176 calltransmit = 1;
178 else
179 calltransmit = 0;
181 spin_unlock(&Adapter->txtransmitlock);
182 #endif
183 if(calltransmit == 1)
184 transmit_packets(Adapter);
185 else
187 if(!atomic_read(&Adapter->TxPktAvail))
189 atomic_set(&Adapter->TxPktAvail, 1);
190 #ifdef BCM_SHM_INTERFACE
191 virtual_mail_box_interrupt();
192 #endif
193 wake_up(&Adapter->tx_packet_wait_queue);
196 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<====");
198 else
199 status = STATUS_FAILURE;
201 exit_path:
203 if(status != STATUS_SUCCESS)
204 bcm_kfree_skb(skb);
206 /* It is expected to return the correct status if running in cut-through mode */
208 if(Adapter->bNetworkInterfaceRegistered == FALSE)
209 return status;
211 /* It is expected to return as Success for Network Stack
212 - This will ensure that the packet is owned by the driver which shall free the same*/
214 else
215 return STATUS_SUCCESS;
221 @ingroup ctrl_pkt_functions
222 This function dispatches control packet to the h/w interface
223 @return zero(success) or -ve value(failure)
225 INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
226 char *pControlPacket/**<Control Packet*/
229 PLEADER PLeader = NULL;
230 struct timeval tv;
231 memset(&tv, 0, sizeof(tv));
235 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "========>");
237 PLeader=(PLEADER)pControlPacket;
238 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
239 if(!pControlPacket || !Adapter)
241 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter");
242 return STATUS_FAILURE;
244 if((atomic_read( &Adapter->CurrNumFreeTxDesc ) <
245 ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
247 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
248 if(Adapter->bcm_jiffies == 0)
250 Adapter->bcm_jiffies = jiffies;
251 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu",
252 Adapter->bcm_jiffies);
254 return STATUS_FAILURE;
257 /* Update the netdevice statistics */
258 /* Dump Packet */
259 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
260 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid);
261 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
262 if(Adapter->device_removed)
263 return 0;
264 #ifndef BCM_SHM_INTERFACE
265 Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
266 pControlPacket, (PLeader->PLength + LEADER_SIZE));
267 #else
268 tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1);
270 if(PLeader->Status==IDLE_MESSAGE)
272 if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD &&
273 ((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)
275 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n");
276 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n");
277 do_gettimeofday(&tv);
278 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);
279 if(Adapter->bDoSuspend != TRUE)
281 Adapter->IdleMode = TRUE;
282 Adapter->bPreparingForLowPowerMode = FALSE ;
286 if((PLeader->Status == LINK_UP_CONTROL_REQ) &&
287 ((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK &&
288 ((PUCHAR)pControlPacket)[sizeof(LEADER)+1] ==
289 LINK_SHUTDOWN_REQ_FROM_FIRMWARE &&
290 ((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER)
292 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n");
293 if(Adapter->bDoSuspend != TRUE)
295 Adapter->bShutStatus = TRUE;
296 Adapter->bPreparingForLowPowerMode = FALSE;
297 Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
301 #endif
303 ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++;
304 ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+=
305 PLeader->PLength;
306 atomic_dec(&Adapter->CurrNumFreeTxDesc);
307 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
308 return STATUS_SUCCESS;
310 static LEADER Leader={0};
312 @ingroup tx_functions
313 This function despatches the IP packets with the given vcid
314 to the target via the host h/w interface.
315 @return zero(success) or -ve value(failure)
317 INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
318 struct sk_buff *Packet, /**<data buffer*/
319 USHORT Vcid) /**<VCID for this packet*/
321 int status=0;
322 #ifdef GDMA_INTERFACE
323 int dontfree = 0;
324 #endif
325 BOOLEAN bHeaderSupressionEnabled = FALSE;
326 B_UINT16 uiClassifierRuleID;
327 int QueueIndex = NO_OF_QUEUES + 1;
328 B_UINT32 time_spent_on_host = 0 ;
329 if(!Adapter || !Packet)
331 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet");
332 return -EINVAL;
334 if(Packet->len > MAX_DEVICE_DESC_SIZE)
336 status = STATUS_FAILURE;
337 goto errExit;
340 /* Get the Classifier Rule ID */
341 uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
342 QueueIndex = SearchVcid( Adapter,Vcid);
343 if(QueueIndex < NO_OF_QUEUES)
345 bHeaderSupressionEnabled =
346 Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
347 bHeaderSupressionEnabled =
348 bHeaderSupressionEnabled & Adapter->bPHSEnabled;
350 if(Adapter->device_removed)
352 status = STATUS_FAILURE;
353 goto errExit;
356 status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
357 (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);
359 if(status != STATUS_SUCCESS)
361 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
362 goto errExit;
365 Leader.Vcid = Vcid;
367 if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
369 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n");
370 Leader.Status = LEADER_STATUS_TCP_ACK;
372 else
374 Leader.Status = LEADER_STATUS;
377 if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
379 Leader.PLength = Packet->len;
380 if(skb_headroom(Packet) < LEADER_SIZE)
382 if((status = skb_cow(Packet,LEADER_SIZE)))
384 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n");
385 goto errExit;
388 skb_push(Packet, LEADER_SIZE);
389 memcpy(Packet->data, &Leader, LEADER_SIZE);
392 else
394 Leader.PLength = Packet->len - ETH_HLEN;
395 memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
398 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len);
399 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid);
401 #ifndef BCM_SHM_INTERFACE
402 status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
403 Packet->data, (Leader.PLength + LEADER_SIZE));
404 #else
405 status = tx_pkts_to_firmware(Packet,Packet->len,0);
406 #endif
407 if(status)
409 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n");
411 else
413 Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
414 atomic_add(Leader.PLength, &Adapter->GoodTxByteCount);
415 atomic_inc(&Adapter->TxTotalPacketCount);
416 #ifdef GDMA_INTERFACE
417 dontfree = 1;
418 #endif
423 time_spent_on_host = jiffies - *((UINT32*) (Packet->cb) + SKB_CB_LATENCY_OFFSET);
424 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_TIME_SPENT_IN_HOST, DBG_LVL_ALL, "TIME SPENT ON HOST :%#X \n",time_spent_on_host);
425 atomic_dec(&Adapter->CurrNumFreeTxDesc);
427 errExit:
429 if(STATUS_SUCCESS == status)
431 Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
432 Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
433 Adapter->PackInfo[QueueIndex].uiSentPackets++;
434 Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
436 atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
437 #ifdef BCM_SHM_INTERFACE
438 if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0)
440 atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0);
442 #endif
443 Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
447 #ifdef GDMA_INTERFACE
448 if(!dontfree){
449 bcm_kfree_skb(Packet);
451 #else
452 bcm_kfree_skb(Packet);
453 #endif
454 return status;
459 @ingroup tx_functions
460 Transmit thread
462 int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
466 #ifndef BCM_SHM_INTERFACE
467 int status = 0;
468 #endif
470 UINT calltransmit = 1;
471 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = 0x%x",(unsigned int) Adapter);
474 while(1)
476 if(Adapter->LinkUpStatus){
477 wait_event_timeout(Adapter->tx_packet_wait_queue,
478 ((atomic_read(&Adapter->TxPktAvail) &&
479 (MINIMUM_PENDING_DESCRIPTORS <
480 atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
481 (Adapter->device_removed == FALSE))) ||
482 (1 == Adapter->uiFirstInterrupt) || kthread_should_stop()
483 #ifndef BCM_SHM_INTERFACE
484 || (TRUE == Adapter->bEndPointHalted)
485 #endif
486 , msecs_to_jiffies(10));
488 else{
489 wait_event(Adapter->tx_packet_wait_queue,
490 ((atomic_read(&Adapter->TxPktAvail) &&
491 (MINIMUM_PENDING_DESCRIPTORS <
492 atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
493 (Adapter->device_removed == FALSE))) ||
494 (1 == Adapter->uiFirstInterrupt) || kthread_should_stop()
495 #ifndef BCM_SHM_INTERFACE
496 || (TRUE == Adapter->bEndPointHalted)
497 #endif
501 if(kthread_should_stop() || Adapter->device_removed)
503 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
504 Adapter->transmit_packet_thread = NULL;
505 return 0;
509 if(Adapter->uiFirstInterrupt == 1)
511 SetUpTargetDsxBuffers(Adapter);
512 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Seting DSX...\n");
513 Adapter->uiFirstInterrupt +=1;
514 #ifndef BCM_SHM_INTERFACE
515 status = download_ddr_settings(Adapter);
516 if(status)
517 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n");
518 #endif
519 continue;
521 #ifndef BCM_SHM_INTERFACE
522 //Check end point for halt/stall.
523 if(Adapter->bEndPointHalted == TRUE)
525 Bcm_clear_halt_of_endpoints(Adapter);
526 Adapter->bEndPointHalted = FALSE;
527 StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
530 if(Adapter->LinkUpStatus && !Adapter->IdleMode)
532 if(atomic_read(&Adapter->TotalPacketCount))
534 update_per_sf_desc_cnts(Adapter);
537 #endif
539 if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
540 Adapter->LinkStatus == SYNC_UP_REQUEST &&
541 !Adapter->bSyncUpRequestSent)
543 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");
544 LinkMessage(Adapter);
547 if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount))
549 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");
550 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
551 Adapter->bWakeUpDevice = TRUE;
552 wake_up(&Adapter->process_rx_cntrlpkt);
555 #ifdef BCM_SHM_INTERFACE
556 spin_lock_bh(&Adapter->txtransmitlock);
557 if(Adapter->txtransmit_running == 0)
559 Adapter->txtransmit_running = 1;
560 calltransmit = 1;
562 else
563 calltransmit = 0;
564 spin_unlock_bh(&Adapter->txtransmitlock);
565 #endif
567 if(calltransmit)
568 transmit_packets(Adapter);
570 atomic_set(&Adapter->TxPktAvail, 0);
572 return 0;
575 #ifdef BCM_SHM_INTERFACE
576 extern PMINI_ADAPTER psAdaptertest;
577 void virtual_mail_box_interrupt(void)
580 #ifndef GDMA_INTERFACE
581 PUINT ptr = (PUINT)CPE_VIRTUAL_MAILBOX_REG;
582 UINT intval = (UINT)((*ptr & 0xFF00) >> 8);
583 if (intval != 0)
585 atomic_set(&psAdaptertest->CurrNumFreeTxDesc, intval);
586 atomic_set (&psAdaptertest->uiMBupdate, TRUE);
588 //make it to 0
589 *ptr = *ptr & 0xffff00ff;
591 #endif
593 unsigned int total_tx_pkts_pending(void)
595 return atomic_read(&psAdaptertest->TotalPacketCount);
598 #endif