diff options
Diffstat (limited to 'drivers/staging/bcm/Transmit.c')
| -rw-r--r-- | drivers/staging/bcm/Transmit.c | 616 |
1 files changed, 153 insertions, 463 deletions
diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 12f9e13457d..49767468ac2 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -1,555 +1,245 @@ /** -@file Transmit.c -@defgroup tx_functions Transmission -@section Queueing -@dot -digraph transmit1 { -node[shape=box] -edge[weight=5;color=red] -bcm_transmit->reply_to_arp_request[label="ARP"] -bcm_transmit->GetPacketQueueIndex[label="IP Packet"] -GetPacketQueueIndex->IpVersion4[label="IPV4"] -GetPacketQueueIndex->IpVersion6[label="IPV6"] -} - -@enddot - -@section De-Queueing -@dot -digraph transmit2 { -node[shape=box] -edge[weight=5;color=red] -interrupt_service_thread->transmit_packets -tx_pkt_hdler->transmit_packets -transmit_packets->CheckAndSendPacketFromIndex -transmit_packets->UpdateTokenCount -CheckAndSendPacketFromIndex->PruneQueue -CheckAndSendPacketFromIndex->IsPacketAllowedForFlow -CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] -SendControlPacket->bcm_cmd53 -CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] -SendPacketFromQueue->SetupNextSend->bcm_cmd53 -} -@enddot -*/ + * @file Transmit.c + * @defgroup tx_functions Transmission + * @section Queueing + * @dot + * digraph transmit1 { + * node[shape=box] + * edge[weight=5;color=red] + * + * bcm_transmit->GetPacketQueueIndex[label="IP Packet"] + * GetPacketQueueIndex->IpVersion4[label="IPV4"] + * GetPacketQueueIndex->IpVersion6[label="IPV6"] + * } + * + * @enddot + * + * @section De-Queueing + * @dot + * digraph transmit2 { + * node[shape=box] + * edge[weight=5;color=red] + * interrupt_service_thread->transmit_packets + * tx_pkt_hdler->transmit_packets + * transmit_packets->CheckAndSendPacketFromIndex + * transmit_packets->UpdateTokenCount + * CheckAndSendPacketFromIndex->PruneQueue + * CheckAndSendPacketFromIndex->IsPacketAllowedForFlow + * CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] + * SendControlPacket->bcm_cmd53 + * CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] + * SendPacketFromQueue->SetupNextSend->bcm_cmd53 + * } + * @enddot + */ #include "headers.h" -/******************************************************************* -* Function - bcm_transmit() -* -* Description - This is the main transmit function for our virtual -* interface(veth0). It handles the ARP packets. It -* clones this packet and then Queue it to a suitable -* Queue. Then calls the transmit_packet(). -* -* Parameter - skb - Pointer to the socket buffer structure -* dev - Pointer to the virtual net device structure -* -* Returns - zero (success) or -ve value (failure) -* -*********************************************************************/ - -INT bcm_transmit(struct sk_buff *skb, /**< skb */ - struct net_device *dev /**< net device pointer */ - ) +/** + * @ingroup ctrl_pkt_functions + * This function dispatches control packet to the h/w interface + * @return zero(success) or -ve value(failure) + */ +int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) { - PMINI_ADAPTER Adapter = NULL; - USHORT qindex=0; - struct timeval tv; - UINT pkt_type = 0; - UINT calltransmit = 0; - - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__); - - memset(&tv, 0, sizeof(tv)); - /* Check for valid parameters */ - if(skb == NULL || dev==NULL) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n"); - return -EINVAL; - } + struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; - Adapter = GET_BCM_ADAPTER(dev); - if(!Adapter) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n"); - return -EINVAL; - } - if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus) - { - if(!netif_queue_stopped(dev)) { - netif_carrier_off(dev); - netif_stop_queue(dev); - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); + if (!pControlPacket || !Adapter) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, + "Got NULL Control Packet or Adapter"); return STATUS_FAILURE; } - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len); - - /*Add Ethernet CS check here*/ - if(Adapter->TransferMode == IP_PACKET_ONLY_MODE ) - { - pkt_type = ntohs(*(PUSHORT)(skb->data + 12)); - /* Get the queue index where the packet is to be queued */ - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index....."); - - qindex = GetPacketQueueIndex(Adapter,skb); - - if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex) - { - if(pkt_type == ETH_ARP_FRAME) - { - /* - Reply directly to ARP request packet - ARP Spoofing only if NO ETH CS rule matches for it - */ - BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x", - - (*(PUCHAR)(skb->data + 21))); - - reply_to_arp_request(skb); - - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n"); - - } - else - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, - "Invalid queue index, dropping pkt\n"); - - bcm_kfree_skb(skb); - } - return STATUS_SUCCESS; - } - - if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) - { - atomic_inc(&Adapter->TxDroppedPacketCount); - bcm_kfree_skb(skb); - return STATUS_SUCCESS; - } - - /* Now Enqueue the packet */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex); - spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); - Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; - Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++; - - *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies; - ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue, - Adapter->PackInfo[qindex].LastTxQueue, skb); - atomic_inc(&Adapter->TotalPacketCount); - spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock); - do_gettimeofday(&tv); - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n", - (skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec); - -#ifdef BCM_SHM_INTERFACE - spin_lock(&Adapter->txtransmitlock); - if(Adapter->txtransmit_running == 0) - { - Adapter->txtransmit_running = 1; - calltransmit = 1; - } - else - calltransmit = 0; - - spin_unlock(&Adapter->txtransmitlock); -#endif - if(calltransmit == 1) - transmit_packets(Adapter); - else - { - if(!atomic_read(&Adapter->TxPktAvail)) - { - atomic_set(&Adapter->TxPktAvail, 1); -#ifdef BCM_SHM_INTERFACE - virtual_mail_box_interrupt(); -#endif - wake_up(&Adapter->tx_packet_wait_queue); - } - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<===="); - } - else - bcm_kfree_skb(skb); - - return STATUS_SUCCESS; -} - - -/** -@ingroup ctrl_pkt_functions -This function dispatches control packet to the h/w interface -@return zero(success) or -ve value(failure) -*/ -INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/ - char *pControlPacket/**<Control Packet*/ - ) -{ - PLEADER PLeader = NULL; - struct timeval tv; - memset(&tv, 0, sizeof(tv)); - - - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "========>"); - - PLeader=(PLEADER)pControlPacket; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); - if(!pControlPacket || !Adapter) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter"); + if ((atomic_read(&Adapter->CurrNumFreeTxDesc) < + ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, + "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); return STATUS_FAILURE; } - if((atomic_read( &Adapter->CurrNumFreeTxDesc ) < - ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); - if(Adapter->bcm_jiffies == 0) - { - Adapter->bcm_jiffies = jiffies; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu", - Adapter->bcm_jiffies); - } - return STATUS_FAILURE; - } /* Update the netdevice statistics */ /* Dump Packet */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength); - if(Adapter->device_removed) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x", PLeader->Vcid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x", PLeader->PLength); + if (Adapter->device_removed) return 0; -#ifndef BCM_SHM_INTERFACE - Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - pControlPacket, (PLeader->PLength + LEADER_SIZE)); -#else - tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1); - - if(PLeader->Status==IDLE_MESSAGE) - { - if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD && - ((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n"); - do_gettimeofday(&tv); - 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); - if(Adapter->bDoSuspend != TRUE) - { - Adapter->IdleMode = TRUE; - Adapter->bPreparingForLowPowerMode = FALSE ; - } - } - } - if((PLeader->Status == LINK_UP_CONTROL_REQ) && - ((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK && - ((PUCHAR)pControlPacket)[sizeof(LEADER)+1] == - LINK_SHUTDOWN_REQ_FROM_FIRMWARE && - ((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n"); - if(Adapter->bDoSuspend != TRUE) - { - Adapter->bShutStatus = TRUE; - Adapter->bPreparingForLowPowerMode = FALSE; - Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; - } - } -#endif + if (netif_msg_pktdata(Adapter)) + print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE, + 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0); + + Adapter->interface_transmit(Adapter->pvInterfaceAdapter, + pControlPacket, (PLeader->PLength + LEADER_SIZE)); - ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++; - ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+= - PLeader->PLength; atomic_dec(&Adapter->CurrNumFreeTxDesc); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<========="); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<========="); return STATUS_SUCCESS; } -static LEADER Leader={0}; + /** -@ingroup tx_functions -This function despatches the IP packets with the given vcid -to the target via the host h/w interface. -@return zero(success) or -ve value(failure) -*/ -INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/ - struct sk_buff *Packet, /**<data buffer*/ - USHORT Vcid) /**<VCID for this packet*/ + * @ingroup tx_functions + * This function despatches the IP packets with the given vcid + * to the target via the host h/w interface. + * @return zero(success) or -ve value(failure) + */ +int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid) { - int status=0; -#ifdef GDMA_INTERFACE - int dontfree = 0; -#endif - BOOLEAN bHeaderSupressionEnabled = FALSE; - B_UINT16 uiClassifierRuleID; - int QueueIndex = NO_OF_QUEUES + 1; - - if(!Adapter || !Packet) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet"); - return -EINVAL; - } - if(Packet->len > MAX_DEVICE_DESC_SIZE) - { + int status = 0; + bool bHeaderSupressionEnabled = false; + B_UINT16 uiClassifierRuleID; + u16 QueueIndex = skb_get_queue_mapping(Packet); + struct bcm_leader Leader = {0}; + + if (Packet->len > MAX_DEVICE_DESC_SIZE) { status = STATUS_FAILURE; goto errExit; } /* Get the Classifier Rule ID */ - uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET); - QueueIndex = SearchVcid( Adapter,Vcid); - if(QueueIndex < NO_OF_QUEUES) - { - bHeaderSupressionEnabled = - Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; - bHeaderSupressionEnabled = - bHeaderSupressionEnabled & Adapter->bPHSEnabled; - } - if(Adapter->device_removed) - { + uiClassifierRuleID = *((UINT32 *) (Packet->cb) + SKB_CB_CLASSIFICATION_OFFSET); + + bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled + & Adapter->bPHSEnabled; + + if (Adapter->device_removed) { status = STATUS_FAILURE; goto errExit; - } + } status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled, - (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport); + (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport); - if(status != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n"); + if (status != STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, + "PHS Transmit failed..\n"); goto errExit; } - Leader.Vcid = Vcid; + Leader.Vcid = Vcid; - if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET )) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n"); + if (TCP_ACK == *((UINT32 *) (Packet->cb) + SKB_CB_TCPACK_OFFSET)) Leader.Status = LEADER_STATUS_TCP_ACK; - } else - { Leader.Status = LEADER_STATUS; - } - if(Adapter->PackInfo[QueueIndex].bEthCSSupport) - { + if (Adapter->PackInfo[QueueIndex].bEthCSSupport) { Leader.PLength = Packet->len; - if(skb_headroom(Packet) < LEADER_SIZE) - { - if((status = skb_cow(Packet,LEADER_SIZE))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n"); + if (skb_headroom(Packet) < LEADER_SIZE) { + status = skb_cow(Packet, LEADER_SIZE); + if (status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n"); goto errExit; } } skb_push(Packet, LEADER_SIZE); memcpy(Packet->data, &Leader, LEADER_SIZE); - } - - else - { + } else { Leader.PLength = Packet->len - ETH_HLEN; - memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); + memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid); - -#ifndef BCM_SHM_INTERFACE status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - Packet->data, (Leader.PLength + LEADER_SIZE)); -#else - status = tx_pkts_to_firmware(Packet,Packet->len,0); -#endif - if(status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n"); - } - else - { + Packet->data, (Leader.PLength + LEADER_SIZE)); + if (status) { + ++Adapter->dev->stats.tx_errors; + if (netif_msg_tx_err(Adapter)) + pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name, + status); + } else { + struct net_device_stats *netstats = &Adapter->dev->stats; Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; - atomic_add(Leader.PLength, &Adapter->GoodTxByteCount); - atomic_inc(&Adapter->TxTotalPacketCount); -#ifdef GDMA_INTERFACE - dontfree = 1; -#endif - } - - atomic_dec(&Adapter->CurrNumFreeTxDesc); -errExit: + netstats->tx_bytes += Leader.PLength; + ++netstats->tx_packets; - if(STATUS_SUCCESS == status) - { Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3; Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len); Adapter->PackInfo[QueueIndex].uiSentPackets++; Adapter->PackInfo[QueueIndex].NumOfPacketsSent++; atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount); -#ifdef BCM_SHM_INTERFACE - if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0) - { - atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0); - } -#endif Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength; } + atomic_dec(&Adapter->CurrNumFreeTxDesc); -#ifdef GDMA_INTERFACE - if(!dontfree){ - bcm_kfree_skb(Packet); - } -#else - bcm_kfree_skb(Packet); -#endif +errExit: + dev_kfree_skb(Packet); return status; } +static int tx_pending(struct bcm_mini_adapter *Adapter) +{ + return (atomic_read(&Adapter->TxPktAvail) + && MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc)) + || Adapter->device_removed || (1 == Adapter->downloadDDR); +} + /** -@ingroup tx_functions -Transmit thread -*/ -int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ - ) + * @ingroup tx_functions + * Transmit thread + */ +int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/) { -#ifndef BCM_SHM_INTERFACE int status = 0; -#endif - - UINT calltransmit = 1; - 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); - - while(1) - { - if(Adapter->LinkUpStatus){ + while (!kthread_should_stop()) { + /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */ + if (Adapter->LinkUpStatus) wait_event_timeout(Adapter->tx_packet_wait_queue, - ((atomic_read(&Adapter->TxPktAvail) && - (MINIMUM_PENDING_DESCRIPTORS < - atomic_read(&Adapter->CurrNumFreeTxDesc)) && - (Adapter->device_removed == FALSE))) || - (1 == Adapter->downloadDDR) || kthread_should_stop() -#ifndef BCM_SHM_INTERFACE - || (TRUE == Adapter->bEndPointHalted) -#endif - , msecs_to_jiffies(10)); - } - else{ - wait_event(Adapter->tx_packet_wait_queue, - ((atomic_read(&Adapter->TxPktAvail) && - (MINIMUM_PENDING_DESCRIPTORS < - atomic_read(&Adapter->CurrNumFreeTxDesc)) && - (Adapter->device_removed == FALSE))) || - (1 == Adapter->downloadDDR) || kthread_should_stop() -#ifndef BCM_SHM_INTERFACE - || (TRUE == Adapter->bEndPointHalted) -#endif - ); - } - - if(kthread_should_stop() || Adapter->device_removed) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); - Adapter->transmit_packet_thread = NULL; - return 0; - } + tx_pending(Adapter), msecs_to_jiffies(10)); + else + wait_event_interruptible(Adapter->tx_packet_wait_queue, + tx_pending(Adapter)); -#ifndef BCM_SHM_INTERFACE + if (Adapter->device_removed) + break; - if(Adapter->downloadDDR == 1) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n"); - Adapter->downloadDDR +=1; + if (Adapter->downloadDDR == 1) { + Adapter->downloadDDR += 1; status = download_ddr_settings(Adapter); - if(status) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n"); + if (status) + pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status); continue; } - //Check end point for halt/stall. - if(Adapter->bEndPointHalted == TRUE) - { + /* Check end point for halt/stall. */ + if (Adapter->bEndPointHalted == TRUE) { Bcm_clear_halt_of_endpoints(Adapter); - Adapter->bEndPointHalted = FALSE; - StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + Adapter->bEndPointHalted = false; + StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); } - if(Adapter->LinkUpStatus && !Adapter->IdleMode) - { - if(atomic_read(&Adapter->TotalPacketCount)) - { + if (Adapter->LinkUpStatus && !Adapter->IdleMode) { + if (atomic_read(&Adapter->TotalPacketCount)) update_per_sf_desc_cnts(Adapter); - } } -#endif - if( atomic_read(&Adapter->CurrNumFreeTxDesc) && + if (atomic_read(&Adapter->CurrNumFreeTxDesc) && Adapter->LinkStatus == SYNC_UP_REQUEST && - !Adapter->bSyncUpRequestSent) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage"); - LinkMessage(Adapter); - } + !Adapter->bSyncUpRequestSent) { - if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up"); - Adapter->usIdleModePattern = ABORT_IDLE_MODE; - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, + DBG_LVL_ALL, "Calling LinkMessage"); + LinkMessage(Adapter); } -#ifdef BCM_SHM_INTERFACE - spin_lock_bh(&Adapter->txtransmitlock); - if(Adapter->txtransmit_running == 0) - { - Adapter->txtransmit_running = 1; - calltransmit = 1; + if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, + TX_PACKETS, DBG_LVL_ALL, + "Device in Low Power mode...waking up"); + Adapter->usIdleModePattern = ABORT_IDLE_MODE; + Adapter->bWakeUpDevice = TRUE; + wake_up(&Adapter->process_rx_cntrlpkt); } - else - calltransmit = 0; - spin_unlock_bh(&Adapter->txtransmitlock); -#endif - - if(calltransmit) - transmit_packets(Adapter); + transmit_packets(Adapter); atomic_set(&Adapter->TxPktAvail, 0); } - return 0; -} - -#ifdef BCM_SHM_INTERFACE -extern PMINI_ADAPTER psAdaptertest; -void virtual_mail_box_interrupt(void) -{ - -#ifndef GDMA_INTERFACE - PUINT ptr = (PUINT)CPE_VIRTUAL_MAILBOX_REG; - UINT intval = (UINT)((*ptr & 0xFF00) >> 8); - if (intval != 0) - { - atomic_set(&psAdaptertest->CurrNumFreeTxDesc, intval); - atomic_set (&psAdaptertest->uiMBupdate, TRUE); - //make it to 0 - *ptr = *ptr & 0xffff00ff; - } -#endif -} -unsigned int total_tx_pkts_pending(void) -{ - return atomic_read(&psAdaptertest->TotalPacketCount); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, + "Exiting the tx thread..\n"); + Adapter->transmit_packet_thread = NULL; + return 0; } - -#endif - - |
