static void read_bulk_callback(struct urb *urb) { struct sk_buff *skb = NULL; BOOLEAN bHeaderSupressionEnabled = FALSE; int QueueIndex = NO_OF_QUEUES + 1; UINT uiIndex=0; int process_done = 1; PUSB_RCB pRcb = (PUSB_RCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter; PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; PLEADER pLeader = urb->transfer_buffer; if (unlikely(netif_msg_rx_status(Adapter))) pr_info(PFX "%s: rx urb status %d length %d\n", Adapter->dev->name, urb->status, urb->actual_length); if((Adapter->device_removed == TRUE) || (TRUE == Adapter->bEndPointHalted) || (0 == urb->actual_length) ) { pRcb->bUsed = FALSE; atomic_dec(&psIntfAdapter->uNumRcbUsed); return; } if(urb->status != STATUS_SUCCESS) { if(urb->status == -EPIPE) { Adapter->bEndPointHalted = TRUE ; wake_up(&Adapter->tx_packet_wait_queue); } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status); } pRcb->bUsed = FALSE; atomic_dec(&psIntfAdapter->uNumRcbUsed); urb->status = STATUS_SUCCESS ; return ; } if(Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"device is going in low power mode while PMU option selected..hence rx packet should not be process"); return ; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength); if(!pLeader->PLength) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0"); atomic_dec(&psIntfAdapter->uNumRcbUsed); return; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid); if(MAX_CNTL_PKT_SIZE < pLeader->PLength) { if (netif_msg_rx_err(Adapter)) pr_info(PFX "%s: corrupted leader length...%d\n", Adapter->dev->name, pLeader->PLength); ++Adapter->dev->stats.rx_dropped; atomic_dec(&psIntfAdapter->uNumRcbUsed); return; } QueueIndex = SearchVcid( Adapter,pLeader->Vcid); if(QueueIndex < NO_OF_QUEUES) { bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; bHeaderSupressionEnabled = bHeaderSupressionEnabled & Adapter->bPHSEnabled; } skb = dev_alloc_skb (pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER); if(!skb) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet"); atomic_dec(&psIntfAdapter->uNumRcbUsed); return; } if((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Received control pkt..."); *(PUSHORT)skb->data = pLeader->Status; memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + (sizeof(LEADER)), pLeader->PLength); skb->len = pLeader->PLength + sizeof(USHORT); spin_lock(&Adapter->control_queue_lock); ENQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail,skb); spin_unlock(&Adapter->control_queue_lock); atomic_inc(&Adapter->cntrlpktCnt); wake_up(&Adapter->process_rx_cntrlpkt); } else { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt..."); skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(LEADER), pLeader->PLength); skb->dev = Adapter->dev; skb_put (skb, pLeader->PLength + ETH_HLEN); Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength; Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength; BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt of len :0x%X", pLeader->PLength); if(netif_running(Adapter->dev)) { skb_pull(skb, ETH_HLEN); PHSReceive(Adapter, pLeader->Vcid, skb, &skb->len, NULL,bHeaderSupressionEnabled); if(!Adapter->PackInfo[QueueIndex].bEthCSSupport) { skb_push(skb, ETH_HLEN); memcpy(skb->data, skb->dev->dev_addr, 6); memcpy(skb->data+6, skb->dev->dev_addr, 6); (*(skb->data+11))++; *(skb->data+12) = 0x08; *(skb->data+13) = 0x00; pLeader->PLength+=ETH_HLEN; } skb->protocol = eth_type_trans(skb, Adapter->dev); process_done = netif_rx(skb); } else { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB..."); dev_kfree_skb(skb); } ++Adapter->dev->stats.rx_packets; Adapter->dev->stats.rx_bytes += pLeader->PLength; for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) { if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) Adapter->aRxPktSizeHist[uiIndex]++; } } Adapter->PrevNumRecvDescs++; pRcb->bUsed = FALSE; atomic_dec(&psIntfAdapter->uNumRcbUsed); }
/** @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*/ { int status=0; #ifdef GDMA_INTERFACE int dontfree = 0; #endif BOOLEAN bHeaderSupressionEnabled = FALSE; B_UINT16 uiClassifierRuleID; int QueueIndex = NO_OF_QUEUES + 1; B_UINT32 time_spent_on_host = 0 ; 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) { 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) { status = STATUS_FAILURE; goto errExit; } status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled, (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"); goto errExit; } 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"); Leader.Status = LEADER_STATUS_TCP_ACK; } else { Leader.Status = LEADER_STATUS; } 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"); goto errExit; } } skb_push(Packet, LEADER_SIZE); memcpy(Packet->data, &Leader, LEADER_SIZE); } else { Leader.PLength = Packet->len - ETH_HLEN; memcpy((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 { Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; atomic_add(Leader.PLength, &Adapter->GoodTxByteCount); atomic_inc(&Adapter->TxTotalPacketCount); #ifdef GDMA_INTERFACE dontfree = 1; #endif } time_spent_on_host = jiffies - *((UINT32*) (Packet->cb) + SKB_CB_LATENCY_OFFSET); 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); atomic_dec(&Adapter->CurrNumFreeTxDesc); errExit: 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; } #ifdef GDMA_INTERFACE if(!dontfree){ bcm_kfree_skb(Packet); } #else bcm_kfree_skb(Packet); #endif return status; }