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.
23 @defgroup tx_functions Transmission
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"]
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
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
;
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");
94 Adapter
= GET_BCM_ADAPTER(dev
);
97 BCM_DEBUG_PRINT (Adapter
, DBG_TYPE_TX
, TX_OSAL_DBG
, DBG_LVL_ALL
, "Got Invalid Adapter\n");
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
;
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");
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
;
147 if(Adapter
->PackInfo
[qindex
].uiCurrentPacketsOnHost
>= SF_MAX_ALLOWED_PACKETS_TO_BACKUP
)
149 atomic_inc(&Adapter
->TxDroppedPacketCount
);
150 status
= STATUS_FAILURE
;
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;
181 spin_unlock(&Adapter
->txtransmitlock
);
183 if(calltransmit
== 1)
184 transmit_packets(Adapter
);
187 if(!atomic_read(&Adapter
->TxPktAvail
))
189 atomic_set(&Adapter
->TxPktAvail
, 1);
190 #ifdef BCM_SHM_INTERFACE
191 virtual_mail_box_interrupt();
193 wake_up(&Adapter
->tx_packet_wait_queue
);
196 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_OSAL_DBG
, DBG_LVL_ALL
, "<====");
199 status
= STATUS_FAILURE
;
203 if(status
!= STATUS_SUCCESS
)
206 /* It is expected to return the correct status if running in cut-through mode */
208 if(Adapter
->bNetworkInterfaceRegistered
== FALSE
)
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*/
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
;
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 */
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
)
264 #ifndef BCM_SHM_INTERFACE
265 Adapter
->interface_transmit(Adapter
->pvInterfaceAdapter
,
266 pControlPacket
, (PLeader
->PLength
+ LEADER_SIZE
));
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
;
303 ((PLINUX_DEP_DATA
)Adapter
->pvOsDepData
)->netstats
.tx_packets
++;
304 ((PLINUX_DEP_DATA
)Adapter
->pvOsDepData
)->netstats
.tx_bytes
+=
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*/
322 #ifdef GDMA_INTERFACE
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");
334 if(Packet
->len
> MAX_DEVICE_DESC_SIZE
)
336 status
= STATUS_FAILURE
;
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
;
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");
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
;
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");
388 skb_push(Packet
, LEADER_SIZE
);
389 memcpy(Packet
->data
, &Leader
, LEADER_SIZE
);
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
));
405 status
= tx_pkts_to_firmware(Packet
,Packet
->len
,0);
409 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, NEXT_SEND
, DBG_LVL_ALL
, "Tx Failed..\n");
413 Adapter
->PackInfo
[QueueIndex
].uiTotalTxBytes
+= Leader
.PLength
;
414 atomic_add(Leader
.PLength
, &Adapter
->GoodTxByteCount
);
415 atomic_inc(&Adapter
->TxTotalPacketCount
);
416 #ifdef GDMA_INTERFACE
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
);
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);
443 Adapter
->PackInfo
[QueueIndex
].uiThisPeriodSentBytes
+= Leader
.PLength
;
447 #ifdef GDMA_INTERFACE
449 bcm_kfree_skb(Packet
);
452 bcm_kfree_skb(Packet
);
459 @ingroup tx_functions
462 int tx_pkt_handler(PMINI_ADAPTER Adapter
/**< pointer to adapter object*/
466 #ifndef BCM_SHM_INTERFACE
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
);
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
)
486 , msecs_to_jiffies(10));
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
)
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
;
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
);
517 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "DDR DOWNLOAD FAILED!\n");
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
);
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;
564 spin_unlock_bh(&Adapter
->txtransmitlock
);
568 transmit_packets(Adapter
);
570 atomic_set(&Adapter
->TxPktAvail
, 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);
585 atomic_set(&psAdaptertest
->CurrNumFreeTxDesc
, intval
);
586 atomic_set (&psAdaptertest
->uiMBupdate
, TRUE
);
589 *ptr
= *ptr
& 0xffff00ff;
593 unsigned int total_tx_pkts_pending(void)
595 return atomic_read(&psAdaptertest
->TotalPacketCount
);